From 72d96b5f54dd5a94df1721e82d8765407256d285 Mon Sep 17 00:00:00 2001 From: "Glitch (neroio2)" Date: Sat, 27 Apr 2024 20:01:20 +0000 Subject: [PATCH 01/15] =?UTF-8?q?=F0=9F=A7=86=F0=9F=97=A8=EF=B8=8F=20Updat?= =?UTF-8?q?ed=20with=20Glitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 4 - .glitch-assets | 190 + LICENSE | 687 +- README.md | 5 +- animation.d.ts | 144 + changelog preview | 499 + features.md | 2 +- images/favicon.png | Bin 0 -> 81775 bytes images/girb.jpg | Bin 0 -> 327303 bytes images/lratio.png | Bin 0 -> 66360 bytes images/neroshitpost.png | Bin 0 -> 192370 bytes images/othergirb.jpg | Bin 0 -> 48408 bytes install.sh | 2 +- neroplayer/script.js | 86 + neroplayer/stylesheet.css | 14 + neroplayer/visual.html | 15 + package-lock.json | 47 - package.json | 6 +- public/app.js | 1326 ++- public/changelog.html | 524 +- public/credits.html | 104 + public/favicon.ico | Bin 21654 -> 225726 bytes public/icon32x32.png | Bin 1898 -> 0 bytes public/index.html | 549 +- public/lib/canvas.js | 93 +- public/lib/color.js | 58 +- public/lib/gameDraw.js | 48 +- public/lib/global.js | 134 +- public/lib/json/color.json | 29 + public/lib/json/manifest.json | 10 +- public/lib/settings.js | 2 +- public/lib/socketInit.js | 28 +- public/lib/tankdesc.js | 545 + public/lib/util.js | 21 +- public/main.css | 1194 +- public/osa_background_tile.png | Bin 748 -> 0 bytes public/round.png | Bin 25179 -> 0 bytes run.bat => public/run.bat | 0 server/config.js | 66 +- server/index.js | 26 +- server/lib/random.js | 2 +- server/modules/debug/speedLoop.js | 3 + server/modules/definitions/addons/amongus.js | 108 + .../definitions/addons/basicChatModeration.js | 3 +- server/modules/definitions/addons/cooper.js | 30 + .../modules/definitions/addons/dailyTanks.js | 1687 +++ server/modules/definitions/addons/dreadv1.js | 64 +- server/modules/definitions/addons/dreadv2.js | 214 +- .../definitions/addons/exampleAddon.js | 2 +- .../definitions/addons/geometryDashDart.js | 72 + server/modules/definitions/addons/labyFood.js | 2 +- server/modules/definitions/addons/lancer.js | 663 ++ .../modules/definitions/addons/playerskins.js | 175 + .../definitions/addons/revolutionistPack.js | 186 + .../definitions/addons/woomeraddonmeow.js | 64 + server/modules/definitions/combined.js | 2 +- server/modules/definitions/constants.js | 6 + server/modules/definitions/facilitators.js | 202 +- server/modules/definitions/groups/bosses.js | 5886 +++++----- server/modules/definitions/groups/dev.js | 1436 ++- server/modules/definitions/groups/food.js | 157 +- server/modules/definitions/groups/generics.js | 15 +- server/modules/definitions/groups/misc.js | 36 +- .../modules/definitions/groups/projectiles.js | 423 +- server/modules/definitions/groups/tanks.js | 9708 ++++++++++------- server/modules/definitions/groups/turrets.js | 433 +- server/modules/definitions/gunvals.js | 65 +- server/modules/gamemodes/maze.js | 2 +- server/modules/global.js | 8 +- server/modules/live/controllers.js | 83 +- server/modules/live/entity.js | 99 +- server/modules/network/sockets.js | 190 +- server/modules/physics/collisionFunctions.js | 138 +- server/modules/setup/rooms/map_apspp_maze.js | 26 + .../modules/setup/rooms/map_apspp_tiletest.js | 42 - .../modules/setup/rooms/map_neroio_arena.js | 27 + .../modules/setup/rooms/map_neroio_banquet.js | 29 + .../setup/rooms/map_neroio_mazearena.js | 27 + .../modules/setup/rooms/overlay_domination.js | 4 +- server/modules/setup/tiles/decoration.js | 29 +- server/modules/setup/tiles/misc.js | 100 +- server/modules/setup/tiles/siege.js | 2 +- server/modules/setup/tiles/tdm.js | 3 +- server/permissions.js | 2 +- shit/randomstuff/aasfsdgsdg | 1 + shit/randomstuff/asajhwerkji | 25 + shit/randomstuff/jfsdfn | 27 + shit/temp/backuo | 2351 ++++ shit/temp/changelog template | 26 + shit/temp/changes | 512 + shit/temp/gifbackround | 33 + shit/temp/music | 20 + shit/temp/mytankcount | 13 + shit/temp/stuff | 137 + shit/temp/woomycolorname | 3 + 95 files changed, 23698 insertions(+), 8363 deletions(-) delete mode 100644 .env create mode 100644 .glitch-assets create mode 100644 animation.d.ts create mode 100644 changelog preview create mode 100644 images/favicon.png create mode 100644 images/girb.jpg create mode 100644 images/lratio.png create mode 100644 images/neroshitpost.png create mode 100644 images/othergirb.jpg mode change 100755 => 100644 install.sh create mode 100644 neroplayer/script.js create mode 100644 neroplayer/stylesheet.css create mode 100644 neroplayer/visual.html delete mode 100644 package-lock.json create mode 100644 public/credits.html delete mode 100644 public/icon32x32.png create mode 100644 public/lib/tankdesc.js delete mode 100644 public/osa_background_tile.png delete mode 100644 public/round.png rename run.bat => public/run.bat (100%) create mode 100644 server/modules/definitions/addons/amongus.js create mode 100644 server/modules/definitions/addons/cooper.js create mode 100644 server/modules/definitions/addons/dailyTanks.js create mode 100644 server/modules/definitions/addons/geometryDashDart.js create mode 100644 server/modules/definitions/addons/lancer.js create mode 100644 server/modules/definitions/addons/playerskins.js create mode 100644 server/modules/definitions/addons/revolutionistPack.js create mode 100644 server/modules/definitions/addons/woomeraddonmeow.js create mode 100644 server/modules/setup/rooms/map_apspp_maze.js delete mode 100644 server/modules/setup/rooms/map_apspp_tiletest.js create mode 100644 server/modules/setup/rooms/map_neroio_arena.js create mode 100644 server/modules/setup/rooms/map_neroio_banquet.js create mode 100644 server/modules/setup/rooms/map_neroio_mazearena.js create mode 100644 shit/randomstuff/aasfsdgsdg create mode 100644 shit/randomstuff/asajhwerkji create mode 100644 shit/randomstuff/jfsdfn create mode 100644 shit/temp/backuo create mode 100644 shit/temp/changelog template create mode 100644 shit/temp/changes create mode 100644 shit/temp/gifbackround create mode 100644 shit/temp/music create mode 100644 shit/temp/mytankcount create mode 100644 shit/temp/stuff create mode 100644 shit/temp/woomycolorname diff --git a/.env b/.env deleted file mode 100644 index 153edd43b..000000000 --- a/.env +++ /dev/null @@ -1,4 +0,0 @@ -TOKEN_1=ExampleToken1 -TOKEN_2=ExampleToken2 -TOKEN_3=ExampleToken3 -TOKEN_4=ExampleToken4 diff --git a/.glitch-assets b/.glitch-assets new file mode 100644 index 000000000..d84afb22e --- /dev/null +++ b/.glitch-assets @@ -0,0 +1,190 @@ +{"name":"2023_10_10_0rf_Kleki.png","date":"2023-10-10T18:58:08.611Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_10_0rf_Kleki.png","type":"image/png","size":30464,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_10_0rf_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"UP44Oex8WvGywkCD"} +{"name":"6avWH55.jpg","date":"2023-10-25T12:45:16.390Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6avWH55.jpg","type":"image/jpeg","size":327303,"imageWidth":2500,"imageHeight":1667,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6avWH55.jpg","thumbnailWidth":330,"thumbnailHeight":221,"uuid":"o6pEXEUSnOPqm4bg"} +{"name":"4073e372df1399336a01c51052a1bbd8.jpg","date":"2023-10-25T13:01:09.623Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4073e372df1399336a01c51052a1bbd8.jpg","type":"image/jpeg","size":48408,"imageWidth":960,"imageHeight":649,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4073e372df1399336a01c51052a1bbd8.jpg","thumbnailWidth":330,"thumbnailHeight":224,"uuid":"w9ZO2wxV83aWhelI"} +{"name":"58563194-553c-49ae-95db-441b06bf9bef.image.png","date":"2023-10-25T13:19:20.463Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/58563194-553c-49ae-95db-441b06bf9bef.image.png","type":"image/png","size":76850,"imageWidth":360,"imageHeight":240,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F58563194-553c-49ae-95db-441b06bf9bef.image.png","thumbnailWidth":330,"thumbnailHeight":220,"uuid":"RsOUyfm1cBYSqbw0"} +{"uuid":"o6pEXEUSnOPqm4bg","deleted":true} +{"name":"girb.jpg","date":"2023-10-25T12:45:16.390Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/girb.jpg","type":"image/jpeg","size":327303,"imageWidth":2500,"imageHeight":1667,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6avWH55.jpg","thumbnailWidth":330,"thumbnailHeight":221,"uuid":"o6pEXEUSnOPqm4bg"} +{"uuid":"w9ZO2wxV83aWhelI","deleted":true} +{"name":"othergirb.jpg","date":"2023-10-25T13:01:09.623Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/othergirb.jpg","type":"image/jpeg","size":48408,"imageWidth":960,"imageHeight":649,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4073e372df1399336a01c51052a1bbd8.jpg","thumbnailWidth":330,"thumbnailHeight":224,"uuid":"w9ZO2wxV83aWhelI"} +{"name":"131107152744-mona-lisa.jpg","date":"2023-10-26T11:10:16.817Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/131107152744-mona-lisa.jpg","type":"image/jpeg","size":747095,"imageWidth":2000,"imageHeight":3000,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F131107152744-mona-lisa.jpg","thumbnailWidth":220,"thumbnailHeight":330,"uuid":"YM7ULs8ieFPfkHTh"} +{"name":"2022_06_23_11e_Kleki.png","date":"2023-10-26T11:10:22.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2022_06_23_11e_Kleki.png","type":"image/png","size":66360,"imageWidth":1009,"imageHeight":601,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2022_06_23_11e_Kleki.png","thumbnailWidth":330,"thumbnailHeight":197,"uuid":"CKrqEXVr9r1fWHQ6"} +{"name":"84812d435b246f4edffe887c5f755008.jpg","date":"2023-10-26T11:10:27.584Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/84812d435b246f4edffe887c5f755008.jpg","type":"image/jpeg","size":111067,"imageWidth":924,"imageHeight":1000,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F84812d435b246f4edffe887c5f755008.jpg","thumbnailWidth":305,"thumbnailHeight":330,"uuid":"iKniUyyIl8sambKK"} +{"name":"videoplayback.mp4","date":"2023-10-26T11:10:49.863Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp4","type":"video/mp4","size":2106277,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"txSk7RsRJ33ZgL0R"} +{"name":"IMG_0316.webp","date":"2023-10-26T11:20:34.628Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_0316.webp","type":"image/webp","size":12986,"imageWidth":640,"imageHeight":494,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_0316.webp","thumbnailWidth":330,"thumbnailHeight":255,"uuid":"ULDBE338jPz5CztZ"} +{"name":"devil vortex.jpg","date":"2023-10-26T11:23:31.448Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/devil%20vortex.jpg","type":"image/jpeg","size":70977,"imageWidth":2048,"imageHeight":1070,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdevil%20vortex.jpg","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"rwxaYBQQ3Vdh4GOB"} +{"uuid":"CKrqEXVr9r1fWHQ6","deleted":true} +{"name":"lratio","date":"2023-10-26T11:10:22.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/lratio","type":"image/png","size":66360,"imageWidth":1009,"imageHeight":601,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2022_06_23_11e_Kleki.png","thumbnailWidth":330,"thumbnailHeight":197,"uuid":"CKrqEXVr9r1fWHQ6"} +{"name":"mqdefault.jpg","date":"2023-10-26T15:51:05.241Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/mqdefault.jpg","type":"image/jpeg","size":8165,"imageWidth":320,"imageHeight":180,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/mqdefault.jpg","thumbnailWidth":320,"thumbnailHeight":180,"uuid":"vUoqYUUmAaCJlbFE"} +{"name":"e4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","date":"2023-10-26T15:52:48.829Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","type":"image/png","size":667529,"imageWidth":970,"imageHeight":750,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fe4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","thumbnailWidth":330,"thumbnailHeight":256,"uuid":"2TdCgTp1qJy5VpQF"} +{"name":"4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","date":"2023-10-26T15:56:52.346Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","type":"image/png","size":13711,"imageWidth":295,"imageHeight":247,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","thumbnailWidth":295,"thumbnailHeight":247,"uuid":"vB57dbf5e3LDGNTc"} +{"name":"9fbac25f-6710-4a95-b963-502275ff8728.image.png","date":"2023-10-26T16:03:48.998Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/9fbac25f-6710-4a95-b963-502275ff8728.image.png","type":"image/png","size":5638,"imageWidth":218,"imageHeight":157,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/9fbac25f-6710-4a95-b963-502275ff8728.image.png","thumbnailWidth":218,"thumbnailHeight":157,"uuid":"AUYt8QpAyhIjzDDo"} +{"uuid":"AUYt8QpAyhIjzDDo","deleted":true} +{"name":"2023_10_26_0ml_Kleki.png","date":"2023-10-26T16:04:27.088Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_26_0ml_Kleki.png","type":"image/png","size":6063,"imageWidth":218,"imageHeight":157,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_26_0ml_Kleki.png","thumbnailWidth":218,"thumbnailHeight":157,"uuid":"XrOWUvHhmVrkljWG"} +{"name":"b6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","date":"2023-10-26T16:06:40.232Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/b6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","type":"image/png","size":155677,"imageWidth":480,"imageHeight":480,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fb6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"ctTmChYwrALlsYSY"} +{"name":"asda.gif","date":"2023-10-26T16:07:13.205Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/asda.gif","type":"image/gif","size":2414319,"imageWidth":1160,"imageHeight":653,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fasda.gif","thumbnailWidth":330,"thumbnailHeight":186,"uuid":"DrNyvjoahVRfPqfc"} +{"name":"freddy.gif","date":"2023-10-26T16:07:33.397Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/freddy.gif","type":"image/gif","size":3807320,"imageWidth":480,"imageHeight":480,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffreddy.gif","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"JZgBnLYoTvZmoiEm"} +{"name":"poop-emoji.jpg","date":"2023-11-27T16:55:26.682Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/poop-emoji.jpg","type":"image/jpeg","size":277135,"imageWidth":1200,"imageHeight":1200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fpoop-emoji.jpg","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"Cb4D9nc5184NLZWn"} +{"name":"Screen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","date":"2023-11-27T16:55:33.660Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","type":"image/webp","size":34994,"imageWidth":1400,"imageHeight":788,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","thumbnailWidth":330,"thumbnailHeight":186,"uuid":"ZVERuCeCDI11tY8f"} +{"name":"videoplayback (5).mp4","date":"2023-11-30T20:09:06.159Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(5).mp4","type":"video/mp4","size":5225498,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(5).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"x22blklePMGQRwIA"} +{"name":"afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","date":"2023-12-01T17:04:48.242Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","type":"image/jpeg","size":673888,"imageWidth":2048,"imageHeight":1365,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fafg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","thumbnailWidth":330,"thumbnailHeight":220,"uuid":"DjbeeYPv58kWZxGT"} +{"name":"Papyrus.webp","date":"2023-12-01T17:04:54.185Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp","type":"image/webp","size":22528,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FPapyrus.webp","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"1oCUTGTCUHSm6Rht"} +{"name":"videoplayback (6).mp4","date":"2023-12-04T12:01:19.895Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(6).mp4","type":"video/mp4","size":107238,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(6).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sKgj926hemecxf1z"} +{"name":"nerd-emoji.gif","date":"2023-12-04T12:10:45.734Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nerd-emoji.gif","type":"image/gif","size":58415,"imageWidth":200,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nerd-emoji.gif","thumbnailWidth":200,"thumbnailHeight":200,"uuid":"IEWg3jT2scnmIEBa"} +{"name":"IMG_20231204_144411762_LAYER.jpg","date":"2023-12-04T18:20:34.323Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144411762_LAYER.jpg","type":"image/jpeg","size":4291465,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144411762_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"kHofB34sB8zK8ghc"} +{"name":"IMG_20231204_144409218_LAYER.jpg","date":"2023-12-04T18:20:37.274Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144409218_LAYER.jpg","type":"image/jpeg","size":4649997,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144409218_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"wy3sATUDmtO4UKav"} +{"name":"IMG_20231204_144406913_LAYER.jpg","date":"2023-12-04T18:20:40.278Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144406913_LAYER.jpg","type":"image/jpeg","size":4663414,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144406913_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"VVnb7tpycOZ96wIM"} +{"name":"IMG_20231204_144358408_LAYER.jpg","date":"2023-12-04T18:20:43.765Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144358408_LAYER.jpg","type":"image/jpeg","size":4910430,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144358408_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"298PzLlhaFIqxxcq"} +{"name":"2023_12_05_0sn_Kleki.png","date":"2023-12-05T20:41:21.532Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_05_0sn_Kleki.png","type":"image/png","size":9872,"imageWidth":91,"imageHeight":93,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_05_0sn_Kleki.png","thumbnailWidth":91,"thumbnailHeight":93,"uuid":"lzgyLwxKAAQT4aRa"} +{"name":"2023_12_06_0yp_Kleki.png","date":"2023-12-07T00:24:27.560Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yp_Kleki.png","type":"image/png","size":70691,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yp_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"lq8MCR84TekmbueY"} +{"name":"2023_12_06_0yt_Kleki.png","date":"2023-12-07T00:24:47.196Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yt_Kleki.png","type":"image/png","size":81775,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yt_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"ggXSa8BNzRjqSBnD"} +{"name":"2023_12_06_0yl_Kleki.png","date":"2023-12-07T00:25:10.293Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png","type":"image/png","size":84439,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"YAFhahkJBvHvomAo"} +{"name":"2023_12_06_0yi_Kleki.png","date":"2023-12-07T00:30:14.507Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yi_Kleki.png","type":"image/png","size":87010,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yi_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"dvm2XAnEJNmrlaoJ"} +{"name":"2023_12_06_0yh_Kleki.png","date":"2023-12-07T00:30:19.835Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yh_Kleki.png","type":"image/png","size":87060,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yh_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"RakITIBsTZAoxn6J"} +{"name":"2023_12_06_0yb_Kleki.png","date":"2023-12-07T00:30:29.284Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yb_Kleki.png","type":"image/png","size":75357,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yb_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"EvxT6uRiwx18Z2e8"} +{"name":"2023_12_06_0za_Kleki.png","date":"2023-12-07T00:49:05.704Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png","type":"image/png","size":72696,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"aoroY4SW6zapPfOE"} +{"name":"2023_12_08_0g8_Kleki.png","date":"2023-12-08T13:15:13.341Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_08_0g8_Kleki.png","type":"image/png","size":142882,"imageWidth":1117,"imageHeight":607,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2023_12_08_0g8_Kleki.png","thumbnailWidth":330,"thumbnailHeight":180,"uuid":"iRH2k0fN1Gx4DUk1"} +{"name":"MOSHED-2023-11-2-9-15-39.gif","date":"2023-12-12T12:59:58.261Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-15-39.gif","type":"image/gif","size":9742202,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-15-39.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"52P1expoZSM3Z2bZ"} +{"name":"MOSHED-2023-11-2-9-16-18.jpg","date":"2023-12-12T13:00:04.817Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-16-18.jpg","type":"image/jpeg","size":122406,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-16-18.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"VyBWbHyBZeQDkCqK"} +{"name":"MOSHED-2023-11-2-9-16-30.jpg","date":"2023-12-12T13:00:12.253Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-16-30.jpg","type":"image/jpeg","size":194318,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-16-30.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"ccSREI092qAxPu6K"} +{"name":"MOSHED-2023-11-2-9-17-44.gif","date":"2023-12-12T13:00:21.674Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-17-44.gif","type":"image/gif","size":8254208,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-17-44.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"vThvLihG3U4Tva8u"} +{"name":"MOSHED-2023-11-2-9-18-42.gif","date":"2023-12-12T13:00:29.800Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-18-42.gif","type":"image/gif","size":22820370,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-18-42.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"Aei1r7CUxV9JTPGZ"} +{"name":"MOSHED-2023-11-2-9-19-19.jpg","date":"2023-12-12T13:00:34.450Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-19-19.jpg","type":"image/jpeg","size":102760,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-19-19.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"lp7GBZ7NYag3ZEM5"} +{"name":"MOSHED-2023-11-2-9-22-40.gif","date":"2023-12-12T13:00:45.756Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-22-40.gif","type":"image/gif","size":13789663,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-22-40.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"b3XRVsDg7Qv5QFYZ"} +{"name":"MOSHED-2023-11-2-9-24-47.gif","date":"2023-12-12T13:00:51.248Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-24-47.gif","type":"image/gif","size":6092682,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-24-47.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"9TjxQT7jJYwEwQZb"} +{"uuid":"Aei1r7CUxV9JTPGZ","deleted":true} +{"name":"MOSHED-2023-11-2-9-18-42.gif","date":"2023-12-12T13:07:15.262Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-18-42.gif","type":"image/gif","size":22820370,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-18-42.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"mFh1JnSydzXR12gh"} +{"uuid":"mFh1JnSydzXR12gh","deleted":true} +{"name":"MOSHED-2023-12-12-10-47-6.gif","date":"2023-12-12T14:17:22.498Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-47-6.gif","type":"image/gif","size":11089695,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-47-6.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"kEzXuIpHEELcAuHJ"} +{"name":"MOSHED-2023-12-12-10-46-41.gif","date":"2023-12-12T14:17:26.360Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-46-41.gif","type":"image/gif","size":12491342,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-46-41.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"MjoGdc3z87JYHYl4"} +{"name":"MOSHED-2023-12-12-10-42-0.gif","date":"2023-12-12T14:17:29.599Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-42-0.gif","type":"image/gif","size":8559279,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-42-0.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"orEDVirkk7HGAjwX"} +{"name":"MOSHED-2023-12-12-10-39-41.gif","date":"2023-12-12T14:17:33.878Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-39-41.gif","type":"image/gif","size":6042203,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-39-41.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"soSGGxLRe87PpUyB"} +{"name":"MOSHED-2023-12-12-10-37-55.gif","date":"2023-12-12T14:17:36.549Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-37-55.gif","type":"image/gif","size":1825419,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-37-55.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"suIcEXpXCuqgBnhb"} +{"uuid":"suIcEXpXCuqgBnhb","deleted":true} +{"uuid":"soSGGxLRe87PpUyB","deleted":true} +{"uuid":"orEDVirkk7HGAjwX","deleted":true} +{"uuid":"MjoGdc3z87JYHYl4","deleted":true} +{"uuid":"kEzXuIpHEELcAuHJ","deleted":true} +{"uuid":"9TjxQT7jJYwEwQZb","deleted":true} +{"uuid":"b3XRVsDg7Qv5QFYZ","deleted":true} +{"uuid":"lp7GBZ7NYag3ZEM5","deleted":true} +{"uuid":"vThvLihG3U4Tva8u","deleted":true} +{"uuid":"ccSREI092qAxPu6K","deleted":true} +{"uuid":"VyBWbHyBZeQDkCqK","deleted":true} +{"uuid":"52P1expoZSM3Z2bZ","deleted":true} +{"name":"fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","date":"2024-01-14T21:10:07.867Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","type":"image/png","size":2376,"imageWidth":96,"imageHeight":96,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","thumbnailWidth":96,"thumbnailHeight":96,"uuid":"uuaOAwjEVYE8UjTl"} +{"name":"oioioi.mp3","date":"2024-01-15T02:47:10.033Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3","type":"audio/mpeg","size":7221396,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Foioioi.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"TLbSQQprOSopfHoY"} +{"name":"Depredation.mp3","date":"2024-01-15T02:47:46.890Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation.mp3","type":"audio/mpeg","size":8288129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"XfFWeHV5t1gcuE4J"} +{"name":"World's End.wav","date":"2024-01-15T02:48:09.038Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav","type":"audio/wav","size":33800236,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FWorld's%20End.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"nFvYO1N5f6xH8PgY"} +{"name":"4Miklipi (Dejected) Preview.mp3","date":"2024-01-15T02:50:22.417Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3","type":"audio/mpeg","size":4125377,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4Miklipi%20(Dejected)%20Preview.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"b0959XaAUwrm5DBm"} +{"name":"nero shitpost.png","date":"2024-01-15T03:46:10.363Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nero%20shitpost.png","type":"image/png","size":192370,"imageWidth":500,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fnero%20shitpost.png","thumbnailWidth":330,"thumbnailHeight":264,"uuid":"27bMMsSzzePzc4gx"} +{"name":"6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","date":"2024-01-15T04:04:38.159Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","type":"image/png","size":151618,"imageWidth":498,"imageHeight":498,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"BS5SvNlFUKcj0C0u"} +{"name":"look_closely.mp3","date":"2024-01-15T04:09:46.778Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/look_closely.mp3","type":"audio/mpeg","size":20922,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flook_closely.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"VlbLJHd2YrAkE8oQ"} +{"name":"e304fc26-480b-47b5-8270-949f7df44d92.image.png","date":"2024-01-15T04:58:22.951Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png","type":"image/png","size":85814,"imageWidth":298,"imageHeight":397,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fe304fc26-480b-47b5-8270-949f7df44d92.image.png","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"JndrzAvoYpyDCqAG"} +{"name":"toilet_flush.mp3","date":"2024-01-15T05:28:22.578Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/toilet_flush.mp3","type":"audio/mpeg","size":94293,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftoilet_flush.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"8EtOGgdbXaVQRsG2"} +{"name":"y2mate_HOnnyD0.mp3","date":"2024-01-15T05:28:25.126Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/y2mate_HOnnyD0.mp3","type":"audio/mpeg","size":50684,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fy2mate_HOnnyD0.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"gZIE2RUndOaeOkpY"} +{"name":"flowing-water-sound-effect.mp3","date":"2024-01-15T06:24:21.150Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/flowing-water-sound-effect.mp3","type":"audio/mpeg","size":164603,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fflowing-water-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"lFzb954crqkjqSxU"} +{"name":"pew_pew-dknight556-1379997159.mp3","date":"2024-01-15T06:26:15.747Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/pew_pew-dknight556-1379997159.mp3","type":"audio/mpeg","size":7551,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fpew_pew-dknight556-1379997159.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"wbsUbQ176JelACja"} +{"name":"2024_01_15_05q_Kleki.png","date":"2024-01-15T06:57:08.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png","type":"image/png","size":20218,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_15_05q_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"FSqPDlLinpE8Loxx"} +{"name":"chipi-chipi-chapa-chapa.mp3","date":"2024-01-15T07:13:52.837Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chipi-chipi-chapa-chapa.mp3","type":"audio/mpeg","size":192826,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchipi-chipi-chapa-chapa.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"yz3SmgjTHe6LnBrF"} +{"name":"neko-arc.mp3","date":"2024-01-15T07:13:55.953Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/neko-arc.mp3","type":"audio/mpeg","size":17901,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fneko-arc.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"u3PHWM6bxDbQa4Z4"} +{"name":"bwomp.mp3","date":"2024-01-15T07:13:59.344Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bwomp.mp3","type":"audio/mpeg","size":6765,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fbwomp.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ORPQeX8y3fWoNeC1"} +{"name":"nfl.mp3","date":"2024-01-15T07:14:03.389Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nfl.mp3","type":"audio/mpeg","size":300347,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fnfl.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ll5dGpaMX1dkzUAc"} +{"name":"Gear-icon-transparent-background.png","date":"2024-01-18T11:59:38.381Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png","type":"image/png","size":14537,"imageWidth":512,"imageHeight":512,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FGear-icon-transparent-background.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"kK6xzuT7nN8es5J9"} +{"name":"Untitled979_20240120123618.png","date":"2024-01-20T17:38:31.845Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled979_20240120123618.png","type":"image/png","size":14246,"imageWidth":350,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FUntitled979_20240120123618.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"izP72RmZ8nLYsSdc"} +{"name":"74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","date":"2024-01-20T17:39:19.444Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","type":"image/png","size":17060,"imageWidth":215,"imageHeight":196,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","thumbnailWidth":215,"thumbnailHeight":196,"uuid":"bJt3vCO1iQJAcPkv"} +{"name":"videoplayback.mp3","date":"2024-01-21T03:17:37.028Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3","type":"audio/mpeg","size":3451436,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"hFAccqiGuKtlcJVr"} +{"name":"jake-chudnow-edited_y1t8j5q.mp3","date":"2024-01-23T13:54:17.534Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jake-chudnow-edited_y1t8j5q.mp3","type":"audio/mpeg","size":340823,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fjake-chudnow-edited_y1t8j5q.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"KsmNUXrjFBTR9nnt"} +{"name":"MemeFeedBot_5.mp4","date":"2024-01-30T20:25:51.474Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MemeFeedBot_5.mp4","type":"video/mp4","size":1311719,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMemeFeedBot_5.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"reUPECkwcraGwOc3"} +{"name":"4 2.wav","date":"2024-01-31T15:49:21.860Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4%202.wav","type":"audio/wav","size":248118,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4%202.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"1E7gld9pLGXWDUC8"} +{"name":"Screen recording 2024-01-23 9.38.41 AM.webm","date":"2024-02-02T01:45:08.442Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screen%20recording%202024-01-23%209.38.41%20AM.webm","type":"video/webm","size":1616860,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreen%20recording%202024-01-23%209.38.41%20AM.webm","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"Lp97bNs9HjhFIlKp"} +{"name":"2024_02_01_112_Kleki.png","date":"2024-02-02T01:45:11.256Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_112_Kleki.png","type":"image/png","size":84804,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_112_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"QZfJ4aPwLpj3gxD9"} +{"name":"2024_02_01_10z_Kleki.png","date":"2024-02-02T01:45:15.168Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_10z_Kleki.png","type":"image/png","size":84316,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_10z_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"nDK0YapB9Y94CjO7"} +{"name":"2024_02_09_11n_Kleki.png","date":"2024-02-10T02:06:04.886Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_09_11n_Kleki.png","type":"image/png","size":53374,"imageWidth":218,"imageHeight":143,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_09_11n_Kleki.png","thumbnailWidth":218,"thumbnailHeight":143,"uuid":"KkGODJKzVOA9trS5"} +{"name":"2024_02_15_0qs_Kleki.png","date":"2024-02-15T19:34:53.434Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","type":"image/png","size":2051,"imageWidth":100,"imageHeight":100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","thumbnailWidth":100,"thumbnailHeight":100,"uuid":"b7U68EwE9UUNAsv8"} +{"uuid":"b7U68EwE9UUNAsv8","deleted":true} +{"name":"Trophy.png","date":"2024-02-15T19:34:53.434Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png","type":"image/png","size":2051,"imageWidth":100,"imageHeight":100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","thumbnailWidth":100,"thumbnailHeight":100,"uuid":"b7U68EwE9UUNAsv8"} +{"name":"download.mp3","date":"2024-02-18T01:07:44.295Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3","type":"audio/mpeg","size":9263777,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdownload.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"cCo9wkdNbXgR9VRm"} +{"name":"download (1).mp3","date":"2024-02-18T01:07:55.743Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3","type":"audio/mpeg","size":6227366,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdownload%20(1).mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"GUN6DCqlRr6SCsv0"} +{"name":"Untitled Project (22).jpg","date":"2024-02-19T15:27:04.097Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg","type":"image/jpeg","size":34686,"imageWidth":159,"imageHeight":159,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg","thumbnailWidth":159,"thumbnailHeight":159,"uuid":"QzQilm4F3P6jalgR"} +{"uuid":"x22blklePMGQRwIA","deleted":true} +{"name":"videoplayback (5).mp4","date":"2024-02-21T15:51:31.894Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(5).mp4","type":"video/mp4","size":2213386,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(5).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"q6L0WZWbnI2dyDzS"} +{"name":"arrow.png","date":"2024-02-21T17:00:37.425Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/arrow.png","type":"image/png","size":20446,"imageWidth":500,"imageHeight":500,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Farrow.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"ZUGJVJXduGCYUybX"} +{"name":"arrow2.png","date":"2024-02-21T17:00:40.066Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/arrow2.png","type":"image/png","size":20272,"imageWidth":500,"imageHeight":500,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Farrow2.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"vTxD8Cdq5AZzpZHG"} +{"name":"2024_01_29_0rx_Kleki.png","date":"2024-02-21T17:30:37.147Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0rx_Kleki.png","type":"image/png","size":44308,"imageWidth":512,"imageHeight":362,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0rx_Kleki.png","thumbnailWidth":330,"thumbnailHeight":234,"uuid":"RyxRk17SDpdmFzRs"} +{"uuid":"RyxRk17SDpdmFzRs","deleted":true} +{"name":"2024_01_29_0ry_Kleki.png","date":"2024-02-21T17:30:52.978Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png","type":"image/png","size":78166,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0ry_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"02ssJF2Tzrmn3sTQ"} +{"uuid":"02ssJF2Tzrmn3sTQ","deleted":true} +{"name":"2024_01_29_0rs_Kleki.png","date":"2024-02-21T17:31:06.919Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0rs_Kleki.png","type":"image/png","size":49959,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0rs_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"HqLijl5c1PuEAXz6"} +{"uuid":"HqLijl5c1PuEAXz6","deleted":true} +{"name":"2024_01_29_0ry_Kleki.png","date":"2024-02-21T17:31:20.813Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png","type":"image/png","size":78166,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0ry_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"teEHfjowTA5oXZNX"} +{"uuid":"ULDBE338jPz5CztZ","deleted":true} +{"name":"onetransparentsingulardamnfuckingpixel.png","date":"2024-02-22T02:16:19.353Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png","type":"image/png","size":81,"imageWidth":1,"imageHeight":1,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png","thumbnailWidth":1,"thumbnailHeight":1,"uuid":"ckPJEBh7eEJWdxnK"} +{"name":"primal.webp","date":"2024-02-22T11:52:43.032Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp","type":"image/webp","size":56824,"imageWidth":350,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fprimal.webp","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"cfHcvjVbbDfZh8xc"} +{"name":"image.webp","date":"2024-02-22T11:52:45.689Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","type":"image/webp","size":59336,"imageWidth":281,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fimage.webp","thumbnailWidth":265,"thumbnailHeight":330,"uuid":"9yXl5YIjYKceliFg"} +{"uuid":"ctTmChYwrALlsYSY","deleted":true} +{"name":"locked.png","date":"2024-02-22T11:55:29.342Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked.png","type":"image/png","size":18202,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"n8yNyvfqwb7DnXAi"} +{"name":"tv.png","date":"2024-02-22T15:17:55.011Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png","type":"image/png","size":106896,"imageWidth":600,"imageHeight":600,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftv.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"IZOWYASNX0WOguf8"} +{"name":"MOSHED-2023-12-14-17-8-14.gif","date":"2024-02-22T16:22:04.966Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif","type":"image/gif","size":710884,"imageWidth":182,"imageHeight":182,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif","thumbnailWidth":182,"thumbnailHeight":182,"uuid":"zoDYKbRylm4uPSua"} +{"name":"skype.png","date":"2024-02-22T16:23:57.464Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png","type":"image/png","size":135963,"imageWidth":2400,"imageHeight":2435,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fskype.png","thumbnailWidth":326,"thumbnailHeight":330,"uuid":"H8TxN9mqnMgaTfLw"} +{"name":"2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","date":"2024-02-22T16:25:46.196Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","type":"image/png","size":163198,"imageWidth":1200,"imageHeight":1200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"BETXanMl4Oa3nyk2"} +{"uuid":"9yXl5YIjYKceliFg","deleted":true} +{"uuid":"H8TxN9mqnMgaTfLw","deleted":true} +{"name":"skype.png","date":"2024-02-22T17:39:54.494Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png","type":"image/png","size":37427,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fskype.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"f8Ge23pxSgxIHP3y"} +{"name":"image.webp","date":"2024-02-22T17:39:56.560Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","type":"image/webp","size":76573,"imageWidth":300,"imageHeight":300,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","thumbnailWidth":300,"thumbnailHeight":300,"uuid":"T4mvFRGVmo7ZSS3r"} +{"name":"locked2.png","date":"2024-02-23T18:43:14.287Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked2.png","type":"image/png","size":17278,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked2.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"M9o7ylMUafge5ugm"} +{"name":"select.png","date":"2024-02-23T19:54:31.992Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png","type":"image/png","size":8705,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fselect.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"VUgg69AS6qvPYYm2"} +{"name":"locked!.png","date":"2024-02-23T19:54:35.601Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png","type":"image/png","size":9307,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked!.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"9TbrgbxQ4qWp7wo8"} +{"name":"selected.png","date":"2024-02-23T19:57:48.075Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png","type":"image/png","size":10342,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fselected.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"FOpbj7lZQ46siJhg"} +{"name":"Coca_Cola_Espuma.mp4","date":"2024-02-25T21:05:14.047Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Coca_Cola_Espuma.mp4","type":"video/mp4","size":104064,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FCoca_Cola_Espuma.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"FGE2VR7615Lfujp8"} +{"name":"channels4_profile.jpg","date":"2024-03-01T20:16:47.088Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/channels4_profile.jpg","type":"image/jpeg","size":99589,"imageWidth":900,"imageHeight":900,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchannels4_profile.jpg","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"jd7joNLFJLt9pfED"} +{"name":"2024_03_02_0yw_Kleki.png","date":"2024-03-03T00:26:41.538Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki.png","type":"image/png","size":2141,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"th3bRPzSTorKXKDi"} +{"name":"2024_03_02_0yw_Kleki (1).png","date":"2024-03-03T00:26:52.528Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki%20(1).png","type":"image/png","size":7139,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki%20(1).png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"p9YoKuARaRk3B841"} +{"uuid":"txSk7RsRJ33ZgL0R","deleted":true} +{"name":"videoplayback.mp4","date":"2024-03-03T01:45:53.601Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp4","type":"video/mp4","size":2796319,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"NKyN5jkpsVkhg3Yl"} +{"uuid":"q6L0WZWbnI2dyDzS","deleted":true} +{"name":"undertakers-bell_2UwFCIe.mp3","date":"2024-03-12T18:42:39.839Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/undertakers-bell_2UwFCIe.mp3","type":"audio/mpeg","size":68055,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fundertakers-bell_2UwFCIe.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"u6xFAcMANHBQhPTB"} +{"name":"aaaaaaaa-online-audio-converter_r9waVUO.mp3","date":"2024-03-12T19:17:49.219Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/aaaaaaaa-online-audio-converter_r9waVUO.mp3","type":"audio/mpeg","size":17807,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Faaaaaaaa-online-audio-converter_r9waVUO.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"aNcuRqu2nQzZStT2"} +{"name":"metal-pipe-clang.mp3","date":"2024-03-12T19:17:53.637Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/metal-pipe-clang.mp3","type":"audio/mpeg","size":45694,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fmetal-pipe-clang.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ro1Gfn5NPJDSpUUK"} +{"name":"vine-boom.mp3","date":"2024-03-12T22:02:49.499Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/vine-boom.mp3","type":"audio/mpeg","size":21230,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvine-boom.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ebMorJE4l2U0t6ec"} +{"name":"tmp_7901-951678082.mp3","date":"2024-03-12T22:02:54.624Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tmp_7901-951678082.mp3","type":"audio/mpeg","size":16425,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftmp_7901-951678082.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ApoIUl7SyuyEaopN"} +{"name":"emotional-damage-meme.mp3","date":"2024-03-12T22:02:59.660Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/emotional-damage-meme.mp3","type":"audio/mpeg","size":54262,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Femotional-damage-meme.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"UNGgdWN3md0VrWpz"} +{"name":"discord-notification.mp3","date":"2024-03-12T22:03:03.356Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/discord-notification.mp3","type":"audio/mpeg","size":8301,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdiscord-notification.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"NCiDWuamdHpEV71a"} +{"name":"wrong-answer-sound-effect.mp3","date":"2024-03-12T22:03:15.813Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/wrong-answer-sound-effect.mp3","type":"audio/mpeg","size":19479,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fwrong-answer-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"cvaZ88hmjymDoYyl"} +{"name":"clash-royale-hog-rider.mp3","date":"2024-03-12T22:03:19.656Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/clash-royale-hog-rider.mp3","type":"audio/mpeg","size":70145,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fclash-royale-hog-rider.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"58kvJm1P0eAgy2zu"} +{"name":"goofy-ahh-car-horn-sound-effect.mp3","date":"2024-03-12T22:03:24.188Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/goofy-ahh-car-horn-sound-effect.mp3","type":"audio/mpeg","size":49456,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fgoofy-ahh-car-horn-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sqlTlpMYSaoC5Ibw"} +{"name":"tf_nemesis.mp3","date":"2024-03-12T22:03:29.502Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tf_nemesis.mp3","type":"audio/mpeg","size":73813,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftf_nemesis.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"pQcX3TfMLczzdXm0"} +{"name":"chinese-rap-song.mp3","date":"2024-03-12T22:03:35.151Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chinese-rap-song.mp3","type":"audio/mpeg","size":160451,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchinese-rap-song.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"UG4BHOkrbtySjMoI"} +{"name":"fire-in-the-hole-geometry-dash.mp3","date":"2024-03-12T22:03:40.367Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fire-in-the-hole-geometry-dash.mp3","type":"audio/mpeg","size":31680,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffire-in-the-hole-geometry-dash.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"RxWARK12ebQVuh9e"} +{"name":"water-on-the-hill.mp3","date":"2024-03-12T22:03:47.326Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/water-on-the-hill.mp3","type":"audio/mpeg","size":13100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fwater-on-the-hill.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"6lJLNPCsgJCtbgrd"} +{"name":"taco-bell-bong-sfx.mp3","date":"2024-03-12T22:03:52.201Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/taco-bell-bong-sfx.mp3","type":"audio/mpeg","size":31599,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftaco-bell-bong-sfx.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"wdvpWAE7Px1X3Z6R"} +{"name":"dun_dun_1.mp3","date":"2024-03-14T15:54:39.063Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/dun_dun_1.mp3","type":"audio/mpeg","size":21607,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdun_dun_1.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"RukfNSPWQfBw87v2"} +{"name":"holy-moly-emoji.mp3","date":"2024-03-14T15:54:42.780Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/holy-moly-emoji.mp3","type":"audio/mpeg","size":22567,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fholy-moly-emoji.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"B3qwwfOmo4IqDjky"} +{"name":"spongebob-boowomp.mp3","date":"2024-03-14T15:54:49.245Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spongebob-boowomp.mp3","type":"audio/mpeg","size":23751,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fspongebob-boowomp.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"WKAEtNX56P5Yjl6G"} +{"name":"bad-to-the-bone-meme.mp3","date":"2024-03-14T15:54:54.343Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bad-to-the-bone-meme.mp3","type":"audio/mpeg","size":41346,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fbad-to-the-bone-meme.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"GE5BxezBXE6OeL3d"} +{"name":"feet-gd.mp3","date":"2024-03-14T15:54:59.794Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/feet-gd.mp3","type":"audio/mpeg","size":8352,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffeet-gd.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"8mtGRsAwmu5czOoy"} +{"name":"5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","date":"2024-03-20T22:15:57.366Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","type":"image/png","size":66868,"imageWidth":1536,"imageHeight":951,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","thumbnailWidth":330,"thumbnailHeight":205,"uuid":"XP09HX2tGTiXNXFs"} +{"name":"2024_03_26_0zp_Kleki.png","date":"2024-03-26T23:55:49.798Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_26_0zp_Kleki.png","type":"image/png","size":8852,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_26_0zp_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"xFkrHKnI6qOjWIB7"} +{"name":"image_2024-04-11_161031965.ico","date":"2024-04-11T18:41:32.273Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image_2024-04-11_161031965.ico","type":"image/x-icon","size":225726,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image_2024-04-11_161031965.ico","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"b73O6MpXAdhV1Rur"} +{"uuid":"XfFWeHV5t1gcuE4J","deleted":true} +{"name":"Action Agenda - Killa DFX Edit.mp3","date":"2024-04-17T11:10:44.240Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3","type":"audio/mpeg","size":7596960,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FAction%20Agenda%20-%20Killa%20DFX%20Edit.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"goq6Nz3Otdd2T6CZ"} +{"uuid":"RsOUyfm1cBYSqbw0","deleted":true} +{"name":"Apotheosis.wav","date":"2024-04-17T11:13:48.783Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.wav","type":"audio/wav","size":33796140,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FApotheosis.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sdKc4c16V8kOoffG"} +{"name":"Depredation.wav","date":"2024-04-17T11:51:30.584Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation.wav","type":"audio/wav","size":39784492,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"vMjHBJ94XqKWFz9b"} +{"name":"2024_04_17_0gh_Kleki.png","date":"2024-04-17T12:23:56.170Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png","type":"image/png","size":2144,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"dAHNcl4YUXtrnYNr"} +{"uuid":"sdKc4c16V8kOoffG","deleted":true} +{"uuid":"vMjHBJ94XqKWFz9b","deleted":true} +{"name":"8mb.video-tQi-0UoaHVvl.mp4","date":"2024-04-18T22:14:20.996Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/8mb.video-tQi-0UoaHVvl.mp4","type":"video/mp4","size":18092799,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F8mb.video-tQi-0UoaHVvl.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"qbGOtBvcJcjg37V9"} +{"uuid":"qbGOtBvcJcjg37V9","deleted":true} +{"name":"Screenshot_2024-04-12_at_2.52.02_PM.png","date":"2024-04-19T10:54:45.626Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screenshot_2024-04-12_at_2.52.02_PM.png","type":"image/png","size":72691,"imageWidth":272,"imageHeight":366,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreenshot_2024-04-12_at_2.52.02_PM.png","thumbnailWidth":246,"thumbnailHeight":330,"uuid":"UmCvpyaMKwvJtjI9"} +{"name":"videoplayback (4).mp4","date":"2024-04-19T10:56:39.084Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(4).mp4","type":"video/mp4","size":258165,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(4).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"DGrL98ImDItr7mJG"} +{"name":"Depredation V2.mp3","date":"2024-04-19T11:12:12.474Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3","type":"audio/mpeg","size":8288129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation%20V2.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"6LtgWCgUdzzqE3hr"} +{"name":"Apotheosis (1).mp3","date":"2024-04-19T11:16:59.376Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis%20(1).mp3","type":"audio/mpeg","size":7040129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FApotheosis%20(1).mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ku50xwnoZ8ABjNcJ"} +{"name":"2024_04_22_0ep_Kleki.png","date":"2024-04-22T11:40:03.892Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0ep_Kleki.png","type":"image/png","size":2169,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0ep_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"KtLhCRh5D7z40ufq"} +{"uuid":"KtLhCRh5D7z40ufq","deleted":true} +{"name":"2024_04_22_0fb_Kleki.png","date":"2024-04-22T11:43:54.204Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0fb_Kleki.png","type":"image/png","size":2165,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0fb_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"Zq5aBpo0JAKsFPSd"} +{"name":"Voicy_Slap Battles Killstreak Kill.mp3","date":"2024-04-25T11:47:23.190Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Voicy_Slap%20Battles%20Killstreak%20Kill.mp3","type":"audio/mpeg","size":45171,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FVoicy_Slap%20Battles%20Killstreak%20Kill.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"YE7Wbxb7eY4uN03N"} +{"name":"1165825970528325682.webp","date":"2024-04-26T18:39:24.280Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp","type":"image/webp","size":1098,"imageWidth":45,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp","thumbnailWidth":45,"thumbnailHeight":48,"uuid":"bAX0kJLTMphe3F8v"} +{"name":"1165934432608321546.webp","date":"2024-04-26T18:39:28.932Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp","type":"image/webp","size":968,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"Ci3JnJpEDmg4VF1c"} +{"name":"1165934167280848969.webp","date":"2024-04-26T18:39:33.284Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp","type":"image/webp","size":1582,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"HTqsPOJz4I9rlBGh"} +{"name":"1165826077843796018.webp","date":"2024-04-26T18:39:38.841Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp","type":"image/webp","size":950,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"eV1sBWslSmqgAf1m"} +{"name":"1165825970528325682l.webp","date":"2024-04-26T18:40:07.621Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp","type":"image/webp","size":864,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"neN7tKpXt8DS0TpV"} diff --git a/LICENSE b/LICENSE index f288702d2..f901c2e81 100644 --- a/LICENSE +++ b/LICENSE @@ -1,674 +1,13 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + +Copyright (C) 2004 Sam Hocevar + +Everyone is permitted to copy and distribute verbatim or modified +copies of this license document, and changing it is allowed as long +as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/README.md b/README.md index fa25247ae..2b6481f00 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Open Source Arras -Logo ![GitHub Release](https://img.shields.io/github/v/release/Taureon/aps-plus-plus) ![Discord](https://img.shields.io/discord/1004907608018264094) @@ -32,7 +31,7 @@ Create a new project and choose to import one from GitHub. When prompted for the Navigate to `server/config.js` and replace `localhost:26301` with the URL for your project. (For Glitch users, it's `your-project.glitch.me` (replace `your-project` with the actual name of your project, it should be above settings)). -**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"` and change your port to something more generic like 3000 or 8080.** +**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"`. Glitch doesn't currently support Node 18.** After doing that, your server should be ready! @@ -45,4 +44,4 @@ After doing that, your server should be ready! ## Other Links - [Our Discord server](https://discord.gg/kvCAZfUCjy) -*p.s. if something goes terribly wrong it's not our fault* +*p.s. if something goes terribly wrong it's not our fault* \ No newline at end of file diff --git a/animation.d.ts b/animation.d.ts new file mode 100644 index 000000000..d7d2359f3 --- /dev/null +++ b/animation.d.ts @@ -0,0 +1,144 @@ +import { Entity, Gun } from "./server/modules/live/entity"; + +type TankShape = number | string | Array + +type TankColor = number | string | { + BASE: number | string; + HUE_SHIFT?: number; + SATURATION_SHIFT?: number; + BRIGHTNESS_SHIFT?: number; + ALLOW_BRIGHTNESS_INVERT?: boolean; + } + +type AnimationEasingValues = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'step' | ((x: number) => number) +type AnimationTypeValues = 'body' | 'gun' | 'turret' + +type AnimationSpec = Record +type AnimationPreset = Array + +type AnimationKeyframe = { + TIME: number; // Percentage + EASING: AnimationEasingValues; + TYPE: AnimationTypeValues; + MOTION: AnimationMotion; +}; + +type AnimationMotion = { + MOVE?: [number, number]; + SCALE?: [number, number] | number; // 2D Vector for guns, 1 number for Turrets and Bodies. + ROTATE?: number; // In Degrees + COLOR?: TankColor; + ASPECT?: number; // Errors if used for any other types except 'gun' + SHAPE?: TankShape; // Errors if used for type 'gun' + ALPHA?: number; +} + +// ------------------------------- + +type OnTriggers = 'fire' | 'altFire' | 'death' | 'collide' | 'damage' | 'upgrade' | 'tick' | 'define' | 'animationStart' | 'animationKeyframe' | 'animationEnd' | 'trigger' +type OnSpec = Array + +type OnEventHandler = { + event: OnTriggers; + handler: (values: TriggerValues) => any; +}; + +interface CommonOnEventHandlerTriggerValues { + body?: Entity; + masterStore?: Entity['store']; + gunStore?: Gun['store']; + globalGunStore?: Gun['globalStore']; + globalMasterStore?: Entity['globalStore']; +} + +interface FireTriggerValues extends CommonOnEventHandlerTriggerValues { + gun?: Gun; + child?: Entity; +} + +interface AltFireTriggerValues extends CommonOnEventHandlerTriggerValues { + gun?: Gun; + child?: Entity; +} + +interface DeathTriggerValues extends CommonOnEventHandlerTriggerValues { + killers?: Array; + killTools?: Array; +} + +interface CollideTriggerValues extends CommonOnEventHandlerTriggerValues { + instance?: Entity; + other?: Entity; +} + +interface DamageTriggerValues extends CommonOnEventHandlerTriggerValues { + damageInflictor?: Entity; + damageTool?: Entity; +} + +interface UpgradeTriggerValues extends CommonOnEventHandlerTriggerValues { + oldEntity?: Entity +} + +interface AnimationStartTriggerValues extends CommonOnEventHandlerTriggerValues { + animationName?: string; + time?: number; +} + +interface AnimationKeyframeTriggerValues extends CommonOnEventHandlerTriggerValues { + animationName?: string; + time?: number; +} + +interface AnimationEndTriggerValues extends CommonOnEventHandlerTriggerValues { + animationName?: string; + time?: number; +} + +interface ManualTriggerValues extends CommonOnEventHandlerTriggerValues { + info?: any; +} + +type TriggerValues = { + fire: FireTriggerValues; + altFire: AltFireTriggerValues; + death: DeathTriggerValues; + collide: CollideTriggerValues; + damage: DamageTriggerValues; + upgrade: UpgradeTriggerValues; + animationStart: AnimationStartTriggerValues; + animationKeyframe: AnimationKeyframeTriggerValues; + animationEnd: AnimationEndTriggerValues; + trigger: ManualTriggerValues; +}; + +/* + Intended Use: + ON: [{ + event: 'animationStart', + handler: ({ body, animationName, time }) => { + //code + } + }, { + event: 'fire', + handler: ({ body, gun, globalMasterStore }) => { + //code + } + }, { + event: 'define', + handler: ({ body, gun, animationName }) => { // Error, no parameter 'animationName' for event 'define' + //code + } + }] + + ANIMATION: { + gunOut: [{ + TIME: 1, + TYPE: 'gun', + EASING: 'linear', + MOTION: { + MOVE: [0, 10] + } + }] + } +*/ \ No newline at end of file diff --git a/changelog preview b/changelog preview new file mode 100644 index 000000000..b15127bb8 --- /dev/null +++ b/changelog preview @@ -0,0 +1,499 @@ +
+

Update 3.1

+ [2024] +
    +
  • fixed date since counter
  • +
  • Added BackShield & Mirror Shield
  • +
  • Fixed Tag Gamemode
  • +
  • Removed Stats Temporarily
  • +
  • Changed Bot Leveling
  • +
  • Nerfs & Buffs
  • +
  • Reorganized Entities
  • +
  • Added New Color System
  • +
  • Fixed Color System
  • +
  • New DFX Maze Map
  • +
  • Added Apotheosis V2 & Depredation Remastered V2 By Deltafyrex and Killa By Action Agenda (DFX Edit) To OST
  • +
  • Fixed Siege
  • +
  • Fixed Movement System
  • +
  • Fixed Death Sounds
  • +
  • Revamped Menu Popups
  • +
  • Added TwinSniper Branch And More to Acid And Chiller Branch
  • +
  • Fixed Music Bug, And Added Aura Basic, Jump Smasher And Whirlwind To The Main game
  • +
  • Fixed Shields
  • +
  • +

    Holay Molay

    +
+
+
+

Update 3.0

+ [2024] +
    +
  • Added Clubbin
  • +
  • Testing Achievements
  • +
  • Added Reset Achievements Button
  • +
  • Added Start Achievement
  • +
  • Added and Fixed Achievement Details
  • +
  • Added Disconnect, Lag, And Killstreak Achievement
  • +
  • Removed Kill Achievement cuz it dont work
  • +
  • Added New Special Achievement Type
  • +
  • Added Special Piss.io Achievement And Funny Skype Achievement
  • +
  • Re-Added And Fixed 5 Killstreak Achievement Again
  • +
  • Added Server to Client Functions
  • +
  • Added 10 Killstreak Achievement
  • +
  • Changed Debug Menu
  • +
  • Added Kill Amount In Debug
  • +
  • Added Audio Visualizer in the title screen
  • +
  • Fixed Embed Not Working Properly
  • +
  • Fixed Bug Where Audio Visualizer Appears In Game
  • +
  • Added Token And Discord Achievement
  • +
  • Added Achievements Tab
  • +
  • Removed Ach Testing
  • +
  • Added Credits Button
  • +
  • fixed credits interfering with changelog
  • +
  • added credits-changelog animation transition
  • +
  • moved credits button (its 1:08 am im soooooo tired)
  • +
  • Fixed Game Breaking Bug
  • +
  • Added Contagion Branch To Subduer & Trapper
  • +
  • Added Longing And Resurgam By Amaryllis To The OST
  • +
  • added credits ach
  • +
  • Added 2 New Branches For Desmos
  • +
  • Testing Skins
  • +
  • Added Beta Skin Menu
  • +
  • Fixed Skin Bug
  • +
  • Fixed Crashing On Respawn
  • +
  • Added More Detail To Skin Menu
  • +
  • Added Cat Code and Chickensandwhichman Skin
  • +
  • Added Daily Tanks
  • +
  • Added Plenty New Skins, New Achievements And Made Achievements Unlockable
  • +
  • Added Skater & Hitman
  • +
  • Added New "Duality" Map
  • +

    Update 2.93 [2024]

    +
  • David Goggins Event
  • +
  • Updated Menu
  • +
  • Added Marksman Branch To Sniper And Car Branch To
  • +
  • Added Trollface Emote (add --troll to the end of a chat message)
  • +
  • Added Waterfall, Acid, Cooler, Rainmaker And New Options Layout
  • +
  • Added Notes Tab + Live Counter
  • +
  • Added More Customization, Graphics, Helecopter And Fixed Music Bug
  • +
  • Added Reverie Branch And Injector
  • +
  • Added Debugger Menu
  • +
  • You Can Now Color Messages With §
  • +

    Niners fucking lost Again Bruh...Fuck Taylor Swift

    +
+
+
+

Update 2.9

+ [2024] +
    +
  • Added Motor
  • +
  • Added Kivaaharatedas (i did not spell that right)
  • +
  • Added Equilibrium, Revobrid, Subverter
  • +
  • shrapnel testing
  • +
  • removed unfinished aimbot/boosting testing
  • +
  • Added Basic Hybrid Tier 3 branch
  • +
  • Bug Fixed Colors
  • +
  • Added Tanks of my friends and tank soundboard support
  • +
  • Added the rest of the Basic Hybrid branch (tier 4)
  • +
  • Fixed changelog not appearing
  • +
  • Added beta music support including 5 songs
  • +
  • changed start button look to not shade out and actually work like a button
  • +
  • fixed debug key (again)
  • +
  • fixed screen tearing
  • +
  • worked bullet spawn position
  • +
  • Better organized dev menu and changed the way utilities looks
  • +
  • Added music recognition in the debug key to see the song name & artist
  • +
  • Added new song (Anybody can find Love (except You) by hkmori
  • +
  • fixed debug not recognizing a song and not updating after a song is finished
  • +
  • Testing wall colors/effects
  • +
  • Added Shield Turrets
  • +
  • Added new tiles (dance floor+black)
  • +
  • added new "banquet" map
  • +
  • Finished Revolutionist Branch
  • +
  • Added Inception & Albuquerque
  • +
  • im a fucking moron
  • +
  • Added Machceptioner & Tailgator
  • +
  • Added Interceptor, Twinceptioner, Inceptionist branch, hybrid/auto ver of inception branch
  • +
  • Added Desmos/Inception/Bascrid Ception
  • +
  • fixed the ceptionist turrets/autobullet turrets
  • +
  • nerfed shit
  • +
  • fixed some upgrades not appearing
  • +
  • no players (dead game and nobody plays is sadly)
  • +
  • so it turns out i forgot to give twinceptionist the right bullets so i fixed that :/
  • +
  • fixed flankcept branch turrets
  • +

    Update 2.91 [2024]

    +
  • Added the subduer branch
  • +
  • Fixed The Rest of the menu buttons and fixed sound effects
  • +
  • Added flankduer
  • +
  • Added Binary branch, Pathogen branch, mitochondrion branch, Subduer-Hybrid branch and Auto-Subduer Branch
  • +
  • fixed missing upgrades
  • +

    Hey! vsauce, Michael here. the game is stable and non buggy...or is it?

    +
+
+
+

Update 2.8

+ [2023] +
    +
  • Tank Adding Wave Two (ex. hadron, dictator, railgun + more)
  • +
  • Debug Key Bug Fix (how ironic)
  • +
  • Fixed Rng Images Bugging Out
  • +
  • Testing Whirlwind Branch
  • +
  • Fixed Maze Gamemode
  • +
  • Added Tooltips (beta)
  • +
  • Added Status Effects (beta+devevent)
  • +
  • Added Addon Support
  • +
  • Fixed button Shadows
  • +
  • Upgraded APS++ Updating Speed
  • +
  • New Mouse Controller
  • +
  • Keybind Fix
  • +
  • Enter can cancel a chat message being sent
  • +
  • CoNgReGaTiOn JuMpScArEs
  • +
  • Images on Tanks/Sound Effects For Tanks (dev)
  • +
  • Blackhole (dont ask just roll with it)
  • +
  • P A P Y R U S
  • +
  • Fixed Some Lag Holding Down Server Speed
  • +
  • 109.43.21.5.14
  • +
  • Added Desmos Branch
  • +
  • Theres Prob More But I Forgor
  • +

    wahhh... (i forgor why im crying)

    +
+
+
+

Update 2.7

+ [2023] +
    +
  • Debuffed Many Tanks
  • +
  • Migrated to new host
  • +
  • Removed all Nero Exclusive Tanks From The Game (for now anyway, dont worry)
  • +
  • Added "revolutionist" to testbed"
  • +
  • Massive Testbed overhaul
  • +
  • Added a funny randomly generated image on the start screen
  • +
  • Readded Sounds, design and other previous widgets
  • +
  • Hired new devs
  • +
  • did some tweaks to bots
  • +
  • got rid of the "nero" theme and the server list
  • +
  • added easter eggs
  • +
  • added random funny image
  • +

    Update 2.71 [2023]

    +
  • Tank Adding Wave One (ex. auto branch, revolutionist, cloner + more)
  • +
  • plenty of new dev features
  • +
  • added gamemode polls (once theres enough people)
  • +

    There are Easter Eggs All Over The Main Menu, You Might Find Something...

    +
+
+
+

Update 2.6

+ [2023] +
    +
  • replaced smashers origional upgrade path with the "armoury" tree -added lancer and smasher upgrades to armoury tree
  • +
  • added "Sword", "Injector" and "Fencer" to lancer upgrades
  • +
  • buffed drone tanks, twin tanks & tank health
  • +
  • added "Dictator" -added "Tripwire"
  • +
  • added "Barricade", "Twister", "Cyclone" and "Architect" -added "Tri-Trapper" tree -added "auto tritrapper", "auto armour" and "autolancer"
  • +
  • added "eagle" and "bulwark"
  • +
  • updated debug menu
  • +
  • removed hivemind from basic
  • +
  • added cloner upgrade
  • +
  • added hivemind and "splitter" to cloner upgrade
  • +
  • added "auto cloner", "auto flamethrower", "flamethrower hybrid" and "lancer hybrid"
  • +
  • updated colorscheme and other color related things
  • +
  • updated teams on 2tdm after 3 team bug -added all new Rock Maze gamemode
  • +

    Ryerson Loves Burger King

    +
+
+
+

Update 2.5

+ [2023] +
    +
  • added new tanks into beta for further testing
  • +
  • hired new devs
  • +
  • neroio discord is up
  • +
  • added new mascallenus tank and section
  • +
  • hired new beta testers
  • +
  • added new easter eggs
  • +
  • tested 2nd server opening
  • +
  • added "Scanner" and "hadoken"
  • +
  • nerfed Hahaugobrr
  • +
  • promoted lucas medieros to co-owner of the game
  • +
  • demoted a few staff
  • +
  • added 2TDM game mode
  • +
  • woomy event is back! now with free access to testbed
  • +
  • added "flankdrive", "twindrive" and "machinedrive"
  • +
  • fixed trapper look
  • +
  • added "infantry", "musket", "Traprid", "Auto Traprid", "Snigrav", "AsWdragafora", "Assasolak", "Builifacate", "Rifagiulus", "Auto Snigrav"
  • +
  • added "flamethrower", "Baker", "Wildfire" and "Equinox"
  • +
  • new nero.io default theme instead of using arras's
  • +
  • added insane af tanks to testbed
  • +
  • added "lancer"
  • +

    Open Na Noor

    +
+
+
+

Update 2.4

+ [2023] +
    +
  • added 2 new admin commands
  • +
  • added homing auto Basic
  • +
  • added bosses tab to AIT
  • +
  • bwomp AA $$ €€
  • +
  • added easter egg name colors
  • +
  • added the tanks "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", and "neptune"
  • +
  • added a new boss
  • +
  • added more natural spawning bosses
  • +
  • added "SpawnTrap"
  • +
  • updated bot names
  • +
  • ended woomy event
  • +

    Oh great red Text of the Changelog, What is your Wisdom?

    +
+
+
+

Update 2.3

+ [2023] +
    +
  • added "maleficator", "stalker", "landmine", "jumpsmash", "speedbent", "heavy3", and re-added "twindrive", "interceptioner", the "drive" subtree to autobasic, plus increased map size
  • +
  • fixed and debuffed jumpsmash
  • +
  • debuffed speedbent
  • +
  • added a public changelog (the one your looking at now)
  • +
  • added the red text
  • +
  • updated sounds and styles
  • +
  • added the "corrupted" button
  • +

    So Hows Ur Day?

    + +
+
+
+

Update 2.2

+ [2023] +
    +
  • added more tanks into beta
  • +
  • added sounds and updated client backround
  • +
  • Decoration finished
  • +
  • started decoration on migration host
  • +
  • added chat feature
  • +
  • migration big fixes
  • +
  • WE DID IT! MIGRATION COMPLETE!
  • +
  • during migration found multiple small bugs that was fixed
  • +
  • 2nd failed migrating attempt, starting yet another
  • +
  • fixed crashing bug
  • +
  • 2nd attempt at migrating
  • +
  • added random bot and skill classes
  • +
  • made bots more op
  • +
  • fixed a bot bug
  • +
  • downgraded bots
  • +
  • added tank visualizers
  • +
  • buffed bots a tiny bit more
  • +
  • fixed visualizer bug
  • +
  • added "rifle"
  • +
  • fixed "lilfact" upgrade path
  • +
  • added auto "lilfact"
  • +
  • renamed "lilfact" to "spawner"
  • +
  • added secret tanks for update 2.3
  • +
  • minor crash bug fixes
  • +
  • removed "rifle" and "autospawner" from beta
  • +
  • fixed smasher bug
  • +
  • failed "lancer" class attempt
  • +
  • secret tank updates
  • +
  • major bug fixes
  • +
  • rainbow color old client fix
  • +
  • last patches before big update
  • +
  • fixed tiny bug
  • +

    I Know Where You Live

    +
+
+
+

Update 2.1

+ [2022] +
    +
  • fixed the 2 game crashing bugs
  • +
  • tried to migrate to another server host but yet failed due to unknown reasons
  • +
  • added "speedbent" to beta
  • +
  • updated messages
  • +

    tbh im sad the 49ers missed the super bowl :/

    +
+
+
+

Update 2.0

+ [2021] +
    +
  • brought the ception tree into beta tanks
  • +
  • figured out that the "ceptions" arent really ceptions
  • +
  • forgot to add the actual way to access it LOL, also added a REAL machine ceptionist as a test
  • +
  • removed ceptionist and drive tanks as they are too overpowered
  • +
  • added lazer guns
  • +
  • stole code from someone elses server
  • +
  • added beta shock and burn
  • +
  • added some secret really stupid tanks
  • +
  • fixed a tank
  • +
  • removed revolutionist for being too buggy
  • +
  • added new auto class branch
  • +
  • added hivemind
  • +
  • bug fixes
  • +
  • major bug that caused no tanks to be added or bugs fixed causing confusion
  • +
  • crashing bug made game unplayable for large amount of time (like a whole 9 months)
  • +

    Whats Up Guys Quandale Dingle Here

    +
+
+
+

Update 1.9

+ [2021] +
    +
  • testing in progress
  • +
  • approved multiple tanks into the game
  • +
  • did some stupidity and added random stuff and figured out that there is indeed, 12882 lines of code in this project
  • +
  • added some dumb tanks like "mInIfLyInGfAsTeRtHiNgY"
  • +
  • added some cool colored objects on the "AsWdWsA" branch
  • +
  • added a secret tank
  • +
  • messed with some things like homing bullets
  • +
  • removed the homing stuff due to bugs
  • +
  • tried to recreate the "revolutionist" tank from woomy arras
  • +
  • more tests
  • +
  • added auto bullets
  • +
  • added drive tanks into beta testing phase
  • +
  • moved where the secret tank is
  • +
  • debuffed "single"
  • +
  • added "Cascal", "Gunto", "Catalyst", And "Cescav" to beta tanks
  • +
  • added a beta version of the drive tree into the game after some testing
  • +

    What A Dumb Fucking Game!

    +
+
+
+

Update 1.8

+ [2021] +
    +
  • completed and put the poison function into the game
  • +
  • completed and put the freeze function into the game
  • +
  • created a seprate freeze and poison bullets
  • +
  • added a stun function
  • +
  • added a healing and speed function
  • +
  • added a stun, healing and speed bullet shooting tanks
  • +
  • added the "AsWdWsA" branch
  • +
  • fixed poison cannon
  • +
  • renamed the bullets to respected name
  • +
  • renamed the cannons to a respected name
  • +
  • created a page 2 for the mascallenus
  • +
  • put multitanks into testbed
  • +
  • put multitanks into testbed
  • +
  • organized the tanks
  • +
  • removed public testbed
  • +

    :skull:

    +
+
+
+

Update 1.7

+ [2020] +
    +
  • added an admin logger
  • +
  • changed the AI color to pink
  • +
  • changed AI to have twin upgrade instead of basic
  • +
  • expanded the map
  • +
  • changed the colors of the spawning player to be random instead of always red or blue
  • +
  • added the tanks "oof" and "oof2" to mascallenus
  • +
  • added the tank "minibee" to testbed
  • +
  • added the tank "hexa trapper" into the game
  • +
  • added the tank "Paint Brush" into the crayon tree
  • +
  • added the tank "brutalizer"
  • +
  • added the premade tank "sidewinder"
  • +

    Share with your friends!

    +
+
+
+

Update 1.6

+ [2020] +
    +
  • added the tank "tower mech"
  • +
  • added the "AIT" category into testbed
  • +
  • added a way to get back to a basic tank after becoming testbed
  • +
  • added the tank "crayon"
  • +
  • added the two tanks "marker" and "pastel"
  • +
  • added the tank "pen"
  • +
  • added a kill button to testbed
  • +
  • added the tank "highlighter"
  • +
  • added a way to immediatly upgrade into a basic trapper
  • +
  • invited some friends to help code my game
  • +

    Yo shout out to Lucas Medeiros

    +
+
+
+

Update 1.5

+ [2020] +
    +
  • removed jesus donut
  • +
  • removed DeltaCannon
  • +
  • fixed some bugs with AI's
  • +
  • fixed some bugs with crashers and bosses
  • +
  • added a bunch of testbed tanks into the real thing
  • +
  • removed fairsquare
  • +
  • added flame killa to testbed
  • +
  • removed access to the recently added tanks from testbed to save space
  • +
  • added Boxer to testbed
  • +
  • removed every testbed tank
  • +
  • added categories to test bed like "beta" and "mascallenus"
  • +

    come down today and try some corn, or we will sacrifice your newborn

    +
+
+
+

Update 1.4

+ [2020] +
    +
  • added Lottery to testbed
  • +
  • added hellblazer and Rocketer to testbed
  • +
  • added Nautilus to testbed
  • +
  • added jesus donut to testbed
  • +
  • experimented with bullet effects
  • +
  • added SleamShot
  • +
  • added TrapHard into testbed
  • +

    LMFAO WHAT A BOZO

    +
+
+
+

Update 1.3

+ [2020] +
    +
  • added master
  • +
  • added lilfact
  • +
  • fixed bug with bots
  • +
  • fixed bug with lilfact
  • +
  • ADDED PUBLIC TESTBED
  • +
  • fixed some bugs
  • +
  • fixed testbed problems
  • +
  • fixed testbed key errors regarding platform
  • +
  • added helltank to testbed
  • +
  • added DeltaCannon to testbed
  • +

    DrUgS aRe BaD fOr YoU1!1!

    +
+
+
+

Update 1.2

+ [2020] +
    +
  • server shutdown due to server problems
  • +
  • fixed problem
  • +
  • fixed some more bugs
  • +
  • fixed bug with the upgrades
  • +
  • added 3 pre-made extra tanks (hive shooter, auto assassin, auto cruiser)
  • +
  • added Unlocked
  • +
  • added more ways to get hive shooter
  • +
  • added more ways to get unlocked
  • +
  • added bots
  • +
  • fixed bad bug with Unlocked
  • +

    tbh play a better game than this

    +
+
+
+

Update 1.1

+ [2019] +
    +
  • added revix
  • +
  • added DeltaGunner
  • +

    OH BABY A TRIPLE

    +
+
+
+

Update 1.0

+ [2019] +
    +
  • just opened server
  • +
  • testing new tanks
  • +

    Bwomp

    +
+
+You've Reached The End UwU ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file diff --git a/features.md b/features.md index f90de395d..cbd7d12bc 100644 --- a/features.md +++ b/features.md @@ -275,4 +275,4 @@ It includes all features up to the latest release version. * Dominator Game Mode. * Doesn't kick for invalid tokens, instead just does not give any perms. * Level Bar now shows max level if you have exactly enough score to reach that level. -* Large `SHAPE`s now work. +* Large `SHAPE`s now work. \ No newline at end of file diff --git a/images/favicon.png b/images/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..9f5538b6397aef7d893a22383aa4842892441986 GIT binary patch literal 81775 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≪+IpQdu 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%0A{#}+RO zc$d%%l~r!8zfFgQ_f{PXu@1MIJxc2pICUOknpuk3YA+Jj%zF+|sFOu!O;7A@V*ZG> zT<0Gscs@Y52gNe)Epf9{-Bq?^qgiS?=9r}R*++(gcsh^DDGIuc z6oi|5N^Fq^#)r!vLil#hwx&ZN(H@8>mi_$%x3=LQg`J$9rD5FkmK~#AE{8Tz z9+9W+hcAK@)~jl|yXWBr*l$1~He7ATdmRM7OlNueKx0ZIrIk$(wSKdl_K zSushkQry*SJRUB1t7hyuvCU}eLG~I?>?xt+YHVFlx*XwdYa6xnr1=uwtQ~Sf@T=E7 zhW_MET@KQEBeQtLO)?a^!c}x8{fz4(L(2;}7a^R~y^BB24(otlQz3btW81zCgTdgN z(P}sB?uCS27AdV(5waBj01WcJq@rCJ2}V_FsK}?Pcg7pP9~RqRH4^ZE=5CTwmro z%S1a~w=5?53cln+lXD)#{=+Kv-@v4>L_%qZc*NJUB2V2+?BV#K*}v3(3}Y4=m!$c7 z`V~qADY;mrTC@0so{7~SCbJ-G=MVPT>>(|*TQ*iLaa#~LdaD&g4PfVl`Z6Y>%yU^2 zpzvjpW?%K@i=M+Y#+HzdT9HXSwh?R>yB%KV(pz&_7FrC26CdD{A^Af~ExTLU{a~jS zT}UmM{{YL$%!+Yruk{CYoKvZg>$}Se#i3%$1+nsnG|S-HVws(OM3=P)=h2XUM9~t% zB{lVfsv?-SY2Jj~*Oo=df5T_ypp=EVw(^hqx|C|`4^p-lTQDX>(Gr$)uhq)uc~hE4 zck?4b8SmY z-iL0~oYR=sZ#Lht-Q2pxFWB!g?!R%T<(lZoWc0{&*Na;Z&HCeK&tEch6p`4B?=Rr* z4`KfRrF5DnOGtI(FXtvIVRg?JJA1F5E7PmX43$?-RQXE!CX%;am|9bXa%3;D*|+dO z{=(Q;E(LuzWuAX0x_p%m>UJI-nxC-)Uc_>UjSxSCc5yF(a4YHBLzw8)`6APB&gz=# zj>#tUL~(APC_~~tIUA*t>dTk@KOzf8<)fSRE7BhPZF>Gn{zMMb*+2Oo5f&c&j literal 0 HcmV?d00001 diff --git a/images/lratio.png b/images/lratio.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c07b64be08ff05f5a549c776aeee6932e58103 GIT binary patch literal 66360 zcmeFYXCPc%*FLVs2%;s79t?vBBVn}BJJAzSqDM_R+v-DpFEU_?pOs3Fm7w5UP! zK6)J`I{(Ri-_P^D&+qy8|N4HKvd`IPt-Z>%_O;iE)X`F*xXE}E4-bz*O;u43504Ow zheu!pxPkj;;j}6n_kr)Kry`G6($Bn(hj$lGO;PSK!fY#p44)3>Ik~yTtQ|gA+hx>ai%r!vM2t_4nC!JJU6^ zwLY`n==153Vbe>4KDP{sRo~U?@7(yLs)Vs|8d-A{UK!yY=U#Q;bar*B^2rp(3{)ae! z?g&bt8jN7;mYvZ2FKGjn>s|j_P6!PFBbJkar;hi(^c#%uy!HR897v=rFU#oOiXU^5K%O*{^zVuPrKWwm zB+0*5|KFpW>>sFQP(c-G|GMmdgpNV1{`<0jkN%$#{%3)3Uh;oN_&XN=FB1NDX#M|B zN6mu(i@b~7K?$1x5QGSq929`W=l?t0gJ#$RDfTtgv@$ToYFckG^ohRrx>pl@g}aYE zNy0t(f-b2CBj(ryokKA znLFd&cK?odT+#z_1TBGU9-)f3#5uazGqn79x(TC&;_R*h!VrYN)d;3=>9_M>tsO6gK|-gS*M3Wk=~>H>D`d4}w7) z!pZo@gNws)km>!++u&b@Nd~`q2RhbrQ61pjYnQ1*EZu1|MwgfV1usDfICo)NZ=P`c z`|9Qp(rIw_rDV3pkpXpsw{YQy6T!VMYYn@RfhljU0 z(TqQVSl<`zlpbQ+DSyinjgzIe%iHYVvar9p08y&Bd}UC+&`7Mm+kG$5*Dsaqgz=yG zQ%G@O>2)C@j#Rb z|9FQ5CsBU}2KrI@!nq%^m}!JO@dTarD|;_1{S)4V95}fA&{B5q?*Iv60q>owu|8A( zk?}l?`nq24-c^iRW7Sf9z29FljmzQ8CMmWyTk(%bABaj)Fx_hXkeq;!VSP^Y16OBg zy8nk9`>%gJz~VE`m&T&T5;gu58_hQX7xFai{ju+IrN2T}t|YtT5K2`ZAR=8 z3*1NGuhQlR?O=pCI^!SbIieBc@6N!bpkxqOVBs)iz`88wQLNDQ8Aw}m|MbYCv$8Y+ zj|rNm?s5sDoNl8nEt_E^Y1RLGW%h8UrVK!CW#QBeGUaTpTz`jp_6g{=no5XgeI=#F znuxhm_%_a?5HdRw4o+uvz96-oCPgFU*RKV-P3}}PZ6l^$|79XEJY1j_SKO}jk47}c991vaO_J#Q&DYN%FY?y;N@VQ^=?gZn z_%^HQ_XzOD;;EWhB8I80QN-u#5)n^~TI8d~Lj3;YGf@t$2-u>}{VXGy0kN>AOCHi8 z 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

hcY(-Z|f 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%0DCMsWA*%R8y=hcM2;LtOxVZb36_sI?bf&-1 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 { + if (document.getElementById("optSound").checked === true) { + global.music2.play() + global.music2.addEventListener('ended', function() {this.currentTime = 0; global.music2.src = pmusic[~~(Math.random() * pmusic.length)]; this.play();}, false); + } else if (document.getElementById("optSound").checked === false) { + global.music2.pause() + global.music2.songname = "Not Playing"; + } + return; };*/ + + var checkbox = document.getElementById("optSound"); + var audio = document.getElementById("audio"); + +checkbox.onclick = function() { + audio.src = randmusic; + audio.load(); + audio.play(); + var context = new AudioContext(); + var src = context.createMediaElementSource(audio); + var analyser = context.createAnalyser(); + + var canvas = document.getElementById("canvas"); + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + var ctx = canvas.getContext("2d"); + + src.connect(analyser); + analyser.connect(context.destination); + + analyser.fftSize = 256; + + var bufferLength = analyser.frequencyBinCount; + console.log(bufferLength); + + var dataArray = new Uint8Array(bufferLength); + + var WIDTH = canvas.width; + var HEIGHT = canvas.height; + + var barWidth = (WIDTH / bufferLength) * 2.5; + var barHeight; + var x = 0; + + function renderFrame() { + requestAnimationFrame(renderFrame); + + x = 0; + + analyser.getByteFrequencyData(dataArray); + + ctx.fillStyle = "#000"; + ctx.fillRect(0, 0, WIDTH, HEIGHT); + + for (var i = 0; i < bufferLength; i++) { + barHeight = dataArray[i]; + + var r = barHeight + (25 * (i/bufferLength)); + var g = 250 * (i/bufferLength); + var b = 50; + + ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; + ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight); + + x += barWidth + 1; + } + } + + audio.play(); + renderFrame(); + }; +}; \ No newline at end of file diff --git a/neroplayer/stylesheet.css b/neroplayer/stylesheet.css new file mode 100644 index 000000000..c6218fa18 --- /dev/null +++ b/neroplayer/stylesheet.css @@ -0,0 +1,14 @@ +#canvas { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +audio { + position: fixed; + left: 10px; + bottom: 10px; + width: calc(100% - 20px); +} \ No newline at end of file diff --git a/neroplayer/visual.html b/neroplayer/visual.html new file mode 100644 index 000000000..658530558 --- /dev/null +++ b/neroplayer/visual.html @@ -0,0 +1,15 @@ + + + + + Audio Visualizer + + +

+ + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 907707baa..000000000 --- a/package-lock.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "arras", - "version": "1.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "arras", - "version": "1.0.0", - "license": "GPL-3.0", - "dependencies": { - "ws": "^8.13.0" - }, - "engines": { - "node": "16.x" - } - }, - "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - } - }, - "dependencies": { - "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "requires": {} - } - } -} diff --git a/package.json b/package.json index 68119883e..b24fc1371 100644 --- a/package.json +++ b/package.json @@ -11,10 +11,10 @@ "build": "node standaloneClient/build minify" }, "dependencies": { - "ws": "^8.13.0" + "ws": "^8.16.0" }, "engines": { - "node": "18.x" + "node": "16.x" }, "license": "GPL-3.0" -} +} \ No newline at end of file diff --git a/public/app.js b/public/app.js index 7db721332..b44b2aad4 100644 --- a/public/app.js +++ b/public/app.js @@ -6,6 +6,7 @@ import { settings } from "./lib/settings.js"; import { Canvas } from "./lib/canvas.js"; import { color } from "./lib/color.js"; import { gameDraw } from "./lib/gameDraw.js"; +import { tankdescs } from "./lib/tankdesc.js"; import * as socketStuff from "./lib/socketInit.js"; (async function (util, global, settings, Canvas, color, gameDraw, socketStuff) { @@ -19,7 +20,732 @@ let { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow } = s // document.getElementById("patchNotes").innerHTML += `
${changelog[0][0].slice(1).trim()}: ${changelog[0].slice(1).join(":") || "Update lol"}
    ${changelog.slice(1).map((line) => `
  • ${line.slice(1).trim()}
  • `).join("")}

`; // } // }); + var playbuttonsound = new Audio(); + playbuttonsound.src = + "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/op1.wav?v=1675463613542"; + function PlaySound69() { + playbuttonsound.play(); + } + var clicked = false; + + var slap = new Audio(); + slap.src = + "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/(Audio)%20videoplayback.m4a?v=1675999054321"; + function PlaySound68() { + slap.play(); + } + + var vsau = new Audio(); + vsau.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jake-chudnow-edited_y1t8j5q.mp3?v=1706018057534" + function PlaySound99() { + vsau.play(); + } + + var clicksound = new Audio(); + clicksound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/sysse_ok.ogg"; + function PlaySound210() { + clicksound.play(); + } + + var trapperclosely = new Audio(); + trapperclosely.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/look_closely.mp3?v=1705291786778"); + function PlaySoundtrap() { + trapperclosely.play(); + } + + var waterflush = new Audio(); + waterflush.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/toilet_flush.mp3?v=1705296502578"); + function PlaySoundwater() { + waterflush.play(); + } + + var undadewatuh = new Audio(); + undadewatuh.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/y2mate_HOnnyD0.mp3?v=1705296505126"); + function PlaySoundwatuh() { + undadewatuh.play(); + } + + var piss = new Audio(); + piss.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/flowing-water-sound-effect.mp3?v=1705299861150"); + function PlaySoundpiss() { + piss.play(); + } + + var pew = new Audio(); + pew.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/pew_pew-dknight556-1379997159.mp3?v=1705299975747"); + function PlaySoundpew() { + pew.play(); + } + var chipi = new Audio(); + chipi.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chipi-chipi-chapa-chapa.mp3?v=1705302832837"); + function PlaySoundchipi() { + chipi.play(); + } + var neko = new Audio(); + neko.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/neko-arc.mp3?v=1705302835953"); + function PlaySoundneko() { + neko.play(); + } + var bwomp = new Audio(); + bwomp.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bwomp.mp3?v=1705302839344"); + function PlaySoundbwomp() { + bwomp.play(); + } + var nfl = new Audio(); + nfl.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nfl.mp3?v=1705302843389"); + function PlaySoundnfl() { + nfl.play(); + } + + function doSomething() { + if (clicked) { + var optionclicksound = new Audio(); + optionclicksound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/cancel.wav"; + optionclicksound.load(); + optionclicksound.play(); + } else { + clicksound.load(); + clicksound.play(); + } + clicked = !clicked; + } + + var smallaudio2 = new Audio(); + smallaudio2.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/error.ogg"; + function PlaySound211() { + smallaudio2.play(); + } + + var smallaudio3 = new Audio( + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/socket.wav" + ); + smallaudio3.loop = false; + function PlaySound212() { + smallaudio3.loop = false; + smallaudio3.play(); + } +var killvariablenamething = true; +let metalpipe = new Audio(); +metalpipe.loop = false; +var randomdeathsound = ["https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/metal-pipe-clang.mp3?v=1710271073637", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/undertakers-bell_2UwFCIe.mp3?v=1710268959839", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/aaaaaaaa-online-audio-converter_r9waVUO.mp3?v=1710271069219", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/vine-boom.mp3?v=1710280969499", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tmp_7901-951678082.mp3?v=1710280974624", + "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/emotional-damage-meme.mp3?v=1710280979660", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/discord-notification.mp3?v=1710280983356", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/wrong-answer-sound-effect.mp3?v=1710280995813", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/clash-royale-hog-rider.mp3?v=1710280999656", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/goofy-ahh-car-horn-sound-effect.mp3?v=1710281004188", + "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tf_nemesis.mp3?v=1710281009502", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chinese-rap-song.mp3?v=1710281015151", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fire-in-the-hole-geometry-dash.mp3?v=1710281020367", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/water-on-the-hill.mp3?v=1710281027326", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/taco-bell-bong-sfx.mp3?v=1710281032201", + "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/download.mp3?v=1699142486910", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/spongebob-fail.mp3?v=1699146799125", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/62640b13-df2b-47d8-a06e-fb63b7fbb06e.mp3?v=1699272890577", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/f93f6d33-9dab-4e9d-aebb-917fe2d22982.mp3?v=1700153956047", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/c647ea60-edf9-4bde-a0af-c49353593c7f.mp3?v=1700153959194", + "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/feet-gd.mp3?v=1710431699794", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bad-to-the-bone-meme.mp3?v=1710431694343", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spongebob-boowomp.mp3?v=1710431689245", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/holy-moly-emoji.mp3?v=1710431682780", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/dun_dun_1.mp3?v=1710431679063"]; +function PlaySound420() { + if (global.killsoundready) { + killvariablenamething = true; + getksound(); + } +} +function getksound() { + if (global.killsoundready) { + if (killvariablenamething) { + metalpipe.src = randomdeathsound[Math.floor(Math.random() * randomdeathsound.length)]; + metalpipe.play(); + global.killsoundready = false; + } + } +} + var grubhub = new Audio(); +grubhub.src = ("https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/d318bd1e-5162-4fae-a757-5c350b16ccc9.mp3?v=1700153738394"); +function PlaySound169() { + grubhub.play(); +} + var smallaudio5 = new Audio(); + smallaudio5.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/poka.wav"; + function PlaySound214() { + smallaudio5.play(); + } + var smallaudio6 = new Audio(); + smallaudio6.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/finish.wav"; + function PlaySound215() { + smallaudio6.play(); + } + var camerasound = new Audio(); + camerasound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/camera.wav"; + function PlaySound213() { + camerasound.play(); + } +//Music functions: + //decide the music + global.music2 = document.getElementById("audio"); + const pmusic = ["https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3?v=1705287022417", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav?v=1705286889038", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3?v=1705807057028", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3?v=1708218475743", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3?v=1708218464295", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.wav?v=1713352428783", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"]; + var randmusic = pmusic[~~(Math.random() * pmusic.length)]; + global.music2.src = (randmusic); + //load the play functions for itasdasf meow + function PlayMusic() { + global.music2.load(); + global.music2.play(); +} + let musicvolume = 0; + +//actually play the audio when the checkbox is clicked on (checked) and stop it when unchecked + $("#optSound").on("click", function() { + if (document.getElementById("optSound").checked === true) { + songrecog() + global.music2.play() + //if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { + document.getElementById("content").style.opacity = 0.5 + //audio.src = randmusic; + //audio.load(); + //audio.play(); + var musiccontext = new AudioContext(); + var musicsrc = musiccontext.createMediaElementSource(global.music2); + var analyser = musiccontext.createAnalyser(); + + let musiccanvas = document.getElementById("canvas"); + musiccanvas.width = window.innerWidth; + musiccanvas.height = window.innerHeight; + var ctx3 = musiccanvas.getContext("2d"); + + musicsrc.connect(analyser); + analyser.connect(musiccontext.destination); + + analyser.fftSize = 2048; + + var bufferLength = analyser.frequencyBinCount; + console.log(bufferLength); + + var WIDTHOFBAR = musiccanvas.width; + var HEIGHTOFBAR = musiccanvas.height; + + var dataArray = new Uint8Array(bufferLength); + + var musicbarWidth = (WIDTHOFBAR / bufferLength) * 2.5; + var musicbarHeight; + var barstuffx = 0; + + function renderFrame() { + + let deviscale = window.devicePixelRatio + + requestAnimationFrame(renderFrame); + + barstuffx = 0; + + analyser.getByteFrequencyData(dataArray); + ctx3.fillStyle = "rgba(0,0,0,0.12)"; + ctx3.fillRect(0, 0, WIDTHOFBAR, global.screenHeight); + + for (var i = 0; i < bufferLength; i++) { + musicbarHeight = dataArray[i]; + musicvolume = musicbarHeight; + + var b = musicbarHeight + (18 * (i/bufferLength)); + var r = 250 * (i/bufferLength); + var g = 50; + + ctx3.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; + ctx3.fillRect(barstuffx, global.screenHeight - musicbarHeight * deviscale, musicbarWidth, musicbarHeight); + + barstuffx += musicbarWidth + 1; + } + } + //audio.play(); + renderFrame(); + //} + global.music2.addEventListener('ended', function() {this.currentTime = 0; global.music2.src = pmusic[~~(Math.random() * pmusic.length)]; this.play(); songrecog();}, false); + } else if (document.getElementById("optSound").checked === false) { + document.getElementById("content").style.opacity = 0 + global.music2.pause() + global.music2.songname = "Not Playing"; + } + return; }); + + let counterthing = document.querySelector(".displaytest"); + let skinnamedisplay = document.querySelector(".displayskinname"); + let myImg = document.querySelector("#skinpreview"); + let lock = document.querySelector("#lockedskin"); + let selectimage = document.querySelector("#selectskin"); + + $("#rightarrowbutton").on("click", function() { + if (global.skinpage === 16) { + global.skinpage = 0; + } else { + global.skinpage += 1; + }; + changeskinpreview(); + }); + $("#leftarrowbutton").on("click", function() { + if (global.skinpage === 0) { + global.skinpage = 16; + } else { + global.skinpage -= 1; + }; + changeskinpreview(); + }); + + $("#selectskin").on("click", function() { + if (global.lockedornot === 0) { + global.skin = global.selectedskin; + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; + } else { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; + } + }) + + + function checkifachieve(ach, lockcolor) { + if (global.selectedskin !== "") { + if (localStorage.getItem(ach) === "YOUDIDIT:D!!!") { + global.lockedornot = 0; + lock.style.display = 'none'; + myImg.style.filter = 'brightness(1)'; + updateskinselectbutton(); + } else { + global.lockedornot = 1; + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; + lock.style.display = 'inline-block'; + myImg.style.filter = 'brightness(0.5)'; + if (lockcolor === "white") { + lock.style.filter = 'invert(1)'; + } else if (lockcolor === "grey") { + lock.style.filter = 'invert(0.7)'; + } else if (lockcolor === "dgrey") { + lock.style.filter = 'invert(0.3)'; + } else { + lock.style.filter = 'invert(0)'; + } + } + } else { + lock.style.display = 'none'; + if (global.skin === global.selectedskin) { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; + } else { + global.skin === global.selectedskin + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png?v=1708718071992"; + }; + } +} + + function updateskinselectbutton() { + if (global.lockedornot === 0) { + if (global.skin === global.selectedskin) { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; + } else { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png?v=1708718071992"; + } + } else { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; + } + } + + function changeskinpreview() { + if (global.skinpage === 0) { + counterthing.textContent = "◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = ""; + skinnamedisplay.textContent = "Default"; + checkifachieve("", ""); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png?v=1708568179353"; + } + if (global.skinpage === 1) { + counterthing.textContent = "○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "bsignalskin"; + skinnamedisplay.textContent = "Broken Signal"; + checkifachieve("disconnectachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png?v=1708615075011" + } + if (global.skinpage === 2) { + counterthing.textContent = "○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "tankcharmskin"; + skinnamedisplay.textContent = "Tank Charm"; + checkifachieve("25killsachievement", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png?v=1708536680813"; + } + if (global.skinpage === 3) { + counterthing.textContent = "○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "dfxskin"; + skinnamedisplay.textContent = "Deltafyrex"; + checkifachieve("50killsachievement", "grey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif?v=1708618924966"; + } + if (global.skinpage === 4) { + counterthing.textContent = "○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "primalskin"; + skinnamedisplay.textContent = "Ultimate Primal"; + checkifachieve("100killsachievement", "white"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp?v=1708602763032"; + } + if (global.skinpage === 5) { + counterthing.textContent = "○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "kangarooskin"; + skinnamedisplay.textContent = "Kangaroo"; + checkifachieve("killachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp?v=1708623596560"; + } + if (global.skinpage === 6) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "cswmskin"; + skinnamedisplay.textContent = "ChickenSandwhichMan"; + checkifachieve("killachievement2", "grey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg?v=1708356424097" + } + if (global.skinpage === 7) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "cogskin"; + skinnamedisplay.textContent = "Cogwheel"; + checkifachieve("lagachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381"; + } + if (global.skinpage === 8) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "eggskin"; + skinnamedisplay.textContent = "Eggbert"; + checkifachieve("100shapesachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp?v=1714156807621"; + } + if (global.skinpage === 9) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "squareskin"; + skinnamedisplay.textContent = "Squarey"; + checkifachieve("250shapesachievement", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp?v=1714156773284"; + } + if (global.skinpage === 10) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "triangleskin"; + skinnamedisplay.textContent = "Triangleton"; + checkifachieve("500shapesachievement", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp?v=1714156768932"; + } + if (global.skinpage === 11) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○"; + global.selectedskin = "pentagonskin"; + skinnamedisplay.textContent = "Pentogan"; + checkifachieve("750shapesachievement", "white"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp?v=1714156764280"; + } + if (global.skinpage === 12) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○"; + global.selectedskin = "gemskin"; + skinnamedisplay.textContent = "Gemy"; + checkifachieve("1000shapesachievement", "grey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp?v=1714156778841"; + } + if (global.skinpage === 13) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○"; + global.selectedskin = "coinskin"; + skinnamedisplay.textContent = "Coined"; + checkifachieve("tokenachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png?v=1708619146196"; + } + if (global.skinpage === 14) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○"; + global.selectedskin = "discordskin"; + skinnamedisplay.textContent = "Sex Update"; + checkifachieve("Getbacktowoooak", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png?v=1701908710293"; + } + if (global.skinpage === 15) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○"; + global.selectedskin = "deltaDecoskin"; + skinnamedisplay.textContent = "Cat-Code"; + checkifachieve("creditsachievement", "grey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png?v=1705301828958"; + } + if (global.skinpage === 16) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉"; + global.selectedskin = "incomskin"; + skinnamedisplay.textContent = "Very Much Incommodiousness"; + checkifachieve("pissio", "grey"); + myImg.style.filter = 'blur(10px)'; + myImg.src = "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/1200px-Icon-round-Question_mark.svg.png?v=1699273933044"; + } + }; + let tanktype = "unfinished", + tankdesc = "unfinished", + tanktier = "???", + tankweap = "???", + tankabil = "???", + tankweak = "unfinished", + tankupto = ["Tier 2: ???", "Tier 3: ???", "Tier 4: ???", "Misc: ???"], + tankupfr = "unfinished", + tankorgn = "???", + tankupad = "???"; + let tabappearance = document.querySelector(".tabappearance"); + let taboptions = document.querySelector(".taboptions"); + let tabcontrols = document.querySelector(".tabcontrols"); + let tablinks = document.querySelector(".tablinks"); + let tabappearancebutton = document.querySelector(".tabappearancebutton"); + let taboptionsbutton = document.querySelector(".taboptionsbutton"); + let tabcontrolsbutton = document.querySelector(".tabcontrolsbutton"); + let tablinksbutton = document.querySelector(".tablinksbutton"); + + function changetab(vroomvroomimaracecarreeeroweaweerrrm) { + switch(vroomvroomimaracecarreeeroweaweerrrm) { + case 0: + tabappearance.style.display = 'block'; + taboptions.style.display = 'none'; + tabcontrols.style.display = 'none'; + tablinks.style.display = 'none'; + tabappearancebutton.classList.add("active"); + taboptionsbutton.classList.remove("active"); + tabcontrolsbutton.classList.remove("active"); + tablinksbutton.classList.remove("active"); + break; + case 1: + tabappearance.style.display = 'none'; + taboptions.style.display = 'block'; + tabcontrols.style.display = 'none'; + tablinks.style.display = 'none'; + tabappearancebutton.classList.remove("active"); + taboptionsbutton.classList.add("active"); + tabcontrolsbutton.classList.remove("active"); + tablinksbutton.classList.remove("active"); + break; + case 2: + tabappearance.style.display = 'none'; + taboptions.style.display = 'none'; + tabcontrols.style.display = 'block'; + tablinks.style.display = 'none'; + tabappearancebutton.classList.remove("active"); + taboptionsbutton.classList.remove("active"); + tabcontrolsbutton.classList.add("active"); + tablinksbutton.classList.remove("active"); + break; + case 3: + tabappearance.style.display = 'none'; + taboptions.style.display = 'none'; + tabcontrols.style.display = 'none'; + tablinks.style.display = 'block'; + tabappearancebutton.classList.remove("active"); + taboptionsbutton.classList.remove("active"); + tabcontrolsbutton.classList.remove("active"); + tablinksbutton.classList.add("active"); + break; + } + } + + if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { + + $(".tabappearancebutton").on("click", function() { + changetab(0); + }); + $(".taboptionsbutton").on("click", function() { + changetab(1); + }); + $(".tabcontrolsbutton").on("click", function() { + changetab(2); + }); + $(".tablinksbutton").on("click", function() { + changetab(3); + }); + +} + +let trollface = null; + +function songrecog() { +//song names for display in the debug menu (may move it to a different place later) +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033") { + global.music2.songname = "OI OI OI --- Action Agenda"; +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3?v=1705287022417") { + global.music2.songname = "Dejected --- Deltafyrex"; +} +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav?v=1705286889038") { + global.music2.songname = "World's End --- Deltafyrex"; +} +if (global.music2.src === "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/Meloncholy.mp3?v=1675465750213") { + global.music2.songname = "Melancholy --- Deltafyrex"; +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474") { + global.music2.songname = "Depredation Remastered V2--- Deltafyrex"; +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3?v=1705807057028") { + global.music2.songname = "Anybody can find Love (except You.) --- hkmori" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3?v=1708218475743") { + global.music2.songname = "Resurgam --- Amaryllis" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3?v=1708218464295") { + global.music2.songname = "Longing --- Amaryllis" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240") { + global.music2.songname = "Killa --- Action Agenda (DFX EDIT)" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis%20(1).mp3?v=1713525419376") { + global.music2.songname = "Apotheosis V2 --- Deltafyrex" +} +} +function lagachloop() { + if (global.metrics.rendertime <= 45 && global.metrics.rendertime >= 15) { + util.submitAchievementToLocalStorage("lagachievement"); + } + if (global.savedkillcount >= 100) { + util.submitAchievementToLocalStorage("100killsachievement"); + } + if (global.savedkillcount >= 50) { + util.submitAchievementToLocalStorage("50killsachievement"); + } + if (global.savedkillcount >= 25) { + util.submitAchievementToLocalStorage("25killsachievement"); + } + if (global.savedshapecount >= 100) { + util.submitAchievementToLocalStorage("100shapesachievement"); + } + if (global.savedshapecount >= 250) { + util.submitAchievementToLocalStorage("250shapesachievement"); + } + if (global.savedshapecount >= 500) { + util.submitAchievementToLocalStorage("500shapesachievement"); + } + if (global.savedshapecount >= 750) { + util.submitAchievementToLocalStorage("750shapesachievement"); + } + if (global.savedshapecount >= 1000) { + util.submitAchievementToLocalStorage("1000shapesachievement"); + } +} +/*if (localStorage.getItem("killachievement") !== "YOUDIDIT:D!!!") { + if (global.achievements.kills >= 4) { + util.submitAchievementToLocalStorage("killachievement"); + } +}*/ +if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { +if (localStorage.getItem("startachievement") !== "YOUDIDIT:D!!!") { +localStorage.setItem("savedkills", 0); +} +} +function resetAllAchievements() { + var zeroyeah = 0; + util.resetAchievementFromLocalStorage("killachievement"); +} + let nIntervId; + if (!nIntervId) { + nIntervId = setInterval(gettimesince, 1000); + } + function gettimesince() { + const date = new Date() + var sec = 0; + var min = 0; + var hour = 0; + var day = 0; + var month = 0; + var year = 0; + var nerosec = ''; + var neromin = ''; + var nerohour = ''; + var neroday = ''; + var neromonth = ''; + var daysinm = 0; + if (date.getMonth() == 8 || 10 || 3 || 5) { + daysinm = 30 + } else { + if (date.getMonth() == 1) { + if (date.getFullYear() == 2024 || 2028 || 2032 || 2036 || 2040 || 2044 || 2048 || 2042) { + daysinm = 29 + } else { + daysinm = 28 + } + } else { + daysinm = 31 + } + } + if (date.getSeconds() + 28 > 59) { + sec = (date.getSeconds() + 60) - 92 + } else { + sec = (date.getSeconds() + 60) - 32 + }; + if (date.getMinutes() < 45) { + if (date.getSeconds() > 31) { + min = (date.getMinutes() + 60) - 44 + } else { + min = (date.getMinutes() + 60) - 45 + } + } else { + if (date.getSeconds() > 31) { + min = (date.getMinutes() + 60) - 104 + } else { + min = (date.getMinutes() + 60) - 105 + } + } + if (date.getHours() < 11) { + if (date.getMinutes() > 44) { + hour = ((date.getHours() + 24) - 10) + } else { + hour = ((date.getHours() + 24) - 11) + } + } else { + if (date.getMinutes() > 44) { + hour = ((date.getHours() + 24) - 34) + } else { + hour = ((date.getHours() + 24) - 35) + } + } + if (date.getDate() < 24) { + if (date.getHours() > 10) { + day = (date.getDate() + daysinm) - 23 + } else { + day = (date.getDate() + daysinm) - 24 + } + } else { + if (date.getHours() > 10) { + day = (date.getDate() + daysinm) - (23 + daysinm) + } else { + day = (date.getDate() + daysinm) - (24 + daysinm) + } + }; + if (date.getMonth() < 4) { + if (date.getDate() > 23) { + if (date.getMonth() == 3) { + month = (date.getMonth() + 11) - 14 + } else { + month = (date.getMonth() + 11) - 2 + } + } else { + month = (date.getMonth() + 11) - 3 + } + } else { + if (date.getDate() > 23) { + month = (date.getMonth() + 11) - 14 + } else { + month = (date.getMonth() + 11) - 15 + } + }; + if (date.getMonth() > 2) { + year = ' | Years: ' + (date.getFullYear() - 2019) + } else { + year = ' | Years: ' + (date.getFullYear() - 2020) + } + if (sec !== 0) { + nerosec = ', Seconds: ' + sec + } else { + nerosec = '' + } + if (min !== 0) { + neromin = ', Minutes: ' + min + } else { + neromin = '' + } + if (hour !== 0) { + nerohour = ', Hours: ' + hour + } else { + nerohour = '' + } + if (day !== 0) { + neroday = ', Days: ' + day + } else { + neroday = '' + } + if (month !== 0) { + neromonth = ', Months: ' + month + } else { + neromonth = '' + } + //const currentdate = ' / Current Year: ' + date.getFullYear() + ' / Current Month: ' + date.getMonth() + ' / Current Day: ' + date.getDate() + ' / Current Hour: ' + date.getHours() + ' / Current Minute: ' + date.getMinutes() + ' / Current Second: ' + date.getSeconds() + ' /' + const nerodate = year + ' ' + neromonth + ' ' + neroday + ' ' + nerohour + ' ' + neromin + ' ' + nerosec + ' |' + $(document.getElementById("updatetime")).html("

" + nerodate + "

"); + //$(document.getElementById("updatetime2")).html("

" + currentdate + "

"); + } fetch("changelog.html", { cache: "no-cache" }) .then(async ChangelogsHTMLFile => { let patchNotes = document.querySelector("#patchNotes"); @@ -39,6 +765,25 @@ fetch("changelog.html", { cache: "no-cache" }) } }); +fetch("credits.html", { cache: "no-cache" }) +.then(async CreditsHTMLFile => { + let patchNotes = document.querySelector("#credits"); + try { + let parser = new DOMParser(), + RawHTMLString = await CreditsHTMLFile.text(), + ParsedHTML = parser.parseFromString(RawHTMLString, "text/html"), + titles = ParsedHTML.documentElement.getElementsByTagName('h1'); + for (const title of titles) { + title.classList.add('title'); + } + + patchNotes.innerHTML += ParsedHTML.documentElement.innerHTML; + } catch (error) { + patchNotes.innerHTML = `

An error occured while trying to fetch 'credits.html'

${error}

`; + console.error(error); + } +}); + class Animation { constructor(start, to, smoothness = 0.05) { this.start = start; @@ -121,6 +866,7 @@ function getMockups() { util.pullJSON("mockups").then(data => { global.mockups = data; console.log('Mockups loading complete.'); + console.log("%cWhy are you here Lmfao", "color: #FFFFFF; font-size: 45px; background: #333333; text-shadow: #FFF 0px 0px 5px, #FFF 0px 0px 10px, #FFF 0px 0px 15px, #FF2D95 0px 0px 20px, #FF2D95 0px 0px 30px, #FF2D95 0px 0px 40px, #FF2D95 0px 0px 50px, #FF2D95 0px 0px 75px;"); Resolve(); }); }); @@ -184,15 +930,24 @@ window.onload = async () => { util.retrieveFromLocalStorage("optCustom"); util.retrieveFromLocalStorage("optNoPointy"); util.retrieveFromLocalStorage("optBorders"); + util.retrieveFromLocalStorage("optResolution"); util.retrieveFromLocalStorage("seperatedHealthbars"); + util.retrieveFromLocalStorage("optOgIcon"); + util.retrieveFromLocalStorage("disableDeathSounds"); + util.retrieveFromLocalStorage("optNoEmojis"); util.retrieveFromLocalStorage("autoLevelUp"); // Set default theme if (document.getElementById("optColors").value === "") { - document.getElementById("optColors").value = "normal"; + document.getElementById("optColors").value = "nero"; } if (document.getElementById("optBorders").value === "") { - document.getElementById("optBorders").value = "normal"; + document.getElementById("optBorders").value = "nero"; } + if (document.getElementById("optResolution").value === "") { + document.getElementById("optResolution").value = "normal"; + } + // Achievement Shit + document.getElementById("resetachievementsbutton").onclick = () => resetAllAchievements(); // Game start stuff document.getElementById("startButton").onclick = () => startGame(); document.onkeydown = (e) => { @@ -204,13 +959,36 @@ window.onload = async () => { window.addEventListener("resize", resizeEvent); resizeEvent(); }; +var callofduty = ""; function resizeEvent() { + if (settings.graphical.quality === undefined) { + settings.graphical.quality = 1; + }; let scale = window.devicePixelRatio; if (!settings.graphical.fancyAnimations) { scale *= 0.5; } + if (typeof settings.graphical.quality === 'string' || settings.graphical.quality instanceof String) { + callofduty = new Image(); // Create new img element + if (settings.graphical.quality == "cod") { + callofduty.src = "https://image.api.playstation.com/cdn/EP0002/CUSA12443_00/VgKYOxWoNSp4mNJ2KvzEFVBWN0idCM5I.png?w=440" + } + } else { + scale *= settings.graphical.quality + } + if (settings.graphical.quality == "1dim") { + global.screenWidth = window.innerWidth * scale; + global.screenHeight = 1 * scale; + } else if (settings.graphical.quality == "d1dim") { + global.screenWidth = 1 * scale; + global.screenHeight = window.innerHeight * scale; + } else if (settings.graphical.quality == "1pix") { + global.screenWidth = 1 * scale; + global.screenHeight = 1 * scale; + } else { global.screenWidth = window.innerWidth * scale; global.screenHeight = window.innerHeight * scale; + } c.resize(global.screenWidth, global.screenHeight); global.ratio = scale; global.screenSize = Math.min(1920, Math.max(window.innerWidth, 1280)); @@ -239,7 +1017,7 @@ function Smoothbar(value, speed, sharpness = 3, lerpValue = 0.025) { display = util.lerp(display, value, lerpValue); if (Math.abs(value - display) < 0.1 && round) display = value; return display; - }, + }, force: (val) => { display = value = val; }, @@ -284,7 +1062,7 @@ function parseTheme(string){ stripped += '='; let data = atob(stripped); - let name = 'Unknown Theme', + let name = 'Unknown Theme', author = ''; let index = data.indexOf('\x00'); if (index === -1) return null; @@ -334,7 +1112,6 @@ function parseTheme(string){ } return { name, author, content }; } catch (e) {} - // Decode from JSON try { let output = JSON.parse(string); @@ -379,22 +1156,36 @@ function parseTheme(string){ } // This starts the game and sets up the websocket function startGame() { + PlaySound69(); + clearInterval(nIntervId); + // release our intervalID from the variable + nIntervId = null; // Set flag global.gameLoading = true; console.log('Started connecting.') + //set start achievement + util.submitAchievementToLocalStorage("startachievement"); // Get options util.submitToLocalStorage("optFancy"); util.submitToLocalStorage("centerTank"); util.submitToLocalStorage("optBorders"); + util.submitToLocalStorage("optResolution"); util.submitToLocalStorage("optNoPointy"); + util.submitToLocalStorage("optOgIcon"); + util.submitToLocalStorage("disableDeathSounds"); + util.submitToLocalStorage("optNoEmojis"); util.submitToLocalStorage("autoLevelUp"); util.submitToLocalStorage("optPredictive"); util.submitToLocalStorage("optScreenshotMode"); util.submitToLocalStorage("coloredHealthbars"); - util.submitToLocalStorage("seperatedHealthbars"); + util.submitToLocalStorage("seperatedHealthbars"); + global.ISTHEGODAMNFUCKINGGAMEON = "yeah"; settings.graphical.fancyAnimations = !document.getElementById("optFancy").checked; settings.graphical.centerTank = document.getElementById("centerTank").checked; settings.graphical.pointy = !document.getElementById("optNoPointy").checked; + settings.game.optOgIcon = !document.getElementById("optOgIcon").checked; + settings.game.disableDeathSounds = !document.getElementById("disableDeathSounds").checked; + settings.game.optNoEmojis = !document.getElementById("optNoEmojis").checked; settings.game.autoLevelUp = document.getElementById("autoLevelUp").checked; settings.lag.unresponsive = document.getElementById("optPredictive").checked; settings.graphical.screenshotMode = document.getElementById("optScreenshotMode").checked; @@ -416,9 +1207,50 @@ function startGame() { settings.graphical.darkBorders = settings.graphical.neon = true; break; } + switch (document.getElementById("optResolution").value) { + case "normal": + settings.graphical.quality = 1; + break; + case "low": + settings.graphical.quality = 0.75; + break; + case "high": + settings.graphical.quality = 1.5; + break; + case "higher": + settings.graphical.quality = 2; + break; + case "rtx": + settings.graphical.quality = 4; + break; + case "really low": + settings.graphical.quality = 0.5; + break; + case "really really low": + settings.graphical.quality = 0.25; + break; + case "unplayable": + settings.graphical.quality = 0.1; + break; + case "1d": + settings.graphical.quality = "1dim"; + break; + case "d1": + settings.graphical.quality = "d1dim"; + break; + case "onepixel": + settings.graphical.quality = "1pix"; + break; + case "codbo4": + settings.graphical.quality = "cod"; + break; + case "drugs": + settings.graphical.quality = "trippy"; + break; + } util.submitToLocalStorage("optColors"); let a = document.getElementById("optColors").value; - color = color[a === "" ? "normal" : a]; + color = color[a === "" ? "nero" : a]; if (a == "custom") { let customTheme = document.getElementById("optCustom").value; color = parseTheme(customTheme).content; @@ -438,6 +1270,8 @@ function startGame() { global.screenHeight = window.innerHeight; document.getElementById("startMenuWrapper").style.maxHeight = "0px"; document.getElementById("gameAreaWrapper").style.opacity = 1; + + document.getElementById("hideongamestart").style.zIndex = "-3"; // Set up the socket if (!global.socket) { global.socket = socketInit(26301); @@ -449,6 +1283,9 @@ function startGame() { setInterval(() => moveCompensation.iterate(global.socket.cmd.getMotion()), 1000 / 30); document.getElementById("gameCanvas").focus(); window.onbeforeunload = () => true; + if (settings.game.optNoEmojis) { + trollface = new Image(); // Create new img element + } } // Background clearing function clearScreen(clearColor, alpha) { @@ -463,7 +1300,7 @@ function arrayifyText(rawText) { // string with double § txt col txt txt // "...§text§§text§..." => [..., "text", "", "text", ...] => [..., "text§text", ...] // this code is balanced on tight threads, holy shit - let textArrayRaw = rawText.split('§'), + let textArrayRaw = rawText.split(/§|;;/), textArray = []; if (!(textArrayRaw.length & 1)) { textArrayRaw.unshift(''); @@ -561,6 +1398,162 @@ function drawText(rawText, x, y, size, defaultFillStyle, align = "left", center } context.restore(); } + +// Library: mltext.js +// Desciption: Extends the CanvasRenderingContext2D that adds two functions: mlFillText and mlStrokeText. +// +// The prototypes are: +// +// function mlFillText(text,x,y,w,h,vAlign,hAlign,lineheight); +// function mlStrokeText(text,x,y,w,h,vAlign,hAlign,lineheight); +// +// Where vAlign can be: "top", "center" or "button" +// And hAlign can be: "left", "center", "right" or "justify" +// Author: Jordi Baylina. (baylina at uniclau.com) +// License: GPL +// Date: 2013-02-21 + +function mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, defaultFillStyle = color.guiwhite, fn = "strokeText") { + textsize += settings.graphical.fontSizeBoost; + // Get text dimensions and resize/reset the canvas + let offset = textsize / 5, + ratio = 1; + if (ctx.getTransform) { + ratio = ctx.getTransform().d; + offset *= ratio; + } + if (ratio !== 1) { + textsize *= ratio; + } + ctx.font = "bold " + textsize + "px Ubuntu"; + text = text.replace(/[\n]/g, " \n "); + text = text.replace(/\r/g, ""); + lineheight += settings.graphical.fontSizeBoost; + var words = text.split(/[ ]+/); + var sp = ctx.measureText(' ').width; + var lines = []; + var actualline = 0; + var actualsize = 0; + var wo; + lines[actualline] = {}; + lines[actualline].Words = []; + let i = 0; + while (i < words.length) { + var word = words[i]; + if (word == "\n") { + lines[actualline].EndParagraph = true; + actualline++; + actualsize = 0; + lines[actualline] = {}; + lines[actualline].Words = []; + i++; + } else { + wo = {}; + wo.l = ctx.measureText(word).width; + if (actualsize === 0) { + while (wo.l > w) { + word = word.slice(0, word.length - 1); + wo.l = ctx.measureText(word).width; + } + if (word === "") return; // I can't fill a single character + wo.word = word; + lines[actualline].Words.push(wo); + actualsize = wo.l; + if (word != words[i]) { + words[i] = words[i].slice(word.length, words[i].length); + } else { + i++; + } + } else { + if (actualsize + sp + wo.l > w) { + lines[actualline].EndParagraph = false; + actualline++; + actualsize = 0; + lines[actualline] = {}; + lines[actualline].Words = []; + } else { + wo.word = word; + lines[actualline].Words.push(wo); + actualsize += sp + wo.l; + i++; + } + } + } + } + if (actualsize === 0) lines[actualline].pop(); + lines[actualline].EndParagraph = true; + + var totalH = lineheight * lines.length; + while (totalH > h) { + lines.pop(); + totalH = lineheight * lines.length; + } + + var yy; + if (vAlign == "bottom") { + yy = y + h - totalH + lineheight; + } else if (vAlign == "center") { + yy = y + h / 2 - totalH / 2 + lineheight; + } else { + yy = y + lineheight; + } + + var oldTextAlign = ctx.textAlign; + ctx.textAlign = "left"; + ctx.strokeStyle = color.black; + ctx.fillStyle = defaultFillStyle; + ctx.lineWidth = (textsize + 1) / settings.graphical.fontStrokeRatio; + + for (var li in lines) { + var totallen = 0; + var xx, usp; + for (wo in lines[li].Words) totallen += lines[li].Words[wo].l; + if (hAlign == "center") { + usp = sp; + xx = x + w / 2 - (totallen + sp * (lines[li].Words.length - 1)) / 2; + } else if ((hAlign == "justify") && (!lines[li].EndParagraph)) { + xx = x; + usp = (w - totallen) / (lines[li].Words.length - 1); + } else if (hAlign == "right") { + xx = x + w - (totallen + sp * (lines[li].Words.length - 1)); + usp = sp; + } else { // left + xx = x; + usp = sp; + } + for (wo in lines[li].Words) { + if (fn == "fillText") { + ctx.fillText(lines[li].Words[wo].word, xx, yy); + } else if (fn == "strokeText") { + ctx.strokeText(lines[li].Words[wo].word, xx, yy); + let textArray = lines[li].Words[wo].word; + var Xoffset = 0; + for (let i = 0; i < textArray.length; i++) { + let str = textArray[i]; + if (i) { + Xoffset += ctx.measureText(textArray[i - 1] + str).width - ctx.measureText(str).width; + } + ctx.fillText(str, xx + Xoffset, yy); + } + } + xx += lines[li].Words[wo].l + usp; + } + yy += lineheight; + } + ctx.textAlign = oldTextAlign; +} + +(function mlInit() { + CanvasRenderingContext2D.prototype.mlFunction = mlFunction; + + CanvasRenderingContext2D.prototype.mlFillText = function (text, x, y, w, h, vAlign, hAlign, lineheight, textsize, defaultFillStyle) { + ctx.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, "fillText"); + }; + + CanvasRenderingContext2D.prototype.mlStrokeText = function (text, x, y, w, h, vAlign, hAlign, lineheight, textsize, defaultFillStyle) { + ctx.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, "strokeText"); + } + })(); // Gui drawing functions function drawGuiRect(x, y, length, height, stroke = false) { switch (stroke) { @@ -570,6 +1563,43 @@ function drawGuiRect(x, y, length, height, stroke = false) { case false: ctx.fillRect(x, y, length, height); break; + case 0: + ctx.beginPath(); + ctx.lineTo(x, y); + ctx.lineTo(x + length, y); + ctx.lineTo(x, y + height); + ctx.lineTo(x + length, y + height); + ctx.closePath(); + ctx.stroke(); + break; + case 1: + ctx.beginPath(); + ctx.roundRect(x, y, length, height, 5); + ctx.stroke(); + break; + case 2: + ctx.beginPath(); + ctx.roundRect(x, y, length, height, 5); + ctx.stroke(); + ctx.fill(); + break; + case 3: + ctx.beginPath(); + ctx.roundRect(x, y, length, height, [5,5,0,0]); + ctx.stroke(); + ctx.fill(); + break; + case 4: + ctx.beginPath(); + ctx.lineTo(x, y); + ctx.lineTo(x + length, y); + ctx.lineTo(x + length, y + height); + ctx.lineTo(x, y + height); + //ctx.lineWidth = strokeWidth; + //ctx.strokeStyle = color; + ctx.closePath(); + ctx.stroke(); + break; } } @@ -929,7 +1959,7 @@ function drawHealth(x, y, instance, ratio, alpha) { let health = instance.render.health.get(), shield = instance.render.shield.get(); if (health < 0.99 || shield < 0.99) { - let col = settings.graphical.coloredHealthbars ? gameDraw.mixColors(gameDraw.modifyColor(instance.color), color.guiwhite, 0.5) : color.lgreen; + let col = settings.graphical.coloredHealthbars ? gameDraw.mixColors(gameDraw.modifyColor(instance.color), color.guiwhite, 0.5) : color.blue; let yy = y + realSize + 15 * ratio; let barWidth = 3 * ratio; ctx.globalAlpha = fade * (alpha ** 2); @@ -959,7 +1989,7 @@ function drawHealth(x, y, instance, ratio, alpha) { ctx.globalAlpha = 1; } } - + const iconColorOrder = [10, 11, 12, 15, 13, 2, 14, 4, 5, 1, 0, 3]; function getIconColor(colorIndex) { return iconColorOrder[colorIndex % 12].toString(); @@ -972,13 +2002,55 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c entityX = x + 0.5 * len, entityY = y + 0.5 * height, baseColor = picture.color; - - // Find x and y shift for the entity image - let xShift = position.middle.x * Math.cos(angle) - position.middle.y * Math.sin(angle), + // Find x and y shift for the entity image + let xShift = position.middle.x * Math.cos(angle) - position.middle.y * Math.sin(angle), yShift = position.middle.x * Math.sin(angle) + position.middle.y * Math.cos(angle); - entityX -= scale * xShift; - entityY -= scale * yShift; + entityX -= scale * xShift; + entityY -= scale * yShift; + + if (settings.game.optOgIcon) { + // Draw box + ctx.strokeStyle = color.black; + ctx.fillStyle = color.black; + ctx.lineWidth = 3 * lineWidthMult; + ctx.globalAlpha = 0.4 + drawGuiRect(x + 8, y + 8, len, height, 2); + ctx.globalAlpha = alpha; + ctx.fillStyle = picture.upgradeColor != null + ? gameDraw.modifyColor(picture.upgradeColor) + : gameDraw.getColor(getIconColor(colorIndex)); + //drawGuiRect(x + 25, y + 25, len - 50, height - 50, 2); + drawGuiRect(x, y, len, height, 2); + ctx.globalAlpha = 0.1; + drawGuiRect(x, y, len, height * 0.6, 3); + ctx.globalAlpha = 0.25 * alpha; + ctx.fillStyle = color.black; + drawGuiRect(x, y + height * 0.6, len, height * 0.4); + // Shading for hover + if (hover) { + ctx.globalAlpha = 0.15 * alpha; + ctx.fillStyle = color.guiwhite; + drawGuiRect(x, y, len, height, 3); + } + ctx.globalAlpha = 1; + if (settings.graphical.quality == "cod") { + ctx.drawImage(callofduty, x, y, len, height); + } + + // Draw Tank + drawEntity(baseColor, entityX, entityY, picture, 1, 1, scale / picture.size, lineWidthMult, angle, true); + + // Tank name + drawText(picture.upgradeName ?? picture.name, x + (upgradeKey ? 0.9 * len : len) / 2, y + height * 0.94, height / 10, color.guiwhite, "center"); + // Upgrade key + if (upgradeKey) { + drawText("[" + upgradeKey + "]", x + len - 4, y + height - 6, height / 8 - 5, color.guiwhite, "right"); + } + ctx.strokeStyle = color.black; + ctx.lineWidth = 3 * lineWidthMult; + drawGuiRect(x, y, len, height, 1); // Border + } else { // Draw box ctx.globalAlpha = alpha; ctx.fillStyle = picture.upgradeColor != null @@ -995,6 +2067,9 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c drawGuiRect(x, y, len, height); } ctx.globalAlpha = 1; + if (settings.graphical.quality == "cod") { + ctx.drawImage(callofduty, x, y, len, height); + } // Draw Tank drawEntity(baseColor, entityX, entityY, picture, 1, 1, scale / picture.size, lineWidthMult, angle, true); @@ -1009,6 +2084,7 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c ctx.strokeStyle = color.black; ctx.lineWidth = 3 * lineWidthMult; drawGuiRect(x, y, len, height, true); // Border + } } // Start animation @@ -1229,8 +2305,15 @@ function drawFloor(px, py, ratio) { ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : color.white; ctx.fillRect(left, top, right - left, bottom - top); ctx.globalAlpha = 0.3; - ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : gameDraw.modifyColor(tile); + if (settings.graphical.quality === "trippy") { + ctx.fillStyle = gameDraw.getColor("animatedepilepsy") + } else { + ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : gameDraw.modifyColor(tile); + } ctx.fillRect(left, top, right - left, bottom - top); + if (settings.graphical.quality == "cod") { + ctx.drawImage(callofduty, left, top, right - left, bottom - top); + } } } ctx.lineWidth = 1.25; @@ -1312,11 +2395,26 @@ function drawEntities(px, py, ratio) { text = chat.text, msgLengthHalf = measureText(text, 15 * ratioForChat) / 2, alpha = Math.max(0, Math.min(1000, chat.expires - now) / 1000); - ctx.globalAlpha = 0.5 * alpha; + if (settings.game.optNoEmojis) { + if (text.includes("--troll")) { + trollface.addEventListener("load", () => { + global.emojiloaded = true; + }); + trollface.src = "https://upload.wikimedia.org/wikipedia/en/thumb/9/9a/Trollface_non-free.png/220px-Trollface_non-free.png"; // Set source path + msgLengthHalf = (measureText(text, 15 * ratioForChat) / 2) - 23; + } + }; drawBar(x - msgLengthHalf, x + msgLengthHalf, y, 30 * ratioForChat, gameDraw.modifyColor(instance.color)); ctx.globalAlpha = alpha; settings.graphical.fontStrokeRatio *= 1.2; + if (settings.game.optNoEmojis) { + if (global.emojiloaded && text.includes("--troll")) { + let wheretrollfaceis = (ratioForChat) - msgLengthHalf; + text = text.replace("--troll", ""); + ctx.drawImage(trollface, x - wheretrollfaceis, y + -1 * ratioForChat, 18 * ratioForChat, 18 * ratioForChat); + } + } drawText(text, x, y + 7 * ratioForChat, 15 * ratioForChat, color.guiwhite, "center"); settings.graphical.fontStrokeRatio /= 1.2; y -= 35 * ratioForChat; @@ -1548,19 +2646,67 @@ function drawSelfInfo(spacing, alcoveSize, max) { ctx.lineWidth = 1; // Draw the exp bar + //ctx.fillStyle = color.black; + //drawGuiRect(x - 13, y - 3, len + 26, (height + 1) + settings.graphical.barChunk); + //ctx.fillStyle = color.grey; + //drawGuiRect(x - 10, y, len + 20, height - settings.graphical.barChunk / 4); + //ctx.fillStyle = color.blue; + //drawGuiRect(x - 10, y, (len + 20) * gui.__s.getProgress(), height - settings.graphical.barChunk / 4); drawBar(x, x + len, y + height / 2, height + settings.graphical.barChunk, color.black); drawBar(x, x + len, y + height / 2, height - settings.graphical.barChunk / 4, color.grey); - drawBar(x, x + len * gui.__s.getProgress(), y + height / 2, height - 2, color.gold); + drawBar(x, x + len * gui.__s.getProgress(), y + height / 2, height - 2, color.blue); // Draw the class type drawText("Level " + gui.__s.getLevel() + " " + gui.class, x + len / 2, y + height / 2 + 1, height - 2.5, color.guiwhite, "center", true); height = 16; y -= height + vspacing; + + if (gui.class === "Winsor") { + PlaySound169(); + } + document.onkeydown = (e) => { + var key = e.which || e.keyCode; + if (gui.class === "Trapper_guy" & key === global.KEY_SHIFT) { + PlaySoundtrap(); + } else { + if (gui.class === "Waduh" & key === global.KEY_SHIFT) { + PlaySoundwater(); + } else { + if (gui.class === "Waduh" & key === global.KEY_CHOOSE_5) { + PlaySoundwatuh(); + } else { + if (gui.class === "Pissliner" & key === global.KEY_SHIFT) { + PlaySoundpiss(); + } else { + if (gui.class === "Pissliner" & key === global.KEY_SPLIT) { + PlaySoundpew(); + } else { + if (gui.class === "Delta Congregation" & key === global.KEY_SPLIT) { + PlaySoundchipi(); + } else { + if (gui.class === "Delta" & key === global.KEY_CHOOSE_5) { + PlaySoundneko(); + } else { + if (gui.class === "Delta" & key === global.KEY_CHOOSE_4) { + PlaySoundbwomp(); + } else { + if (gui.class === "Delta" & key === global.KEY_CHOOSE_3) { + PlaySoundnfl(); + } + } + } + } + } + } + } + } + } + } // Draw the %-of-leader bar drawBar(x + len * 0.1, x + len * 0.9, y + height / 2, height - 3 + settings.graphical.barChunk, color.black); drawBar(x + len * 0.1, x + len * 0.9, y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.grey); - drawBar(x + len * 0.1, x + len * (0.1 + 0.8 * (max ? Math.min(1, gui.__s.getScore() / max) : 1)), y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.green); + drawBar(x + len * 0.1, x + len * (0.1 + 0.8 * (max ? Math.min(1, gui.__s.getScore() / max) : 1)), y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.teal); //write the score and name drawText("Score: " + util.formatLargeNumber(Math.floor(gui.__s.getScore())), x + len / 2, y + height / 2 + 1, height - 3.5, color.guiwhite, "center", true); @@ -1614,7 +2760,6 @@ function drawMinimapAndDebug(spacing, alcoveSize) { ctx.globalAlpha = 1; ctx.lineWidth = 3; ctx.fillStyle = color.black; - drawGuiRect(x, y, len, height, true); // Border for (let entity of minimap.get()) { ctx.fillStyle = gameDraw.mixColors(gameDraw.modifyColor(entity.color), color.black, 0.3); ctx.globalAlpha = entity.alpha; @@ -1631,29 +2776,38 @@ function drawMinimapAndDebug(spacing, alcoveSize) { } } ctx.globalAlpha = 1; - ctx.lineWidth = 1; - ctx.strokeStyle = color.guiblack; - ctx.fillStyle = color.guiblack; + ctx.lineWidth = 3; + ctx.fillStyle = color.black; + if (settings.game.optOgIcon) { + drawGuiRect(x, y, len, height, 1); // Border ctx.lineWidth = 1; + } else { + drawGuiRect(x, y, len, height, true); // Border ctx.lineWidth = 1; + } + ctx.strokeStyle = color.black; + ctx.fillStyle = color.black; drawGuiCircle(x + (global.player.cx / global.gameWidth) * len - 1, y + (global.player.cy / global.gameHeight) * height - 1, 2, false); if (global.showDebug) { drawGuiRect(x, y - 40, len, 30); lagGraph(lag.get(), x, y - 40, len, 30, color.teal); gapGraph(global.metrics.rendergap, x, y - 40, len, 30, color.pink); - timingGraph(GRAPHDATA, x, y - 40, len, 30, color.yellow); + //timingGraph(GRAPHDATA, x, y - 40, len, 30, color.yellow); } //minimap stuff ends here //debug stuff if (!global.showDebug) y += 14 * 3; // Text if (global.showDebug) { - drawText("Open Source Arras", x + len, y - 50 - 5 * 14 - 2, 15, "#B6E57C", "right"); - drawText("Prediction: " + Math.round(GRAPHDATA) + "ms", x + len, y - 50 - 4 * 14, 10, color.guiwhite, "right"); - drawText(`Bandwidth: ${gui.bandwidth.in} in, ${gui.bandwidth.out} out`, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); - drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); - drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); - drawText(global.metrics.latency + " ms - " + global.serverName, x + len, y - 50, 10, color.guiwhite, "right"); + drawText("Nero Engine v3.1", x + len, y - 50 - 7 * 14 - 2, 15, "#6a36e3", "right"); + //drawText("Prediction: " + Math.round(GRAPHDATA) + "ms", x + len, y - 50 - 4 * 14, 10, color.guiwhite, "right"); + drawText("Update Version: " + "v3.112", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); + drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 5 * 14, 10, color.guiwhite, "right"); + drawText("Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 4 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); + drawText("Server Speed: " + ((global.metrics.updatetime * global.metrics.rendergap-global.metrics.lag) / 10).toFixed(2) + "%", x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); + drawText("Kills: " + global.metrics.killcount + " Shapes: " + global.metrics.shapecount, x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); + drawText("Song: " + global.music2.songname, x + len, y - 50 - 1 * 14, 10, color.guiwhite, "right"); + drawText(global.metrics.latency + " ms - neroio2 :FFA:", x + len, y - 50, 10, color.guiwhite, "right"); } else { - drawText("Open Source Arras", x + len, y - 50 - 2 * 14 - 2, 15, "#B6E57C", "right"); + drawText("Nero.io v3.1", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); drawText(global.metrics.latency + " ms : " + global.metrics.updatetime + "Hz", x + len, y - 50, 10, color.guiwhite, "right"); } @@ -1689,16 +2843,16 @@ function drawLeaderboard(spacing, alcoveSize, max) { y += vspacing + height; } } - function drawAvailableUpgrades(spacing, alcoveSize) { // Draw upgrade menu if (gui.upgrades.length > 0) { let internalSpacing = 15; let len = alcoveSize / 2; let height = len; - + // Animation processing - let columnCount = Math.max(3, Math.floor(gui.upgrades.length ** 0.55)); +// let columnCount = Math.max(Math.ceil(gui.upgrades.length / 5), 3); + let columnCount = Math.max(3, Math.ceil(gui.upgrades.length / 3)); upgradeMenu.set(0); if (!global.canUpgrade) { upgradeMenu.force(-columnCount * 3) @@ -1719,7 +2873,7 @@ function drawAvailableUpgrades(spacing, alcoveSize) { let lastBranch = -1; let upgradeHoverIndex = global.clickables.upgrade.check({x: global.mouse.x, y: global.mouse.y}); upgradeSpin += 0.01; - + for (let i = 0; i < gui.upgrades.length; i++) { let upgrade = gui.upgrades[i]; let upgradeBranch = upgrade[0]; @@ -1746,10 +2900,12 @@ function drawAvailableUpgrades(spacing, alcoveSize) { if (y > initialY) initialY = y; rowWidth = x; - - global.clickables.upgrade.place(i, x * clickableRatio, y * clickableRatio, len * clickableRatio, height * clickableRatio); - let upgradeKey = getClassUpgradeKey(upgradeNum); - + +// global.clickables.upgrade.place(i, y * clickableRatio, x * clickableRatio, len * clickableRatio, height * clickableRatio); + global.clickables.upgrade.place(i, x * clickableRatio, y * clickableRatio, len * clickableRatio, height * clickableRatio); + let upgradeKey = getClassUpgradeKey(upgradeNum); + +// drawEntityIcon(model, y, x, len, height, 1, upgradeSpin, 0.5, colorIndex++, upgradeKey); drawEntityIcon(model, x, y, len, height, 1, upgradeSpin, 0.6, colorIndex++, upgradeKey, upgradeNum == upgradeHoverIndex); ticker++; @@ -1912,17 +3068,80 @@ const gameDrawDead = () => { drawText("(press enter to respawn)", x, y + 125, 16, color.guiwhite, "center"); ctx.translate(0, shift * global.screenHeight); }; +const gameDrawWiki = () => { + clearScreen(color.black, 0.5); + let ratio = util.getScreenRatio(); + scaleScreenRatio(ratio, true); + let shift = animations.deathScreen.get(); + ctx.translate(0, -shift * global.screenHeight); + let x = global.screenWidth / 2 - 215, + y = global.screenHeight / 2 - 50; + let len = 140, + position = global.mockups[parseInt(gui.type.split("-")[0])].position, + scale = len / position.axis, + xx = global.screenWidth / 2 - scale * position.middle.x * 0.707 - 215, + yy = global.screenHeight / 2 - 35 + scale * position.middle.y * 0.707, + picture = util.getEntityImageFromMockup(global.wikidisplaytank.toString(), color.blue), + baseColor = picture.color; + if (eval(`tankdescs.${picture.className}`) !== undefined) { + tanktype = eval(`tankdescs.${picture.className}.type`); + tankdesc = eval(`tankdescs.${picture.className}.desc`); + tanktier = eval(`tankdescs.${picture.className}.tier`); + tankweap = eval(`tankdescs.${picture.className}.weapons`); + tankabil = eval(`tankdescs.${picture.className}.abilities`); + tankweak = eval(`tankdescs.${picture.className}.weak`); + tankupto = eval(`tankdescs.${picture.className}.upgradesto`); + tankupfr = eval(`tankdescs.${picture.className}.upgradesfrom`); + tankorgn = eval(`tankdescs.${picture.className}.origin`); + tankupad = eval(`tankdescs.${picture.className}.updateadded`); + } else { + tanktype = "???"; + tankdesc = "???"; + tanktier = "???"; + tankweap = "???"; + tankabil = "???"; + tankweak = "???"; + tankupto = ["Tier 2: ???", "Tier 3: ???", "Tier 4: ???", "Misc: ???"]; + tankupad = "???"; + tankupfr = "???"; + tankorgn = "???"; + }; + drawEntity(baseColor, (xx - 190 - len / 2 + 0.5) | 0, (yy - 10 + 0.5) | 0, picture, 1.5, 1, (0.6 * scale) / picture.realSize, 1, -Math.PI / 4, true); + drawText(picture.name, (xx - 190 - len / 2 + 0.5) | 0, (yy + 78.5 + 0.5) | 0, 18, color.guiwhite, "center"); + drawText("Class." + picture.className, (xx - 190 - len / 2 + 0.5) | 0, (yy - 80 + 0.5) | 0, 14, color.guiwhite, "center"); + drawText(global.wikidisplaytank.toString(), (xx - 190 - len / 2 + 0.5) | 0, (yy - 100 + 0.5) | 0, 16, color.guiwhite, "center"); + drawText("Description:", x - 185, y - 70, 17, color.guiwhite, "left"); + ctx.mlStrokeText(tankdesc, x - 185, y - 70, 215, 200, 'top', 'left', 20, 14); + drawText("Do yall think this will work?", x + 100, y + 130, 16, color.guiwhite, "center"); + drawText("[Esc] Exit Entity Debugger", 10, global.screenHeight - 56, 12, color.guiwhite, "left"); + drawText("[Enter] Search Entity ID", 10, global.screenHeight - 33, 12, color.guiwhite, "left"); + drawText("[A] Cycle Left || [D] Cycle Right", 10, global.screenHeight - 10, 12, color.guiwhite, "left"); + drawGuiLine(x + 40, y - 90, x + 40, (yy + 58 + 0.5)); + drawText("Tier: " + tanktier, x + 60, y - 75, 14, color.guiwhite, "left"); + drawText("Weapons: " + tankweap, x + 60, y - 52, 14, color.guiwhite, "left"); + drawText("Abilities: " + tankabil, x + 60, y - 29, 14, color.guiwhite, "left"); + drawText("Upgrades From: " + tankupfr, x + 60, y - 6, 14, color.guiwhite, "left"); + drawText("Weak To: " + tankweak, x + 60, y + 17, 14, color.guiwhite, "left"); + drawText("Type: " + tanktype, x + 60, y + 40, 14, color.guiwhite, "left"); + drawText("Update: " + tankupad, x + 60, y + 63, 14, color.guiwhite, "left"); + drawText("Origin: " + tankorgn, x + 60, y + 86, 14, color.guiwhite, "left"); + drawGuiLine(x + 300, y - 90, x + 300, (yy + 58 + 0.5)); + drawText("Upgrades To: ", x + 320, y - 75, 14, color.guiwhite, "left"); + ctx.mlStrokeText(tankupto[0] + " \n " + tankupto[1] + " \n " + tankupto[2] + " \n " + tankupto[3], x + 320, y - 75, 350, 200, 'top', 'left', 16, 11); + ctx.translate(0, shift * global.screenHeight); +}; const gameDrawBeforeStart = () => { let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); - clearScreen(color.white, 0.5); + clearScreen(color.white, 1); let shift = animations.connecting.get(); ctx.translate(0, -shift * global.screenHeight); drawText("Connecting...", global.screenWidth / 2, global.screenHeight / 2, 30, color.guiwhite, "center"); - drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.lgreen, "center"); + drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.blue, "center"); ctx.translate(0, shift * global.screenHeight); }; const gameDrawDisconnected = () => { + util.submitAchievementToLocalStorage("disconnectachievement"); let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(gameDraw.mixColors(color.red, color.guiblack, 0.3), 0.25); @@ -1933,13 +3152,14 @@ const gameDrawDisconnected = () => { ctx.translate(0, shift * global.screenHeight); }; const gameDrawError = () => { + util.submitAchievementToLocalStorage("disconnectachievement"); let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(gameDraw.mixColors(color.red, color.guiblack, 0.2), 0.35); let shift = animations.error.get(); ctx.translate(0, -shift * global.screenHeight); drawText("There has been an error!", global.screenWidth / 2, global.screenHeight / 2 - 50, 50, color.guiwhite, "center"); - drawText("Check the browser console for details.", global.screenWidth / 2, global.screenHeight / 2, 30, color.guiwhite, "center"); + drawText("(This Either Means The Dev's Working On The Game Or Its Bugged)", global.screenWidth / 2, global.screenHeight / 1.8, 20, color.blue, "center"); drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.orange, "center"); ctx.translate(0, shift * global.screenHeight); }; @@ -1954,6 +3174,7 @@ function animloop() { ctx.lineJoin = "round"; // Draw the game if (global.gameStart && !global.disconnected) { + lagachloop(); global.time = getNow(); if (global.time - lastPing > 1000) { // Latency @@ -1978,22 +3199,35 @@ function animloop() { } if (global.died) { gameDrawDead(); + if (settings.game.disableDeathSounds) { + PlaySound420(); + } + global.metrics.killcount = 0; + } else { + if (global.stopthefuckingkillsoundyouprick) { + metalpipe.pause(); + metalpipe.currentTime = 0; + global.stopthefuckingkillsoundyouprick = false; + } } if (global.disconnected) { gameDrawDisconnected(); } + if (global.wiki) { + gameDrawWiki(); + } ctx.translate(-0.5, -0.5); - //oh no we need to throw an error! } catch (e) { - + //hold on.... gameDrawError(); ctx.translate(-0.5, -0.5); - + //okay, NOW throw the error! throw e; + } } -})(util, global, settings, Canvas, color, gameDraw, socketStuff); +})(util, global, settings, Canvas, color, gameDraw, socketStuff); \ No newline at end of file diff --git a/public/changelog.html b/public/changelog.html index 0d2f173ba..c31a69522 100644 --- a/public/changelog.html +++ b/public/changelog.html @@ -1,18 +1,506 @@ -
-

Title 1: optional description

- optional date -
    -
  • Change 1
  • -
  • Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, excepturi.
  • -
  • Change 3
  • -
-
-
-

Title 2: optional description

- optional date -
    -
  • Change 1
  • -
  • Change 2
  • -
  • Change 3
  • -
-
\ No newline at end of file +
+

Update 3.1

+ [2024] +
    +
  • fixed date since counter
  • +
  • Added BackShield & Mirror Shield
  • +
  • Fixed Tag Gamemode
  • +
  • Removed Stats Temporarily
  • +
  • Changed Bot Leveling
  • +
  • Nerfs & Buffs
  • +
  • Reorganized Entities
  • +
  • Added New Color System
  • +
  • Fixed Color System
  • +
  • New DFX Maze Map
  • +
  • Added Apotheosis V2 & Depredation Remastered V2 By Deltafyrex and Killa By Action Agenda (DFX Edit) To OST
  • +
  • Fixed Siege
  • +
  • Fixed Movement System
  • +
  • Fixed Death Sounds
  • +
  • Revamped Menu Popups
  • +
  • Added TwinSniper Branch And More to Acid And Chiller Branch
  • +
  • Fixed Music Bug, And Added Aura Basic, Jump Smasher And Whirlwind To The Main game
  • +
  • Fixed Shields
  • +
  • Moved Aura From Tier 3 To Tier 2 And Added Aura Branch
  • +
  • Added Flail & Buffed Auras
  • +
  • Added Firecracker, Douverie & Auto-2 Branch
  • +
  • Added Brella (upgrades from backshield) And Lancer Branch
  • +
  • Added More Options For Quality Of Life Features
  • +
  • Added New Achievements & Skins
  • +
  • Fixed Player Skin Bug
  • +
  • Fixed Color System Again And Added Glow + Nerfs/Buffs And other Bug Fixes
  • +

    Holay Molay

    +
+
+
+

Update 3.0

+ [2024] +
    +
  • Added Clubbin
  • +
  • Testing Achievements
  • +
  • Added Reset Achievements Button
  • +
  • Added Start Achievement
  • +
  • Added and Fixed Achievement Details
  • +
  • Added Disconnect, Lag, And Killstreak Achievement
  • +
  • Removed Kill Achievement cuz it dont work
  • +
  • Added New Special Achievement Type
  • +
  • Added Special Piss.io Achievement And Funny Skype Achievement
  • +
  • Re-Added And Fixed 5 Killstreak Achievement Again
  • +
  • Added Server to Client Functions
  • +
  • Added 10 Killstreak Achievement
  • +
  • Changed Debug Menu
  • +
  • Added Kill Amount In Debug
  • +
  • Added Audio Visualizer in the title screen
  • +
  • Fixed Embed Not Working Properly
  • +
  • Fixed Bug Where Audio Visualizer Appears In Game
  • +
  • Added Token And Discord Achievement
  • +
  • Added Achievements Tab
  • +
  • Removed Ach Testing
  • +
  • Added Credits Button
  • +
  • fixed credits interfering with changelog
  • +
  • added credits-changelog animation transition
  • +
  • moved credits button (its 1:08 am im soooooo tired)
  • +
  • Fixed Game Breaking Bug
  • +
  • Added Contagion Branch To Subduer & Trapper
  • +
  • Added Longing And Resurgam By Amaryllis To The OST
  • +
  • added credits ach
  • +
  • Added 2 New Branches For Desmos
  • +
  • Testing Skins
  • +
  • Added Beta Skin Menu
  • +
  • Fixed Skin Bug
  • +
  • Fixed Crashing On Respawn
  • +
  • Added More Detail To Skin Menu
  • +
  • Added Cat Code and Chickensandwhichman Skin
  • +
  • Added Daily Tanks
  • +
  • Added Plenty New Skins, New Achievements And Made Achievements Unlockable
  • +
  • Added Skater & Hitman
  • +
  • Added New "Duality" Map
  • +

    Update 2.93 [2024]

    +
  • David Goggins Event
  • +
  • Updated Menu
  • +
  • Added Marksman Branch To Sniper And Car Branch To
  • +
  • Added Trollface Emote (add --troll to the end of a chat message)
  • +
  • Added Waterfall, Acid, Cooler, Rainmaker And New Options Layout
  • +
  • Added Notes Tab + Live Counter
  • +
  • Added More Customization, Graphics, Helecopter And Fixed Music Bug
  • +
  • Added Reverie Branch And Injector
  • +
  • Added Debugger Menu
  • +
  • You Can Now Color Messages With §
  • +

    Niners fucking lost Again Bruh...Fuck Taylor Swift

    +
+
+
+

Update 2.9

+ [2024] +
    +
  • Added Motor
  • +
  • Added Kivaaharatedas (i did not spell that right)
  • +
  • Added Equilibrium, Revobrid, Subverter
  • +
  • shrapnel testing
  • +
  • removed unfinished aimbot/boosting testing
  • +
  • Added Basic Hybrid Tier 3 branch
  • +
  • Bug Fixed Colors
  • +
  • Added Tanks of my friends and tank soundboard support
  • +
  • Added the rest of the Basic Hybrid branch (tier 4)
  • +
  • Fixed changelog not appearing
  • +
  • Added beta music support including 5 songs
  • +
  • changed start button look to not shade out and actually work like a button
  • +
  • fixed debug key (again)
  • +
  • fixed screen tearing
  • +
  • worked bullet spawn position
  • +
  • Better organized dev menu and changed the way utilities looks
  • +
  • Added music recognition in the debug key to see the song name & artist
  • +
  • Added new song (Anybody can find Love (except You) by hkmori
  • +
  • fixed debug not recognizing a song and not updating after a song is finished
  • +
  • Testing wall colors/effects
  • +
  • Added Shield Turrets
  • +
  • Added new tiles (dance floor+black)
  • +
  • added new "banquet" map
  • +
  • Finished Revolutionist Branch
  • +
  • Added Inception & Albuquerque
  • +
  • im a fucking moron
  • +
  • Added Machceptioner & Tailgator
  • +
  • Added Interceptor, Twinceptioner, Inceptionist branch, hybrid/auto ver of inception branch
  • +
  • Added Desmos/Inception/Bascrid Ception
  • +
  • fixed the ceptionist turrets/autobullet turrets
  • +
  • nerfed shit
  • +
  • fixed some upgrades not appearing
  • +
  • no players (dead game and nobody plays is sadly)
  • +
  • so it turns out i forgot to give twinceptionist the right bullets so i fixed that :/
  • +
  • fixed flankcept branch turrets
  • +

    Update 2.91 [2024]

    +
  • Added the subduer branch
  • +
  • Fixed The Rest of the menu buttons and fixed sound effects
  • +
  • Added flankduer
  • +
  • Added Binary branch, Pathogen branch, mitochondrion branch, Subduer-Hybrid branch and Auto-Subduer Branch
  • +
  • fixed missing upgrades
  • +

    Hey! vsauce, Michael here. the game is stable and non buggy...or is it?

    +
+
+
+

Update 2.8

+ [2023] +
    +
  • Tank Adding Wave Two (ex. hadron, dictator, railgun + more)
  • +
  • Debug Key Bug Fix (how ironic)
  • +
  • Fixed Rng Images Bugging Out
  • +
  • Testing Whirlwind Branch
  • +
  • Fixed Maze Gamemode
  • +
  • Added Tooltips (beta)
  • +
  • Added Status Effects (beta+devevent)
  • +
  • Added Addon Support
  • +
  • Fixed button Shadows
  • +
  • Upgraded APS++ Updating Speed
  • +
  • New Mouse Controller
  • +
  • Keybind Fix
  • +
  • Enter can cancel a chat message being sent
  • +
  • CoNgReGaTiOn JuMpScArEs
  • +
  • Images on Tanks/Sound Effects For Tanks (dev)
  • +
  • Blackhole (dont ask just roll with it)
  • +
  • P A P Y R U S
  • +
  • Fixed Some Lag Holding Down Server Speed
  • +
  • 109.43.21.5.14
  • +
  • Added Desmos Branch
  • +
  • Theres Prob More But I Forgor
  • +

    wahhh... (i forgor why im crying)

    +
+
+
+

Update 2.7

+ [2023] +
    +
  • Debuffed Many Tanks
  • +
  • Migrated to new host
  • +
  • Removed all Nero Exclusive Tanks From The Game (for now anyway, dont worry)
  • +
  • Added "revolutionist" to testbed"
  • +
  • Massive Testbed overhaul
  • +
  • Added a funny randomly generated image on the start screen
  • +
  • Readded Sounds, design and other previous widgets
  • +
  • Hired new devs
  • +
  • did some tweaks to bots
  • +
  • got rid of the "nero" theme and the server list
  • +
  • added easter eggs
  • +
  • added random funny image
  • +

    Update 2.71 [2023]

    +
  • Tank Adding Wave One (ex. auto branch, revolutionist, cloner + more)
  • +
  • plenty of new dev features
  • +
  • added gamemode polls (once theres enough people)
  • +

    There are Easter Eggs All Over The Main Menu, You Might Find Something...

    +
+
+
+

Update 2.6

+ [2023] +
    +
  • replaced smashers origional upgrade path with the "armoury" tree -added lancer and smasher upgrades to armoury tree
  • +
  • added "Sword", "Injector" and "Fencer" to lancer upgrades
  • +
  • buffed drone tanks, twin tanks & tank health
  • +
  • added "Dictator" -added "Tripwire"
  • +
  • added "Barricade", "Twister", "Cyclone" and "Architect" -added "Tri-Trapper" tree -added "auto tritrapper", "auto armour" and "autolancer"
  • +
  • added "eagle" and "bulwark"
  • +
  • updated debug menu
  • +
  • removed hivemind from basic
  • +
  • added cloner upgrade
  • +
  • added hivemind and "splitter" to cloner upgrade
  • +
  • added "auto cloner", "auto flamethrower", "flamethrower hybrid" and "lancer hybrid"
  • +
  • updated colorscheme and other color related things
  • +
  • updated teams on 2tdm after 3 team bug -added all new Rock Maze gamemode
  • +

    Ryerson Loves Burger King

    +
+
+
+

Update 2.5

+ [2023] +
    +
  • added new tanks into beta for further testing
  • +
  • hired new devs
  • +
  • neroio discord is up
  • +
  • added new mascallenus tank and section
  • +
  • hired new beta testers
  • +
  • added new easter eggs
  • +
  • tested 2nd server opening
  • +
  • added "Scanner" and "hadoken"
  • +
  • nerfed Hahaugobrr
  • +
  • promoted lucas medieros to co-owner of the game
  • +
  • demoted a few staff
  • +
  • added 2TDM game mode
  • +
  • woomy event is back! now with free access to testbed
  • +
  • added "flankdrive", "twindrive" and "machinedrive"
  • +
  • fixed trapper look
  • +
  • added "infantry", "musket", "Traprid", "Auto Traprid", "Snigrav", "AsWdragafora", "Assasolak", "Builifacate", "Rifagiulus", "Auto Snigrav"
  • +
  • added "flamethrower", "Baker", "Wildfire" and "Equinox"
  • +
  • new nero.io default theme instead of using arras's
  • +
  • added insane af tanks to testbed
  • +
  • added "lancer"
  • +

    Open Na Noor

    +
+
+
+

Update 2.4

+ [2023] +
    +
  • added 2 new admin commands
  • +
  • added homing auto Basic
  • +
  • added bosses tab to AIT
  • +
  • bwomp AA $$ €€
  • +
  • added easter egg name colors
  • +
  • added the tanks "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", and "neptune"
  • +
  • added a new boss
  • +
  • added more natural spawning bosses
  • +
  • added "SpawnTrap"
  • +
  • updated bot names
  • +
  • ended woomy event
  • +

    Oh great red Text of the Changelog, What is your Wisdom?

    +
+
+
+

Update 2.3

+ [2023] +
    +
  • added "maleficator", "stalker", "landmine", "jumpsmash", "speedbent", "heavy3", and re-added "twindrive", "interceptioner", the "drive" subtree to autobasic, plus increased map size
  • +
  • fixed and debuffed jumpsmash
  • +
  • debuffed speedbent
  • +
  • added a public changelog (the one your looking at now)
  • +
  • added the red text
  • +
  • updated sounds and styles
  • +
  • added the "corrupted" button
  • +

    So Hows Ur Day?

    + +
+
+
+

Update 2.2

+ [2023] +
    +
  • added more tanks into beta
  • +
  • added sounds and updated client backround
  • +
  • Decoration finished
  • +
  • started decoration on migration host
  • +
  • added chat feature
  • +
  • migration big fixes
  • +
  • WE DID IT! MIGRATION COMPLETE!
  • +
  • during migration found multiple small bugs that was fixed
  • +
  • 2nd failed migrating attempt, starting yet another
  • +
  • fixed crashing bug
  • +
  • 2nd attempt at migrating
  • +
  • added random bot and skill classes
  • +
  • made bots more op
  • +
  • fixed a bot bug
  • +
  • downgraded bots
  • +
  • added tank visualizers
  • +
  • buffed bots a tiny bit more
  • +
  • fixed visualizer bug
  • +
  • added "rifle"
  • +
  • fixed "lilfact" upgrade path
  • +
  • added auto "lilfact"
  • +
  • renamed "lilfact" to "spawner"
  • +
  • added secret tanks for update 2.3
  • +
  • minor crash bug fixes
  • +
  • removed "rifle" and "autospawner" from beta
  • +
  • fixed smasher bug
  • +
  • failed "lancer" class attempt
  • +
  • secret tank updates
  • +
  • major bug fixes
  • +
  • rainbow color old client fix
  • +
  • last patches before big update
  • +
  • fixed tiny bug
  • +

    I Know Where You Live

    +
+
+
+

Update 2.1

+ [2022] +
    +
  • fixed the 2 game crashing bugs
  • +
  • tried to migrate to another server host but yet failed due to unknown reasons
  • +
  • added "speedbent" to beta
  • +
  • updated messages
  • +

    tbh im sad the 49ers missed the super bowl :/

    +
+
+
+

Update 2.0

+ [2021] +
    +
  • brought the ception tree into beta tanks
  • +
  • figured out that the "ceptions" arent really ceptions
  • +
  • forgot to add the actual way to access it LOL, also added a REAL machine ceptionist as a test
  • +
  • removed ceptionist and drive tanks as they are too overpowered
  • +
  • added lazer guns
  • +
  • stole code from someone elses server
  • +
  • added beta shock and burn
  • +
  • added some secret really stupid tanks
  • +
  • fixed a tank
  • +
  • removed revolutionist for being too buggy
  • +
  • added new auto class branch
  • +
  • added hivemind
  • +
  • bug fixes
  • +
  • major bug that caused no tanks to be added or bugs fixed causing confusion
  • +
  • crashing bug made game unplayable for large amount of time (like a whole 9 months)
  • +

    Whats Up Guys Quandale Dingle Here

    +
+
+
+

Update 1.9

+ [2021] +
    +
  • testing in progress
  • +
  • approved multiple tanks into the game
  • +
  • did some stupidity and added random stuff and figured out that there is indeed, 12882 lines of code in this project
  • +
  • added some dumb tanks like "mInIfLyInGfAsTeRtHiNgY"
  • +
  • added some cool colored objects on the "AsWdWsA" branch
  • +
  • added a secret tank
  • +
  • messed with some things like homing bullets
  • +
  • removed the homing stuff due to bugs
  • +
  • tried to recreate the "revolutionist" tank from woomy arras
  • +
  • more tests
  • +
  • added auto bullets
  • +
  • added drive tanks into beta testing phase
  • +
  • moved where the secret tank is
  • +
  • debuffed "single"
  • +
  • added "Cascal", "Gunto", "Catalyst", And "Cescav" to beta tanks
  • +
  • added a beta version of the drive tree into the game after some testing
  • +

    What A Dumb Fucking Game!

    +
+
+
+

Update 1.8

+ [2021] +
    +
  • completed and put the poison function into the game
  • +
  • completed and put the freeze function into the game
  • +
  • created a seprate freeze and poison bullets
  • +
  • added a stun function
  • +
  • added a healing and speed function
  • +
  • added a stun, healing and speed bullet shooting tanks
  • +
  • added the "AsWdWsA" branch
  • +
  • fixed poison cannon
  • +
  • renamed the bullets to respected name
  • +
  • renamed the cannons to a respected name
  • +
  • created a page 2 for the mascallenus
  • +
  • put multitanks into testbed
  • +
  • put multitanks into testbed
  • +
  • organized the tanks
  • +
  • removed public testbed
  • +

    :skull:

    +
+
+
+

Update 1.7

+ [2020] +
    +
  • added an admin logger
  • +
  • changed the AI color to pink
  • +
  • changed AI to have twin upgrade instead of basic
  • +
  • expanded the map
  • +
  • changed the colors of the spawning player to be random instead of always red or blue
  • +
  • added the tanks "oof" and "oof2" to mascallenus
  • +
  • added the tank "minibee" to testbed
  • +
  • added the tank "hexa trapper" into the game
  • +
  • added the tank "Paint Brush" into the crayon tree
  • +
  • added the tank "brutalizer"
  • +
  • added "sidewinder"
  • +

    Share with your friends!

    +
+
+
+

Update 1.6

+ [2020] +
    +
  • added the tank "tower mech"
  • +
  • added the "AIT" category into testbed
  • +
  • added a way to get back to a basic tank after becoming testbed
  • +
  • added the tank "crayon"
  • +
  • added the two tanks "marker" and "pastel"
  • +
  • added the tank "pen"
  • +
  • added a kill button to testbed
  • +
  • added the tank "highlighter"
  • +
  • added a way to immediatly upgrade into a basic trapper
  • +
  • invited some friends to help code my game
  • +

    Yo shout out to Lucas Medeiros

    +
+
+
+

Update 1.5

+ [2020] +
    +
  • removed jesus donut
  • +
  • removed DeltaCannon
  • +
  • fixed some bugs with AI's
  • +
  • fixed some bugs with crashers and bosses
  • +
  • added a bunch of testbed tanks into the real thing
  • +
  • removed fairsquare
  • +
  • added flame killa to testbed
  • +
  • removed access to the recently added tanks from testbed to save space
  • +
  • added Boxer to testbed
  • +
  • removed every testbed tank
  • +
  • added categories to test bed like "beta" and "mascallenus"
  • +

    come down today and try some corn, or we will sacrifice your newborn

    +
+
+
+

Update 1.4

+ [2020] +
    +
  • added Lottery to testbed
  • +
  • added hellblazer and Rocketer to testbed
  • +
  • added Nautilus to testbed
  • +
  • added jesus donut to testbed
  • +
  • experimented with bullet effects
  • +
  • added SleamShot
  • +
  • added TrapHard into testbed
  • +

    LMFAO WHAT A BOZO

    +
+
+
+

Update 1.3

+ [2020] +
    +
  • added master
  • +
  • added lilfact
  • +
  • fixed bug with bots
  • +
  • fixed bug with lilfact
  • +
  • ADDED PUBLIC TESTBED
  • +
  • fixed some bugs
  • +
  • fixed testbed problems
  • +
  • fixed testbed key errors regarding platform
  • +
  • added helltank to testbed
  • +
  • added DeltaCannon to testbed
  • +

    DrUgS aRe BaD fOr YoU1!1!

    +
+
+
+

Update 1.2

+ [2020] +
    +
  • server shutdown due to server problems
  • +
  • fixed problem
  • +
  • fixed some more bugs
  • +
  • fixed bug with the upgrades
  • +
  • added 3 pre-made extra tanks (hive shooter, auto assassin, auto cruiser)
  • +
  • added Unlocked
  • +
  • added more ways to get hive shooter
  • +
  • added more ways to get unlocked
  • +
  • added bots
  • +
  • fixed bad bug with Unlocked
  • +

    tbh play a better game than this

    +
+
+
+

Update 1.1

+ [2019] +
    +
  • added revix
  • +
  • added DeltaGunner
  • +

    OH BABY A TRIPLE

    +
+
+
+

Update 1.0

+ [2019] +
    +
  • just opened server
  • +
  • testing new tanks
  • +

    Bwomp

    +
+
+You've Reached The End
?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file diff --git a/public/credits.html b/public/credits.html new file mode 100644 index 000000000..ecb93e106 --- /dev/null +++ b/public/credits.html @@ -0,0 +1,104 @@ +
+

Deltafyrex

+ [Lead Dev, Game Owner and Discord Owner] +
    +
  • certified moron
  • +
  • pissass
  • +
  • favorite colors are cyan, white and black
  • +
  • does everything in this game
  • +
  • the reason you get disconnected often while in game lol
  • +
  • game founder
  • +
  • working on nero since 2019
  • +
+
+
+

Can Karaman

+ [Site Manager, Co-Lead Dev] +
    +
  • second most helpful person here
  • +
  • sets up the whole domain and security section of the site
  • +
  • absolutely just an all around amazing person
  • +
  • nero would be nowhere without him
  • +
  • bill nye the server guy
  • +
  • pulling nero out of the glitch rabbit hole
  • +
  • Scares the fuck out of me when he takes such an authoritarian position
  • +
+
+
+

Eguy

+ [Lead Beta Tester] +
    +
  • third most helpful person here
  • +
  • helps deltafyrex all the time
  • +
  • cool guy 😎
  • +
  • nero would fr be not as cool as it is without eguy
  • +
  • helps test and balance tanks
  • +
+
+
+

Ultimate primal

+ [Beta Tester and Discord Server Admin] +
    +
  • actually cares about nero.io
  • +
  • Pretty fun to have around
  • +
  • quite a chill fellow
  • +
  • will definitely destroy you
  • +
+
+
+

"Wait What!?"

+ [Helper] +
    +
  • quite wise
  • +
  • owner of phoearras
  • +
  • gives Deltafyrex wisdom and pieces of code sometimes (very nice)
  • +
+
+
+

MGLIFEYT

+ [Fucking Dipshit (only still on the team because he made the damn discord bot)] +
    +
  • SeX uPdAtE wHeN!/!?11/
  • +
  • RoBlOx NeRo BeTtEr!!!!! (spoiler alert: it doesn't even fucking exist)
  • +
  • useless asshole who has bad taste in imagery
  • +
  • Discord Bot maker
  • +
  • owner of vehicle wars on roblox
  • +
+
+
+

"C"

+ [Dev In Training (i have a good feeling about him)] +
    +
  • Deltafyrex's Best Friend irl
  • +
  • bro looks like a fucking mexican border crosser in yearbook photos ☠☠☠
  • +
  • Hair that could mop a floor lol
  • +
  • O U R P l E
  • +
  • severe alastor enthusiast
  • +
  • ChickenSandwhichMan
  • +
+
+
+

Special Thanks:

+ [Other Special Thank-you's] +
    +
  • Meta (sip!)
  • +
  • Maeka09 (Also Deltafyrex's best friend)
  • +
  • Darkfrost (No need to Specify >:3)
  • +
  • "D" (I AM THE GREENMAN I SPEAK FOR THE TREES)
  • +
  • O_S (YIPPEE)
  • +
  • SafariSE (helped delta start out on creating nero all those years ago)
  • +
  • Lucas Medeiros (Fellow Faithful Member)
  • +
  • Fruitmelon (gave delta some tips awhile back)
  • +
  • The Piss Cult (yeah you know who you are)
  • +
  • Maaxxi3114 Yesus' Pet Roblox Nero Endorser
  • +
  • Galaxy Dash (David Goggins, "I cant even count that high")
  • +
  • NoahPlays (Funny Nero Hater Lol)
  • +
  • Tokay Dragon (Furry)
  • +
  • Deltas Youtube Subscribers (Thanks!)
  • +
  • Deltas Body (worked on nero through countless hours of sleep deprivation HOLY SHIT ITS 12:00 AM)
  • +
  • APS++ Developers (very nice)
  • +
  • Arras Mayhem (this is here cuz some dude got mad at me for not crediting mayhem bc i used 2 of their sounds like boohoo)
  • +
  • im not putting any other license than the "do whatever the fuck you want" license
  • +
+
+You've Reached The End OwO ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ diff --git a/public/favicon.ico b/public/favicon.ico index 263db474e5caa9ef7a67202982a0bbf6d98f2ac4..23a67e49d6cba160f4370dbeb97260b1bcfa0641 100644 GIT binary patch literal 225726 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 z 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¥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 literal 21654 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 diff --git a/public/index.html b/public/index.html index 602027ceb..253455d22 100644 --- a/public/index.html +++ b/public/index.html @@ -3,59 +3,277 @@ - + - + + + + - Open Source Arras + + Nero.io 3.1 - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
- +
@@ -578,4 +628,4 @@

Bwomp

-You've Reached The End ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file +You've Reached The End ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file diff --git a/public/app.js b/public/app.js index 8a9c5a410..028e1efa0 100644 --- a/public/app.js +++ b/public/app.js @@ -185,21 +185,26 @@ var pmusic = new Array(); if (localStorage.getItem("oioioi" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033"); if (localStorage.getItem("dejected" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417"); if (localStorage.getItem("worldsend" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3?v=1714399132177"); -if (localStorage.getItem("depredation" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474"); -if (localStorage.getItem("anybody" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028"); -if (localStorage.getItem("resurgam" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3?v=1708218475743"); -if (localStorage.getItem("longing" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295"); +if (localStorage.getItem("nerosong" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nero.wav?v=1727644028814"); +//if (localStorage.getItem("anybody" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028"); +//if (localStorage.getItem("resurgam" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3?v=1708218475743"); +//if (localStorage.getItem("longing" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295"); if (localStorage.getItem("apotheosis" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3?v=1713525419376"); if (localStorage.getItem("killa" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"); -//if (localStorage.getItem("melancholy" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Meloncholy.mp3?v=1675465750213"); -if (localStorage.getItem("demol1sh" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787"); -if (localStorage.getItem("demoli2h" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3?v=1714414714759"); -if (localStorage.getItem("d3molish" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3?v=1714414706958"); -if (localStorage.getItem("souven1r" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/souven1r.mp3?v=1714414684036"); -if (localStorage.getItem("2ouvenir" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2ouvenir.mp3?v=1714414700719"); -if (localStorage.getItem("routine2" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3?v=1714414889291"); -if (localStorage.getItem("routin3s" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3?v=1714414850230"); -if (localStorage.getItem("jitt3rs" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287"); +if (localStorage.getItem("failedconnection" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Failed%20Connection.mp3?v=1727645304666"); +//if (localStorage.getItem("demol1sh" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787"); +//if (localStorage.getItem("demoli2h" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3?v=1714414714759"); +//if (localStorage.getItem("d3molish" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3?v=1714414706958"); +//if (localStorage.getItem("souven1r" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/souven1r.mp3?v=1714414684036"); +//if (localStorage.getItem("2ouvenir" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2ouvenir.mp3?v=1714414700719"); +//if (localStorage.getItem("routine2" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3?v=1714414889291"); +//if (localStorage.getItem("routin3s" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3?v=1714414850230"); +//if (localStorage.getItem("jitt3rs" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287"); +if (localStorage.getItem("atomic" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Atomic.wav?v=1727644048951"); +if (localStorage.getItem("ascension" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Acension%20(Apotheosis%202).wav?v=1729515166145"); +if (localStorage.getItem("nadir" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nadir%20(Apotheosis%203).wav?v=1729515170342"); +if (localStorage.getItem("phacktomine" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Methemphetaphacktomine.wav?v=1729515173719"); +if (localStorage.getItem("polychromatism" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav?v=1729515177274"); //Music functions: //decide the music @@ -534,8 +539,8 @@ if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-669 if (global.music2.src === "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/Meloncholy.mp3?v=1675465750213") { global.music2.songname = "Melancholy --- Deltafyrex"; } -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474") { - global.music2.songname = "Depredation Remastered V2--- Deltafyrex"; +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nero.wav?v=1727644028814") { + global.music2.songname = "Nero --- Deltafyrex"; } if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028") { global.music2.songname = "Anybody can find Love (except You.) --- hkmori" @@ -576,6 +581,24 @@ if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-669 if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287") { global.music2.songname = "Jitt3rs --- Nintendo" } +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Atomic.wav?v=1727644048951") { + global.music2.songname = "Atomic --- Deltafyrex" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Failed%20Connection.mp3?v=1727645304666") { + global.music2.songname = "Failed Connection --- Deltafyrex" +} +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Acension%20(Apotheosis%202).wav?v=1729515166145") { + global.music2.songname = "Ascension --- Deltafyrex" +} +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nadir%20(Apotheosis%203).wav?v=1729515170342") { + global.music2.songname = "Nadir --- Deltafyrex" +} +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Methemphetaphacktomine.wav?v=1729515173719") { + global.music2.songname = "Phacktomine --- Deltafyrex" +} +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav?v=1729515177274") { + global.music2.songname = "Polychromatism --- Deltafyrex" +} } function lagachloop() { if (global.metrics.rendertime <= 45 && global.metrics.rendertime >= 15) { @@ -1069,21 +1092,26 @@ window.onload = async () => { util.retrieveFromLocalStorageCheckDefault("oioioi"); util.retrieveFromLocalStorageCheckDefault("dejected"); util.retrieveFromLocalStorageCheckDefault("worldsend"); - util.retrieveFromLocalStorageCheckDefault("depredation"); - util.retrieveFromLocalStorage("anybody"); + util.retrieveFromLocalStorageCheckDefault("nerosong"); + /*util.retrieveFromLocalStorage("anybody"); util.retrieveFromLocalStorageCheckDefault("resurgam"); - util.retrieveFromLocalStorageCheckDefault("longing"); + util.retrieveFromLocalStorageCheckDefault("longing");*/ util.retrieveFromLocalStorageCheckDefault("apotheosis"); util.retrieveFromLocalStorageCheckDefault("killa"); - util.retrieveFromLocalStorageCheckDefault("melancholy"); - util.retrieveFromLocalStorageCheckDefault("demol1sh"); + util.retrieveFromLocalStorageCheckDefault("failedconnection"); +/* util.retrieveFromLocalStorageCheckDefault("demol1sh"); util.retrieveFromLocalStorageCheckDefault("demoli2h"); util.retrieveFromLocalStorage("d3molish"); util.retrieveFromLocalStorageCheckDefault("souven1r"); util.retrieveFromLocalStorageCheckDefault("2ouvenir"); util.retrieveFromLocalStorage("routine2"); util.retrieveFromLocalStorage("routin3s"); - util.retrieveFromLocalStorage("jitt3rs"); + util.retrieveFromLocalStorage("jitt3rs");*/ + util.retrieveFromLocalStorageCheckDefault("atomic"); + util.retrieveFromLocalStorageCheckDefault("ascension"); + util.retrieveFromLocalStorageCheckDefault("nadir"); + util.retrieveFromLocalStorage("phacktomine"); + util.retrieveFromLocalStorageCheckDefault("polychromatism"); // Set default theme if (document.getElementById("optColors").value === "") { document.getElementById("optColors").value = "nero"; @@ -1453,21 +1481,26 @@ function startGame() { util.submitToLocalStorage("oioioi"); util.submitToLocalStorage("dejected"); util.submitToLocalStorage("worldsend"); - util.submitToLocalStorage("depredation"); - util.submitToLocalStorage("anybody"); + util.submitToLocalStorage("nerosong"); + /*util.submitToLocalStorage("anybody"); util.submitToLocalStorage("resurgam"); - util.submitToLocalStorage("longing"); + util.submitToLocalStorage("longing");*/ util.submitToLocalStorage("apotheosis"); util.submitToLocalStorage("killa"); - util.submitToLocalStorage("melancholy"); - util.submitToLocalStorage("demol1sh"); + util.submitToLocalStorage("failedconnection"); + util.submitToLocalStorage("ascension"); + util.submitToLocalStorage("nadir"); + util.submitToLocalStorage("phacktomine"); + util.submitToLocalStorage("polychromatism"); +/* util.submitToLocalStorage("demol1sh"); util.submitToLocalStorage("demoli2h"); util.submitToLocalStorage("d3molish"); util.submitToLocalStorage("souven1r"); util.submitToLocalStorage("2ouvenir"); util.submitToLocalStorage("routine2"); util.submitToLocalStorage("routin3s"); - util.submitToLocalStorage("jitt3rs"); + util.submitToLocalStorage("jitt3rs");*/ + util.submitToLocalStorage("atomic"); util.submitToLocalStorage("optNoGrid"); // GUI util.submitToLocalStorage("optRenderGui"); @@ -1505,21 +1538,26 @@ function startGame() { if (document.getElementById("oioioi").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033"); if (document.getElementById("dejected").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417"); if (document.getElementById("worldsend").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3?v=1714399132177"); - if (document.getElementById("depredation").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474"); - if (document.getElementById("anybody").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028"); + if (document.getElementById("nerosong").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nero.wav?v=1727644028814"); + /*if (document.getElementById("anybody").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028"); if (document.getElementById("resurgam").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3?v=1708218475743"); - if (document.getElementById("longing").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295"); + if (document.getElementById("longing").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295");*/ if (document.getElementById("apotheosis").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3?v=1713525419376"); if (document.getElementById("killa").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"); - if (document.getElementById("melancholy").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Meloncholy.mp3?v=1675465750213"); - if (document.getElementById("demol1sh").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787"); + if (document.getElementById("failedconnection").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Failed%20Connection.mp3?v=1727645304666"); +/* if (document.getElementById("demol1sh").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787"); if (document.getElementById("demoli2h").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3?v=1714414714759"); if (document.getElementById("d3molish").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3?v=1714414706958"); if (document.getElementById("souven1r").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/souven1r.mp3?v=1714414684036"); if (document.getElementById("2ouvenir").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2ouvenir.mp3?v=1714414700719"); if (document.getElementById("routine2").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3?v=1714414889291"); if (document.getElementById("routin3s").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3?v=1714414850230"); - if (document.getElementById("jitt3rs").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287"); + if (document.getElementById("jitt3rs").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287");*/ + if (document.getElementById("atomic").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Atomic.wav?v=1727644048951"); + if (document.getElementById("ascension").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Acension%20(Apotheosis%202).wav?v=1729515166145"); + if (document.getElementById("nadir").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nadir%20(Apotheosis%203).wav?v=1729515170342"); + if (document.getElementById("phacktomine").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Methemphetaphacktomine.wav?v=1729515173719"); + if (document.getElementById("polychromatism").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav?v=1729515177274"); switch (document.getElementById("optBorders").value) { case "normal": @@ -2626,7 +2664,7 @@ function drawFloor(px, py, ratio) { if (settings.graphical.quality === "trippy") { ctx.fillStyle = gameDraw.getColor("animatedepilepsy") } else { - ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : gameDraw.modifyColor(tile); + ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : global.blackhole ? color.guiblack : gameDraw.modifyColor(tile); } ctx.fillRect(left, top, right - left, bottom - top); if (settings.graphical.quality == "cod") { @@ -3215,20 +3253,19 @@ function drawMinimapAndDebug(spacing, alcoveSize, GRAPHDATA) { if (global.metrics.rendertime < 10) orangeColor = true; // Text if (global.showDebug) { - drawText("Nero Engine v3.2", x + len, y - 50 - 8 * 14 - 2, 15, "#6a36e3", "right"); + drawText("Nero Engine v3.3", x + len, y - 50 - 8 * 14 - 2, 15, "#6a36e3", "right"); drawText("Prediction: " + Math.round(GRAPHDATA) + "ms : " + global.mspt + " mspt", x + len, y - 50 - 7 * 14, 10, color.guiwhite, "right"); // drawText(`Bandwidth: ${gui.bandwidth.in} in, ${gui.bandwidth.out} out`, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); drawText("Memory: " + global.metrics.rendergap.toFixed(1) + " Mib : " + "Class: " + gui.class, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); - drawText("Update Version: " + "v3.206", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); + drawText("Update Version: " + "v3.3", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 5 * 14, 10, color.guiwhite, "right"); - drawText("Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 4 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); - drawText("Server Speed: " + (100 * gui.fps).toFixed(2) + "% : Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, orangeColor ? color.orange : color.guiwhite, "right"); + drawText("Server Speed: " + (100 * gui.fps).toFixed(2) + "% : Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 4 * 14, 10, orangeColor ? color.orange : color.guiwhite, "right"); drawText("Kills: " + global.metrics.killcount + " Shapes: " + global.metrics.shapecount, x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); drawText("Song: " + global.music2.songname, x + len, y - 50 - 1 * 14, 10, color.guiwhite, "right"); drawText(global.metrics.latency + " ms - " + global.serverName, x + len, y - 50, 10, color.guiwhite, "right"); document.getElementById("content").style.opacity = 1; } else if (!global.GUIStatus.minimapReducedInfo) { - drawText("Nero.io v3.2", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); + drawText("Nero.io v3.3", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, orangeColor ? color.orange : color.guiwhite, "right"); drawText(global.metrics.latency + " ms : " + global.metrics.updatetime + "Hz", x + len, y - 50, 10, color.guiwhite, "right"); document.getElementById("content").style.opacity = 0; @@ -3678,8 +3715,7 @@ const gameDrawDead = () => { drawText(getDeath(), x - 170, y + 99, 16, color.guiwhite); drawText(getTips(), x - 170, y + 122, 16, color.guiwhite); drawText("🦆 The server was " + +(100 * gui.fps).toFixed(0) + "%" + " active", x - 170, y + 144, 16, color.guiwhite); - drawText(global.cannotRespawn ? global.respawnTimeout ? "(" + global.respawnTimeout + " Secon" + `${global.respawnTimeout <= 1 ? 'd' : 'ds'} ` + "left to respawn)" : "(You cannot respawn)" : global.mobile ? "(Tap to respawn)" : "(Press enter to respawn)", x, y + 189, 16, color.guiwhite, "center"); - ctx.translate(0, shift * global.screenHeight); + drawText(global.cannotRespawn ? global.respawnTimeout ? "(" + global.respawnTimeout + " Secon" + `${global.respawnTimeout <= 1 ? 'd' : 'ds'} ` + "left to respawn)" : "(you cannot respawn!)" : global.mobile ? "(tap to respawn)" : "(press enter to respawn)", x, y + 189, 16, color.guiwhite, "center"); ctx.translate(0, shift * global.screenHeight); }; const gameDrawOldDead = () => { clearScreen(color.black, 0.25); @@ -3842,11 +3878,13 @@ function animloop() { PlaySound420(); } global.metrics.killcount = 0; + global.metrics.shapecount = 0; } else { if (global.stopthefuckingkillsoundyouprick) { metalpipe.pause(); metalpipe.currentTime = 0; global.stopthefuckingkillsoundyouprick = false; + console.log("Respawned") } } if (global.disconnected) { // Draw disconnection screen if the client lost connection to the server. diff --git a/public/changelog.html b/public/changelog.html index 02ce797c1..5d7aae1e9 100644 --- a/public/changelog.html +++ b/public/changelog.html @@ -1,3 +1,66 @@ +
+

Update 3.3

+ [2024] +
    +
  • Added new server
  • +
  • changed menu layout
  • +
  • updated gamemodes
  • +
  • small fixes im too lazy to write
  • +
  • changed server box
  • +
  • small minion bugfixes
  • +
  • forgot to remove mace
  • +
  • dreads update
  • +
  • got rid of trilancer branch
  • +
  • dreadv1 changes
  • +
  • undertow update
  • +
  • removed a bunch of songs from ost
  • +
  • removed european server
  • +
  • updated credits
  • +
  • buffed albequerqe
  • +
  • fixed a bug where cloner hybrid did not show up when upgrading from cloner (dunno how i missed that)
  • +
  • removed ranch, marksman and cocci
  • +
  • fixed a bug where autocloner and cloner hybrid having instant clone respawn time
  • +
  • added visualizer to Nero brella
  • +
  • removed sidewinder
  • +
  • removed ceptions
  • +
  • nerfed auras (-100 aura points)
  • +
  • buffed surges emp attack
  • +
  • added choker
  • +
  • added X-Pathogen
  • +
  • added wyrm
  • +
  • added noble branch
  • +
  • added more descriptions
  • +
  • added gatling gun
  • +
  • removed more ceptions
  • +
  • removed aura branch from tier 1
  • +
  • removed auto branch from tier 1
  • +
  • removed hybrid branch from tier 1
  • +
  • removed flankinception branch
  • +
  • added more machceptioner upgrades
  • +
  • added 4 new ost tracks
  • +
  • fixed debug menu
  • +
  • makes shapes killed on run in debug menu reset on death
  • +
  • fixed solario bossfight
  • +
  • fixed bug where recoil doesnt work when upgrading from lancer tree
  • +
  • added charger
  • +
  • revolutionist now upgrades from whirlwind
  • +
  • saturn now upgrades from revolutionist
  • +
  • added formal dehyde and frostbite
  • +
  • buffed smashers
  • +
  • buffed skaters movement speed
  • +
  • gave pion the hadron ability and changed ring color to red
  • +
  • changed bayonet to tier 3
  • +
  • added icegun, fencer arisaka, wakazashi and fireblanket
  • +
  • removed mirror backshield
  • +
  • fixed death sounds
  • +
  • added wark branch
  • +
  • fixed auto2brid not having its main autocannon
  • +
  • fixed bug where scowerer and swivel2brid did not upgrade from its intended branches
  • +
  • fixed grazerbrid not having its autocannon
  • +
  • fixed the skype achievement
  • +

    Big ass update :blehh:

    +
+

Update 3.2

[2024] @@ -565,4 +628,4 @@

Update 1.0

Bwomp

-You've Reached The End ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file +You've Reached The End ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file diff --git a/public/credits.html b/public/credits.html index ecb93e106..a3fb5f904 100644 --- a/public/credits.html +++ b/public/credits.html @@ -11,24 +11,11 @@

Deltafyrex

  • working on nero since 2019
  • -
    -

    Can Karaman

    - [Site Manager, Co-Lead Dev] -
      -
    • second most helpful person here
    • -
    • sets up the whole domain and security section of the site
    • -
    • absolutely just an all around amazing person
    • -
    • nero would be nowhere without him
    • -
    • bill nye the server guy
    • -
    • pulling nero out of the glitch rabbit hole
    • -
    • Scares the fuck out of me when he takes such an authoritarian position
    • -
    -

    Eguy

    [Lead Beta Tester]
      -
    • third most helpful person here
    • +
    • second most helpful person here
    • helps deltafyrex all the time
    • cool guy 😎
    • nero would fr be not as cool as it is without eguy
    • @@ -44,7 +31,25 @@

      Ultimate primal

    • quite a chill fellow
    • will definitely destroy you
    -
    + +
    +

    123Pet

    + [Beta Tester] +
      +
    • also actually cares about nero.io
    • +
    • helps delta with problems
    • +
    • nice guy
    • +
    +
    +
    +

    JBX

    + [Helper and Server Manager] +
      +
    • server knowledge
    • +
    • teaches people valuble server things
    • +
    • helps delta with servers
    • +
    +

    "Wait What!?"

    [Helper] @@ -65,36 +70,26 @@

    MGLIFEYT

  • owner of vehicle wars on roblox
  • -
    -

    "C"

    - [Dev In Training (i have a good feeling about him)] -
      -
    • Deltafyrex's Best Friend irl
    • -
    • bro looks like a fucking mexican border crosser in yearbook photos ☠☠☠
    • -
    • Hair that could mop a floor lol
    • -
    • O U R P l E
    • -
    • severe alastor enthusiast
    • -
    • ChickenSandwhichMan
    • -
    -

    Special Thanks:

    [Other Special Thank-you's]
    • Meta (sip!)
    • -
    • Maeka09 (Also Deltafyrex's best friend)
    • -
    • Darkfrost (No need to Specify >:3)
    • +
    • Maeka09 (old beta tester)
    • +
    • Darkfrost (No need to Specify)
    • "D" (I AM THE GREENMAN I SPEAK FOR THE TREES)
    • +
    • "C" (Chicken Sandwhich Man)
    • O_S (YIPPEE)
    • SafariSE (helped delta start out on creating nero all those years ago)
    • Lucas Medeiros (Fellow Faithful Member)
    • Fruitmelon (gave delta some tips awhile back)
    • -
    • The Piss Cult (yeah you know who you are)
    • -
    • Maaxxi3114 Yesus' Pet Roblox Nero Endorser
    • +
    • [Ult] Arras Clan
    • +
    • Maaxxi3114 (Yesus' Pet Roblox Nero Endorser)
    • Galaxy Dash (David Goggins, "I cant even count that high")
    • NoahPlays (Funny Nero Hater Lol)
    • Tokay Dragon (Furry)
    • Deltas Youtube Subscribers (Thanks!)
    • +
    • mr squif server people!!!!! (splatoon people)
    • Deltas Body (worked on nero through countless hours of sleep deprivation HOLY SHIT ITS 12:00 AM)
    • APS++ Developers (very nice)
    • Arras Mayhem (this is here cuz some dude got mad at me for not crediting mayhem bc i used 2 of their sounds like boohoo)
    • diff --git a/public/index.html b/public/index.html index 8411f736b..5ae2218c3 100644 --- a/public/index.html +++ b/public/index.html @@ -12,7 +12,7 @@ - Nero.io 3.2 + Nero.io 3.3 @@ -23,7 +23,7 @@ - + @@ -154,7 +154,7 @@

      SWAGGITY WAGGITY EVENT!!! Join Or Tokayed On Dragon!!!

    - +
    @@ -198,7 +198,7 @@

    SWAGGITY WAGGITY EVENT!!! Join Or Tokayed On Dragon!!!

    image[12] = 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png?v=1705266607867' //oldnerologo image[13] = 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/freddy.gif?v=1698336453397' //freddy default dance image[14] = 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/asda.gif?v=1698336433205' //synthwave - image[15] = 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp?v=1701104133660' //avacado + image[15] = 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/eb38cb57-74b4-4965-b9b5-f4b83bd80de3.image.png?v=1726371143116' //avacado image[16] = 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/poop-emoji.jpg?v=1701104126682' //shart image[17] = 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(6).mp4?v=1701691279895' //i beleive i made myself clear image[18] = 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nero%20shitpost.png?v=1705290370363' //shitpost @@ -237,10 +237,10 @@

    SWAGGITY WAGGITY EVENT!!! Join Or Tokayed On Dragon!!!

    } //--> -
    +

    view notes ▸

    -
    -
    +
    +
    @@ -272,7 +272,7 @@


    -
    AppearanceOptionsControlsLinks
    +
    AppearanceOptionsControlsMisc
    Themes
    Auto-Level Up
    +
    @@ -457,13 +457,13 @@

    Oi Oi Oi
  • Dejected
  • World's End
  • -
  • Depredation
  • -
  • Anybody
  • +
  • Nero
  • +
  • Apotheosis
  • Killa
  • -
  • Melancholy
  • + +
  • Atomic
  • +
  • Failed Connection
  • +
  • Ascension
  • +
  • Nadir
  • +
  • Phacktomine
  • +
  • Polychromatism
  • diff --git a/public/lib/canvas.js b/public/lib/canvas.js index 174d5e35b..dd0a1b6ac 100644 --- a/public/lib/canvas.js +++ b/public/lib/canvas.js @@ -126,6 +126,7 @@ class Canvas { // Enter to respawn if (global.died && !global.cannotRespawn) { global.killsoundready = true; + global.stopthefuckingkillsoundyouprick = true; this.socket.talk("s", global.playerName, 0, 1 * settings.game.autoLevelUp, global.skin); global.died = false; break; @@ -647,11 +648,11 @@ class Canvas { if (this.videoRecorder) switch (this.videoRecorder.state) { case "inactive": - global.createMessage("Recorder Started!", 2_000); + global.createMessage("Recorder started!", 2_000); this.videoRecorder.start(); break; case "recording": - global.createMessage("Recorder Stopped! Saving file...", 5_000); + global.createMessage("Recorder stopped! Saving file...", 5_000); this.videoRecorder.stop(); } else { @@ -667,7 +668,7 @@ class Canvas { let k = URL.createObjectURL(a), q = document.createElement("a"); q.style.display = "none"; - q.setAttribute("download", "arras.mp4"); + q.setAttribute("download", "nero.mp4"); q.setAttribute("href", k); document.body.appendChild(q); setTimeout(() => { @@ -676,11 +677,11 @@ class Canvas { }, 100); q.click(); }; - global.createMessage("Recorder Started!", 2_000); + global.createMessage("Recorder started!", 2_000); this.videoRecorder.start(); } else - global.createMessage("Cannot record due to outdated/unsupported browser. Please update your browser!", 6_000); + global.createMessage("Recording video requires an up-to-date browser.", 6_000); } screenshot() { var x = this.cv.toDataURL(), @@ -691,7 +692,7 @@ class Canvas { let q = URL.createObjectURL(new Blob([p], {type: x})), w = document.createElement("a"); w.style.display = "none"; - w.setAttribute("download", "arras.png"); + w.setAttribute("download", "nero-screenshot.png"); w.setAttribute("href", q); document.body.appendChild(w); setTimeout(() => { diff --git a/public/lib/global.js b/public/lib/global.js index 67b84a495..de4f8c5f4 100644 --- a/public/lib/global.js +++ b/public/lib/global.js @@ -195,7 +195,7 @@ const global = { minimapReducedInfo: false, }, emojiloaded: false, - wikidisplaytank: 999, + wikidisplaytank: 17, ISTHEGODAMNFUCKINGGAMEON: "no", killsoundready: true, skin: "", @@ -217,6 +217,6 @@ const global = { songname: "", }, stopthefuckingkillsoundyouprick: false, - + blackhole: false }; export { global } diff --git a/public/lib/socketInit.js b/public/lib/socketInit.js index bf25e408a..b461058b0 100644 --- a/public/lib/socketInit.js +++ b/public/lib/socketInit.js @@ -809,6 +809,7 @@ const socketInit = port => { }); }; var KillSound = new Audio(); + KillSound.volume = 0.5; function PlaySoundKS() { KillSound.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Voicy_Slap%20Battles%20Killstreak%20Kill.mp3?v=1714045643190"); KillSound.play(); @@ -884,6 +885,9 @@ const socketInit = port => { case "killstreakreset": global.metrics.killcount = 0; break; + case "blackhole": + m[0] ? global.blackhole = true : global.blackhole = false; + break case 'c': // force camera move global.player.renderx = global.player.cx = m[0]; global.player.rendery = global.player.cy = m[1]; @@ -931,7 +935,6 @@ const socketInit = port => { global.entities = []; global.message = ''; global.canThrowClosedMessage = true; - global.stopthefuckingkillsoundyouprick = true; } break; case 'm': // message diff --git a/public/lib/tankdesc.js b/public/lib/tankdesc.js index 97161a3f6..83bea5ad5 100644 --- a/public/lib/tankdesc.js +++ b/public/lib/tankdesc.js @@ -2,6 +2,7 @@ //this is my server! //its called nero.io, in development for 5 years now..... //i mean...you can remix it if you want! just uh...idk...nvm +//type: Assaulter, Spammer, Defender, Controller, Ranger, Basher, Supporter, Catalyst const tankdescs = { /* template: { @@ -111,7 +112,7 @@ const tankdescs = { updateadded: "1.0", }, pounder: { - type: "Lobber", + type: "Assaulter", desc: "Heavier Bullets With More Of A Kick To Them. Great For Close Combat, Just Dont Let The Slower Fire Rate And Bullet Speed Kill You!", tier: "2", weapons: "Bullet", @@ -141,7 +142,7 @@ const tankdescs = { updateadded: "1.6", }, desmos: { - type: "Siner", + type: "Spammer", desc: "Gives Bullets The Ability To Act Like Waves, Helpful For Getting Around High Bullet Health Coming Straight At You", tier: "2", weapons: "Sine-Bullets", @@ -156,7 +157,7 @@ const tankdescs = { updateadded: "2.8", }, smasher: { - type: "Banger", + type: "Basher", desc: "No Guns, Only Melee Damage. For People Who Like Agressive Playstyles Or Just Want Something More In Your Control", tier: "3", weapons: "Armour", @@ -321,7 +322,7 @@ const tankdescs = { updateadded: "1.0", }, hunter: { - type: "Ranger-Stacker", + type: "Ranger", desc: "", tier: "3", weapons: "Bullets", @@ -350,6 +351,21 @@ const tankdescs = { origin: "arras.io", updateadded: "2.2", }, + marksman: { + type: "Ranger", + desc: "", + tier: "3", + weapons: "Splitter Bullets", + abilities: "N/A", + weak: "High DPS", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper", + origin: "arras.io", + updateadded: "N/A", + }, ranger: { type: "Ranger", desc: "", @@ -366,7 +382,7 @@ const tankdescs = { updateadded: "1.0", }, stalker: { - type: "Ranger-Ghoster", + type: "Ranger", desc: "", tier: "3", weapons: "Bullets", @@ -396,7 +412,7 @@ const tankdescs = { updateadded: "1.0", }, predator: { - type: "Ranger-Stacker", + type: "Ranger", desc: "", tier: "4", weapons: "Bullets", @@ -411,7 +427,7 @@ const tankdescs = { updateadded: "1.0", }, xHunter: { - type: "Ranger-Stacker", + type: "Ranger", desc: "", tier: "4", weapons: "Bullets", @@ -426,7 +442,7 @@ const tankdescs = { updateadded: "2.7", }, dual: { - type: "Ranger-Stacker", + type: "Ranger-Assaulter", desc: "Hunter With Dual Barrels Similar To Twin", tier: "4", weapons: "Bullets", @@ -470,6 +486,66 @@ const tankdescs = { origin: "arras.io", updateadded: "2.2", }, + deadeye: { + type: "", + desc: "Marksman but same stats as asassin", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "???", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Asassin, Marksman", + origin: "arras.io", + updateadded: "N/A", + }, + nimrod: { + type: "", + desc: "Marksman but same as Hunter", + tier: "4", + weapons: "Bullets", + abilities: "Scope", + weak: "???", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Hunter, Marksman", + origin: "arras.io", + updateadded: "N/A", + }, + revolver: { + type: "", + desc: "Marksman but same stats as Rifle", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "???", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Rifle, Marksman", + origin: "arras.io", + updateadded: "N/A", + }, + fork: { + type: "", + desc: "Marksman but more split bullets", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "???", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Marksman", + origin: "arras.io", + updateadded: "N/A", + }, minigun: { type: "Spammer", desc: "3 Stacked Barrels Firing Very Fast", @@ -544,6 +620,156 @@ const tankdescs = { upgradesfrom: "Trapper, Minigun", origin: "arras.io", updateadded: "2.6", + }, + nailgun: { + type: "Spammer", + desc: "Small, fast and high pen bullets that can penetrate enemy fire", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Minigun", + origin: "arras.io", + updateadded: "1.0", + }, + machineGunner: { + type: "Spammer", + desc: "High fire rate spammer", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Gunner", + origin: "arras.io", + updateadded: "1.0", + }, + machineGunner: { + type: "Spammer", + desc: "High fire rate spammer", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Gunner", + origin: "arras.io", + updateadded: "1.0", + }, + redistributor: { + type: "Spammer", + desc: "Sprayer with an extra barrel", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Minigun, Sprayer", + origin: "arras.io", + updateadded: "2.9", + }, + atomizer: { + type: "Spammer", + desc: "Machine gun with an extra smaller machine gun", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sprayer", + origin: "arras.io", + updateadded: "2.9", + }, + focal: { + type: "Spammer", + desc: "Machine gun with smaller funnel barrel for more accuracy", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sprayer", + origin: "arras.io", + updateadded: "2.9", + }, + hexaTank: { + type: "Assaulter", + desc: "6 Basic barrels on all sides", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Flank Guard, Twin", + origin: "arras.io", + updateadded: "1.0", + }, + triAngle: { + type: "Assaulter", + desc: "Machine gun with an extra smaller machine gun", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Flank Guard, Propel", + origin: "diep.io", + updateadded: "1.0", + }, + auto3: { + type: "Assaulter", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Flank Guard, Auto-2", + origin: "diep.io", + updateadded: "1.0", + }, + octoTank: { + type: "Assaulter", + desc: "has 8 barrels surrounding the tank", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Flank Guard, Auto-2", + origin: "diep.io", + updateadded: "1.0", } }; export { tankdescs } \ No newline at end of file diff --git a/public/lib/util.js b/public/lib/util.js index 4a8c2197e..4423157a5 100644 --- a/public/lib/util.js +++ b/public/lib/util.js @@ -226,6 +226,7 @@ const util = { layer: mainMockup.layer, position: util.sizeMultipleMockups(positionData), rerootUpgradeTree, + trueupgrades: mainMockup.trueupgrades, guns: { length: guns.length, getPositions: () => Array(guns.length).fill(0), diff --git a/server/lib/util.js b/server/lib/util.js index 58e3ff91d..7c2e46d15 100644 --- a/server/lib/util.js +++ b/server/lib/util.js @@ -95,7 +95,6 @@ exports.flattenDefinition = (output, definition) => { if (!Array.isArray(definition.PARENT)) { exports.flattenDefinition(output, definition.PARENT); } else for (let parent of definition.PARENT) { - if(mockupsLoaded) for (let k in parent) console.log(k, parent[k]) exports.flattenDefinition(output, parent); } } diff --git a/server/modules/definitions/addons/dreadv1.js b/server/modules/definitions/addons/dreadv1.js index b3caf31bc..54e0d8af5 100644 --- a/server/modules/definitions/addons/dreadv1.js +++ b/server/modules/definitions/addons/dreadv1.js @@ -2,10 +2,9 @@ const { combineStats, makeAuto, weaponArray, makeTurret } = require('../facilita const { smshskl, base, basePolygonDamage, basePolygonHealth } = require('../constants.js'); const g = require('../gunvals.js'); const dreadnoughtBody = { - SPEED: base.SPEED * 0.5, - HEALTH: base.HEALTH * 7, - DAMAGE: base.DAMAGE * 3.5, - PENETRATION: base.PENETRATION * 2, + SPEED: base.SPEED * 0.6, + HEALTH: base.HEALTH * 4, + DAMAGE: base.DAMAGE * 2.5, SHIELD: base.SHIELD * 2.5, FOV: base.FOV * 1.25, DENSITY: base.DENSITY * 6, @@ -36,16 +35,16 @@ g.dreadv1Slow = { } g.dreadv1Drone = { health: 1.1, - speed: 0.68, - maxSpeed: 0.68, - reload: 1.2, + speed: 0.77, + maxSpeed: 0.77, + reload: 1.65, size: 1.2, recoil: 0, } g.dreadv1Trap = { range: 1.3, shudder: 0.2, - speed: 1.05, + speed: 0.95, reload: 2.8, damage: 1.45, health: 1.35, @@ -272,7 +271,7 @@ Class.dreadv1BodyTurret = makeTurret({ GUNS: [{ POSITION: [22, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 0.7 }, g.turret, { size: 0.8, health: 0.75, speed: 0.4, maxSpeed: 0.4, reload: 0.7 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 0.7 }, g.turret, { size: 0.8, damage: 1.05, speed: 0.4, maxSpeed: 0.4, reload: 0.7 }]), TYPE: "bullet" } }] @@ -499,7 +498,7 @@ Class.peacekeeperOfficialV1 = { GUNS: weaponArray({ POSITION: [17.5, 9, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.dreadv1Generic, g.dreadv1Slow, {reload: 1.3, health: 1.3, range: 1.1}]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.dreadv1Generic, g.dreadv1Slow, {reload: 1.3, health: 1.2, range: 1.1}]), TYPE: "bullet", } }, 3) diff --git a/server/modules/definitions/addons/playerskins.js b/server/modules/definitions/addons/playerskins.js index 4895f3232..87b674545 100644 --- a/server/modules/definitions/addons/playerskins.js +++ b/server/modules/definitions/addons/playerskins.js @@ -26,7 +26,7 @@ Class.bsignalskin = { SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], SKILL: Array(10).fill(12), TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], + POSITION: [18, 0, 0, 0, 360, -2], TYPE: "bsignalcharm" }] }; @@ -44,7 +44,7 @@ Class.dfxskin = { SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], SKILL: Array(10).fill(12), TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], + POSITION: [10, 6, 5.5, 0, 360, 3], TYPE: "dfxcharm" }] }; @@ -53,7 +53,7 @@ Class.primalskin = { SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], SKILL: Array(10).fill(12), TURRETS: [{ - POSITION: [20, 0, 0, 0, 360, 3], + POSITION: [10, 6, 5.5, 0, 360, 3], TYPE: "primalcharm" }] }; @@ -62,7 +62,7 @@ Class.kangarooskin = { SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], SKILL: Array(10).fill(12), TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], + POSITION: [10, 6, 5.5, 0, 360, 3], TYPE: "kangaroocharm" }] }; @@ -71,7 +71,7 @@ Class.cswmskin = { SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], SKILL: Array(10).fill(12), TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 0.5], + POSITION: [10, 6, 5.5, 0, 360, 3], TYPE: "sandwichdeco" }] }; @@ -89,7 +89,7 @@ Class.skypeskin = { SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], SKILL: Array(10).fill(12), TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], + POSITION: [10, 6, 5.5, 0, 360, 3], TYPE: "skypecharm" }] }; @@ -98,7 +98,7 @@ Class.coinskin = { SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], SKILL: Array(10).fill(12), TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], + POSITION: [10, 6, 5.5, 0, 360, 3], TYPE: "coincharm" }] }; @@ -107,7 +107,7 @@ Class.discordskin = { SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], SKILL: Array(10).fill(12), TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 3], + POSITION: [15, -5, 5.5, 0, 360, 3], TYPE: "discordcharm" }] }; diff --git a/server/modules/definitions/addons/solario.js b/server/modules/definitions/addons/solario.js index 92d2bac1a..77b48d610 100644 --- a/server/modules/definitions/addons/solario.js +++ b/server/modules/definitions/addons/solario.js @@ -342,10 +342,10 @@ Class.solariobase = { LABEL: "Solario", SHAPE: 0, BODY: { - HEALTH: 1000, + HEALTH: 8000, }, SIZE: 15, - DANGER: 10, + DANGER: 15, } Class.solario = { PARENT: "solariobase", @@ -394,7 +394,7 @@ Class.solario = { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), - TYPE: "blackholeondeath", + TYPE: ["blackholeondeath", { PERSISTS_AFTER_DEATH: true }], SHOOT_ON_DEATH: true, ALT_FIRE: true } @@ -428,7 +428,6 @@ Class.solario = { switch(attack) { case 0: body.guns[4].fire(); - setTimeout(() => { if (body != null) body.guns[4].fire(); }, 6000); setTimeout(() => { if (body != null) body.guns[4].fire(); }, 12000); break; case 1: @@ -466,7 +465,7 @@ Class.solariolaser = { POSITION: [15, 10, 1, 0, 0, 0, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -474,7 +473,7 @@ Class.solariolaser = { POSITION: [15, 10, 1, 0, 0, 180, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -577,7 +576,7 @@ Class.solariophase2 = { }, { POSITION: [1, 10, 1, 0, 0, 0, 1], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.fake, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.fake, { reload: 75 }]), TYPE: "bullet", AUTOFIRE: true, IDENTIFIER: "solarioAttack" @@ -641,8 +640,7 @@ Class.solariophase2 = { switch(attack) { case 0: body.guns[6].fire(); - setTimeout(() => { if (body != null) body.guns[6].fire(); }, 4000); - setTimeout(() => { if (body != null) body.guns[6].fire(); }, 8000); + setTimeout(() => { if (body != null) body.guns[6].fire(); }, 6000); setTimeout(() => { if (body != null) body.guns[6].fire(); }, 12000); break; case 1: @@ -653,8 +651,6 @@ Class.solariophase2 = { setTimeout(() => { if (body != null) body.guns[8].fire(); }, 500); setTimeout(() => { if (body != null) body.guns[8].fire(); }, 1000); setTimeout(() => { if (body != null) body.guns[8].fire(); }, 1500); - setTimeout(() => { if (body != null) body.guns[8].fire(); }, 2000); - setTimeout(() => { if (body != null) body.guns[8].fire(); }, 2500); break; } } @@ -681,7 +677,7 @@ Class.solariolaserphase2 = { POSITION: [15, 10, 1, 0, 0, 0, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -689,7 +685,7 @@ Class.solariolaserphase2 = { POSITION: [15, 10, 1, 0, 0, 90, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -697,7 +693,7 @@ Class.solariolaserphase2 = { POSITION: [15, 10, 1, 0, 0, 180, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -705,7 +701,7 @@ Class.solariolaserphase2 = { POSITION: [15, 10, 1, 0, 0, 270, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -840,10 +836,10 @@ Class.solariophase3 = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), - TYPE: "blackholeondeath", - SHOOT_ON_DEATH: true, - ALT_FIRE: true + SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, range: 7, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), + TYPE: ["blackholeondeath", { PERSISTS_AFTER_DEATH: true }], + ALT_FIRE: true, + SHOOT_ON_DEATH: true } }, ], @@ -881,9 +877,8 @@ Class.solariophase3 = { switch(attack) { case 0: body.guns[8].fire(); - setTimeout(() => { if (body != null) body.guns[8].fire(); }, 3000); - setTimeout(() => { if (body != null) body.guns[8].fire(); }, 6000); - setTimeout(() => { if (body != null) body.guns[8].fire(); }, 9000); + setTimeout(() => { if (body != null) body.guns[8].fire(); }, 4000); + setTimeout(() => { if (body != null) body.guns[8].fire(); }, 8000); setTimeout(() => { if (body != null) body.guns[8].fire(); }, 12000); break; case 1: @@ -898,10 +893,6 @@ Class.solariophase3 = { setTimeout(() => { if (body != null) body.guns[10].fire(); }, 2000); setTimeout(() => { if (body != null) body.guns[10].fire(); }, 2500); setTimeout(() => { if (body != null) body.guns[10].fire(); }, 3000); - setTimeout(() => { if (body != null) body.guns[10].fire(); }, 3500); - setTimeout(() => { if (body != null) body.guns[10].fire(); }, 4000); - setTimeout(() => { if (body != null) body.guns[10].fire(); }, 4500); - setTimeout(() => { if (body != null) body.guns[10].fire(); }, 5000); break; } } @@ -909,7 +900,8 @@ Class.solariophase3 = { }, { event: "death", handler: ({ body }) => { - sockets.broadcast('NOOOOOOO!') + sockets.broadcast('NOOOOOOO!'); + let o = new Entity(body).define("blackholeondeath") } }, ], @@ -920,7 +912,7 @@ Class.solariolaserphase3 = { POSITION: [15, 20, 1, 0, 0, 0, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast, { spread: 0, size: 0.6 }]), - TYPE: ["hyperlaser", {ARENA_CLOSER: true}], + TYPE: "hyperlaser", AUTOFIRE: true, COLOR: "red", }, @@ -928,7 +920,7 @@ Class.solariolaserphase3 = { POSITION: [15, 10, 1, 0, 0, 60, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -936,7 +928,7 @@ Class.solariolaserphase3 = { POSITION: [15, 10, 1, 0, 0, 120, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -944,7 +936,7 @@ Class.solariolaserphase3 = { POSITION: [15, 20, 1, 0, 0, 180, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast, { spread: 0, size: 0.6 }]), - TYPE: ["hyperlaser", {ARENA_CLOSER: true}], + TYPE: "hyperlaser", AUTOFIRE: true, COLOR: "red", } @@ -952,7 +944,7 @@ Class.solariolaserphase3 = { POSITION: [15, 10, 1, 0, 0, 240, 5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), - TYPE: ["laser", {ARENA_CLOSER: true}], + TYPE: "laser", AUTOFIRE: true, COLOR: "red", }, @@ -1012,9 +1004,9 @@ Class.solariolaserphase3 = { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, range: 7, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), - TYPE: "blackholeondeath", + TYPE: ["blackholeondeath", { PERSISTS_AFTER_DEATH: true }], + ALT_FIRE: true, SHOOT_ON_DEATH: true, - ALT_FIRE: true } }, ], @@ -1030,17 +1022,32 @@ Class.solariolaserphase3 = { }, { event: "death", handler: ({ body }) => { - sockets.broadcast('NOOOOOOO!') + sockets.broadcast('NOOOOOOO!'); + let o = new Entity(body).define("blackholeondeath") } - } + }, ], } Class.blackholeondeath = { - PARENT: "bullet", PERSISTS_AFTER_DEATH: true, COLOR: "black", MOTION_TYPE: ["grow", { growSpeed: 1.4 }], ARENA_CLOSER: true, + TYPE: "bullet", + ACCEPTS_SCORE: false, + BODY: { + PENETRATION: 99, + SPEED: 1, + RANGE: 200, + DENSITY: 38281381283, + RESIST: 38281381283, + HEALTH: 124124, + DAMAGE: 124124, + }, + FACING_TYPE: "smoothWithMotion", + CAN_GO_OUTSIDE_ROOM: true, + HITS_OWN_TYPE: "never", + DIE_AT_RANGE: true, GUNS: [{ POSITION: [4, 4, 1, 0, 0, 0, 0], PROPERTIES: { @@ -1084,7 +1091,11 @@ Class.blackholeondeath = { } } } - }, + }, { + event: "death", + handler: ({ body }) => { + } + }, ], } Class.devBosses.UPGRADES_TIER_0.push('solario', 'solariophase2', 'solariophase3') \ No newline at end of file diff --git a/server/modules/definitions/groups/bosses.js b/server/modules/definitions/groups/bosses.js index 70ba3ba50..82840bc3e 100644 --- a/server/modules/definitions/groups/bosses.js +++ b/server/modules/definitions/groups/bosses.js @@ -3211,4 +3211,225 @@ Class.AEMKShipBoss = { } return e; })(), +} +Class.helenaBossBaseAura = addAura(2, 2, 0) +const helenaBossBase = { + PARENT: "genericTank", + COLOR: "crasher", + UPGRADE_COLOR: "crasher", + LABEL: "AV-512-F", + NAME: "Helena", + SHAPE: 3.5, + SIZE: 28, + VALUE: 1e9, + DANGER: 100, + GLOW: { + RADIUS: 9, + COLOR: "mirror", + ALPHA: 1, + RECURSION: 3 + }, + BODY: { + HEALTH: 1180, + DAMAGE: 18, + REGEN: 3 * base.REGEN, + SHIELD: 3 * base.SHIELD, + SPEED: 0.35 * base.SPEED + }, + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 0], + TYPE: "helenaBossBaseAura" + } + ] +} +Class.helenaDpProp = makeDeco(3.5, "crasher") +Class.helenaBossDpProp2 = makeDeco(3.5, "black") +Class.helenaBossDpPropArmed = { + PARENT: "genericTank", + COLOR: "crasher", + SHAPE: 3, + GUNS: weaponArray( + { + POSITION: [15, 8, 1, 0, 0, 60, 0], + PROPERTIES: { + COLOR: "crasher", + } + }, 3 + ) +} +Class.helenaBossHDDProp = makeDeco(3.5, "darkGrey") +Class.helenaBossHDDProp2 = makeDeco(3.5, "crasher") +Class.helenaBossMinionProp = makeDeco(3.5, "black") +Class.helenaBossHDDMinion = { + PARENT: "minion", + LABEL: "AV-16-X", + SHAPE: 3.5, + DRAW_HEALTH: true, + PROPS: [ + { + POSITION: { SIZE: 30, LAYER: 0, ANGLE: 360 }, + TYPE: "helenaBossMinionProp" + }, + { + POSITION: { SIZE: 25, LAYER: 0, ANGLE: 360 }, + TYPE: ["helenaBossMinionProp", { COLOR: "white"}] + }, + { + POSITION: { SIZE: 11, LAYER: 1, ANGLE: 360 }, + TYPE: "helenaBossMinionProp" + } + ], + GUNS: [ + ...weaponArray([ + { + POSITION: [10.5, 7.5, 1.3, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { reload: 1.15 }]), + TYPE: "swarm", + STAT_CALCULATOR: "swarm", + COLOR: "white" + }, + } + ], 3 + ) + ] +} +Class.helenaBossAuraBulletAura = addAura(0.333, 1.5, 0.3, "crasher") +Class.helenaBossAuraBullet = { + PARENT: "bullet", + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "helenaBossAuraBulletAura" + } + ] +} +Class.helenaBossChip = { + PARENT: "drone", + LABEL: "Helenchip", + PROPS: [ + { + POSITION: { SIZE: 10, LAYER: 1, ANGLE: 180 }, + TYPE: ["triangle", { COLOR: "crasher" }] + } + ] +} +Class.helenaBoss = { + ...helenaBossBase, + UPGRADE_TOOLTIP: "A crasher that descended upon the Universe, from the Crasher Heavens.\nAlso known as the \"Prime Crasher\".\nMore stories are to be told about her...", + CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal", ["minion", { orbit: 240 }]], + PROPS: [ + { + POSITION: { SIZE: 25, LAYER: 0, ANGLE: 360 }, + TYPE: "helenaBossDpProp2" + }, + { + POSITION: { SIZE: 16, LAYER: 1, ANGLE: 360 }, + TYPE: "helenaBossHDDProp" + }, + { + POSITION: { SIZE: 12.5, LAYER: 1, ANGLE: 360 }, + TYPE: "helenaBossHDDProp2" + }, + { + POSITION: { SIZE: 7.75, LAYER: 1, ANGLE: 360 }, + TYPE: "helenaBossHDDProp" + }, + { + POSITION: { SIZE: 5.25, LAYER: 1, ANGLE: 360 }, + TYPE: ["helenaBossHDDProp", { COLOR: "white" }] + }, + { + POSITION: { SIZE: 3, LAYER: 1, ANGLE: 360 }, + TYPE: "helenaBossHDDProp2" + } + ], + GUNS: [ + ...weaponArray( + [{ + POSITION: [7.5, 11.75, 1.33, 5.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { reload: 3, health: 2 }]), + TYPE: ["helenaBossHDDMinion", { INDEPENDENT: true }], + COLOR: "black", + MAX_CHILDREN: 2 + }, + }, + { + POSITION: [8.5, 5, 1.25, 8.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single, { reload: 1.1, size: 1.5 }]), + TYPE: "helenaBossAuraBullet", + COLOR: "white" + } + }, + { + POSITION: [8.5, 5, 1.25, 8.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.twin, g.pounder, {reload: 1.15, health: 0.85, speed: 0.5, maxSpeed: 0.5, range: 0.25, size: 1.5}]), + TYPE: "unsetPillbox", + STAT_CALCULATOR: "block", + ALPHA: 0 + } + }, + { + POSITION: [8.5, 5, 1.25, 6.5, 5.5, 15, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, {shudder: 0.6, health: 0.55, reload: 1.2, speed: 1, maxSpeed: 1, range: 0.33}]), + TYPE: "trap", + STAT_CALCULATOR: "trap", + COLOR: "white" + } + }, + { + POSITION: [8.5, 5, 1.25, 6.5, -5.5, -15, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, {shudder: 0.6, health: 0.55, reload: 1.2, speed: 1, maxSpeed: 1, range: 0.33}]), + TYPE: "trap", + STAT_CALCULATOR: "trap", + COLOR: "white" + } + }, + { + POSITION: [8.5, 5, 1.25, 6.5, 5.5, 15, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.pounder, { size: 1.75, speed: 1.6, maxSpeed: 1.6 }]), + TYPE: "helenaBossChip", + STAT_CALCULATOR: "drone", + ALPHA: 0, + MAX_CHILDREN: 2 + } + }, + { + POSITION: [8.5, 5, 1.25, 6.5, -5.5, -15, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.pounder, { size: 1.75, speed: 1.6, maxSpeed: 1.6 }]), + TYPE: "helenaBossChip", + STAT_CALCULATOR: "drone", + ALPHA: 0, + MAX_CHILDREN: 2 + } + }, + ], 3 + ) + ], + ON: [ + { + event: "tick", + handler: ({ body }) => { + body.store.ticks ??= 0 + body.store.ticks++ + const spawnCrashers = body.store.ticks % 6 == 0 // a lot + const spawnSentries = body.store.ticks % 240 == 0 // ~8 seconds + const spawnLegions = body.store.ticks % 1300 == 0 // about every minute + const sentries = ["sentrySwarm", "sentryGun", "sentryTrap"] + const legions = ["eliteDestroyer", "eliteGunner", "eliteSprayer", "eliteBattleship", "eliteSpawner", "eliteTrapGuard", "eliteSpinner", "eliteSkimmer", "guardian", "defender", "sprayerLegion"] + if (spawnCrashers) new Entity(body, body).define("crasher") + if (spawnSentries) new Entity(body, body).define(sentries[Math.floor(Math.random() * sentries.length)]) + if (spawnLegions) new Entity(body, body).define(legions[Math.floor(Math.random() * legions.length)]) + } + }, + ] } \ No newline at end of file diff --git a/server/modules/definitions/groups/dev.js b/server/modules/definitions/groups/dev.js index e7eb4196f..d9ef58f6a 100644 --- a/server/modules/definitions/groups/dev.js +++ b/server/modules/definitions/groups/dev.js @@ -708,7 +708,7 @@ Class.turretStatScaleTest = { })) } -Class.auraBasicGen = addAura(4.3, 1.3); +Class.auraBasicGen = addAura(1, 1.3); Class.auraHealerGen = addAura(-1); Class.auraHealer = { PARENT: "genericTank", @@ -1090,7 +1090,7 @@ Class.gunBenchmark = { Class.levels = menu("Levels") Class.levels.UPGRADES_TIER_0 = [] -for (let i = 0; i < 12; i++) { +for (let i = 0; i < 16; i++) { let LEVEL = i * Config.TIER_MULTIPLIER; Class["level" + LEVEL] = { PARENT: "levels", @@ -1112,6 +1112,12 @@ for (let i = 1; i <= 8; i++) { }; Class.teams.UPGRADES_TIER_0.push("Team" + TEAM); } +Class['Team' + TEAM_DREADNOUGHTS] = { + PARENT: "teams", + TEAM: TEAM_DREADNOUGHTS, + COLOR: getTeamColor(TEAM_DREADNOUGHTS), + LABEL: "Dreads Team" +}; Class['Team' + TEAM_ROOM] = { PARENT: "teams", TEAM: TEAM_ROOM, @@ -1124,7 +1130,7 @@ Class['Team' + TEAM_ENEMIES] = { COLOR: "yellow", LABEL: "Enemies Team" }; -Class.teams.UPGRADES_TIER_0.push('Team' + TEAM_ROOM, 'Team' + TEAM_ENEMIES); +Class.teams.UPGRADES_TIER_0.push('Team' + TEAM_DREADNOUGHTS, 'Team' + TEAM_ROOM, 'Team' + TEAM_ENEMIES); Class.testing = menu("Beta Tanks") Class.features = menu("Features") @@ -1206,6 +1212,34 @@ Class.sidewinderOld = { }, ], } +Class.tetraGunner = { + PARENT: "genericTank", + LABEL: "Tetra Gunner", + DANGER: 7, + GUNS: weaponArray([ + { + POSITION: [14, 3.5, 1, 0, 4, 0, 1 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 3.5, 1, 0, -4, 0, 2 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), + TYPE: "bullet", + }, + } + ], 4) +} // Whirlwind Class.whirlwindDeco = makeDeco(6) @@ -3413,15 +3447,19 @@ Class.alchem = { { POSITION: [19, 8, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { range: 50, damage: 0, pen: 0, health: 100 }]), + SHOOT_SETTINGS: combineStats([g.basic, { damage: 0, pen: 10, health: 100 }]), TYPE: "stickyTrap" } }, { - POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + POSITION: [5.5, 8, -1.6, 6.5, 0, 0, 0] + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "white" + } } - ], - MAX_CHILDREN: 6 + ] }; Class.speedoflight = { PARENT: "genericTank", @@ -3892,6 +3930,7 @@ Class.oppenheimer = { PARENT: "genericTank", LABEL: "Oppen Heimer", DANGER: 7, + ARENA_CLOSER: true, GUNS: [ { POSITION: [19, 8, 1, 0, 0, 0, 0], @@ -3931,28 +3970,6 @@ Class.homingdev = { } ] } -Class.brella = { - PARENT: "genericTank", - LABEL: "Nero-Brella", - DANGER: 7, - SYNC_TURRET_SKILLS: true, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet" - } - }, { - POSITION: [1, 10, 0, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.brella]), - TYPE: "brellaShield", - ALT_FIRE: true, - MAX_CHILDREN: 1, - //ALPHA: 1 - } - }] -}; Class.winsor0 = { PARENT: "genericTank", LABEL: "Wi3nsor", @@ -4318,7 +4335,52 @@ Class.kivaship = { TYPE: "turretBaseKiva", }], } - +Class.blaster = { + PARENT: "genericTank", + LABEL: "Blaster", + DANGER: 7, + GUNS: [{ + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { damage: 0.8, health: 0.1, speed: 1.5, range: 0.25 } ]), + TYPE: "blasterbullet" + } + } + ], + TURRETS: [{ + POSITION: [8.2, 8, 5, 0, 0, 0], + TYPE: ["grenadeDeco", { MIRROR_MASTER_ANGLE: true }], + },{ + POSITION: [8.2, 8, -5, 0, 0, 0], + TYPE: ["grenadeDeco", { MIRROR_MASTER_ANGLE: true }], + } + ] +} +Class.trapperdesmos = { + PARENT: "genericTank", + LABEL: "Repeater", + GUNS: [ + { + POSITION: [30, 20, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { reload: 0.5 }]), + TYPE: ["snakeOld", {MOTION_TYPE: "desmos"}] + } + }, + { + POSITION: [4.625, 9.5, 3, 0.375, -8, 91.5, 0] + }, + { + POSITION: [4.625, 9.5, 3, 0.375, 8, -91.5, 0] + }, + { + POSITION: [5.75, 10, 2.125, 0, -5.75, 30, 0] + }, + { + POSITION: [5.75, 10, 2.125, 0, 5.75, -30, 0] + } + ] +} Class.utilities = { PARENT: "genericTank", LABEL: "Utilities", @@ -4340,14 +4402,16 @@ Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons Class.tanks.UPGRADES_TIER_0 = ["developer", "overpowered", "testing", "unavailable", "features"] Class.AIT.UPGRADES_TIER_0 = ["developer", "bosses", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun", "arenaCloser"] Class.utilities.UPGRADES_TIER_0 = ["developer", "levels", "teams", "eggGenerator", "spectator", "wallPlacer", "lavenderspawner"] - Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "flail", "winsor0", "volute", "whirlwind"] + Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "doubleFlail", "mace", "flangle", "winsor0", "volute", "tetraGunner", "sidewinder", "marksman", "basicCeption", "mirrorBackShield"] + Class.sidewinder.UPGRADES_TIER_3 = ["coil", "oroboros", "cocci", "ranch", "python"] + Class.marksman.UPGRADES_TIER_3 = ["deadeye", "nimrod", "revolver", "fork"] Class.volute.UPGRADES_TIER_3 = ["sidewinderOld"] - Class.flail.UPGRADES_TIER_2 = ["doubleFlail", "mace", "flangle"] + //Class.flail.UPGRADES_TIER_2 = ["doubleFlail", "mace", "flangle"] Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] Class.mace.UPGRADES_TIER_3 = ["bigMama", "itHurtsDontTouchIt", "flace"] Class.flangle.UPGRADES_TIER_3 = ["flooster", "flace"] Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] - Class.whirlwind.UPGRADES_TIER_2 = ["tornado", "hurricane"] + Class.whirlwind.UPGRADES_TIER_2 = ["tornado", "hurricane", "revolutionist"] Class.whirlwind.UPGRADES_TIER_3 = ["hexaWhirl", "munition", "whirl3", "whirlGuard",/* "prophet",*/ "vortex"] Class.tornado.UPGRADES_TIER_3 = ["megaTornado", "tempest", "thunderbolt"] Class.hurricane.UPGRADES_TIER_3 = ["typhoon", "blizzard"] @@ -4365,10 +4429,10 @@ Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons Class.terrestrials.UPGRADES_TIER_0 = ["bosses", "ares", "gersemi", "ezekiel", "eris", "selene"] Class.celestials.UPGRADES_TIER_0 = ["bosses", "paladin", "freyja", "zaphkiel", "nyx", "theia", "atlas", "rhea", "julius", "genghis", "napoleon"] Class.eternals.UPGRADES_TIER_0 = ["bosses", "odin", "kronos"] - Class.devBosses.UPGRADES_TIER_0 = ["bosses", "taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss"] + Class.devBosses.UPGRADES_TIER_0 = ["taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss", "AEMKShipBoss", "helenaBoss"] Class.features.UPGRADES_TIER_0 = ["tanks", "diamondShape", "rotatedTrap", "colorMan", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "radialAutoTest", "makeAutoTest", "imageShapeTest", "turretStatScaleTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "gunBenchmark", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] - Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight", "rayofdeath", "biggerCheese", "kivaship"] + Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight", "rayofdeath", "biggerCheese", "kivaship", "blaster", "trapperdesmos"] Class.goofytanks.UPGRADES_TIER_0 = ["overpowered", "pisseroo", "papyrus", "Trapper_guy", "watertank", "piszerbeam", "baseThrowerDelta", "pouner", "adsfoipuasdfiopu", "goofywhirlwind", "gettingoverit", "alchem", "stupidpony", "billcipher"] //the "winsor" tank needs this to function, it worked before the "ON" thing was added diff --git a/server/modules/definitions/groups/food.js b/server/modules/definitions/groups/food.js index cdd90eec2..221d29251 100644 --- a/server/modules/definitions/groups/food.js +++ b/server/modules/definitions/groups/food.js @@ -124,10 +124,11 @@ Class.pentagon = { COLOR: "purple", BODY: { DAMAGE: 1.5 * basePolygonDamage, - DENSITY: 8, + DENSITY: 80, HEALTH: 10 * basePolygonHealth, - RESIST: 1.25, - PENETRATION: 1.1, + RESIST: 1, + //PENETRATION: 0.7, + PENETRATION: 0.7, ACCELERATION: 0.0035 }, DRAW_HEALTH: true, @@ -204,7 +205,8 @@ Class.hexagon = { HEALTH: 20 * basePolygonHealth, RESIST: 1.3, SHIELD: 50 * basePolygonHealth, - PENETRATION: 1.1, + //PENETRATION: 1.1, + PENETRATION: 0.5, ACCELERATION: 0.003 }, DRAW_HEALTH: true, @@ -263,7 +265,7 @@ Class.cube = { VALUE: 2e7, SIZE: 10, COLOR: "egg", - SHAPE: "M -0.13 0.07 L -0.87 -0.35 L -0.87 0.5 L -0.13 0.93 Z M 0.13 0.07 L 0.13 0.93 L 0.87 0.5 L 0.87 -0.35 Z M 0 -0.15 L 0.74 -0.57 L 0 -1 L -0.74 -0.57 Z", + SHAPE: "M -0.065 0.037 L -0.866 -0.425 L -0.866 0.5 L -0.065 0.962 Z M 0.065 0.037 L 0.065 0.962 L 0.866 0.5 L 0.866 -0.425 Z M 0 -0.075 L 0.801 -0.537 L 0 -1 L -0.801 -0.537 Z", BODY: { DAMAGE: 4.8, DENSITY: 20, @@ -282,7 +284,7 @@ Class.tetrahedron = { VALUE: 3e7, SIZE: 12, COLOR: "egg", - SHAPE: "M -0.13 0.07 L -0.87 -0.35 L -0.13 0.92 Z M 0.13 0.07 L 0.13 0.92 L 0.87 -0.35 Z M 0 -0.15 L 0.74 -0.57 L -0.74 -0.57 Z", + SHAPE: "M -0.065 0.037 L -0.934 -0.477 L -0.054 1.047 Z M 0.065 0.037 L 0.054 1.047 L 0.934 -0.477 Z M 0 -0.075 L 0.88 -0.57 L -0.88 -0.57 Z", BODY: { DAMAGE: 6, DENSITY: 23, @@ -300,7 +302,7 @@ Class.octahedron = { VALUE: 4e7, SIZE: 13, COLOR: "egg", - SHAPE: "M -0.12 -0.12 L -0.12 -0.88 L -0.88 -0.12 Z M -0.12 0.12 L -0.88 0.12 L -0.12 0.88 Z M 0.12 0.12 L 0.12 0.88 L 0.88 0.12 Z M 0.12 -0.12 L 0.88 -0.12 L 0.12 -0.88 Z", + SHAPE: "M -0.053 0.053 L -0.947 0.053 L -0.053 0.947 Z M 0.053 0.053 L 0.053 0.947 L 0.947 0.053 Z M 0.053 -0.053 L 0.947 -0.053 L 0.053 -0.947 Z M -0.053 -0.053 L -0.053 -0.947 L -0.947 -0.053 Z", BODY: { DAMAGE: 6.5, DENSITY: 26, @@ -318,7 +320,7 @@ Class.dodecahedron = { VALUE: 5e7, SIZE: 18, COLOR: "egg", - SHAPE: "M -0.28 -0.39 H 0.28 L 0.455 0.15 L 0 0.48 L -0.455 0.15 Z M -0.951 -0.309 L -0.957 0.194 L -0.659 0.102 L -0.473 -0.469 L -0.66 -0.719 Z M -0.588 0.809 L -0.111 0.97 L -0.107 0.658 L -0.592 0.305 L -0.888 0.406 Z M 0.588 0.809 L 0.888 0.406 L 0.593 0.305 L 0.107 0.658 L 0.111 0.97 Z M 0.951 -0.309 L 0.66 -0.719 L 0.473 -0.469 L 0.659 0.102 L 0.957 0.194 Z M 0 -1 L -0.48 -0.85 L -0.3 -0.595 H 0.3 L 0.48 -0.85 Z", + SHAPE: "M -0.341 -0.469 H 0.341 L 0.552 0.179 L 0 0.58 L -0.552 0.179 Z M -0.951 -0.309 L -0.95 0.238 L -0.674 0.149 L -0.458 -0.517 L -0.629 -0.751 Z M -0.588 0.809 L -0.067 0.977 L -0.067 0.687 L -0.633 0.276 L -0.909 0.366 Z M 0.588 0.809 L 0.908 0.366 L 0.633 0.276 L 0.067 0.687 L 0.067 0.977 Z M 0.951 -0.309 L 0.629 -0.751 L 0.458 -0.517 L 0.674 0.149 L 0.95 0.238 Z M 0 -1 L -0.52 -0.83 L -0.35 -0.595 H 0.35 L 0.52 -0.83 Z", BODY: { DAMAGE: 7, DENSITY: 28, @@ -336,7 +338,7 @@ Class.icosahedron = { VALUE: 1e8, SIZE: 20, COLOR: "egg", - SHAPE: "M -0.84 0.485 L -0.196 0.621 L -0.636 -0.141 Z M 0.733 -0.319 L 0.912 0.27 L 0.911 -0.422 Z M 0.643 -0.475 L 0.222 -0.925 L 0.821 -0.578 Z M 0.84 0.485 L 0.636 -0.141 L 0.196 0.621 Z M -0.643 -0.475 L -0.222 -0.925 L -0.821 -0.578 Z M -0.733 -0.319 L -0.912 0.27 L -0.911 -0.422 Z M 0 -0.97 L -0.44 -0.48 L 0.44 -0.48 Z M -0.09 0.794 L -0.69 0.655 L -0.09 1 Z M 0.09 0.794 L 0.69 0.655 L 0.09 1 Z M 0 0.62 L -0.537 -0.31 L 0.537 -0.31 Z", + SHAPE: "M -0.836 0.482 L -0.127 0.639 L -0.617 -0.209 Z M 0.699 -0.333 L 0.913 0.362 L 0.896 -0.447 Z M 0.638 -0.439 L 0.143 -0.972 L 0.836 -0.553 Z M 0.836 0.482 L 0.617 -0.209 L 0.127 0.639 Z M -0.638 -0.439 L -0.143 -0.972 L -0.836 -0.553 Z M -0.699 -0.333 L -0.913 0.362 L -0.896 -0.447 Z M 0 -0.965 L -0.49 -0.43 H 0.49 Z M -0.061 0.772 L -0.77 0.61 L -0.061 1 Z M 0.061 0.772 L 0.77 0.61 L 0.061 1 Z M 0 0.62 L -0.537 -0.31 L 0.537 -0.31 Z", BODY: { DAMAGE: 9, DENSITY: 30, @@ -385,7 +387,7 @@ Class.tesseract = { VALUE: 42e7, SIZE: 25, COLOR: "egg", - SHAPE: "M 0.34 0.47 L 0.58 0.71 L -0.58 0.71 L -0.34 0.47 Z M 0.47 -0.34 L 0.71 -0.58 L 0.71 0.58 L 0.47 0.34 Z M -0.34 -0.47 L -0.58 -0.71 L 0.58 -0.71 L 0.34 -0.47 Z M -0.47 0.34 L -0.71 0.58 L -0.71 -0.58 L -0.47 -0.34 Z M 0.32 0.32 L 0.32 -0.32 L -0.32 -0.32 L -0.32 0.32 L 0.32 0.32", + SHAPE: "M 0.47 -0.375 L 0.71 -0.615 L 0.71 0.615 L 0.47 0.375 Z M -0.375 -0.47 L -0.615 -0.71 L 0.615 -0.71 L 0.375 -0.47 Z M -0.47 0.375 L -0.71 0.615 L -0.71 -0.615 L -0.47 -0.375 Z M 0.375 0.47 L 0.615 0.71 L -0.615 0.71 L -0.375 0.47 Z M 0.35 0.35 L 0.35 -0.35 L -0.35 -0.35 L -0.35 0.35 Z", BODY: { DAMAGE: 10, DENSITY: 40, diff --git a/server/modules/definitions/groups/generics.js b/server/modules/definitions/groups/generics.js index ffef019de..4476a5fa3 100644 --- a/server/modules/definitions/groups/generics.js +++ b/server/modules/definitions/groups/generics.js @@ -134,7 +134,7 @@ Class.genericTank = { } Class.genericLancer = { PARENT: "genericTank", - DANGER: 6, + DANGER: 5, SKILL_CAP: [dfltskl, dfltskl, dfltskl, dfltskl, dfltskl, dfltskl, dfltskl, dfltskl, dfltskl, dfltskl], STAT_NAMES: statnames.lancer, } @@ -146,7 +146,12 @@ Class.genericSmasher = { STAT_NAMES: statnames.smasher, BODY: { FOV: 1.05 * base.FOV, - DENSITY: 2 * base.DENSITY + SPEED: 1.3 * base.SPEED, + DENSITY: 2 * base.DENSITY, + HEALTH: 2 * base.HEALTH, + PUSHABILITY: 0, + ACCELERATION: 1.3 * base.ACCEL, + DAMAGE: 1.5 * base.DAMAGE } } Class.genericBoss = { diff --git a/server/modules/definitions/groups/projectiles.js b/server/modules/definitions/groups/projectiles.js index c6c4aa1d6..527e50711 100644 --- a/server/modules/definitions/groups/projectiles.js +++ b/server/modules/definitions/groups/projectiles.js @@ -70,6 +70,36 @@ Class.casing = { LABEL: "Shell", TYPE: "swarm", } +Class.forkSplitterBullet = { + PARENT: "bullet", + INDEPENDENT: true, + GUNS: [ + { + POSITION: [8, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { damage: 0.65, size: 2.4 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + } + }, + { + POSITION: [8, 8, 1, 0, 0, 30, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { damage: 0.65, size: 2.4 } ]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + } + }, + { + POSITION: [8, 8, 1, 0, 0, -30, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { damage: 0.65, size: 2.4 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + } + }, + ] +} // Missiles Class.missile = { @@ -598,7 +628,6 @@ Class.shotTrapBox = { Class.pillbox = { PARENT: "setTrap", LABEL: "Pillbox", - CONTROLLERS: ["nearestDifferentMaster"], INDEPENDENT: true, DIE_AT_RANGE: true, TURRETS: [ @@ -611,7 +640,6 @@ Class.pillbox = { Class.unsetPillbox = { PARENT: "unsetTrap", LABEL: "Pillbox", - CONTROLLERS: ["nearestDifferentMaster"], INDEPENDENT: true, DIE_AT_RANGE: true, TURRETS: [ @@ -753,6 +781,19 @@ Class.grenade = { } ] } +Class.blasterbullet = { + PARENT: "bullet", + INDEPENDENT: true, + GUNS: [{ + POSITION: [1, 8, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { range: 0.1, size: 10, damage: 1.5, maxSpeed: 0.01, speed: 0.01 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, TYPE: "shield" }], + SHOOT_ON_DEATH: true, + } + } + ] +} Class.firecrackerbomb = { PARENT: "bullet", INDEPENDENT: true, @@ -817,6 +858,9 @@ Class.brellaShield = { //SHAPE: 'M 1 3.5 L 2 2 L 2 0 L 1 -1.5 L 0 -1.8 L 0 -1 L 2 0.5 L 0 -1 L 0 0 L 2 0.85 L 0 0 L 0 1 L 2 1 L 0 1 L 0 1 L 0 2 L 2 1.15 L 0 2 L 0 3 L 2 1.5 L 0 3 L 0 3.8 L 1 3.5', SHAPE: 'M -0 2.2587 L 0.9 0.905 L 0.9 -0.9 L -0 -2.2537 L -0.9 -2.5245 L -0.9 2.5295 L -0 2.2587', INDEPENDENT: true, + BODY: { + PENETRATION: 0.01 + }, COLOR: "grey", GUNS: [ { @@ -1030,6 +1074,29 @@ Class.icebullet = { } }] } +Class.poisonicebullet = { + PARENT: "bullet", + GLOW: { + RADIUS: 2, + COLOR: "#28dead", + ALPHA: 1, + RECURSION: 4, + }, + TURRETS: [{ + POSITION: [5, 0, 0, 0, 0, 2], + TYPE: ["effectBulletDeco", { color: "#28B1DE" }] + }, { + POSITION: [7, 0, 0, 0, 0, 1], + TYPE: ["effectBulletDeco", { color: "green" }] + }], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + damageOnTick(body, damageTool[0], 2, 1, 1, false); + iceOnTick(body, damageTool[0], 1, 1, true); + } + }] +} Class.empBullet = { PARENT: "bullet", ON: [{ @@ -1075,40 +1142,6 @@ Class.denseasfbullet = { SPEED: 12 } } -Class.undertowbullet = { - PARENT: "bullet", - GUNS: [{ - POSITION: [4, 4, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.magnet]), - TYPE: ["bullet", { SIZE: 5, ALPHA: 0.5 }], - AUTOFIRE: true - }, - }], - ON: [{ - event: "tick", - handler: ({ body }) => { - for (let instance of entities) { - if (instance.team != body.team && (instance.isPlayer || instance.master.isPlayer || instance.type == "food")) { - let diffX = instance.x - body.x, - diffY = instance.y - body.y, - dist2 = diffX ** 2 + diffY ** 2, - number1 = 1, - number2 = 1, - number3 = 1/7, - number4 = 1, - number5 = 1, - forceMulti = (((((body.size / 14)*150) ** 2)** number1) * number2) / dist2; - if (dist2 <= (((body.size / 14)*150) ** 2) * 2) { - instance.velocity.x += util.clamp(body.x - instance.x, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 - instance.velocity.y += util.clamp(body.y - instance.y, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 - } - } - } - } - }, - ], -} Class.surgeempBullet = { PARENT: "bullet", HITS_OWN_TYPE: "never", @@ -1150,7 +1183,8 @@ Class.stickyTrap = { TYPE: "popup", HITS_OWN_TYPE: "hard", LABEL: "Sticky Trap", - SHAPE: -5, + SHAPE: -8, + COLOR: "white", GUNS: [{ POSITION: [4, 4, 1, 0, 0, 0, 0], PROPERTIES: { @@ -1162,12 +1196,14 @@ Class.stickyTrap = { ON: [{ event: "collide", handler: ({ body, other }) => { + if ((other.team != body.team || other.master.id != body.master.id) && other.type != "wall" && other.isTurret != true) { body.velocity.x = 0; body.velocity.y = 0; let amount = util.getDistance(body, other), angle = Math.atan2(body.y - other.y, body.x - other.x); other.velocity.x += amount * Math.cos(angle); other.velocity.y += amount * Math.sin(angle); + } } }], } diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 608e90963..72fb47ed2 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -1117,7 +1117,6 @@ Class.fork = { BODY: { FOV: 1.2 * base.FOV }, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", GUNS: [ { POSITION: { @@ -1157,8 +1156,8 @@ Class.fork = { WIDTH: 8.5 }, PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, { pen: 2 }]), - TYPE: "bullet" + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, { pen: 2, reload: 3.5 }]), + TYPE: "forkSplitterBullet" } } ] @@ -3109,28 +3108,89 @@ Class.sidewinder = { } ] } -Class.undertow = { - PARENT: "genericTank", - LABEL: "Undertow", - DANGER: 6, - //UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", - GUNS: [ - { - POSITION: [14, 12, 0.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { health: 1.5, damage: 0.05 }]), - TYPE: "undertowbullet", - MAX_CHILDREN: 2, +Class.undertowEffect = { + PARENT: 'genericTank', + TYPE: 'undertowEffect', + SIZE: 5, + COLOR: 1, + HITS_OWN_TYPE: "never", + GIVE_KILL_MESSAGE: false, + ACCEPTS_SCORE: false, + DRAW_HEALTH: false, + DIE_AT_RANGE: true, + BODY: { + HEALTH: 9e99, + DAMAGE: 0, + RANGE: 5, + PUSHABILITY: 0, + } + }; + Class.undertowBullet = { + PARENT: 'bullet', + ON: [ + { + event: "tick", + handler: ({ body }) => { + for (let instance of entities) { + let diffX = instance.x - body.x, + diffY = instance.y - body.y, + dist2 = diffX ** 2 + diffY ** 2; + if (dist2 <= ((body.size / 12)*250) ** 1.9) { + if ((instance.team != body.team || (instance.type == "undertowEffect" && instance.master.id == body.master.id)) && instance.type != "wall" && instance.isTurret != true) { + if (instance.type == "undertowEffect") { + forceMulti = 1 + } + else if (instance.type == "food") { + forceMulti = (6 / instance.size) + } + else { + forceMulti = (2 / instance.size) + } + instance.velocity.x += util.clamp(body.x - instance.x, -90, 90) * instance.damp * forceMulti;//0.05 + instance.velocity.y += util.clamp(body.y - instance.y, -90, 90) * instance.damp * forceMulti;//0.05 + if (instance.type != "undertowEffect" && instance.type != "bullet" && instance.type != "swarm" && instance.type != "drone" && instance.type != "trap" && instance.type != "dominator") { + let o = new Entity({x: instance.x, y: instance.y}) + o.define('undertowEffect') + o.team = body.team; + o.color = instance.color; + o.alpha = 0.3; + o.master = body.master; + } + } + } + if (dist2 < body.size ** 3 + instance.size ** 3) { + if (instance.master.id == body.master.id) { + if (instance.type == "undertowEffect") + { + instance.kill(); + } + } + } + } } - }, - { - POSITION: [11.25, 8, 0.15, 4.25, 4, 13.5, 0] - }, - { - POSITION: [11.25, 8, 0.15, 4.25, -4, -13.5, 0] } - ] -} + ], + } + Class.undertow = { + PARENT: "genericTank", + LABEL: "Undertow", + DANGER: 6, + GUNS: [ + { + POSITION: [14, 12, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { size: 0.8, reload: 1.2 }]), + TYPE: 'undertowBullet' + } + }, + { + POSITION: [11.25, 8, 0.15, 4.25, 4, 13.5, 0] + }, + { + POSITION: [11.25, 8, 0.15, 4.25, -4, -13.5, 0] + } + ] + } Class.repeater = { PARENT: "genericTank", LABEL: "Repeater", @@ -3446,7 +3506,6 @@ Class.riptide = { PARENT: "genericTank", LABEL: "Riptide", DANGER: 7, - //UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", GUNS: [ { POSITION: [6.5, 23.5, 0.25, 3, 0, 180, 0], @@ -3454,9 +3513,8 @@ Class.riptide = { { POSITION: [18, 16, 0.75, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { size: 0.9, speed: 0.75, reload: 1.5, health: 2, damage: 0.1, maxSpeed: 0.8 }]), - TYPE: "undertowbullet", - MAX_CHILDREN: 2, + SHOOT_SETTINGS: combineStats([g.basic, { size: 0.9, reload: 1.2 }]), + TYPE: "undertowBullet" } }, { @@ -3548,9 +3606,10 @@ Class.megaSmasher = { PARENT: "genericSmasher", LABEL: "Mega-Smasher", BODY: { - SPEED: 1.05 * base.SPEED, + SPEED: 1.5 * base.SPEED, FOV: 1.1 * base.FOV, DENSITY: 4 * base.DENSITY, + ACCELERATION: 1.5 * base.ACCEL, }, TURRETS: [ { @@ -3563,8 +3622,7 @@ Class.spike = { PARENT: "genericSmasher", LABEL: "Spike", BODY: { - SPEED: base.SPEED * 0.9, - DAMAGE: base.DAMAGE * 1.1, + DAMAGE: base.DAMAGE * 2, }, TURRETS: [ { @@ -3591,7 +3649,7 @@ Class.landmine = { INVISIBLE: [0.06, 0.01], TOOLTIP: "Stay still to turn invisible.", BODY: { - SPEED: 1.1 * base.SPEED + SPEED: 1.45 * base.SPEED }, TURRETS: [ { @@ -3849,7 +3907,7 @@ Class.overtrapper = makeOver({ Class.minilaser = { PARENT: "genericTank", LABEL: "Plasma SMG", - DANGER: 6, + DANGER: 7, BODY: { FOV: 1.2, }, @@ -3921,7 +3979,7 @@ Class.shrapnelgun = { GUNS: [{ POSITION: [17, 13, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, { reload: 1.8 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed]), TYPE: "grenade" } } @@ -4017,7 +4075,7 @@ Class.twinceptionist = { Class.machinception = { PARENT: "genericTank", LABEL: "Machceptioner", - DANGER: 4, + DANGER: 6, GUNS: [ { POSITION: [12, 10, 1.4, 8, 0, 0, 0], @@ -4269,6 +4327,9 @@ Class.pion = { PARENT: "genericSmasher", LABEL: "Pion", DANGER: 6, + BODY: { + SPEED: 2.5 * base.SPEED + }, TURRETS: [ { POSITION: [21.5, 0, 0, 0, 360, 0], @@ -4486,7 +4547,7 @@ Class.cockatiel = makeBird({ Class.binary = { PARENT: "genericTank", LABEL: "Binary", - DANGER: 5, + DANGER: 6, BODY: { ACCELERATION: base.ACCEL * 0.9, FOV: 1.1 @@ -4517,6 +4578,42 @@ Class.binary = { } }] } +Class.twincontagion = { + PARENT: "genericTank", + LABEL: "Contagiwark", + DANGER: 7, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, -5.5, -8, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.twin]), + TYPE: "bullet" + } + }, { + POSITION: [13, 8, 1, 0, -5.5, -8, 0] + }, { + POSITION: [4, 8, 1.7, 13, -5.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.halfrange]), + TYPE: "trap", + STAT_CALCULATOR: "trap", + } + }, { + POSITION: [19, 5.5, 1, 0, 5.5, 8, 0.7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.twin]), + TYPE: "bullet" + } + }, { + POSITION: [13, 8, 1, 0, 5.5, 8, 0.5] + }, { + POSITION: [4, 8, 1.7, 13, 5.5, 8, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.halfrange]), + TYPE: "trap", + STAT_CALCULATOR: "trap", + } + }] +} Class.trinary = { PARENT: "genericTank", LABEL: 'Trinary', @@ -4673,21 +4770,21 @@ Class.accelminigun = { { POSITION: [21, 8, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange, g.morerange]), TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] } }, { POSITION: [19, 8, 1, 0, 0, 0, 1/3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange, g.morerange]), TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] } }, { POSITION: [17, 8, 1, 0, 0, 0, 2/3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange, g.morerange]), TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] } } @@ -4742,8 +4839,7 @@ Class.skater = { LABEL: "Skater", DANGER: 6, BODY: { - SPEED: base.SPEED * 2.4, - ACCELERATION: base.ACCEL * 0.56, + SPEED: base.SPEED * 2.3, }, TURRETS: [ @@ -4816,10 +4912,6 @@ Class.contagion = { PARENT: "genericTank", LABEL: 'Contagion', DANGER: 6, - BODY: { - FOV: 1.1, - ACCELERATION: base.ACCEL * 0.9 - }, STAT_NAMES: statnames.mixed, GUNS: [{ POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], @@ -4832,7 +4924,7 @@ Class.contagion = { }, { POSITION: [4, 8, 1.7, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.morerange, g.lessspread]), + SHOOT_SETTINGS: combineStats([g.trap]), TYPE: "trap", STAT_CALCULATOR: "trap", } @@ -4841,11 +4933,7 @@ Class.contagion = { Class.triContagion = { PARENT: "genericTank", LABEL: "Tri-Contagion", - DANGER: 6, - BODY: { - FOV: 1.1, - ACCELERATION: base.ACCEL * 0.9 - }, + DANGER: 7, STAT_NAMES: statnames.mixed, GUNS: weaponArray([{ POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], @@ -4858,7 +4946,7 @@ Class.triContagion = { }, { POSITION: [4, 8, 1.7, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.morerange, g.lessspread, g.flankGuard]), + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), TYPE: "trap", STAT_CALCULATOR: "trap", } @@ -4995,6 +5083,67 @@ Class.gundirector = { } }] } +Class.gundirectorbig = { + PARENT: "genericTank", + LABEL: "X-Pathogen", + STAT_NAMES: statnames.mixed, + DANGER: 6, + BODY: { + ACCELERATION: base.ACCEL * 0.8, + FOV: 1.2, + }, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { speed: 1.25, reload: 0.95, maxSpeed: 1.15 } ]), + TYPE: "bullet" + } + }, { + POSITION: [6, 16, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.bitlessreload, { speed: 1.1, maxSpeed: 1.1 }]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: "drone", + MAX_CHILDREN: 6 + } + }] +} +Class.wyrm = { + PARENT: "genericTank", + LABEL: "Wyrm", + DANGER: 7, + FACING_TYPE: "locksFacing", + STAT_NAMES: statnames.swarm, + BODY: { + FOV: 1.2 * base.FOV, + }, + GUNS: [ +{ + POSITION: [18, 5.5, 1, 0, 0, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [7, 7.5, 0.6, 7, 4, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "swarm", + STAT_CALCULATOR: "swarm", + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, -4, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "swarm", + STAT_CALCULATOR: "swarm", + }, + }, + ], +} Class.protist = { PARENT: "genericTank", LABEL: "Protist", @@ -5057,7 +5206,7 @@ Class.acid = { }; Class.disintegrator = { PARENT: "genericTank", - DANGER: 6, + DANGER: 7, LABEL: "Disintegrator", GLOW: { RADIUS: 2, @@ -5087,6 +5236,123 @@ Class.disintegrator = { } ] } +Class.formaldehyde = { + PARENT: "genericTank", + LABEL: "Formaldehyde", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2 + }, + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + GUNS: [ + { + POSITION: [21, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "poisonbullet" + } + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "poisonbullet" + } + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "poisonbullet" + } + }, { + POSITION: [16, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "green" + } + } + ] +} +Class.icegun = { + PARENT: "genericTank", + LABEL: "Icegun", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2 + }, + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + GUNS: [ + { + POSITION: [21, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "icebullet" + } + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "icebullet" + } + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "icebullet" + } + }, { + POSITION: [16, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + } + ] +} +Class.frostbite = { + PARENT: "genericTank", + LABEL: 'Frostbite', + DANGER: 6, + GLOW: { + RADIUS: 2, + COLOR: "#28dead", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: base.SPEED * 0.85, + FOV: base.FOV * 1.2, + }, + GUNS: [{ + POSITION: [24, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "poisonicebullet", + } + }, { + POSITION: [19, 2.5, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "green" + } + }] +}; Class.chiller = { PARENT: "genericTank", LABEL: 'Chiller', @@ -5229,7 +5495,7 @@ Class.twinsniper = { Class.backShield = { PARENT: "genericTank", LABEL: 'BackShield', - DANGER: 7, + DANGER: 6, GUNS: [{ POSITION: [18, 8, 1, 0, 0, 0, 0], PROPERTIES: { @@ -5243,6 +5509,23 @@ Class.backShield = { VULNERABLE: true }] }; +Class.bigBackShield = { + PARENT: "genericTank", + LABEL: 'Mega BackShield', + DANGER: 7, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }], + TURRETS: [{ + POSITION: [32, 25, 0, 180, 360, 1], + TYPE: ["backshieldturret", { SHAPE: 12 }], + VULNERABLE: true + }] +}; Class.mirrorBackShield = { PARENT: "genericTank", LABEL: 'BackMirror', @@ -5260,20 +5543,44 @@ Class.mirrorBackShield = { VULNERABLE: true }] }; -Class.waterfall = { +Class.wark = { PARENT: "genericTank", - LABEL: "Waterfall", + LABEL: "Wark", DANGER: 6, - GUNS: [ - { - POSITION: [21, 14, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), - TYPE: "bullet", - }, - }, - { - POSITION: [19, 2, 1, 0, -2.5, 180, 0], + GUNS: [{ + POSITION: [13, 8, 1, 0, -5.5, -8, 0] + }, { + POSITION: [4, 8, 1.7, 13, -5.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.halfrange]), + TYPE: "trap", + STAT_CALCULATOR: "trap", + } + }, { + POSITION: [13, 8, 1, 0, 5.5, 8, 0.5] + }, { + POSITION: [4, 8, 1.7, 13, 5.5, 8, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.halfrange]), + TYPE: "trap", + STAT_CALCULATOR: "trap", + } + }] +} +Class.waterfall = { + PARENT: "genericTank", + LABEL: "Waterfall", + DANGER: 6, + GUNS: [ + { + POSITION: [21, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 2, 1, 0, -2.5, 180, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), TYPE: "bullet", @@ -5364,9 +5671,6 @@ Class.acidsmasher = { PARENT: "genericSmasher", LABEL: "Injector", DANGER: 6, - BODY: { - DAMAGE: base.DAMAGE * 0.87, - }, TURRETS: [ { POSITION: [21.8, 0, 0, 0, 360, 0], @@ -5455,7 +5759,7 @@ Class.surge = { break; case 3: body.guns[0].recoilVelocity = 0; - body.guns[0].shootSettings = combineStats([g.basic, { health: 1.3, pen: 1.6, speed: 3, maxSpeed: 3, size: 1.2, range: 0.5, recoil: 5 }, g.tonsmorerecoil, g.noSpread]); + body.guns[0].shootSettings = combineStats([g.basic, { health: 2, pen: 2.5, speed: 3, maxSpeed: 3, size: 1.2, range: 0.5, recoil: 5 }, g.tonsmorerecoil, g.noSpread]); body.guns[0].setBulletType('lineEMP'); body.guns[0].fire(); body.variables.firingStage++; @@ -5479,21 +5783,48 @@ Class.surge = { RECURSION: 3, } } +Class.brella = { + PARENT: "genericTank", + LABEL: "Nero-Brella", + DANGER: 7, + SYNC_TURRET_SKILLS: true, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [1, 10, 0, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.brella]), + TYPE: "brellaShield", + ALT_FIRE: true, + MAX_CHILDREN: 1, + //ALPHA: 1 + } + }], + TURRETS: [ + { + POSITION: [5, 0, 0, 0, 360, 1], + TYPE: "brellaDeco", + }, + ], +}; Class.lancer = { PARENT: "genericLancer", LABEL: "Lancer", //UPGRADE_TOOLTIP: "Daily Tank!", //UPGRADE_COLOR: "rainbow", BODY: { - SPEED: base.SPEED * 1.2, + SPEED: base.SPEED * 1.3, DAMAGE: base.DAMAGE * 0.9 }, - HAS_NO_RECOIL: true, GUNS: [ { POSITION: [20, 15, 0.001, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + SHOOT_SETTINGS: combineStats([g.basic, g.lance, { recoil: 0 }]), TYPE: ["bullet", { ALPHA: 0 }], AUTOFIRE: true, STAT_CALCULATOR: "lancer" @@ -5507,61 +5838,20 @@ Class.lancer = { Class.lancebrid = makeOver('lancer', "Lancebrid", {count: 1, independent: true, cycle: false}); Class.autolancer = makeAuto('lancer', "Auto-Lancer"); Class.autolancebrid = makeAuto('lancebrid', "Auto-Lancebrid"); -Class.trilancer = { - PARENT: "genericLancer", - LABEL: "Tri-Lancer", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - GUNS: weaponArray([{ - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true, - STAT_CALCULATOR: "lancer" - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }], 3) -} -Class.hexalancer = { - PARENT: "genericLancer", - LABEL: "Hexa Lancer", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - GUNS: weaponArray([{ - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true, - STAT_CALCULATOR: "lancer" - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }], 6) -} Class.chasseur = { PARENT: "genericLancer", LABEL: "Chasseur", + DANGER: 6, BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 1 + SPEED: base.SPEED * 1.3, + DAMAGE: base.DAMAGE * 1.1 }, HAS_NO_RECOIL: true, GUNS: [ { POSITION: [25, 15, 0.001, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + SHOOT_SETTINGS: combineStats([g.basic, g.chasseur]), TYPE: ["bullet", { ALPHA: 0 }], AUTOFIRE: true, STAT_CALCULATOR: "lancer" @@ -5572,61 +5862,17 @@ Class.chasseur = { } ] } -Class.autochasseur = makeAuto('chasseur', "Auto-Chasseur"); -Class.lancerception = makeAuto('lancer', "Lancer-Ception"); -Class.autotrilancer = makeAuto('trilancer', "Auto-Trilancer"); -Class.chasseubrid = makeOver('chasseur', "Chasseubrid", {count: 1, independent: true, cycle: false}); -Class.trilancebrid = makeOver('trilancer', "Trilancebrid", {count: 1, independent: true, cycle: false}); -Class.trichasseur = { - PARENT: "genericLancer", - LABEL: "Tri-Chasseur", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 1 - }, - HAS_NO_RECOIL: true, - GUNS: weaponArray([{ - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true, - STAT_CALCULATOR: "lancer" - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - }], 3) -} -Class.tripleur = { - PARENT: "genericLancer", - LABEL: "Tripleur", - BODY: { - SPEED: base.SPEED * 1.1, - DAMAGE: base.DAMAGE * 1 - }, - HAS_NO_RECOIL: true, - GUNS: weaponArray([{ - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true, - STAT_CALCULATOR: "lancer" - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - }], 3) -} Class.trailblazer = { PARENT: "genericLancer", LABEL: "Trailblazer", + DANGER: 7, BODY: { HEALTH: 0.8 * base.HEALTH, SHIELD: 0.8 * base.SHIELD, DENSITY: 0.6 * base.DENSITY, + DAMAGE: 0.9 * base.DAMAGE }, + HAS_NO_RECOIL: false, GUNS: [ { POSITION: [20, 15, 0.001, 0, 0, 0, 0], @@ -5662,8 +5908,9 @@ Class.trailblazer = { Class.katana = { PARENT: "genericLancer", LABEL: "Katana", + DANGER: 7, BODY: { - SPEED: base.SPEED * 1.2, + SPEED: base.SPEED * 1.4, DAMAGE: base.DAMAGE * 0.9 }, VARIABLES: { @@ -5722,8 +5969,9 @@ Class.katana = { Class.dasher = { PARENT: "genericLancer", LABEL: "Dasher", + DANGER: 7, BODY: { - SPEED: base.SPEED * 1.2, + SPEED: base.SPEED * 1.4, DAMAGE: base.DAMAGE * 0.9 }, VARIABLES: { @@ -5775,8 +6023,9 @@ Class.dasher = { Class.bayonet = { PARENT: "genericLancer", LABEL: "Bayonet", + DANGER: 6, BODY: { - SPEED: base.SPEED * 1.2, + SPEED: base.SPEED * 1.3, DAMAGE: base.DAMAGE * 0.9 }, HAS_NO_RECOIL: true, @@ -5795,7 +6044,37 @@ Class.bayonet = { }, { POSITION: [13, 7, 1, 0, 0, 0, 0.2], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter]), + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + } + ] +} +Class.wakizashi = { + PARENT: "genericLancer", + LABEL: "Wakizashi", + DANGER: 6, + BODY: { + SPEED: base.SPEED * 1.3, + DAMAGE: base.DAMAGE * 1.1 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.chasseur]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true, + STAT_CALCULATOR: "lancer" + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, { + POSITION: [13, 7, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), TYPE: "bullet" } } @@ -5926,6 +6205,7 @@ Class.rocker = { Class.jouster = { PARENT: "genericLancer", LABEL: "Jouster", + DANGER: 6, BODY: { HEALTH: 0.7 * base.HEALTH, SHIELD: 0.7 * base.SHIELD, @@ -5958,6 +6238,7 @@ Class.jouster = { Class.knight = { PARENT: "genericLancer", LABEL: "Knight", + DANGER: 7, BODY: { HEALTH: 0.6 * base.HEALTH, SHIELD: 0.6 * base.SHIELD, @@ -5988,6 +6269,80 @@ Class.knight = { }, ] } +Class.fencer = { + PARENT: "genericLancer", + LABEL: "Fencer", + DANGER: 6, + BODY: { + HEALTH: 0.7 * base.HEALTH, + SHIELD: 0.7 * base.SHIELD, + DENSITY: 0.7 * base.DENSITY, + DAMAGE: base.DAMAGE * 1.1 + }, + HAS_NO_RECOIL: false, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.chasseur, { recoil: 2 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true, + STAT_CALCULATOR: "lancer" + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [16, 8, 1, 0, 0, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster, { recoil: 0.6 }]), + TYPE: "bullet", + LABEL: "thruster", + }, + }, + ] +} +Class.arisaka = { + PARENT: "genericLancer", + LABEL: "Arisaka", + DANGER: 6, + BODY: { + HEALTH: 0.7 * base.HEALTH, + SHIELD: 0.7 * base.SHIELD, + DENSITY: 0.7 * base.DENSITY, + DAMAGE: base.DAMAGE * 1.1 + }, + HAS_NO_RECOIL: false, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance, { recoil: 2 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true, + STAT_CALCULATOR: "lancer" + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, { + POSITION: [13, 7, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + TYPE: "bullet" + } + }, + { + POSITION: [16, 8, 1, 0, 0, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster, { recoil: 0.6 }]), + TYPE: "bullet", + LABEL: "thruster", + }, + }, + ] +} Class.saturn = { PARENT: "genericSmasher", LABEL: "Saturn", @@ -6009,6 +6364,220 @@ Class.saturn = { } ], } + Class.choker = { + PARENT: "genericTank", + LABEL: "Choker", + DANGER: 6, + GUNS: [ + { + POSITION: [14, 12, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { size: 0.8, reload: 1.2 }]), + TYPE: 'undertowBullet' + } + }, + { + POSITION: [11.25, 8, 0.15, 4.25, 4, 13.5, 0] + }, + { + POSITION: [11.25, 8, 0.15, 4.25, -4, -13.5, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance, { recoil: 0 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true, + STAT_CALCULATOR: "lancer" + } + }, + ] + } +Class.noble = { + PARENT: "director", + LABEL: "Noble", + DANGER: 6, + BODY: { + ACCELERATION: base.ACCEL * 2, + SPEED: base.SPEED * 1.8 + }, + TURRETS: [{ + POSITION: [14, 0, 0, 0, 360, 2], + TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + } + ], +} +Class.helium = { + PARENT: "overseer", + LABEL: "Helium", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 2, + SPEED: base.SPEED * 1.8 + }, + TURRETS: [{ + POSITION: [14, 0, 0, 0, 360, 2], + TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + } + ], +} +Class.neon = { + PARENT: "cruiser", + LABEL: "Neon", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 2, + SPEED: base.SPEED * 1.8 + }, + TURRETS: [{ + POSITION: [14, 0, 0, 0, 360, 2], + TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + } + ], +} +Class.argon = { + PARENT: "underseer", + LABEL: "Argon", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 2, + SPEED: base.SPEED * 1.8 + }, + TURRETS: [{ + POSITION: [14, 0, 0, 0, 360, 2], + TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + } + ], +} +Class.krypton = { + PARENT: "gundirector", + LABEL: "Krypton", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 2, + SPEED: base.SPEED * 1.8 + }, + TURRETS: [{ + POSITION: [14, 0, 0, 0, 360, 2], + TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + } + ], +} +Class.xenon = { + PARENT: "spawner", + LABEL: "Xenon", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 2, + SPEED: base.SPEED * 1.8 + }, + TURRETS: [{ + POSITION: [14, 0, 0, 0, 360, 2], + TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + } + ], +} +Class.radon = { + PARENT: "directdrive", + LABEL: "Radon", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 2, + SPEED: base.SPEED * 1.8 + }, + TURRETS: [{ + POSITION: [14, 0, 0, 0, 360, 2], + TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + }, { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "overdriveDeco", + }, + ], +} +Class.gatlinggun = { + PARENT: "genericTank", + LABEL: "Gatling Gun", + DANGER: 6, + GUNS: [{ + POSITION: [14, 10, 1.3, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal]), + TYPE: "bullet", + }, + }, + ], +} +Class.accelgatlinggun = { + PARENT: "genericTank", + LABEL: "Charger", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2 + }, + GUNS: [ + { + POSITION: [8, .1, -54, 21, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal, g.fake]), + TYPE: "bullet", + COLOR: 12 + } + }, + { + POSITION: [14, 10, 1.3, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal, g.rainmaker]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + }, + }, + ] +} +Class.Gatlinception = { + PARENT: "genericTank", + LABEL: "Gatceptioner", + DANGER: 7, + GUNS: [ +{ + POSITION: [14, 10, 1.3, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal]), + TYPE: "autobullet", + }, + }, + ], + TURRETS: [{ + POSITION: [6.5, 22, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.Sprayinception = { + PARENT: "genericTank", + LABEL: "Sprayceptioner", + DANGER: 7, + GUNS: [ + { + POSITION: [23, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.lowPower, g.pelleter, { recoil: 1.15 }]), + TYPE: "bullet" + } + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "autobullet" + } + }, + ], + TURRETS: [{ + POSITION: [6.5, 20, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} + // Auto tanks Class.autoBasic = makeAuto("basic", "Auto-Basic"); @@ -6040,7 +6609,8 @@ Class.autoCloner = makeAuto({ PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.slow]), TYPE: "autoclonerprobe", - MAX_CHILDREN: 1 + MAX_CHILDREN: 1, + WAIT_TO_CYCLE: true } } ], @@ -6064,6 +6634,7 @@ Class.autoBuilder = makeAuto("builder") Class.autoBinary = makeAuto("binary", "Computist") Class.autoinceptionist = makeAuto("autoinceptionistbody", "Poster", {type: 'ceptionistturret'}); Class.autoGundirector = makeAuto("gundirector", "Virus") +Class.oganesson = makeAuto("noble", "Oganesson") Class.autoBigSubduer = makeAuto("bigSubduer", "Membrane") Class.autoFlankdue = makeAuto("flankdue", "Flank-Duelist") Class.autoBateau = makeAuto("bateau", "Riverboat") @@ -6112,6 +6683,10 @@ Class.autoflankinception = makeAuto("flankinception", "Flank-Deployer"); Class.autoBackShield = makeAuto("backShield", "Coverer"); Class.autoSwivel2 = makeAuto("swivel2", "Scowerer"); Class.autoJouster = makeAuto("jouster", "Horse"); +Class.autochasseur = makeAuto('chasseur', "Auto-Chasseur"); +Class.autobayonet = makeAuto('bayonet', "Auto-Bayonet"); +Class.autoGatlinggun = makeAuto("gatlinggun", "A-Gatling Gun"); +Class.autowark = makeAuto("wark", "WaWark"); Class.autoSmasher = makeAuto({ PARENT: "genericSmasher", DANGER: 6, @@ -6161,7 +6736,8 @@ Class.clonebrid = makeOver({ PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.slow]), TYPE: "hybridclonerprobe", - MAX_CHILDREN: 1 + MAX_CHILDREN: 1, + WAIT_TO_CYCLE: true } } ], @@ -6201,6 +6777,12 @@ Class.flankinceptionbrid = makeOver('flankinception', "Flankinceptibrid", {count Class.bateaubrid = makeOver('bateau', "Kayak", {count: 1, independent: true, cycle: false}) Class.swivel2brid = makeOver('swivel2', "Swivel2brid", {count: 1, independent: true, cycle: false}) Class.jousterbrid = makeOver('jouster', "Jousterbrid", {count: 1, independent: true, cycle: false}) +Class.bayonetbrid = makeOver('bayonet', "Bayonet-Hybrid", {count: 1, independent: true, cycle: false}); +Class.chasseubrid = makeOver('chasseur', "Chasseubrid", {count: 1, independent: true, cycle: false}); +Class.backshieldbrid = makeOver('backShield', "Fireblanket", {count: 1, independent: true, cycle: false}) +Class.gatlinggunbrid = makeOver('gatlinggun', "H-Gatling Gun", {count: 1, independent: true, cycle: false}) +Class.warkbrid = makeOver('wark', "Waarrk", {count: 1, independent: true, cycle: false}) + //auto hybrid tanks Class.autotwinbrid = makeOver('autoTwin', "Auto-Twinbrid", {count: 1, independent: true, cycle: false}) @@ -6213,8 +6795,8 @@ Class.autodesmosbrid = makeOver('autoDesmos', "Chartebrid", {count: 1, independe Class.autobascrid = makeOver('autoBasic', "Auto-Basebrid", {count: 1, independent: true, cycle: false}) Class.autoinceptionbrid = makeOver('autoinception', "Deployerbrid", {count: 1, independent: true, cycle: false}) Class.autolittleHunterbrid = makeOver('autolittleHunter', "Auto-Subbrid", {count: 1, independent: true, cycle: false}) -Class.autopropelbrid = makeOver('propel', "Grazerbrid", {count: 1, independent: true, cycle: false}) -Class.autoauto2brid = makeOver('auto2', "Auto²-2brid", {count: 1, independent: true, cycle: false}) +Class.autopropelbrid = makeOver('autoPropel', "Grazerbrid", {count: 1, independent: true, cycle: false}) +Class.autoauto2brid = makeOver('autoauto2', "Auto²-2brid", {count: 1, independent: true, cycle: false}) //hybrid drive tanks Class.car = makeOver('basic', "Car", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) @@ -6246,6 +6828,7 @@ Class.bascridCeption = makeCeption('bascrid', "Baseception"); Class.littleHunterCeption = makeCeption('littleHunter', "Subception"); Class.inceptCeption = makeCeption('inception', "Incepticon"); Class.propelCeption = makeCeption('propel', "Propeleception"); +Class.lancerception = makeAuto('lancer', "Lanceception"); Class.auto2Ception = makeCeption('auto2', "Auto-2²"); Class.revoception = makeCeption('revolutionist', "revonception"); @@ -6348,6 +6931,7 @@ Class.auraChiller = makeAura(Class.chiller); Class.auraMinigun = makeAura(Class.minigun); Class.auraGunner = makeAura(Class.gunner); Class.auraSprayer = makeAura(Class.sprayer); +Class.auraGatlinggun = makeAura(Class.gatlinggun); Class.auraHexaTank = makeAura(Class.hexaTank); Class.auraTriAngle = makeAura(Class.triAngle); @@ -6359,6 +6943,7 @@ Class.auraCruiser = makeAura(Class.cruiser); Class.auraUnderseer = makeAura(Class.underseer); Class.auraSpawner = makeAura(Class.spawner); Class.auraDirectdrive = makeAura(Class.directdrive); +Class.auraNoble = makeAura(Class.noble); Class.auraDestroyer = makeAura(Class.destroyer); Class.auraArtillery = makeAura(Class.artillery); @@ -6367,6 +6952,7 @@ Class.auraLauncher = makeAura(Class.launcher); Class.auraBuilder = makeAura(Class.builder); Class.auraTriTrapper = makeAura(Class.triTrapper); Class.auraTrapGuard = makeAura(Class.trapGuard); +Class.auraWark = makeAura(Class.wark); Class.auraAutoTwin = makeAura(Class.autoTwin); Class.auraAutoSniper = makeAura(Class.autoSniper); @@ -6385,8 +6971,8 @@ Class.auraAutoPropel = makeAura(Class.propel); Class.auraBasicCeption = makeAura(Class.basicCeption); Class.auraHomingautoBasic = makeAura(Class.homingautoBasic); -Class.auratwinbrid = makeAura(Class.launcher); -Class.aurasnipebrid = makeAura(Class.launcher); +Class.auratwinbrid = makeAura(Class.twinbrid); +Class.aurasnipebrid = makeAura(Class.snipebrid); Class.auramachbrid = makeAura(Class.machbrid); Class.auraflankbrid = makeAura(Class.flankbrid); Class.aurapoundbrid = makeAura(Class.poundbrid); @@ -6398,7 +6984,7 @@ Class.aurainceptionbrid = makeAura(Class.inceptionbrid); Class.aurapropelbrid = makeAura(Class.auto2brid); Class.auraauto2brid = makeAura(Class.auto2brid); Class.auralancebrid = makeAura(Class.lancebrid); -Class.jeep = makeAura(Class.car, "jeep"); +Class.jeep = makeAura(Class.car, "Jeep"); Class.auraBinary = makeAura(Class.binary); Class.auraContagion = makeAura(Class.contagion); @@ -6420,80 +7006,81 @@ Class.auraSwivel2 = makeAura(Class.swivel2); Class.auraLancer = makeAura(Class.lancer); Class.auraChasseur = makeAura(Class.chasseur); -Class.auraTriLancer = makeAura(Class.trilancer); +Class.auraBayonet = makeAura(Class.bayonet); Class.auraBateau = makeAura(Class.bateau); Class.auraJouster = makeAura(Class.jouster); // TANK UPGRADE PATHS -Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "autoBasic", "desmos", "bascrid", "littleHunter", "inception", "propel", "lancer", "auto2", "auraBasic", "whirlwind"] +Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", /*"autoBasic", */"desmos", /*"bascrid", */"littleHunter", "inception", "propel", "lancer", "auto2", /*"auraBasic", */"whirlwind"] Class.basic.UPGRADES_TIER_2 = ["smasher", "cloner"] - Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "landmine", "cocci", "pion", "trackerSmasher", "saturn", "skater", "acidsmasher", "flail", "autoSmasher", "auraSmasher", "jumpSmasher"] + Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "landmine", "pion", "trackerSmasher", "saturn", "skater", "acidsmasher", "flail", "autoSmasher", "auraSmasher", "jumpSmasher"] Class.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] - Class.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner"] + Class.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner", "clonebrid"] - Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "autoTwin", "helix", "twinbrid", "binary", "twinsniper", "auraTwin"] - Class.twin.UPGRADES_TIER_3 = ["bulwark"] - Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble", "doubletwinbrid", "auraDoubleTwin"] + Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "helix", "wark", "binary", "twinsniper", "autoTwin", "twinbrid", "auraTwin"] + Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "bulwark", "autoDouble", "bentDouble", "doubletwinbrid", "auraDoubleTwin"] Class.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentDouble", "triplet", "autoTripleShot", "triplex", "bentHybrid", "trinary", "auraTripleShot"] - Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "marksman", "twinsniper", "autoSniper", "snipebrid", "trackerSniper", "acid", "chiller", "chasseur", "auraSniper"] + Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "twinsniper", "autoSniper", "snipebrid", "trackerSniper", "acid", "chiller", "chasseur", "auraSniper"] Class.sniper.UPGRADES_TIER_3 = ["bushwhacker"] - Class.assassin.UPGRADES_TIER_3 = ["ranger", "xHunter", "falcon", "stalker", "autoAssassin", "deadeye", "assbrid", "trackerAssassin", "disintegrator", "freezer", "auraAssassin", "single"] - Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "railgun", "dual", "nimrod", "autoHunter", "trackerHunter", 'auraHunter'] - Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman", "revolver", "autoRifle", "trackerRifle", "auraRifle"] - Class.marksman.UPGRADES_TIER_3 = ["deadeye", "nimrod", "revolver", "fork"] + Class.assassin.UPGRADES_TIER_3 = ["ranger", "xHunter", "falcon", "stalker", "autoAssassin", "assbrid", "trackerAssassin", "disintegrator", "freezer", "auraAssassin", "single"] + Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "railgun", "dual", "wakizashi", "autoHunter", "trackerHunter", 'auraHunter'] + Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman", "autoRifle", "trackerRifle", "auraRifle"] Class.trackerSniper.UPGRADES_TIER_3 = ["trackerAssassin", "trackerHunter", "trackerMini", "trackerRifle", "trackerTwinsniper", "trackerSniperHybrid", "trackerAcid", "trackerChill", "auraTrackerSniper"] Class.twinsniper.UPGRADES_TIER_3 = ["dual", "musket", "autoTwinsniper", "twipebrid", "trackerTwinsniper", "auraTwinSniper"] - Class.acid.UPGRADES_TIER_3 = ["disintegrator", "acidsmasher", "autoAcid", "acidbrid", "trackerAcid", "auraAcid"] - Class.chiller.UPGRADES_TIER_3 = ["freezer", "autoChill", "chillbrid", "trackerChill", "auraChiller", "surge"] + Class.acid.UPGRADES_TIER_3 = ["disintegrator", "acidsmasher", "formaldehyde", "frostbite", "autoAcid", "acidbrid", "trackerAcid", "auraAcid"] + Class.chiller.UPGRADES_TIER_3 = ["freezer", "icegun", "frostbite", "autoChill", "chillbrid", "trackerChill", "auraChiller", "surge"] - Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "autoMach", "machbrid", "machinception", "auraMachineGun"] - Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture", "minilaser", "autoMini", "trackerMini", "accelminigun", "auraMinigun"] + Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "gatlinggun", "autoMach", "machbrid", "machinception", "auraMachineGun"] + Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture", "minilaser", "formaldehyde", "icegun", "autoMini", "trackerMini", "accelminigun", "auraMinigun"] Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner", "waterfall", "helecopter", "auraGunner"] - Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "autoSprayer", "spraybrid", "auraSprayer"] + Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "Sprayinception", "autoSprayer", "spraybrid", "auraSprayer"] + Class.gatlinggun.UPGRADES_TIER_3 = ["focal", "Gatlinception", "accelgatlinggun", "autoGatlinggun", "gatlinggunbrid", "auraGatlinggun"] - Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank", "flankbrid", "flankdue", "flankinception", "trilancer", "backShield", "auraFlankGuard"] + Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank", "flankbrid", "flankdue", /*"flankinception", */"backShield", "auraFlankGuard"] Class.flankGuard.UPGRADES_TIER_3 = ["tripleTwin", "quadruplex"] - Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper", "autoHexaTank", "hexatankbrid", "hexalancer", "auraHexaTank", "auraHexaTank", "hexaWhirl"] - Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "trianglebrid", "surfer", "eagle", "phoenix", "vulture", "subway", "helecopter", "trailblazer", "rocker", "cockatiel"] - Class.backShield.UPGRADES_TIER_3 = ["mirrorBackShield", "brella", "autoBackShield", "auraBackShield"] + Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper", "autoHexaTank", "hexatankbrid", "auraHexaTank", "hexaWhirl"] + Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "trianglebrid", "surfer", "eagle", "phoenix", "vulture", "subway", "helecopter", "trailblazer", "rocker", "cockatiel", "auraTriAngle"] + Class.backShield.UPGRADES_TIER_3 = ["bigBackShield", "brella", "autoBackShield", "backshieldbrid", "auraBackShield"] - Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "gundirector", "spawner", "directdrive", "autoDirector", "auraDirector"] + Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "gundirector", "spawner", "directdrive", "noble", "autoDirector", "auraDirector"] Class.director.UPGRADES_TIER_3 = ["manager", "bigCheese"] - Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "trojan", "overdrive", "commander", "auraOverseer"] - Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "surfer", "autoCruiser", "commander", "auraCruiser"] - Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor", "autoUnderseer", "auraUnderseer"/* "prophet",*/] - Class.spawner.UPGRADES_TIER_3 = ["factory", "protist", "ranch", "autoSpawner", "auraSpawner"] - Class.directdrive.UPGRADES_TIER_3 = ["overdrive", "cruiserdrive", "revodirector", "honda", "dictator", "factory", "autoMotor", "auraDirectdrive"] + Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "trojan", "overdrive", "commander", "helium", "auraOverseer"] + Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "surfer", "wyrm", "autoCruiser", "commander", "neon", "auraCruiser"] + Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor", "autoUnderseer", "argon", "auraUnderseer"/* "prophet",*/] + Class.spawner.UPGRADES_TIER_3 = ["factory", "protist", "autoSpawner", "xenon", "auraSpawner"] + Class.directdrive.UPGRADES_TIER_3 = ["overdrive", "cruiserdrive", "revodirector", "honda", "dictator", "radon", "autoMotor", "auraDirectdrive"] + Class.noble.UPGRADES_TIER_3 = ["helium", "neon", "argon", "krypton", "xenon", "radon", "oganesson", "auraNoble"] - Class.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher", "autoPound", "sidewinder", "poundbrid", "tailgator", "auraPounder"] + Class.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher", "autoPound", "poundbrid", "tailgator", "auraPounder"] Class.pounder.UPGRADES_TIER_3 = ["shotgun", "eagle"] Class.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct", "autoDestroy", "waterfall", "interceptor", "auraDestroyer"] Class.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun", "autoArtillery", "artilbrid", "auraArtillery", "munition"] - Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun", "shrapnelgun", "firecracker", "python", "autoLaunch", "launchbrid", "auraLauncher", "vortex"] + Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun", "shrapnelgun", "firecracker", "autoLaunch", "launchbrid", "auraLauncher", "vortex"] - Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "contagion", "autoTrap", "trapbrid", "auraTrapper"] + Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "wark", "contagion", "autoTrap", "trapbrid", "auraTrapper"] Class.trapper.UPGRADES_TIER_3 = ["barricade"] - Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "builderbrid"] - Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "triContagion", "autoTriTrapper", "tritrapperbrid"] + Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "builderbrid", "auraBuilder"] + Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "triContagion", "autoTriTrapper", "tritrapperbrid", "auraTriTrapper"] Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "autoTrapGuard", "trapguardbrid", "auraTrapGuard", "whirlGuard"] + Class.wark.UPGRADES_TIER_3 = ["bulwark", "twincontagion", "autowark", "warkbrid", "auraWark"] - Class.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "autoDesmos", "basicCeption", "autobascrid", "autolittleHunter", "autoinception", "autoPropel", "autolancer", "autoauto2", "auraAutoBasic", "homingautoBasic"] + Class.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "autoDesmos", "autobascrid", "autolittleHunter", "autoinception", "autoPropel", "autolancer", "autoauto2", "auraAutoBasic", "homingautoBasic"] Class.autoBasic.UPGRADES_TIER_3 = ["autoSmasher", "autoCloner"] - Class.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "equilibrium", "autoBinary", "autoTwinsniper", "twinCeption", "autotwinbrid", "auraAutoTwin", "homingautoTwin"] - Class.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "autoTwinsniper", "autoAcid", "autoChill", "snipeCeption", "autosnipebrid", "autochasseur", "auraAutoSniper", "homingautoSniper"] - Class.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "machCeption", "automachbrid", "automachinception", "auraAutoMach", "homingautoMach"] - Class.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "autoTriTrapper", "flankCeption", "autoflankbrid", "autoFlankdue", "autoflankinception", "autotrilancer", "auraAutoFlank", "homingautoFlank"] - Class.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoGundirector", "autoSpawner", "directCeption", "auraAutoDirector", "homingautoDirector"] - Class.autoPound.UPGRADES_TIER_3 = ["autoDestroy", "autoBuilder", "autoArtillery", "autoLaunch", "poundCeption", "autoSidewinder", "autopoundbrid", "autotailgator", "auraAutoPound", "homingautoPound"] - Class.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "autoTriTrapper", "autoTrapGuard", "autoContagion", "trapCeption", "autotrapbrid", "auraAutoTrap", "homingautoTrap"] - Class.autoDesmos.UPGRADES_TIER_3 = ["autoSidewinder", "autoHelix", "autoUndertow", "autoRepeater", "desmosCeption", "autodesmosbrid", "auraAutoDesmos", "homingautoDesmos"] - Class.autolittleHunter.UPGRADES_TIER_3 = ["autoMini", "autoBinary", "autoHunter", "autoSprayer", "autoContagion", "autoGundirector", "autoBigSubduer", "autoFlankdue", "autolittleHunterbrid", "littleHunterCeption", "auraAutoLittleHunter", "homingautolittleHunter"] - Class.autoinception.UPGRADES_TIER_3 = ["autoinceptionist", "automachinception", "autotailgator", "autoflankinception", "autoinceptionbrid", "inceptCeption", "auraAutoInception", "homingautoinception"] - Class.autoPropel.UPGRADES_TIER_3 = ["autoTriAngle", "autoBateau", "autoJouster", "propelCeption", "autopropelbrid", "auraAutoPropel", "homingautopropel"] - Class.autoauto2.UPGRADES_TIER_3 = ["autoAuto3", "autoRevolutionist", "autoauto2brid", "auto2Ception", "auraAutoAuto2", "homingautoauto2"] - Class.autolancer.UPGRADES_TIER_3 = ["autochasseur", "autotrilancer", "autoJouster", "lancerception", "autolancebrid", "auraAutoLancer", "homingautolancer"] + Class.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "equilibrium", "autoBinary", "autoTwinsniper", "autotwinbrid", "auraAutoTwin", "homingautoTwin"] + Class.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "autoTwinsniper", "autoAcid", "autoChill", "autosnipebrid", "autochasseur", "auraAutoSniper", "homingautoSniper"] + Class.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "autoGatlinggun", "automachbrid", "automachinception", "auraAutoMach", "homingautoMach"] + Class.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "autoTriTrapper", "autoflankbrid", "autoFlankdue", "autoflankinception", "auraAutoFlank", "homingautoFlank"] + Class.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoGundirector", "autoSpawner", "auraAutoDirector", "homingautoDirector"] + Class.autoPound.UPGRADES_TIER_3 = ["autoDestroy", "autoBuilder", "autoArtillery", "autoLaunch", "autopoundbrid", "autotailgator", "auraAutoPound", "homingautoPound"] + Class.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "autoTriTrapper", "autoTrapGuard", "autoContagion", "autotrapbrid", "auraAutoTrap", "homingautoTrap"] + Class.autoDesmos.UPGRADES_TIER_3 = ["autoHelix", "autoUndertow", "autoRepeater", "autodesmosbrid", "auraAutoDesmos", "homingautoDesmos"] + Class.autolittleHunter.UPGRADES_TIER_3 = ["autoMini", "autoBinary", "autoHunter", "autoSprayer", "autoContagion", "autoGundirector", "autoBigSubduer", "autoFlankdue", "autobayonet", "autolittleHunterbrid", "auraAutoLittleHunter", "homingautolittleHunter"] + Class.autoinception.UPGRADES_TIER_3 = ["autoinceptionist", "automachinception", "autotailgator", "autoflankinception", "autoinceptionbrid", "auraAutoInception", "homingautoinception"] + Class.autoPropel.UPGRADES_TIER_3 = ["autoTriAngle", "autoBateau", "autoJouster", "autopropelbrid", "auraAutoPropel", "homingautopropel"] + Class.autoauto2.UPGRADES_TIER_3 = ["autoAuto3", "autoRevolutionist", "autoSwivel2", "autoauto2brid", "auraAutoAuto2", "homingautoauto2"] + Class.autolancer.UPGRADES_TIER_3 = ["autochasseur", "autoJouster", "autobayonet", "autolancebrid", "auraAutoLancer", "homingautolancer"] Class.basicCeption.UPGRADES_TIER_3 = ["twinCeption", "snipeCeption", "machCeption", "flankCeption", "directCeption", "poundCeption", "trapCeption", "desmosCeption", "bascridCeption", "littleHunterCeption", "inceptCeption", "propelCeption", "lancerception", "auto2Ception", "auraBasicCeption"] Class.homingautoBasic.UPGRADES_TIER_3 = ["homingautoTwin", "homingautoSniper", "homingautoMach", "homingautoFlank", "homingautoDirector", "homingautoPound", "homingautoTrap", "homingautoDesmos", "homingautobascrid", "homingautolittleHunter", "homingautoinception", "homingautopropel", "homingautolancer", "homingautoauto2", "auraHomingautoBasic"] @@ -6501,70 +7088,68 @@ Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "di Class.bascrid.UPGRADES_TIER_3 = ["clonebrid"] Class.twinbrid.UPGRADES_TIER_3 = ["doubletwinbrid", "bentHybrid", "overgunner", "hexatankbrid", "autotwinbrid", "helixbrid", "binarybrid", "twipebrid", "mercedes", "auratwinbrid"] Class.snipebrid.UPGRADES_TIER_3 = ["assbrid", "poacher", "cropDuster", "armsman", "twipebrid", "autosnipebrid", "trackerSniperHybrid", "acidbrid", "chillbrid", "chasseubrid", "tesla", "aurasnipebrid"] - Class.machbrid.UPGRADES_TIER_3 = ["artilbrid", "cropDuster", "overgunner", "spraybrid", "automachbrid", "machinceptionbrid", "toyota", "auramachbrid"] - Class.flankbrid.UPGRADES_TIER_3 = ["hexatankbrid", "trianglebrid", "auto3brid", "trapguardbrid", "tritrapperbrid", "autoflankbrid", "flankduebrid", "flankinceptionbrid", "trilancebrid", "ford", "auraflankbrid"] - Class.poundbrid.UPGRADES_TIER_3 = ["hybrid", "builderbrid", "artilbrid", "launchbrid", "autopoundbrid", "sidewinderbrid", "tailgatorbrid", "honda", "aurapoundbrid"] + Class.machbrid.UPGRADES_TIER_3 = ["artilbrid", "cropDuster", "overgunner", "spraybrid", "gatlinggunbrid", "automachbrid", "machinceptionbrid", "toyota", "auramachbrid"] + Class.flankbrid.UPGRADES_TIER_3 = ["hexatankbrid", "trianglebrid", "auto3brid", "trapguardbrid", "tritrapperbrid", "autoflankbrid", "flankduebrid", "flankinceptionbrid", "ford", "auraflankbrid"] + Class.poundbrid.UPGRADES_TIER_3 = ["hybrid", "builderbrid", "artilbrid", "launchbrid", "autopoundbrid", "tailgatorbrid", "honda", "aurapoundbrid"] Class.trapbrid.UPGRADES_TIER_3 = ["builderbrid", "tritrapperbrid", "trapguardbrid", "contagionbrid", "autotrapbrid", "overtrapper", "gmc", "auratrapbrid"] - Class.autobascrid.UPGRADES_TIER_3 = ["autotwinbrid", "autosnipebrid", "automachbrid", "autoflankbrid", "autopoundbrid", "autotrapbrid", "autodesmosbrid", "autolittleHunterbrid", "autoinceptionbrid", "autopropelbrid", "autolancebrid", "bascridCeption", "porsche", "auraautobascrid"] - Class.desmosbrid.UPGRADES_TIER_3 = ["sidewinderbrid", "helixbrid", "undertowbrid", "repeaterbrid", "autodesmosbrid", "mazda", "auradesmosbrid"] - Class.littleHunterbrid.UPGRADES_TIER_3 = ["cropDuster", "binarybrid", "poacher", "spraybrid", "contagionbrid", "bigsubduerbrid", "flankduebrid", "autolittleHunterbrid", "volkswagen", "auralittlehunterbrid"] + Class.autobascrid.UPGRADES_TIER_3 = ["autotwinbrid", "autosnipebrid", "automachbrid", "autoflankbrid", "autopoundbrid", "autotrapbrid", "autodesmosbrid", "autolittleHunterbrid", "autoinceptionbrid", "autopropelbrid", "autolancebrid", "porsche", "auraautobascrid"] + Class.desmosbrid.UPGRADES_TIER_3 = ["helixbrid", "undertowbrid", "repeaterbrid", "autodesmosbrid", "mazda", "auradesmosbrid"] + Class.littleHunterbrid.UPGRADES_TIER_3 = ["cropDuster", "binarybrid", "poacher", "spraybrid", "contagionbrid", "bigsubduerbrid", "flankduebrid", "bayonetbrid", "autolittleHunterbrid", "volkswagen", "auralittlehunterbrid"] Class.inceptionbrid.UPGRADES_TIER_3 = ["trianglebrid", "machinceptionbrid", "tailgatorbrid", "flankinceptionbrid", "overdrive", "autoinceptionbrid", "audi", "aurainceptionbrid"] Class.propelbrid.UPGRADES_TIER_3 = ["trianglebrid", "bateaubrid", "jousterbrid", "autopropelbrid", "mustang", "aurapropelbrid"] - Class.auto2brid.UPGRADES_TIER_3 = ["auto3brid", "revobrid", "autoauto2brid", "ferrari", "auraauto2brid"] - Class.lancebrid.UPGRADES_TIER_3 = ["chasseubrid", "trilancebrid", "jousterbrid", "autolancebrid", "ram", "auralancebrid"] + Class.auto2brid.UPGRADES_TIER_3 = ["auto3brid", "revobrid", "swivel2brid", "autoauto2brid", "ferrari", "auraauto2brid"] + Class.lancebrid.UPGRADES_TIER_3 = ["chasseubrid", "jousterbrid", "bayonetbrid", "autolancebrid", "ram", "auralancebrid"] Class.car.UPGRADES_TIER_3 = ["mercedes", "tesla", "toyota", "ford", "overdrive", "honda", "gmc", "porsche", "mazda", "volkswagen", "audi", "mustang", "ram", "ferrari", "jeep"] - Class.littleHunter.UPGRADES_TIER_2 = ["minigun", "binary", "hunter", "sprayer", "contagion", "gundirector", "bigSubduer", "flankdue", "autolittleHunter", "littleHunterbrid", "auraLittleHunter"] - Class.littleHunter.UPGRADES_TIER_3 = ["bayonet"] - Class.binary.UPGRADES_TIER_3 = ["trinary", "dual", "autoBinary", "binarybrid", "auraBinary"] - Class.contagion.UPGRADES_TIER_3 = ["fort", "triContagion", "autoContagion", "droneTrapper", "cockatiel", "contagionbrid", "auraContagion"] - Class.gundirector.UPGRADES_TIER_3 = ["trojan", "protist", "droneTrapper", "autoGundirector"] + Class.littleHunter.UPGRADES_TIER_2 = ["minigun", "binary", "hunter", "sprayer", "contagion", "gundirector", "bigSubduer", "flankdue", "bayonet", "autolittleHunter", "littleHunterbrid", "auraLittleHunter"] + Class.binary.UPGRADES_TIER_3 = ["trinary", "dual", "twincontagion", "autoBinary", "binarybrid", "auraBinary"] + Class.contagion.UPGRADES_TIER_3 = ["fort", "triContagion", "twincontagion", "droneTrapper", "cockatiel", "autoContagion", "contagionbrid", "auraContagion"] + Class.gundirector.UPGRADES_TIER_3 = ["trojan", "protist", "wyrm", "gundirectorbig", "droneTrapper", "autoGundirector", "krypton", "auraGundirector"] Class.bigSubduer.UPGRADES_TIER_3 = ["predator", "redistributor", "biggerSubduer", "clubbin", "autoBigSubduer", "bigsubduerbrid", "auraBigSubduer"] Class.flankdue.UPGRADES_TIER_3 = ["subway", "triContagion", "clubbin", "autoFlankdue", "flankduebrid", "auraFlankdue"] - Class.inception.UPGRADES_TIER_2 = ["inceptionist", "machinception", "tailgator", "launcher", "flankinception", "directdrive", "spawner", "autoinception", "inceptionbrid", "auraInception"] - Class.inceptionist.UPGRADES_TIER_3 = ["twinceptionist", "machceptionist", "poundceptionist", "flankceptionist", "factory", "autoinceptionist", "inceptionistbrid", "auraInceptionist"] - Class.machinception.UPGRADES_TIER_3 = ["machceptionist", "automachinception", "machinceptionbrid", "auraMachinception"] + Class.inception.UPGRADES_TIER_2 = ["inceptionist", "machinception", "tailgator", "launcher", /*"flankinception", */"directdrive", "spawner", "autoinception", "inceptionbrid", "auraInception"] + Class.inceptionist.UPGRADES_TIER_3 = ["twinceptionist", "machceptionist", "poundceptionist", /*"flankceptionist", */"factory", "autoinceptionist", "inceptionistbrid", "auraInceptionist"] + Class.machinception.UPGRADES_TIER_3 = ["machceptionist", "Sprayinception", "Gatlinception", "automachinception", "machinceptionbrid", "auraMachinception"] Class.tailgator.UPGRADES_TIER_3 = ["poundceptionist", "interceptor", "engineer", "shrapnelgun", "autotailgator", "tailgatorbrid", "auraTailgator"] - Class.flankinception.UPGRADES_TIER_3 = ["flankceptionist", "autoflankinception", "flankinceptionbrid", "auraFlankinception", "auraFlankinception"] + Class.flankinception.UPGRADES_TIER_3 = ["flankceptionist", "autoflankinception", "flankinceptionbrid", "auraFlankinception"] - Class.desmos.UPGRADES_TIER_2 = ["helix", "sidewinder", "undertow", "repeater", "autoDesmos", "desmosbrid", "auraDesmos"] - Class.sidewinder.UPGRADES_TIER_3 = ["coil", "python", "ranch", "oroboros", "cocci"] - Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "coil", "duplicator", "autoHelix", "helixbrid", "auraHelix"] - Class.undertow.UPGRADES_TIER_3 = ["riptide", "autoUndertow", "undertowbrid", "auraUndertow"] + Class.desmos.UPGRADES_TIER_2 = ["helix", "undertow", "repeater", "autoDesmos", "desmosbrid", "auraDesmos"] + Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "duplicator", "autoHelix", "helixbrid", "auraHelix"] + Class.undertow.UPGRADES_TIER_3 = ["riptide", "choker", "autoUndertow", "undertowbrid", "auraUndertow"] Class.repeater.UPGRADES_TIER_3 = ["iterator", "duplicator", "autoRepeater", "repeaterbrid", "auraRepeater"] Class.auraBasic.UPGRADES_TIER_2 = ["auraTwin", "auraSniper", "auraMachineGun", "auraFlankGuard", "auraDirector", "auraPounder", "auraTrapper", "auraAutoBasic", "auraDesmos", "auraBascrid", "auraLittleHunter", "auraInception", "auraLancer", "auraAuto2", "damageAuraBasic", "rangeAuraBasic"] Class.auraBasic.UPGRADES_TIER_3 = ["auraSmasher"] Class.auraTwin.UPGRADES_TIER_3 = ["auraDoubleTwin", "auraTripleShot", "auraGunner", "auraHexaTank", "auraAutoTwin", "auraHelix", "auratwinbrid", "auraBinary", "auraTwinSniper", "damageAuraTwin", "rangeAuraTwin"] Class.auraSniper.UPGRADES_TIER_3 = ["auraAssassin", "auraHunter", "auraMinigun", "auraRifle", "auraTwinSniper", "auraAutoSniper", "aurasnipebrid", "auraTrackerSniper", "auraAcid", "auraChiller", "auraChasseur", "damageAuraSniper", "rangeAuraSniper"] - Class.auraMachineGun.UPGRADES_TIER_3 = ["auraArtillery", "auraMinigun", "auraGunner", "auraSprayer", "auraAutoMach", "auramachbrid", "auraMachinception", "damageAuraMachineGun", "rangeAuraMachineGun"] - Class.auraFlankGuard.UPGRADES_TIER_3 = ["auraHexaTank", "auraTriAngle", "auraAuto3", "auraTrapGuard", "auraTriTrapper", "auraAutoFlank", "auraflankbrid", "auraFlankdue", "auraFlankinception", "auraTriLancer", "auraBackShield", "damageAuraFlankGuard", "rangeAuraFlankGuard"] - Class.auraDirector.UPGRADES_TIER_3 = ["auraOverseer", "auraCruiser", "auraUnderseer", "auraSpawner", "auraDirectdrive", "auraAutoDirector", "damageAuraDirector", "rangeAuraDirector"] - Class.auraPounder.UPGRADES_TIER_3 = ["auraBuilder", "auraArtillery", "auraLauncher", "auraAutoPound", "auraSidewinder", "aurapoundbrid", "auraTailgator", "damageAuraPounder", "rangeAuraPounder"] + Class.auraMachineGun.UPGRADES_TIER_3 = ["auraArtillery", "auraMinigun", "auraGunner", "auraSprayer", "auraGatlinggun", "auraAutoMach", "auramachbrid", "auraMachinception", "damageAuraMachineGun", "rangeAuraMachineGun"] + Class.auraFlankGuard.UPGRADES_TIER_3 = ["auraHexaTank", "auraTriAngle", "auraAuto3", "auraTrapGuard", "auraTriTrapper", "auraAutoFlank", "auraflankbrid", "auraFlankdue", "auraFlankinception", "auraBackShield", "damageAuraFlankGuard", "rangeAuraFlankGuard"] + Class.auraDirector.UPGRADES_TIER_3 = ["auraOverseer", "auraCruiser", "auraUnderseer", "auraSpawner", "auraDirectdrive", "auraAutoDirector", "auraNoble", "damageAuraDirector", "rangeAuraDirector"] + Class.auraPounder.UPGRADES_TIER_3 = ["auraBuilder", "auraArtillery", "auraLauncher", "auraAutoPound", "aurapoundbrid", "auraTailgator", "damageAuraPounder", "rangeAuraPounder"] Class.auraTrapper.UPGRADES_TIER_3 = ["auraBuilder", "auraTriTrapper", "auraTrapGuard", "auraContagion", "auraAutoTrap", "auratrapbrid", "damageAuraTrapper", "rangeAuraTrapper"] - Class.auraAutoBasic.UPGRADES_TIER_3 = ["auraAutoTwin", "auraAutoSniper", "auraAutoMach", "auraAutoFlank", "auraAutoDirector", "auraAutoPound", "auraAutoTrap", "auraAutoDesmos", "auraautobascrid", "auraAutoLittleHunter", "auraAutoInception", "auraBasicCeption", "auraHomingautoBasic", "damageAuraAutoBasic", "rangeAuraAutoBasic"] + Class.auraAutoBasic.UPGRADES_TIER_3 = ["auraAutoTwin", "auraAutoSniper", "auraAutoMach", "auraAutoFlank", "auraAutoDirector", "auraAutoPound", "auraAutoTrap", "auraAutoDesmos", "auraautobascrid", "auraAutoLittleHunter", "auraAutoInception", "auraHomingautoBasic", "damageAuraAutoBasic", "rangeAuraAutoBasic"] Class.auraBascrid.UPGRADES_TIER_3 = ["auratwinbrid", "aurasnipebrid", "auramachbrid", "auraflankbrid", "aurapoundbrid", "auratrapbrid", "auradesmosbrid", "auraautobascrid", "auralittlehunterbrid", "aurainceptionbrid", "jeep", "damageAuraBascrid", "rangeAuraBascrid"] - Class.auraDesmos.UPGRADES_TIER_3 = ["auraSidewinder", "auraHelix", "auraUndertow", "auraRepeater", "auraAutoDesmos", "auradesmosbrid", "damageAuraDesmos", "rangeAuraDesmos"] - Class.auraLittleHunter.UPGRADES_TIER_3 = ["auraMinigun", "auraBinary", "auraHunter", "auraSprayer", "auraContagion", "auraGundirector", "auraBigSubduer", "auraFlankdue", "auraAutoLittleHunter", "auralittlehunterbrid", "damageAuraLittleHunter", "rangeAuraLittleHunter"] + Class.auraDesmos.UPGRADES_TIER_3 = ["auraHelix", "auraUndertow", "auraRepeater", "auraAutoDesmos", "auradesmosbrid", "damageAuraDesmos", "rangeAuraDesmos"] + Class.auraLittleHunter.UPGRADES_TIER_3 = ["auraMinigun", "auraBinary", "auraHunter", "auraSprayer", "auraContagion", "auraGundirector", "auraBigSubduer", "auraFlankdue", "auraBayonet", "auraAutoLittleHunter", "auralittlehunterbrid", "damageAuraLittleHunter", "rangeAuraLittleHunter"] Class.auraInception.UPGRADES_TIER_3 = ["auraInceptionist", "auraMachinception", "auraTailgator", "auraFlankinception", "auraAutoInception", "aurainceptionbrid", "damageAuraInception", "rangeAuraInception"] Class.auraPropel.UPGRADES_TIER_3 = ["auraTriAngle", "auraBateau", "auraJouster", "auraAutoPropel", "aurapropelbrid", "damageAuraPropel", "rangeAuraPropel"] Class.auraAuto2.UPGRADES_TIER_3 = ["auraAuto3", "auraRevolutionist", "auraAutoAuto2", "auraauto2brid", "damageAuraAuto2", "rangeAuraAuto2"] - Class.auraLancer.UPGRADES_TIER_3 = ["auraChasseur", "auraTriLancer", "auraJouster", "auraAutoLancer", "auralancebrid", "damageAuraLancer", "rangeAuraLancer"] + Class.auraLancer.UPGRADES_TIER_3 = ["auraChasseur", "auraJouster", "auraBayonet", "auraAutoLancer", "auralancebrid", "damageAuraLancer", "rangeAuraLancer"] Class.damageAuraBasic.UPGRADES_TIER_3 = ["damageAuraTwin", "damageAuraSniper", "damageAuraMachineGun", "damageAuraFlankGuard", "damageAuraDirector", "damageAuraPounder", "damageAuraTrapper", "damageAuraAutoBasic", "damageAuraBascrid", "damageAuraDesmos", "damageAuraLittleHunter", "damageAuraInception", "damageAuraPropel", "damageAuraAuto2", "damageAuraLancer", "moredamageAuraBasic", "damagerangeAuraBasic"] Class.rangeAuraBasic.UPGRADES_TIER_3 = ["rangeAuraTwin", "rangeAuraSniper", "rangeAuraMachineGun", "rangeAuraFlankGuard", "rangeAuraDirector", "rangeAuraPounder", "rangeAuraTrapper", "rangeAuraAutoBasic", "rangeAuraBascrid", "rangeAuraDesmos", "rangeAuraLittleHunter", "rangeAuraInception", "rangeAuraPropel", "rangeAuraAuto2", "rangeAuraLancer", "morerangeAuraBasic", "damagerangeAuraBasic"] Class.auto2.UPGRADES_TIER_2 = ["auto3", "revolutionist", "swivel2", "autoauto2", "auto2brid", "auraAuto2"] Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee", "autoAuto3", "auto3brid", "auraAuto3", "whirl3"] - Class.revolutionist.UPGRADES_TIER_3 = ["subverter", "autoRevolutionist", "proton", "pion", "hadron", "equilibrium", "revobrid", "baseThrower", "revodirector", "auraRevolutionist"] + Class.revolutionist.UPGRADES_TIER_3 = ["subverter", "autoRevolutionist", "proton", "pion", "hadron", "equilibrium", "revobrid", "baseThrower", "revodirector", "saturn", "auraRevolutionist"] Class.swivel2.UPGRADES_TIER_3 = ["swivel3", "autoSwivel2", "swivel2brid", "auraSwivel2"] - Class.lancer.UPGRADES_TIER_2 = ["chasseur", "trilancer", "jouster", "autolancer", "lancebrid", "auraLancer"] - Class.lancer.UPGRADES_TIER_3 = ["bayonet", "katana"] - Class.chasseur.UPGRADES_TIER_3 = ["tripleur", "flail", "trichasseur", "autochasseur", "chasseubrid", "auraChasseur"] - Class.trilancer.UPGRADES_TIER_3 = ["trichasseur", "hexalancer", "trailblazer", "autotrilancer", "trilancebrid", "auraTriLancer"] + Class.lancer.UPGRADES_TIER_2 = ["chasseur", "jouster", "bayonet", "autolancer", "lancebrid", "auraLancer"] + Class.lancer.UPGRADES_TIER_3 = ["katana"] + Class.chasseur.UPGRADES_TIER_3 = ["flail", "fencer", "wakizashi", "autochasseur", "chasseubrid", "auraChasseur"] + Class.bayonet.UPGRADES_TIER_3 = ["choker", "arisaka", "wakizashi", "autobayonet", "bayonetbrid", "auraBayonet"] Class.propel.UPGRADES_TIER_2 = ["triAngle", "bateau", "jouster", "autoPropel", "propelbrid", "auraPropel"] Class.propel.UPGRADES_TIER_3 = ["jumpSmasher"] Class.bateau.UPGRADES_TIER_3 = ["assblaster", "rocker", "knight", "autoBateau", "bateaubrid", "auraBateau"] - Class.jouster.UPGRADES_TIER_3 = ["trailblazer", "knight", "autoJouster", "jousterbrid", "auraJouster"] \ No newline at end of file + Class.jouster.UPGRADES_TIER_3 = ["trailblazer", "knight", "fencer", "arisaka", "autoJouster", "jousterbrid", "auraJouster"] \ No newline at end of file diff --git a/server/modules/definitions/groups/turrets.js b/server/modules/definitions/groups/turrets.js index 87ac6371a..3ac6eba2b 100644 --- a/server/modules/definitions/groups/turrets.js +++ b/server/modules/definitions/groups/turrets.js @@ -584,10 +584,11 @@ Class.pillboxTurret = makeTurret({ PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, { density: 0.1 }]), TYPE: "bullet", + WAIT_TO_CYCLE: true }, }, ], -}, {extraStats: []}) +}, {independent: true, extraStats: []}) Class.autoSmasherMissileTurret = makeTurret({ HAS_NO_RECOIL: true, GUNS: [ @@ -978,9 +979,8 @@ Class.protonturretBase = { Class.pionturretBase = { LABEL: "Base", SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, + COLOR: 'red', + CONTROLLERS: ["hadron"], TURRETS: [{ POSITION: [5, 10.5, 0, 90, 220, 1], TYPE: ["revosheild", { SHAPE: 12 }], @@ -1102,7 +1102,7 @@ Class.revosheild = { SHAPE: 0, INDEPENDENT: true, BODY: { - PUSHABILITY: 0, + PUSHABILITY: 1, HEALTH: 10000, SHIELD: 10000, REGEN: 1000, @@ -1110,6 +1110,7 @@ Class.revosheild = { RESIST: 100, STEALTH: 1, DENSITY: 10000, + PENETRATION: 0.01 }, } Class.backshieldturret = { @@ -1123,6 +1124,7 @@ Class.backshieldturret = { HEALTH: 10000, SHIELD: 10000, REGEN: 1000, + PENETRATION: 0.01 }, } Class.mirrorDeco = makeDeco("M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -0.9 A 0.001 0.001 0 0 1 0 0.9 A 0.001 0.001 0 0 1 0 -0.9") @@ -1134,6 +1136,7 @@ Class.mirrorbackshieldturret = { HEALTH: 10000, SHIELD: 10000, REGEN: 1000, + PENETRATION: 0.01 }, SHAPE: "m -0.7020 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099", COLOR: "#FF7F00", @@ -1187,7 +1190,6 @@ Class.droneturretBase = { SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', COLOR: 9, CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, SYNC_TURRET_SKILLS: true, TURRETS: [{ POSITION: [4.65, 10.5, 0, 90, 220, 1], @@ -1252,11 +1254,12 @@ Class.skaterDeco.STROKE_WIDTH = 2; Class.switcherDeco = makeDeco('M 0 0 M 2 -1 L -2 -1 L -2 8 L -1 8 L 1 8 L 2 8') Class.effectBulletDeco = makeDeco(0) Class.firecrackerDeco = makeDeco(-6) -Class.auraDamageGen = addAura(7.5, 1.3, 0.3, "red"); -Class.auraRangeGen = addAura(4.3, 1.8, 0.3, "teal", "rangeAuraSymbol"); -Class.auraDamageRangeGen = addAura(7, 1.8, 0.3, "red", "rangeAuraSymbol"); -Class.auraMoreDamageGen = addAura(9, 1.3, 0.3, "orange"); -Class.auraMoreRangeGen = addAura(4.3, 2.3, 0.3, "aqua", "rangeAuraSymbol"); +Class.auraDamageGen = addAura(2, 1.3, 0.3, "red"); +Class.auraRangeGen = addAura(2, 1.8, 0.3, "teal", "rangeAuraSymbol"); +Class.auraDamageRangeGen = addAura(2, 1.8, 0.3, "red", "rangeAuraSymbol"); +Class.auraMoreDamageGen = addAura(3, 1.3, 0.3, "orange"); +Class.auraMoreRangeGen = addAura(1, 2.3, 0.3, "aqua", "rangeAuraSymbol"); Class.auraSmasherGen = addAura(11, 1.3); Class.surgeDeco = makeDeco(-1, "spaceGem"); -Class.katanaDeco = makeDeco('M 0 2 L 0 -1 L 1 0 L 0 -1 L -1 0 L 0 -1', "#add6f7"); \ No newline at end of file +Class.katanaDeco = makeDeco('M 0 2 L 0 -1 L 1 0 L 0 -1 L -1 0 L 0 -1', "#add6f7"); +Class.brellaDeco = makeDeco('M -0 2.2587 L 0.9 0.905 L 0.9 -0.9 L -0 -2.2537 L -0.9 -2.5245 L -0.9 2.5295 L -0 2.2587', "gray") \ No newline at end of file diff --git a/server/modules/definitions/gunvals.js b/server/modules/definitions/gunvals.js index 41f6c2ed1..6261074d5 100644 --- a/server/modules/definitions/gunvals.js +++ b/server/modules/definitions/gunvals.js @@ -19,7 +19,7 @@ module.exports = { triplet: { reload: 1.2, recoil: 2/3, shudder: 0.9, health: 0.85, damage: 0.85, pen: 0.9, density: 1.1, spray: 0.9, resist: 0.95 }, turret: { reload: 2, health: 0.8, damage: 0.6, pen: 0.7, density: 0.1 }, autoTurret: { reload: 0.9, recoil: 0.75, shudder: 0.5, size: 0.8, health: 0.9, damage: 0.6, pen: 1.2, speed: 1.1, range: 0.8, density: 1.3, resist: 1.25 }, - littleHunter: { recoil: 0.9, shudder: 0.9, health: 0.9, damage: 0.7, pen: 0.9 }, + littleHunter: { recoil: 0.9, shudder: 0.9, health: 0.9, damage: 0.7, pen: 0.9, reload: 0.9 }, // Snipers sniper: { reload: 1.35, shudder: 0.25, damage: 0.8, pen: 1.1, speed: 1.5, maxSpeed: 1.5, density: 1.5, spray: 0.2, resist: 1.15 }, @@ -148,18 +148,19 @@ module.exports = { // Misc 2 fakewithrecoil: { recoil: 1, size: 0.00001, health: 0.0001, speed: 0.00001, maxSpeed: 2, range: 0 }, - kiva: { damage: 0.7, pen: 0, health: 4, range: 1.5, speed: 1, maxSpeed: 1.4 }, + kiva: { damage: 0.3, pen: 0.2, health: 4, range: 1.5, speed: 1, maxSpeed: 1.4 }, xxtrahealth: { health: 999 }, lance: { reload: 0.4, speed: 0.18, maxSpeed: 0.18, range: 0.07, pen: 3, health: 0.8, recoil: 0 }, + chasseur: { reload: 0.4, speed: 0.28, maxSpeed: 0.28, range: 0.07, pen: 3, health: 0.8, recoil: 0 }, lesspower: { health: 0.9, damage: 0.9, pen: 0.9 }, grenade_explosion: { reload: 8, recoil: 0, shudder: 4.25, size: 2, health: 2.25, damage: 1.75, pen: 1.5, speed: 1.35, spray: 4 }, literallyamachinegun: { reload: 0.2, speed: 5, maxSpeed: 5, spray: 0.3, shudder: 0.6 }, - rainmaker: { speed: 0.03, maxSpeed: 0.5, health: 0.9, damage: 0.85 }, + rainmaker: { speed: 0.03, maxSpeed: 0.5, health: 0.9, damage: 0.85, range: 0.25 }, acceltospeedoflight: { speed: 0.001, maxSpeed: 1000 }, explosion: { speed: 0.01, maxSpeed: 0.01, health: 5, damage: 4, pen: 5, density: 3.7, resist: 3 }, brella: { reload: 2.5, health: 35, pen: 0, damage: 0.2, maxSpeed: 0.8, spray: 0, range: 2.25, size: 2.4, shudder: 0.1 }, magnet: { damage: 0, health: 0.8, spray: 45, range: 0.08, recoil: 0, speed: 0.8, pen: 0 }, - solarioblast: { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.12 }, + solarioblast: { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }, emplaser: { reload: 1.25, recoil: 0, size: 1.7 }, empbullet: { reload: 1.25, recoil: 0, size: 2.5, speed: 1.1, maxSpeed: 1.1, spray: 0.2 }, cloner: { damage: 0.78, pen: 0.85 }, diff --git a/server/modules/gamemodes/oldDreadnoughts.js b/server/modules/gamemodes/oldDreadnoughts.js index d3db773f4..4f05734f4 100644 --- a/server/modules/gamemodes/oldDreadnoughts.js +++ b/server/modules/gamemodes/oldDreadnoughts.js @@ -193,17 +193,24 @@ class PortalLoop { buffer: 0, spawnArray: validPositions, handler: (entity) => { + if (entity.team == TEAM_DREADNOUGHTS) return; + entity.reset(); // Remove non-player controllers + entity.skill.set(Array(10).fill(0)); // Purge skill upgrades entity.define({ // Purge all unwanted entity config STAT_NAMES: {}, IS_SMASHER: false, ALPHA: [0, 1], INVISIBLE: [0, 0], }); - entity.destroyAllChildren(); entity.upgrades = []; entity.define('dreadOfficialV1'); entity.team = TEAM_DREADNOUGHTS; + + // Fix minimap + if (entity.socket) { + entity.socket.player.team = entity.team; + } }, entryBarrier: (entity) => { return entity.skill.level >= 150; @@ -263,7 +270,7 @@ class PortalLoop { if (other.type != 'tank') { if ( other.type != "miniboss" && other.type != "food" && other.type != "crasher" && other.type != "aura" && other.type != "wall" && other.type != "unknown" && - (other.x - entity.x) ** 2 + (other.y - entity.y) ** 2 <= 625 + (other.x - entity.x) ** 2 + (other.y - entity.y) ** 2 <= (other.size + entity.size) ** 2 ) { other.kill(); } @@ -283,6 +290,7 @@ class PortalLoop { other.y = ran.irandomRange(portal.destination.yMin, portal.destination.yMax); } other.invuln = true; + other.destroyAllChildren(); // Set new confinement other.confinement.xMin = portal.destination.xMin - portal.buffer; diff --git a/server/modules/global.js b/server/modules/global.js index 430c5a3ab..da4b0f24d 100644 --- a/server/modules/global.js +++ b/server/modules/global.js @@ -34,9 +34,9 @@ global.TEAM_DREADNOUGHTS = -10; global.TEAM_ROOM = -100; global.TEAM_ENEMIES = -101; global.getSpawnableArea = team => ran.choose((team in room.spawnable && room.spawnable[team].length) ? room.spawnable[team] : room.spawnableDefault).randomInside(); -global.getTeamName = team => ["BLUE", "GREEN", "RED", "PURPLE", "YELLOW", "ORANGE", "BROWN", "CYAN"][-team - 1] || "An unknown team"; -global.getTeamColor = team => ([10, 11, 12, 15, 25, 26, 27, 28][-team - 1] || 3); -global.isPlayerTeam = team => /*team < 0 && */team > -9; +global.getTeamName = team => ["BLUE", "GREEN", "RED", "PURPLE", "YELLOW", "ORANGE", "BROWN", "CYAN", , "DREADNOUGHTS"][-team - 1] ?? "An unknown team"; +global.getTeamColor = team => ([10, 11, 12, 15, 25, 26, 27, 28, , 4][-team - 1] ?? 3); +global.isPlayerTeam = team => /*team < 0 && */team > -11; global.getWeakestTeam = () => { let teamcounts = {}; for (let i = -Config.TEAMS; i < 0; i++) { diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index c3f4eff6e..65e84cff2 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -175,6 +175,10 @@ class Gun extends EventEmitter { } else { this.defineBullet(bullet); } + // Set confinement + for (let k in this.master.confinement) { + bullet.confinement[k] = this.master.confinement[k]; + } bullet.life(); // Emit fire event @@ -1374,6 +1378,7 @@ class Entity extends EventEmitter { for (let j = 0; j < type.length; j++) { o.define(type[j]); if (type.TURRET_DANGER) turretDanger = true; + o.isTurret = true; } if (!turretDanger) o.define({ DANGER: 0 }); o.bindToMaster(def.POSITION, this); @@ -1808,10 +1813,10 @@ class Entity extends EventEmitter { case "accelerate": this.velocity.x = this.velocity.x + (4.5 * Math.cos(this.facing)) this.velocity.y = this.velocity.y + (4.5 * Math.sin(this.facing)) - this.topSpeed += 10; - this.maxSpeed += 10; + this.topSpeed += 30; + this.maxSpeed += 30; this.damp = -0.0125; - this.damage += 1 + this.damage += 1.3 break; case "acceleratetothespeedoflight": this.velocity.x = this.velocity.x + ((1 * this.maxSpeed + 0.5) * Math.cos(this.facing)) @@ -1889,7 +1894,7 @@ class Entity extends EventEmitter { this.firingArc = [ref.facing + bound.angle, bound.arc / 2]; this.accel.null(); this.blend = ref.blend; - if (this.bond.syncTurretSkills) this.skill.set(this.bond.skill.raw); + if (this.bond.syncTurretSkills) this.skill.set(this.bond.master.skill.raw); break; case "withMaster": this.x = this.source.x; diff --git a/server/modules/network/discoverability.js b/server/modules/network/discoverability.js index ae2cf3a17..afba6da56 100644 --- a/server/modules/network/discoverability.js +++ b/server/modules/network/discoverability.js @@ -1,6 +1,5 @@ // IP and if has https proxy // NOTE: Server auto adds itself to the list module.exports = [ - ["us.neroio.xyz", "USA", true], [] ]; \ No newline at end of file diff --git a/server/modules/setup/mockups.js b/server/modules/setup/mockups.js index 536c17c63..df32a2002 100644 --- a/server/modules/setup/mockups.js +++ b/server/modules/setup/mockups.js @@ -29,6 +29,7 @@ function getMockup(e, positionInfo) { tier: r.tier, index: r.index })), + trueupgrades: [e.UPGRADES_TIER_2, e.UPGRADES_TIER_3, e.UPGRADES_TIER_4, e.UPGRADES_TIER_0 + e.UPGRADES_TIER_1], guns: e.guns.map(function(gun) { return { offset: util.rounder(gun.offset), From 67812f191e51453e1f604476c965f02cc249fd4e Mon Sep 17 00:00:00 2001 From: "Glitch (neroio2)" Date: Tue, 6 May 2025 14:29:50 +0000 Subject: [PATCH 14/15] =?UTF-8?q?=F0=9F=90=9D=E2=8C=9A=20Updated=20with=20?= =?UTF-8?q?Glitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .glitch-assets | 28 + CHAT.txt | 1 + README.md | 50 +- changelog preview | 77 + neroplayer/visual.html | 153 +- package.json | 2 +- public/app.js | 198 +- public/changelog.html | 74 + public/credits.html | 89 +- public/index.html | 136 +- public/{ => lib}/browser.js | 0 public/lib/canvas.js | 9 +- public/lib/config.js | 9 +- public/lib/gameDraw.js | 4 - public/lib/global.js | 4 +- public/lib/socketInit.js | 11 +- public/lib/tankdesc.js | 16 +- public/main.css | 6 +- server/config.js | 18 +- server/index.js | 6 +- .../modules/definitions/addons/playerskins.js | 10 + .../modules/definitions/addons/poundsnipe.js | 434 ++++ server/modules/definitions/addons/solario.js | 233 +- server/modules/definitions/constants.js | 9 +- server/modules/definitions/facilitators.js | 8 +- server/modules/definitions/groups/dev.js | 57 +- server/modules/definitions/groups/generics.js | 10 +- .../modules/definitions/groups/projectiles.js | 113 +- server/modules/definitions/groups/tanks.js | 2023 +++++++++++++++-- server/modules/definitions/groups/turrets.js | 22 +- server/modules/definitions/gunvals.js | 14 +- server/modules/live/entity.js | 6 +- server/modules/network/sockets.js | 42 +- server/modules/network/webServer.js | 25 +- .../modules/setup/gamemodeconfigs/sandbox.js | 1 + .../modules/setup/rooms/map_neroio_blank3.js | 26 + .../setup/rooms/map_neroio_mazearena2.js | 26 + .../modules/setup/rooms/map_neroio_zerolag.js | 6 +- server/modules/setup/tiles/misc.js | 30 +- server/permissions.js | 19 +- shit/randomstuff/aasfsdgsdg | 3 +- shit/secret.html | 8 + 42 files changed, 3411 insertions(+), 605 deletions(-) create mode 100644 CHAT.txt rename public/{ => lib}/browser.js (100%) create mode 100644 server/modules/definitions/addons/poundsnipe.js create mode 100644 server/modules/setup/gamemodeconfigs/sandbox.js create mode 100644 server/modules/setup/rooms/map_neroio_blank3.js create mode 100644 server/modules/setup/rooms/map_neroio_mazearena2.js create mode 100644 shit/secret.html diff --git a/.glitch-assets b/.glitch-assets index 565d2ec8d..048535638 100644 --- a/.glitch-assets +++ b/.glitch-assets @@ -244,3 +244,31 @@ {"name":"Nadir (Apotheosis 3).wav","date":"2024-10-21T12:52:50.342Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Nadir%20(Apotheosis%203).wav","type":"audio/wav","size":33538092,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FNadir%20(Apotheosis%203).wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"K21MpQlwwaIrOtvb"} {"name":"Methemphetaphacktomine.wav","date":"2024-10-21T12:52:53.719Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Methemphetaphacktomine.wav","type":"audio/wav","size":35811372,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMethemphetaphacktomine.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"m3VznFUfVCNRCqkm"} {"name":"Polychromatism.wav","date":"2024-10-21T12:52:57.274Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav","type":"audio/wav","size":35762220,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FPolychromatism.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"TMDLz8dUptnSYX70"} +{"name":"untitled.wav","date":"2024-12-07T23:27:09.212Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/untitled.wav","type":"audio/wav","size":382666,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Funtitled.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"i8XyLCBQNVS9ekCd"} +{"name":"open.wav","date":"2024-12-07T23:27:19.155Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/open.wav","type":"audio/wav","size":208940,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fopen.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"Q3pKhBCulXVUEcTg"} +{"name":"close.wav","date":"2024-12-07T23:27:24.438Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/close.wav","type":"audio/wav","size":192556,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fclose.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"B7z9HLLBtg9ZUDxa"} +{"name":"click.wav","date":"2024-12-08T01:25:43.102Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/click.wav","type":"audio/wav","size":65580,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fclick.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"jsuQL8QqGsmt5sdo"} +{"name":"hover.wav","date":"2024-12-08T01:25:44.155Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/hover.wav","type":"audio/wav","size":49196,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fhover.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"5kUX1PsGm18svZGJ"} +{"name":"441307__aptbr__glitched-piano.wav","date":"2024-12-08T01:39:40.735Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/441307__aptbr__glitched-piano.wav","type":"audio/wav","size":13578284,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F441307__aptbr__glitched-piano.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"voDkVj4LNaOeuV5N"} +{"name":"84f6ebcc-bf57-42e0-8e5f-85de3dfea363.image.png","date":"2024-12-08T02:37:33.065Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/84f6ebcc-bf57-42e0-8e5f-85de3dfea363.image.png","type":"image/png","size":67048,"imageWidth":1976,"imageHeight":113,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F84f6ebcc-bf57-42e0-8e5f-85de3dfea363.image.png","thumbnailWidth":330,"thumbnailHeight":19,"uuid":"Qy3JRwgw0f4Ni6g7"} +{"uuid":"Qy3JRwgw0f4Ni6g7","deleted":true} +{"name":"2024_12_07_12i_Kleki.png","date":"2024-12-08T02:37:46.333Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_12_07_12i_Kleki.png","type":"image/png","size":208820,"imageWidth":1800,"imageHeight":300,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_12_07_12i_Kleki.png","thumbnailWidth":330,"thumbnailHeight":55,"uuid":"J2MhNe7jtKFr0qko"} +{"name":"123123.wav","date":"2024-12-14T14:48:06.345Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/123123.wav","type":"audio/wav","size":326690,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F123123.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"507in5wEQolRBako"} +{"name":"Wednesday, Friday (1).wav","date":"2025-01-15T21:59:59.984Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Wednesday%2C%20Friday%20(1).wav","type":"audio/wav","size":30724140,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FWednesday%2C%20Friday%20(1).wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"D2CJZv4jtDlBS3Iq"} +{"name":"Heresy.wav","date":"2025-01-15T22:15:37.244Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Heresy.wav","type":"audio/wav","size":31236140,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FHeresy.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"xXMQVZpDac8bWpYX"} +{"name":"Reconstructed.wav","date":"2025-01-15T22:17:04.454Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Reconstructed.wav","type":"audio/wav","size":33796140,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FReconstructed.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"pXbPNfcnn18rVlF5"} +{"name":"06f19349-48de-46ec-9877-6ea585848961.image.png","date":"2025-02-08T19:41:52.157Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/06f19349-48de-46ec-9877-6ea585848961.image.png","type":"image/png","size":180026,"imageWidth":512,"imageHeight":512,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F06f19349-48de-46ec-9877-6ea585848961.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"EloWZczA1qI50ZEl"} +{"name":"Touch the Diddy.mp3","date":"2025-03-21T20:02:03.413Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Touch%20the%20Diddy.mp3","type":"audio/mpeg","size":658319,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FTouch%20the%20Diddy.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"fDhaJLhOBLmkgDIR"} +{"name":"e1aa2990-5b79-4e6b-b81d-411440f5df7e.image.png","date":"2025-04-30T21:31:27.745Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e1aa2990-5b79-4e6b-b81d-411440f5df7e.image.png","type":"image/png","size":719025,"imageWidth":645,"imageHeight":460,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fe1aa2990-5b79-4e6b-b81d-411440f5df7e.image.png","thumbnailWidth":330,"thumbnailHeight":236,"uuid":"7kN7jYXmaLNnUqgX"} +{"name":"d52124ef-c203-4a8e-aeef-279d97931cf0.image.png","date":"2025-04-30T21:32:16.528Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d52124ef-c203-4a8e-aeef-279d97931cf0.image.png","type":"image/png","size":779166,"imageWidth":828,"imageHeight":831,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fd52124ef-c203-4a8e-aeef-279d97931cf0.image.png","thumbnailWidth":329,"thumbnailHeight":330,"uuid":"JaSFmVApie8SMINn"} +{"name":"c9d5bfb7-5d6e-4165-a769-f28b8503ba99.image.png","date":"2025-04-30T21:34:31.797Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/c9d5bfb7-5d6e-4165-a769-f28b8503ba99.image.png","type":"image/png","size":389888,"imageWidth":606,"imageHeight":432,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fc9d5bfb7-5d6e-4165-a769-f28b8503ba99.image.png","thumbnailWidth":330,"thumbnailHeight":236,"uuid":"xnm9dsorODy1Iorg"} +{"name":"d9ff0c74-0202-469a-b614-e91c290e2ee6.image.png","date":"2025-04-30T21:36:37.970Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d9ff0c74-0202-469a-b614-e91c290e2ee6.image.png","type":"image/png","size":236026,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fd9ff0c74-0202-469a-b614-e91c290e2ee6.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"Drk1peEBoDOAaMZM"} +{"name":"bleKXO-ad3W-OuOT.mp4","date":"2025-04-30T21:39:25.620Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bleKXO-ad3W-OuOT.mp4","type":"video/mp4","size":2444928,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FbleKXO-ad3W-OuOT.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"GNonG59eQmNqQnUW"} +{"name":"creature_of_steel.mp4.mp4","date":"2025-04-30T21:41:52.412Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/creature_of_steel.mp4.mp4","type":"video/mp4","size":1203981,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fcreature_of_steel.mp4.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"q40C8H0R0jkXZ2VF"} +{"name":"04fda090-a3d9-47f1-ba34-76d37bbaca6a.image.png","date":"2025-04-30T21:45:52.738Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/04fda090-a3d9-47f1-ba34-76d37bbaca6a.image.png","type":"image/png","size":666682,"imageWidth":750,"imageHeight":508,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F04fda090-a3d9-47f1-ba34-76d37bbaca6a.image.png","thumbnailWidth":330,"thumbnailHeight":224,"uuid":"lFB9sOuBtKEa9eoN"} +{"name":"c35cdf3d-4d0c-48e6-b226-cf4d38a30adf.image.png","date":"2025-04-30T21:46:32.068Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/c35cdf3d-4d0c-48e6-b226-cf4d38a30adf.image.png","type":"image/png","size":284274,"imageWidth":828,"imageHeight":794,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fc35cdf3d-4d0c-48e6-b226-cf4d38a30adf.image.png","thumbnailWidth":330,"thumbnailHeight":317,"uuid":"NTN69skUBtiNuLdh"} +{"name":"eEKak-MBdeQGYORG.mp4","date":"2025-04-30T21:50:22.570Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/eEKak-MBdeQGYORG.mp4","type":"video/mp4","size":593267,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FeEKak-MBdeQGYORG.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"jy4YrZZgOEJQ1w3Y"} +{"name":"lil_sis.mp4","date":"2025-04-30T21:56:01.145Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/lil_sis.mp4","type":"video/mp4","size":268471,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flil_sis.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"s6YYdhm2a6O8A1aP"} +{"name":"78ef256e-6586-43e1-9028-b0d3e8e829f6.image.png","date":"2025-04-30T21:56:55.645Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/78ef256e-6586-43e1-9028-b0d3e8e829f6.image.png","type":"image/png","size":5139345,"imageWidth":2880,"imageHeight":1800,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F78ef256e-6586-43e1-9028-b0d3e8e829f6.image.png","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"1LTYT8YpDR2YN6JL"} +{"name":"adacb81f-a679-413e-8499-6005e1cc4b05.image.png","date":"2025-04-30T21:59:45.838Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/adacb81f-a679-413e-8499-6005e1cc4b05.image.png","type":"image/png","size":100807,"imageWidth":162,"imageHeight":230,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/adacb81f-a679-413e-8499-6005e1cc4b05.image.png","thumbnailWidth":162,"thumbnailHeight":230,"uuid":"NJEBu3CqFufkB37c"} +{"name":"43e3e1ea-297c-435c-8198-04760b9427f7.image.png","date":"2025-04-30T22:03:01.478Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/43e3e1ea-297c-435c-8198-04760b9427f7.image.png","type":"image/png","size":665522,"imageWidth":720,"imageHeight":946,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F43e3e1ea-297c-435c-8198-04760b9427f7.image.png","thumbnailWidth":252,"thumbnailHeight":330,"uuid":"5wmKnV6rum0h1RL6"} diff --git a/CHAT.txt b/CHAT.txt new file mode 100644 index 000000000..8da6eedfd --- /dev/null +++ b/CHAT.txt @@ -0,0 +1 @@ +leaked chat documente eith the develpoters of neroio the sequel \ No newline at end of file diff --git a/README.md b/README.md index 1aef42a73..b992c6b79 100644 --- a/README.md +++ b/README.md @@ -1,50 +1,22 @@ -# Open Source Arras +# Nero.io 2 -Logo +Logo -![GitHub Release](https://img.shields.io/github/v/release/Taureon/aps-plus-plus) -![Discord](https://img.shields.io/discord/1004907608018264094) -![GitHub repo size](https://img.shields.io/github/repo-size/Taureon/aps-plus-plus) +![GitHub Release](https://img.shields.io/github/v/release/DELTAFYREX/neroio) +![Discord](https://img.shields.io/discord/1073429163823869952) +![GitHub repo size](https://img.shields.io/github/repo-size/DELTAFYREX/neroio) ## Important Notice -**Open Source Arras is beta software.** This build is **not** representative of the final product. Expect bugs and missing features. +**Nero.io is under constant development** This build is **not** a final product. -Major updates may introduce breaking changes that alter how certain things work. It is **your responsibility** to keep your private server up-to-date and functioning. +Bugs are likely common so expect the unexpected -## Setup Guide (Localhost) +## Looking for other developers -This guide covers setting up your server on your own hardware and only supports PCs running up-to-date versions of Windows/macOS/Linux. +Nero is a ~~two~~ three man project currently and any help would be appreciated greatly -You'll first need to install [Node.js](https://nodejs.org). It doesn't matter if you pick the LTS or Latest version, they'll both work fine. - -Once `Node.js` is installed, open Terminal and run the command `npm i ws`. This will install the WebSocket library that Open Source Arras uses. - -After installing `ws`, [download the source code of the latest release of Open Source Arras](https://github.com/Taureon/aps-plus-plus/releases). Extract it once it's downloaded and open either `run.bat` (if you're on Windows) or `run.sh` (if you're not). If there aren't any errors, your server will start up. Go to `localhost:26301` in your favourite web browser (keep the terminal window open, closing it will shut down the server) to play. - -[If you need a more detailed guide, click here for a step by step list.](https://github.com/Taureon/aps-plus-plus/wiki/Frequently-Asked-Questions#how-do-i-set-up-my-server) - -If you want to stay up to date, fork this template, download a git client, and sync the fork whenever there's a major update. - -## Setup Guide (Webhost) - -Don't have a supported device or don't want to mess around with localhost? Get a webhost to do the dirty work for you. - -Create a new project and choose to import one from GitHub. When prompted for the URL of the repository, type in `https://github.com/Taureon/aps-plus-plus.git`. - -Navigate to `server/config.js` and replace `localhost:26301` with the URL for your project. (For Glitch users, it's `your-project.glitch.me` (replace `your-project` with the actual name of your project, it should be above settings)). - -**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"` and change your port to something more generic like 3000 or 8080.** - -After doing that, your server should be ready! - -## Useful Tools -- [Create a custom shape](https://arras.io/ext/custom-shape) -- [Create a custom tank](https://zyrafaq.com/arras-tank-builder) -- [Official Addon list](https://github.com/Taureon/aps-plus-plus-addons) -- [Unofficial Server list](https://zyrafaq.com/arras-server-list/) +Join the discord server if your interested in helping out ## Other Links -- [Our Discord server](https://discord.gg/kvCAZfUCjy) - -*p.s. if something goes terribly wrong it's not our fault* \ No newline at end of file +- [Our Discord server](https://discord.gg/GmhACsX9aF) \ No newline at end of file diff --git a/changelog preview b/changelog preview index 5d7aae1e9..472a5ee98 100644 --- a/changelog preview +++ b/changelog preview @@ -1,3 +1,75 @@ +
    +

    Update 3.5

    + [2025] +
      +
    • Added 3 new tracks
    • +
    • slightly improved server loading
    • +
    • added water with physics
    • +
    • added minishot
    • +
    • added the minishot branches
    • +
    • added new 75 kill achivement
    • +
    • minos prime skin
    • +
    • nerfed firecracker
    • +
    • added new ffa map
    • +
    • addded the rest of the tier 3 upgrade variants for minishot to the rest of the tier 2 branches
    • +
    • added mini mortar variations of the t2 tanks
    • +
    • made assblasters back thruster bullets transparent
    • +
    • added submachine gun branch to machine gun
    • +
    • fixed date since creation counter turning to a year ahead when its not supposed to
    • +
    • added missing tanks to unavailable developer
    • +
    • added missing stat names to tanks
    • +
    • fixed turret danger values
    • +
    • fixed a bug where recoil wouldnt exist if upgrading from beyonet
    • +
    • removed scope from twiper
    • +
    • added flashfire
    • +
    • buffed firecrackers reload time
    • +
    • buffed shape health
    • +
    • added shadow
    • +
    • fixed Hypothermia not actually shooting ice traps
    • +
    • renamed acidilizer and icilizer to arsenic and devils breath
    • +
    • allowed you to set your tank to any entity via debug/wiki menu in sandbox
    • +
    • fixed the rocks not reflecting bullets in sandbox server
    • +
    • added numbers for health bar
    • +
    • buffed swarm tank damage by a multiplier of 2
    • +
    • nerfed flail damage from 3 to 1.95
    • +
    • buffed whirlwind damage from 1.875 to 4
    • +
    • buffed revolutionist turrets reload from 0.45 to 0.9
    • +
    • made jump smashers bullets half opacity
    • +
    • bayonet reload nerfed from 1 to 1.3
    • +
    • fixed cloner not cloning
    • +
    • nerfed probe cloning reload
    • +

      Ay, Anguish on that beat ho'

      +
    +
    +
    +

    Update 3.4

    + [2024] +
      +
    • buffed backshield
    • +
    • added slasher and attacker
    • +
    • readded trapception
    • +
    • added homing auto basic to desmos branch
    • +
    • made homing auto-2 upgrade from auto-3
    • +
    • removed auto-2 (except homing auto-2)
    • +
    • fixed upgrading issus
    • +
    • fixed kivaaritehdas
    • +
    • fixed trollface emoji
    • +
    • added sandbox mode
    • +
    • updated sound effects
    • +
    • fixed favicon not appearing on neroio.xyz
    • +
    • balanced rainmaker
    • +
    • fixed wall spawning shift key
    • +
    • added developer basic to testbed
    • +
    • removed mini defender
    • +
    • added ice Trapper branch
    • +
    • nerfed destroyer
    • +
    • nerfed repeater branch
    • +
    • added Kevin and Speed Triple
    • +
    • fixed visual bug with speedtriple
    • +
    • patched crash exploit
    • +

      RANDOM BULLSHIT, GO AGAIN!

      +
    +

    Update 3.3

    [2024] @@ -58,6 +130,11 @@
  • fixed bug where scowerer and swivel2brid did not upgrade from its intended branches
  • fixed grazerbrid not having its autocannon
  • fixed the skype achievement
  • +
  • updated loading screen tooltips
  • +
  • fixed wark upgrades
  • +
  • nerfed solarios health from 8000 to 5500
  • +
  • nerfed solarios spin speed
  • +
  • disabled regen during solarios laser attack
  • Big ass update :blehh:

    diff --git a/neroplayer/visual.html b/neroplayer/visual.html index 658530558..90658cec2 100644 --- a/neroplayer/visual.html +++ b/neroplayer/visual.html @@ -12,4 +12,155 @@
    - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/package.json b/package.json index f6d8d3e47..3217ba878 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "node standaloneClient/build minify" }, "dependencies": { - "ws": "^8.17.1" + "ws": "^8.18.1" }, "engines": { "node": "16.x" diff --git a/public/app.js b/public/app.js index 028e1efa0..c8b7661df 100644 --- a/public/app.js +++ b/public/app.js @@ -8,6 +8,7 @@ import { color } from "./lib/color.js"; import { gameDraw } from "./lib/gameDraw.js"; import { tankdescs } from "./lib/tankdesc.js"; import * as socketStuff from "./lib/socketInit.js"; + (async function (util, global, settings, Canvas, color, gameDraw, socketStuff) { let { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow } = socketStuff; @@ -97,7 +98,16 @@ let { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow } = s function PlaySoundnfl() { nfl.play(); } - +var open = new Audio(); +open.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/close.wav?v=1733614044438"); +function PlaySoundOpen() { + open.play(); +} +var close = new Audio(); +close.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/open.wav?v=1733614039155"); +function PlaySoundClose() { + close.play(); +} function doSomething() { if (clicked) { var optionclicksound = new Audio(); @@ -182,16 +192,16 @@ checkList.getElementsByClassName('anchor')[0].onclick = function(evt) { } var pmusic = new Array(); -if (localStorage.getItem("oioioi" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033"); -if (localStorage.getItem("dejected" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417"); -if (localStorage.getItem("worldsend" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3?v=1714399132177"); -if (localStorage.getItem("nerosong" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nero.wav?v=1727644028814"); +pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033"); +pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417"); +pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3?v=1714399132177"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nero.wav?v=1727644028814"); //if (localStorage.getItem("anybody" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028"); //if (localStorage.getItem("resurgam" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3?v=1708218475743"); //if (localStorage.getItem("longing" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295"); -if (localStorage.getItem("apotheosis" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3?v=1713525419376"); -if (localStorage.getItem("killa" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"); -if (localStorage.getItem("failedconnection" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Failed%20Connection.mp3?v=1727645304666"); +pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3?v=1713525419376"); +pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"); +pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Failed%20Connection.mp3?v=1727645304666"); //if (localStorage.getItem("demol1sh" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787"); //if (localStorage.getItem("demoli2h" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3?v=1714414714759"); //if (localStorage.getItem("d3molish" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3?v=1714414706958"); @@ -200,11 +210,14 @@ if (localStorage.getItem("failedconnection" + 'Checked')) pmusic.push("https://c //if (localStorage.getItem("routine2" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3?v=1714414889291"); //if (localStorage.getItem("routin3s" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3?v=1714414850230"); //if (localStorage.getItem("jitt3rs" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287"); -if (localStorage.getItem("atomic" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Atomic.wav?v=1727644048951"); -if (localStorage.getItem("ascension" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Acension%20(Apotheosis%202).wav?v=1729515166145"); -if (localStorage.getItem("nadir" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nadir%20(Apotheosis%203).wav?v=1729515170342"); -if (localStorage.getItem("phacktomine" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Methemphetaphacktomine.wav?v=1729515173719"); -if (localStorage.getItem("polychromatism" + 'Checked')) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav?v=1729515177274"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Atomic.wav?v=1727644048951"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Acension%20(Apotheosis%202).wav?v=1729515166145"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nadir%20(Apotheosis%203).wav?v=1729515170342"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Methemphetaphacktomine.wav?v=1729515173719"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav?v=1729515177274"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Wednesday%2C%20Friday%20(1).wav?v=1736978399984"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Heresy.wav?v=1736979337244"); +pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Reconstructed.wav?v=1736979424454"); //Music functions: //decide the music @@ -231,7 +244,11 @@ if (localStorage.getItem("polychromatism" + 'Checked')) pmusic.push("https://cdn //audio.play(); var musiccontext = new AudioContext(); var musicsrc = musiccontext.createMediaElementSource(global.music2); + // var filter = musiccontext.createBiquadFilter(); + // musicsrc.connect(filter); + // filter.connect(musiccontext.destination); var analyser = musiccontext.createAnalyser(); +// global.blackhole ? filter.type = "lowpass" : filter.type = "allpass"; let musiccanvas = document.getElementById("canvas"); musiccanvas.width = window.innerWidth * 1.3; @@ -311,7 +328,7 @@ if (localStorage.getItem("polychromatism" + 'Checked')) pmusic.push("https://cdn let selectimage = document.querySelector("#selectskin"); $("#rightarrowbutton").on("click", function() { - if (global.skinpage === 17) { + if (global.skinpage === 18) { global.skinpage = 0; } else { global.skinpage += 1; @@ -320,7 +337,7 @@ if (localStorage.getItem("polychromatism" + 'Checked')) pmusic.push("https://cdn }); $("#leftarrowbutton").on("click", function() { if (global.skinpage === 0) { - global.skinpage = 17; + global.skinpage = 18; } else { global.skinpage -= 1; }; @@ -384,119 +401,119 @@ if (localStorage.getItem("polychromatism" + 'Checked')) pmusic.push("https://cdn function changeskinpreview() { if (global.skinpage === 0) { - counterthing.textContent = "◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = ""; skinnamedisplay.textContent = "Default"; checkifachieve("", ""); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png?v=1708568179353"; } if (global.skinpage === 1) { - counterthing.textContent = "○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "bsignalskin"; skinnamedisplay.textContent = "Broken Signal"; checkifachieve("disconnectachievement", "black"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png?v=1708615075011" } if (global.skinpage === 2) { - counterthing.textContent = "○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "tankcharmskin"; skinnamedisplay.textContent = "Tank Charm"; checkifachieve("25killsachievement", "dgrey"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png?v=1708536680813"; } if (global.skinpage === 3) { - counterthing.textContent = "○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "dfxskin"; skinnamedisplay.textContent = "Deltafyrex"; checkifachieve("50killsachievement", "grey"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif?v=1708618924966"; } if (global.skinpage === 4) { - counterthing.textContent = "○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "primalskin"; skinnamedisplay.textContent = "Ultimate Primal"; checkifachieve("100killsachievement", "white"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp?v=1708602763032"; } if (global.skinpage === 5) { - counterthing.textContent = "○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "kangarooskin"; skinnamedisplay.textContent = "Kangaroo"; checkifachieve("killachievement", "black"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp?v=1708623596560"; } if (global.skinpage === 6) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "cswmskin"; skinnamedisplay.textContent = "ChickenSandwhichMan"; checkifachieve("killachievement2", "grey"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg?v=1708356424097" } if (global.skinpage === 7) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "cogskin"; skinnamedisplay.textContent = "Cogwheel"; checkifachieve("lagachievement", "black"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381"; } if (global.skinpage === 8) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "eggskin"; skinnamedisplay.textContent = "Eggbert"; checkifachieve("100shapesachievement", "black"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp?v=1714156807621"; } if (global.skinpage === 9) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "squareskin"; skinnamedisplay.textContent = "Squarey"; checkifachieve("250shapesachievement", "dgrey"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp?v=1714156773284"; } if (global.skinpage === 10) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "triangleskin"; skinnamedisplay.textContent = "Triangleton"; checkifachieve("500shapesachievement", "dgrey"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp?v=1714156768932"; } if (global.skinpage === 11) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○"; global.selectedskin = "pentagonskin"; skinnamedisplay.textContent = "Pentogan"; checkifachieve("750shapesachievement", "white"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp?v=1714156764280"; } if (global.skinpage === 12) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○"; global.selectedskin = "gemskin"; skinnamedisplay.textContent = "Gemy"; checkifachieve("1000shapesachievement", "grey"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp?v=1714156778841"; } if (global.skinpage === 13) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○"; global.selectedskin = "coinskin"; skinnamedisplay.textContent = "Coined"; checkifachieve("tokenachievement", "black"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png?v=1708619146196"; } if (global.skinpage === 14) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○"; global.selectedskin = "discordskin"; skinnamedisplay.textContent = "Sex Update"; checkifachieve("Getbacktowoooak", "dgrey"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png?v=1701908710293"; } if (global.skinpage === 15) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○"; global.selectedskin = "deltaDecoskin"; skinnamedisplay.textContent = "Cat-Code"; checkifachieve("creditsachievement", "grey"); myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png?v=1705301828958"; } if (global.skinpage === 16) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○"; global.selectedskin = "incomskin"; skinnamedisplay.textContent = "Very Much Incommodiousness"; checkifachieve("pissio", "grey"); @@ -504,13 +521,19 @@ if (localStorage.getItem("polychromatism" + 'Checked')) pmusic.push("https://cdn myImg.src = "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/1200px-Icon-round-Question_mark.svg.png?v=1699273933044"; } if (global.skinpage === 17) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉"; + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○"; global.selectedskin = "tokayskin"; skinnamedisplay.textContent = "Swaggity Waggity"; checkifachieve("bossachivement", "white"); - myImg.style.filter = 'blur(10px)'; myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spider_2.png?v=1722633319003"; } + if (global.skinpage === 18) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉"; + global.selectedskin = "minosskin"; + skinnamedisplay.textContent = "THY END IS NOW!"; + checkifachieve("75killsachievement", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/06f19349-48de-46ec-9877-6ea585848961.image.png?v=1739043712157"; + } }; let tanktype = "unfinished", tankdesc = "unfinished", @@ -599,6 +622,15 @@ if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a4 if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav?v=1729515177274") { global.music2.songname = "Polychromatism --- Deltafyrex" } +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Wednesday%2C%20Friday%20(1).wav?v=1736978399984") { + global.music2.songname = "Wednesday, Friday --- Deltafyrex" +} +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Heresy.wav?v=1736979337244") { + global.music2.songname = "Heresy --- Deltafyrex" +} +if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Reconstructed.wav?v=1736979424454") { + global.music2.songname = "Reconstructed --- Deltafyrex" +} } function lagachloop() { if (global.metrics.rendertime <= 45 && global.metrics.rendertime >= 15) { @@ -607,6 +639,9 @@ function lagachloop() { if (global.savedkillcount >= 100) { util.submitAchievementToLocalStorage("100killsachievement"); } + if (global.savedkillcount >= 75) { + util.submitAchievementToLocalStorage("75killsachievement"); + } if (global.savedkillcount >= 50) { util.submitAchievementToLocalStorage("50killsachievement"); } @@ -735,7 +770,7 @@ function resetAllAchievements() { month = (date.getMonth() + 11) - 15 } }; - if (date.getMonth() > 2) { + if (date.getMonth() > 2 & date.getDate() > 23) { year = ' | Years: ' + (date.getFullYear() - 2019) } else { year = ' | Years: ' + (date.getFullYear() - 2020) @@ -1089,29 +1124,29 @@ window.onload = async () => { util.retrieveFromLocalStorage("disableDeathSounds"); util.retrieveFromLocalStorage("optNoEmojis"); util.retrieveFromLocalStorage("autoLevelUp"); - util.retrieveFromLocalStorageCheckDefault("oioioi"); + /*util.retrieveFromLocalStorageCheckDefault("oioioi"); util.retrieveFromLocalStorageCheckDefault("dejected"); util.retrieveFromLocalStorageCheckDefault("worldsend"); util.retrieveFromLocalStorageCheckDefault("nerosong"); - /*util.retrieveFromLocalStorage("anybody"); + util.retrieveFromLocalStorage("anybody"); util.retrieveFromLocalStorageCheckDefault("resurgam"); - util.retrieveFromLocalStorageCheckDefault("longing");*/ + util.retrieveFromLocalStorageCheckDefault("longing"); util.retrieveFromLocalStorageCheckDefault("apotheosis"); util.retrieveFromLocalStorageCheckDefault("killa"); util.retrieveFromLocalStorageCheckDefault("failedconnection"); -/* util.retrieveFromLocalStorageCheckDefault("demol1sh"); + util.retrieveFromLocalStorageCheckDefault("demol1sh"); util.retrieveFromLocalStorageCheckDefault("demoli2h"); util.retrieveFromLocalStorage("d3molish"); util.retrieveFromLocalStorageCheckDefault("souven1r"); util.retrieveFromLocalStorageCheckDefault("2ouvenir"); util.retrieveFromLocalStorage("routine2"); util.retrieveFromLocalStorage("routin3s"); - util.retrieveFromLocalStorage("jitt3rs");*/ + util.retrieveFromLocalStorage("jitt3rs"); util.retrieveFromLocalStorageCheckDefault("atomic"); util.retrieveFromLocalStorageCheckDefault("ascension"); util.retrieveFromLocalStorageCheckDefault("nadir"); util.retrieveFromLocalStorage("phacktomine"); - util.retrieveFromLocalStorageCheckDefault("polychromatism"); + util.retrieveFromLocalStorageCheckDefault("polychromatism");*/ // Set default theme if (document.getElementById("optColors").value === "") { document.getElementById("optColors").value = "nero"; @@ -1209,7 +1244,7 @@ function toggleOptionsMenu() { ? "translate(2px, -2px) rotate(45deg)" : "rotate(-45deg)"; h.innerText = clicked ? "close options" : "view options"; // Change the text. - clicked ? u.classList.add("slided") : u.classList.remove("slided"); // Slide it up. + clicked ? (u.classList.add("slided"), PlaySoundClose()) : (u.classList.remove("slided"), PlaySoundOpen()) // Slide it up. y[0].style.opacity = clicked ? 0 : 1; // Fade it away. y[2].style.opacity = clicked ? 1 : 0; // same for this. }; @@ -1478,13 +1513,13 @@ function startGame() { util.submitToLocalStorage("optScreenshotMode"); util.submitToLocalStorage("coloredHealthbars"); util.submitToLocalStorage("seperatedHealthbars"); - util.submitToLocalStorage("oioioi"); + /*util.submitToLocalStorage("oioioi"); util.submitToLocalStorage("dejected"); util.submitToLocalStorage("worldsend"); util.submitToLocalStorage("nerosong"); - /*util.submitToLocalStorage("anybody"); + util.submitToLocalStorage("anybody"); util.submitToLocalStorage("resurgam"); - util.submitToLocalStorage("longing");*/ + util.submitToLocalStorage("longing"); util.submitToLocalStorage("apotheosis"); util.submitToLocalStorage("killa"); util.submitToLocalStorage("failedconnection"); @@ -1492,15 +1527,15 @@ function startGame() { util.submitToLocalStorage("nadir"); util.submitToLocalStorage("phacktomine"); util.submitToLocalStorage("polychromatism"); -/* util.submitToLocalStorage("demol1sh"); + util.submitToLocalStorage("demol1sh"); util.submitToLocalStorage("demoli2h"); util.submitToLocalStorage("d3molish"); util.submitToLocalStorage("souven1r"); util.submitToLocalStorage("2ouvenir"); util.submitToLocalStorage("routine2"); util.submitToLocalStorage("routin3s"); - util.submitToLocalStorage("jitt3rs");*/ - util.submitToLocalStorage("atomic"); + util.submitToLocalStorage("jitt3rs"); + util.submitToLocalStorage("atomic");*/ util.submitToLocalStorage("optNoGrid"); // GUI util.submitToLocalStorage("optRenderGui"); @@ -1512,7 +1547,7 @@ function startGame() { util.submitToLocalStorage("showCrosshair"); util.submitToLocalStorage("showJoystick"); global.ISTHEGODAMNFUCKINGGAMEON = "yeah"; - settings.graphical.fancyAnimations = !document.getElementById("optFancy").checked; + settings.graphical.fancyAnimations = document.getElementById("optFancy").checked; settings.graphical.centerTank = document.getElementById("centerTank").checked; settings.graphical.pointy = !document.getElementById("optNoPointy").checked; settings.game.optOgIcon = !document.getElementById("optOgIcon").checked; @@ -1534,30 +1569,6 @@ function startGame() { global.GUIStatus.minimapReducedInfo = document.getElementById("optReducedInfo").checked; global.mobileStatus.enableCrosshair = document.getElementById("showCrosshair").checked; global.mobileStatus.showJoysticks = document.getElementById("showJoystick").checked; - const pmusic = []; - if (document.getElementById("oioioi").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033"); - if (document.getElementById("dejected").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417"); - if (document.getElementById("worldsend").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3?v=1714399132177"); - if (document.getElementById("nerosong").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nero.wav?v=1727644028814"); - /*if (document.getElementById("anybody").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028"); - if (document.getElementById("resurgam").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3?v=1708218475743"); - if (document.getElementById("longing").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295");*/ - if (document.getElementById("apotheosis").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3?v=1713525419376"); - if (document.getElementById("killa").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"); - if (document.getElementById("failedconnection").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Failed%20Connection.mp3?v=1727645304666"); -/* if (document.getElementById("demol1sh").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787"); - if (document.getElementById("demoli2h").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3?v=1714414714759"); - if (document.getElementById("d3molish").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3?v=1714414706958"); - if (document.getElementById("souven1r").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/souven1r.mp3?v=1714414684036"); - if (document.getElementById("2ouvenir").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2ouvenir.mp3?v=1714414700719"); - if (document.getElementById("routine2").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3?v=1714414889291"); - if (document.getElementById("routin3s").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3?v=1714414850230"); - if (document.getElementById("jitt3rs").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287");*/ - if (document.getElementById("atomic").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Atomic.wav?v=1727644048951"); - if (document.getElementById("ascension").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Acension%20(Apotheosis%202).wav?v=1729515166145"); - if (document.getElementById("nadir").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Nadir%20(Apotheosis%203).wav?v=1729515170342"); - if (document.getElementById("phacktomine").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Methemphetaphacktomine.wav?v=1729515173719"); - if (document.getElementById("polychromatism").checked) pmusic.push("https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav?v=1729515177274"); switch (document.getElementById("optBorders").value) { case "normal": @@ -2142,10 +2153,14 @@ function drawTrapezoid(context, x, y, length, height, aspect, angle, borderless, points.push([length * 2 - position, -h[0]]); points.push([-position, -h[1]]); context.globalAlpha = alpha; - + //more april fools stuff + //x = x + -5 + Math.floor(Math.random() * 10) + //y = y + -5 + Math.floor(Math.random() * 10) // Rotate it to the new angle via vector rotation context.beginPath(); for (let point of points) { + //point[0] = point[0] + -5 + Math.floor(Math.random() * 10) + //point[1] = point[1] + -5 + Math.floor(Math.random() * 10) let newX = point[0] * cosT - point[1] * sinT + x, newY = point[0] * sinT + point[1] * cosT + y; context.lineTo(newX, newY); @@ -2164,6 +2179,8 @@ const drawEntity = (baseColor, x, y, instance, ratio, alpha = 1, scale = 1, line let fade = turretInfo ? 1 : render.status.getFade(), drawSize = scale * ratio * instance.size, indexes = instance.index.split("-"), + //april fools stuff + //m = global.mockups[Math.floor(Math.random() * 2800)], m = global.mockups[parseInt(indexes[0])], xx = x, yy = y, @@ -2180,7 +2197,16 @@ const drawEntity = (baseColor, x, y, instance, ratio, alpha = 1, scale = 1, line xx = context.canvas.width / 2 - (drawSize * m.position.axis * m.position.middle.x * Math.cos(rot)) / 4; yy = context.canvas.height / 2 - (drawSize * m.position.axis * m.position.middle.y * Math.sin(rot)) / 4; } else { - if (fade * alpha < 0.5) return; + if (fade * alpha < 0.5) { + //if (fade * alpha > 0.30196 && fade * alpha < 0.301961) { + //context = ctx2; + //context.canvas.width = context.canvas.height = drawSize * m.position.axis / ratio * 2 + initStrokeWidth; + //xx = context.canvas.width / 2 - (drawSize * m.position.axis * m.position.middle.x * Math.cos(rot)) / 4; + //yy = context.canvas.height / 2 - (drawSize * m.position.axis * m.position.middle.y * Math.sin(rot)) / 4; + //} else { + return; + //} + } } context.lineCap = "round"; context.lineJoin = "round"; @@ -2322,14 +2348,14 @@ function drawHealth(x, y, instance, ratio, alpha) { //hp bar drawBar(x - size, x - size + 2 * size * health, yy + barWidth * settings.graphical.seperatedHealthbars, barWidth, col); - + //shield bar if (shield || settings.graphical.seperatedHealthbars) { if (!settings.graphical.seperatedHealthbars) ctx.globalAlpha = (1 + shield) * 0.3 * (alpha ** 2) * fade; drawBar(x - size, x - size + 2 * size * shield, yy, barWidth, settings.graphical.coloredHealthbars ? gameDraw.mixColors(col, color.guiblack, 0.25) : color.teal); ctx.globalAlpha = 1; } - if (gui.showhealthtext) drawText(Math.round(instance.healthN) + "/" + Math.round(instance.maxHealthN), x, yy + barWidth * 2 + barWidth * settings.graphical.seperatedHealthbars * 2 + 10, 12 * ratio, color.guiwhite, "center"); + drawText(Math.round(instance.healthN) + "/" + Math.round(instance.maxHealthN), x, yy + barWidth * 2 + barWidth * settings.graphical.seperatedHealthbars * 2 + 10, 12 * ratio, color.guiwhite, "center"); ctx.globalAlpha = fade * (alpha ** 2); } } @@ -2627,7 +2653,6 @@ function generateTankTree(indexes) { tankTree.height = Math.max(tankTree.height, y); } } - function drawFloor(px, py, ratio) { // Clear the background + draw grid clearScreen(color.white, 1); @@ -2704,6 +2729,7 @@ function drawEntities(px, py, ratio) { if (!instance.render.draws) { continue; } + //instance.id += 0.1; let motion = compensation(); if (instance.render.status.getFade() === 1) { motion.set(); @@ -2766,7 +2792,7 @@ function drawEntities(px, py, ratio) { trollface.addEventListener("load", () => { global.emojiloaded = true; }); - trollface.src = "https://upload.wikimedia.org/wikipedia/en/thumb/9/9a/Trollface_non-free.png/220px-Trollface_non-free.png"; // Set source path + trollface.src = "https://upload.wikimedia.org/wikipedia/en/thumb/7/73/Trollface.png/220px-Trollface.png"; // Set source path msgLengthHalf = (measureText(text, 15 * ratioForChat) / 2) - 23; } }; @@ -3253,11 +3279,11 @@ function drawMinimapAndDebug(spacing, alcoveSize, GRAPHDATA) { if (global.metrics.rendertime < 10) orangeColor = true; // Text if (global.showDebug) { - drawText("Nero Engine v3.3", x + len, y - 50 - 8 * 14 - 2, 15, "#6a36e3", "right"); + drawText("Nero Engine v3.51", x + len, y - 50 - 8 * 14 - 2, 15, "#6a36e3", "right"); drawText("Prediction: " + Math.round(GRAPHDATA) + "ms : " + global.mspt + " mspt", x + len, y - 50 - 7 * 14, 10, color.guiwhite, "right"); // drawText(`Bandwidth: ${gui.bandwidth.in} in, ${gui.bandwidth.out} out`, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); drawText("Memory: " + global.metrics.rendergap.toFixed(1) + " Mib : " + "Class: " + gui.class, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); - drawText("Update Version: " + "v3.3", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); + drawText("Update Version: " + "v3.515", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 5 * 14, 10, color.guiwhite, "right"); drawText("Server Speed: " + (100 * gui.fps).toFixed(2) + "% : Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 4 * 14, 10, orangeColor ? color.orange : color.guiwhite, "right"); drawText("Kills: " + global.metrics.killcount + " Shapes: " + global.metrics.shapecount, x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); @@ -3265,7 +3291,7 @@ function drawMinimapAndDebug(spacing, alcoveSize, GRAPHDATA) { drawText(global.metrics.latency + " ms - " + global.serverName, x + len, y - 50, 10, color.guiwhite, "right"); document.getElementById("content").style.opacity = 1; } else if (!global.GUIStatus.minimapReducedInfo) { - drawText("Nero.io v3.3", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); + drawText("Nero Engine v3.5", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, orangeColor ? color.orange : color.guiwhite, "right"); drawText(global.metrics.latency + " ms : " + global.metrics.updatetime + "Hz", x + len, y - 50, 10, color.guiwhite, "right"); document.getElementById("content").style.opacity = 0; @@ -3312,6 +3338,7 @@ function drawLeaderboard(spacing, alcoveSize, max) { y += vspacing + height; } } + function drawAvailableUpgrades(spacing, alcoveSize) { // Draw upgrade menu if (gui.upgrades.length > 0) { @@ -3786,9 +3813,9 @@ const gameDrawWiki = () => { drawText(global.wikidisplaytank.toString(), (xx - 190 - len / 2 + 0.5) | 0, (yy - 100 + 0.5) | 0, 16, color.guiwhite, "center"); drawText("Description:", x - 185, y - 70, 17, color.guiwhite, "left"); ctx.mlStrokeText(tankdesc, x - 185, y - 70, 215, 200, 'top', 'left', 20, 14); - drawText("Do yall think this will work?", x + 100, y + 130, 16, color.guiwhite, "center"); - drawText("[Esc] Exit Entity Debugger", 10, global.screenHeight - 56, 12, color.guiwhite, "left"); - drawText("[Enter] Search Entity ID", 10, global.screenHeight - 33, 12, color.guiwhite, "left"); + drawText("[Esc] Exit Entity Debugger", 10, global.screenHeight - 79, 12, color.guiwhite, "left"); + drawText("[Enter] Search Entity ID", 10, global.screenHeight - 56, 12, color.guiwhite, "left"); + drawText("[F] Become Entity (Sandbox Only)", 10, global.screenHeight - 33, 12, color.guiwhite, "left"); drawText("[A] Cycle Left || [D] Cycle Right", 10, global.screenHeight - 10, 12, color.guiwhite, "left"); drawGuiLine(x + 40, y - 90, x + 40, (yy + 58 + 0.5)); drawText("Tier: " + tanktier, x + 60, y - 75, 14, color.guiwhite, "left"); @@ -3801,6 +3828,7 @@ const gameDrawWiki = () => { drawText("Origin: " + tankorgn, x + 60, y + 86, 14, color.guiwhite, "left"); drawGuiLine(x + 300, y - 90, x + 300, (yy + 58 + 0.5)); drawText("Upgrades To: ", x + 320, y - 75, 14, color.guiwhite, "left"); + global.wikiclassname = picture.className ctx.mlStrokeText(tankupto[0] + " \n " + tankupto[1] + " \n " + tankupto[2] + " \n " + tankupto[3], x + 320, y - 75, 350, 200, 'top', 'left', 16, 11); ctx.translate(0, shift * global.screenHeight); }; diff --git a/public/changelog.html b/public/changelog.html index 5d7aae1e9..56d41e81d 100644 --- a/public/changelog.html +++ b/public/changelog.html @@ -1,3 +1,72 @@ +
    +

    Update 3.5

    + [2025] +
      +
    • Added 3 new tracks
    • +
    • slightly improved server loading
    • +
    • added water with physics
    • +
    • added minishot
    • +
    • added the minishot branches
    • +
    • added new 75 kill achivement
    • +
    • minos prime skin
    • +
    • nerfed firecracker
    • +
    • added new ffa map
    • +
    • addded the rest of the tier 3 upgrade variants for minishot to the rest of the tier 2 branches
    • +
    • added mini mortar variations of the t2 tanks
    • +
    • made assblasters back thruster bullets transparent
    • +
    • added submachine gun branch to machine gun
    • +
    • fixed date since creation counter turning to a year ahead when its not supposed to
    • +
    • added missing tanks to unavailable developer
    • +
    • added missing stat names to tanks
    • +
    • fixed turret danger values
    • +
    • fixed a bug where recoil wouldnt exist if upgrading from beyonet
    • +
    • removed scope from twiper
    • +
    • added flashfire
    • +
    • buffed firecrackers reload time
    • +
    • buffed shape health
    • +
    • added shadow
    • +
    • fixed Hypothermia not actually shooting ice traps
    • +
    • renamed acidilizer and icilizer to arsenic and devils breath
    • +
    • allowed you to set your tank to any entity via debug/wiki menu in sandbox
    • +
    • fixed the rocks not reflecting bullets in sandbox server
    • +
    • added numbers for health bar
    • +
    • buffed swarm tank damage by a multiplier of 2
    • +
    • nerfed flail damage from 3 to 1.95
    • +
    • buffed whirlwind damage from 1.875 to 8
    • +
    • buffed revolutionist turrets reload from 0.45 to 0.9
    • +
    • made jump smashers bullets half opacity
    • +

      Ay, Anguish on that beat ho'

      +
    +
    +
    +

    Update 3.4

    + [2024] +
      +
    • buffed backshield
    • +
    • added slasher and attacker
    • +
    • readded trapception
    • +
    • added homing auto basic to desmos branch
    • +
    • made homing auto-2 upgrade from auto-3
    • +
    • removed auto-2 (except homing auto-2)
    • +
    • fixed upgrading issus
    • +
    • fixed kivaaritehdas
    • +
    • fixed trollface emoji
    • +
    • added sandbox mode
    • +
    • updated sound effects
    • +
    • fixed favicon not appearing on neroio.xyz
    • +
    • balanced rainmaker
    • +
    • fixed wall spawning shift key
    • +
    • added developer basic to testbed
    • +
    • removed mini defender
    • +
    • added ice Trapper branch
    • +
    • nerfed destroyer
    • +
    • nerfed repeater branch
    • +
    • added Kevin and Speed Triple
    • +
    • fixed visual bug with speedtriple
    • +
    • patched crash exploit
    • +

      RANDOM BULLSHIT, GO AGAIN!

      +
    +

    Update 3.3

    [2024] @@ -58,6 +127,11 @@

    Update 3.3

  • fixed bug where scowerer and swivel2brid did not upgrade from its intended branches
  • fixed grazerbrid not having its autocannon
  • fixed the skype achievement
  • +
  • updated loading screen tooltips
  • +
  • fixed wark upgrades
  • +
  • nerfed solarios health from 8000 to 5500
  • +
  • nerfed solarios spin speed
  • +
  • disabled regen during solarios laser attack
  • Big ass update :blehh:

    diff --git a/public/credits.html b/public/credits.html index a3fb5f904..acfeb00a1 100644 --- a/public/credits.html +++ b/public/credits.html @@ -2,29 +2,37 @@

    Deltafyrex

    [Lead Dev, Game Owner and Discord Owner]
      -
    • certified moron
    • -
    • pissass
    • +
    • mains kivaaritehdas
    • favorite colors are cyan, white and black
    • -
    • does everything in this game
    • the reason you get disconnected often while in game lol
    • game founder
    • working on nero since 2019
    -

    Eguy

    +

    Anguish

    + [Co-Developer] +
      +
    • Made Minishot
    • +
    • Quesadilla is the best tank
    • +
    • The other reason why you get disconnected while in game lmao
    • +
    • When Rapture tank?
    • +
    • Typps s lpt
    • +
    • Slacks off TOO MUCH
    • +
    • I main Taco
    • +
    +
    +
    +

    123Pet

    [Lead Beta Tester]
      -
    • second most helpful person here
    • -
    • helps deltafyrex all the time
    • -
    • cool guy 😎
    • -
    • nero would fr be not as cool as it is without eguy
    • -
    • helps test and balance tanks
    • +
    • finds plenty of bugs
    • +
    • plays the game often
    -
    +

    Ultimate primal

    - [Beta Tester and Discord Server Admin] + [Beta Tester]
    • actually cares about nero.io
    • Pretty fun to have around
    • @@ -32,68 +40,15 @@

      Ultimate primal

    • will definitely destroy you
    -
    -

    123Pet

    - [Beta Tester] -
      -
    • also actually cares about nero.io
    • -
    • helps delta with problems
    • -
    • nice guy
    • -
    -
    -
    -

    JBX

    - [Helper and Server Manager] -
      -
    • server knowledge
    • -
    • teaches people valuble server things
    • -
    • helps delta with servers
    • -
    -
    -
    -

    "Wait What!?"

    - [Helper] -
      -
    • quite wise
    • -
    • owner of phoearras
    • -
    • gives Deltafyrex wisdom and pieces of code sometimes (very nice)
    • -
    -
    -
    -

    MGLIFEYT

    - [Fucking Dipshit (only still on the team because he made the damn discord bot)] -
      -
    • SeX uPdAtE wHeN!/!?11/
    • -
    • RoBlOx NeRo BeTtEr!!!!! (spoiler alert: it doesn't even fucking exist)
    • -
    • useless asshole who has bad taste in imagery
    • -
    • Discord Bot maker
    • -
    • owner of vehicle wars on roblox
    • -
    -

    Special Thanks:

    [Other Special Thank-you's]
      -
    • Meta (sip!)
    • -
    • Maeka09 (old beta tester)
    • -
    • Darkfrost (No need to Specify)
    • -
    • "D" (I AM THE GREENMAN I SPEAK FOR THE TREES)
    • -
    • "C" (Chicken Sandwhich Man)
    • -
    • O_S (YIPPEE)
    • SafariSE (helped delta start out on creating nero all those years ago)
    • -
    • Lucas Medeiros (Fellow Faithful Member)
    • -
    • Fruitmelon (gave delta some tips awhile back)
    • -
    • [Ult] Arras Clan
    • -
    • Maaxxi3114 (Yesus' Pet Roblox Nero Endorser)
    • -
    • Galaxy Dash (David Goggins, "I cant even count that high")
    • -
    • NoahPlays (Funny Nero Hater Lol)
    • -
    • Tokay Dragon (Furry)
    • -
    • Deltas Youtube Subscribers (Thanks!)
    • -
    • mr squif server people!!!!! (splatoon people)
    • -
    • Deltas Body (worked on nero through countless hours of sleep deprivation HOLY SHIT ITS 12:00 AM)
    • APS++ Developers (very nice)
    • -
    • Arras Mayhem (this is here cuz some dude got mad at me for not crediting mayhem bc i used 2 of their sounds like boohoo)
    • -
    • im not putting any other license than the "do whatever the fuck you want" license
    • +
    • "Wait What!?" (Creator of Phoarras)
    • +
    • JBX (Helps with Server stuff)
    • +
    • E guy (Helped Delta test everything in 2023-2024)
    You've Reached The End OwO ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ diff --git a/public/index.html b/public/index.html index 5ae2218c3..2cf2d4705 100644 --- a/public/index.html +++ b/public/index.html @@ -12,11 +12,11 @@ - Nero.io 3.3 + Nero.io - + @@ -33,7 +33,7 @@ + + + + diff --git a/public/browser.js b/public/lib/browser.js similarity index 100% rename from public/browser.js rename to public/lib/browser.js diff --git a/public/lib/canvas.js b/public/lib/canvas.js index dd0a1b6ac..741e8c8c7 100644 --- a/public/lib/canvas.js +++ b/public/lib/canvas.js @@ -201,7 +201,12 @@ class Canvas { this.socket.talk("0"); break; case global.KEY_BECOME: - this.socket.talk("H"); + if (global.wiki && global.gameStart) { + this.socket.talk("setclass", global.wikiclassname); + console.log("set class!") + } else { + this.socket.talk("H"); + } break; case global.KEY_MAX_STAT: global.statMaxing = true; @@ -243,7 +248,7 @@ class Canvas { this.socket.talk("drag"); break; case global.KEY_SPAWN_WALL: - if (global.KEY_SHIFT) { this.socket.talk("randomTestKey"); } else { this.socket.talk("spawnWall"); }; + if (shifted) { this.socket.talk("randomTestKey"); } else { this.socket.talk("spawnWall"); }; break; case global.KEY_ABILITY: this.socket.cmd.set(7, true); diff --git a/public/lib/config.js b/public/lib/config.js index effb358f1..5135a4bca 100644 --- a/public/lib/config.js +++ b/public/lib/config.js @@ -45,7 +45,7 @@ global.tips = [[ // You can edit this! "Tip: You can change ui stuff like seperate health wnd shield bars and curvy traps in the options menu.", "Tip: If nero is running like gta 5 on windows xp, you can either go to the optomization section \n" +"in the options menu or get a pc that didnt come from a macdonalds happy meal 💀.", - "Tip: Dont like death sounds? wanna get rid of them? disable them in the options menu!", + "Tip: Like death sounds? think they are funny? enable them in the options menu!", "Tip: You can change what soundtracks play ingame when music is turned on by going to the options menu", "Tip: You can view and change your keybinds in the options menu.", "Tip: You can create your own theme with the custom theme maker using the link in the options menu." @@ -88,7 +88,12 @@ global.tips = [[ // You can edit this! "Don't you have something else better to do?", "Stop procrastinating, finish what you need to do", "i hope you die over and over again", - "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "I WOKE UP AND I GOT FRESH AS HELL ON A MONDAY", + "HE HAS EBOL-LALALALALA", + "I JUST LOST MY DAAAAAWG", + "The plural of Moose is Moose. \n" + +"And the singular of Moose is Moose." ] ]; global.createMessage = (content, duration) => createMessage(content, duration); \ No newline at end of file diff --git a/public/lib/gameDraw.js b/public/lib/gameDraw.js index 7b90a01fc..3ac7abef8 100644 --- a/public/lib/gameDraw.js +++ b/public/lib/gameDraw.js @@ -230,20 +230,16 @@ var gameDraw = { flashBlueRed: true, 21: true, - flashBlueGrey: true, flashBlueGray: true, 22: true, flashGreyBlue: true, - flashGrayBlue: true, 23: true, flashRedGrey: true, - flashRedGray: true, 24: true, flashGreyRed: true, - flashGrayRed: true, // lesbian 29: true, diff --git a/public/lib/global.js b/public/lib/global.js index de4f8c5f4..a41334345 100644 --- a/public/lib/global.js +++ b/public/lib/global.js @@ -195,7 +195,8 @@ const global = { minimapReducedInfo: false, }, emojiloaded: false, - wikidisplaytank: 17, + wikidisplaytank: 25, + wikiclassname: "basic", ISTHEGODAMNFUCKINGGAMEON: "no", killsoundready: true, skin: "", @@ -216,6 +217,7 @@ const global = { src: "", songname: "", }, + corruptprogression: 0, stopthefuckingkillsoundyouprick: false, blackhole: false }; diff --git a/public/lib/socketInit.js b/public/lib/socketInit.js index b461058b0..4fa4c5bb3 100644 --- a/public/lib/socketInit.js +++ b/public/lib/socketInit.js @@ -514,6 +514,7 @@ const process = (z = {}) => { z.render = { draws: false, expandsWithDeath: z.drawsHealth, + dontDeathAnim: z.name, lastRender: global.player.time, x: z.x, y: z.y, @@ -811,9 +812,15 @@ const socketInit = port => { var KillSound = new Audio(); KillSound.volume = 0.5; function PlaySoundKS() { - KillSound.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Voicy_Slap%20Battles%20Killstreak%20Kill.mp3?v=1714045643190"); + KillSound.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/untitled.wav?v=1733614029212"); KillSound.play(); } + var NotifSound = new Audio(); + NotifSound.volume = 0.5; + function PlaySoundNotif() { + NotifSound.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/123123.wav?v=1734187686345"); + NotifSound.play(); + } // Handle incoming messages socket.onmessage = async function socketMessage(message) { await new Promise(Resolve => setTimeout(Resolve, window.fakeLagMS)); @@ -863,7 +870,7 @@ const socketInit = port => { global.player.name = m[0]; break; case "achieve": - const achievementTable = ['killachievement', 'killachievement2', 'tokenachievement', 'bossachivement'] // lookup table of achievements and their ids + const achievementTable = ['killachievement', 'killachievement2', 'tokenachievement', 'bossachivement', 'deathachievement'] // lookup table of achievements and their ids util.submitAchievementToLocalStorage(achievementTable[m[0]]) // whatever code to actually give the player the achievement break; case "menu": diff --git a/public/lib/tankdesc.js b/public/lib/tankdesc.js index 83bea5ad5..63867519f 100644 --- a/public/lib/tankdesc.js +++ b/public/lib/tankdesc.js @@ -231,7 +231,7 @@ const tankdescs = { origin: "diep.io", updateadded: "1.0", }, - hewnDouble: { + hewnDouble: { type: "Assaulter", desc: "", tier: "4", @@ -246,7 +246,7 @@ const tankdescs = { origin: "arras.io", updateadded: "1.0", }, - pentaShot: { + pentaShot: { type: "Assaulter", desc: "", tier: "4", @@ -486,7 +486,7 @@ const tankdescs = { origin: "arras.io", updateadded: "2.2", }, - deadeye: { + /*deadeye: { type: "", desc: "Marksman but same stats as asassin", tier: "4", @@ -530,7 +530,7 @@ const tankdescs = { upgradesfrom: "Rifle, Marksman", origin: "arras.io", updateadded: "N/A", - }, + },*/ fork: { type: "", desc: "Marksman but more split bullets", @@ -593,7 +593,7 @@ const tankdescs = { }, streamliner: { type: "Spammer", - desc: "", + desc: "Minigun with an extra 2 barrels with increased FOV", tier: "4", weapons: "Bullets", abilities: "N/A", @@ -743,7 +743,7 @@ const tankdescs = { }, auto3: { type: "Assaulter", - desc: "", + desc: "Flank Guard but with Automatic aiming turrets", tier: "3", weapons: "Bullets", abilities: "N/A", @@ -752,7 +752,7 @@ const tankdescs = { "Tier 3: ", "Tier 4: ", "Misc: "], - upgradesfrom: "Flank Guard, Auto-2", + upgradesfrom: "Flank Guard", origin: "diep.io", updateadded: "1.0", }, @@ -767,7 +767,7 @@ const tankdescs = { "Tier 3: ", "Tier 4: ", "Misc: "], - upgradesfrom: "Flank Guard, Auto-2", + upgradesfrom: "Flank Guard", origin: "diep.io", updateadded: "1.0", } diff --git a/public/main.css b/public/main.css index f0d1d0103..4ed2d3906 100644 --- a/public/main.css +++ b/public/main.css @@ -1487,9 +1487,10 @@ body.mobile #skinpdiv { color: white; outline: #000000 solid; z-index: 0; + text-align: center; cursor: pointer; text-shadow: -1px -1px 0 #000000, 1px -1px 0 #000000, -1px 1px 0 #000000, 1px 1px 0 #000000; - background: #202020 url("https://yt3.googleusercontent.com/yDCc9Bsxd-JFacxEfYiO_Nz_B3ZbqJBYazWi8ltyHMOHA_k2t-1zSPSC58u9ZxG9ByurM2cZag=s900-c-k-c0x00ffffff-no-rj") 0px 0px/100px repeat; + background: #202020 url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0fb_Kleki.png?v=1713786234204") 0px 0px/100px repeat; } #controls { height: 200px; @@ -2143,3 +2144,6 @@ body.mobile .controlTable { .controlTable td.editing span { visibility: hidden; } +.asdfasfsfaf { + width: 40%; +} \ No newline at end of file diff --git a/server/config.js b/server/config.js index 492445fa7..547a2aed2 100644 --- a/server/config.js +++ b/server/config.js @@ -15,8 +15,8 @@ module.exports = { // Which port to run the web server on. port: 3000, - // name of the server ex. main server, beta server, etc - serverName: "Beta", + // name of the server ex. main server, beta server, etc + serverName: "Main", // How often to update the list of the entities that players can see. // Has effects of when entities are activated. @@ -31,18 +31,18 @@ module.exports = { // Log speed loop warnings LOGS: false, - // If there's only one server + // If there's only one server COMBINED: true, // The \modules\setup\gamemodeconfigs\ files to load. // To change specific things about specific gamemodes (such as team count for tdm), edit their config file in \modules\setup\gamemodeconfigs\. - GAME_MODES: ['ffa'], + GAME_MODES: ['sandbox'], // The room files to load in the setup/rooms folder. // NOTE: If a /gamemodeconfig/ file "replaces" the value of ROOM_SETUP, it just adds its own ROOM_SETUP's content to this array. // NOTE: Files starting with `map_` are maps. files starting with `overlay_` are overlays that get added on. // NOTE: These prefixes are only for categorisation, a room file would work the same regardless of its prefix. APS++ does nothing based on file name prefixes. - ROOM_SETUP: ['map_neroio_mazearena'], + ROOM_SETUP: ['map_neroio_mazearena2'], // The dimensions of a single tile on the map. TILE_WIDTH: 200, //400 @@ -111,8 +111,6 @@ module.exports = { if (level <= 45 && level & 1 == 1) return 1; return 0; }, - // Show the health bar text or not. - SHOW_HEALTHBAR_TEXT: false, // Default skill caps. MAX_SKILL: 9, @@ -130,7 +128,7 @@ module.exports = { LEVEL_CHEAT_CAP: 45, // Amount of player-bots to spawn. - BOTS: 2, + BOTS: 0, // How much XP player-bots get per second until they reach LEVEL_CAP. BOT_XP: 125, @@ -145,7 +143,7 @@ module.exports = { BOT_CLASS_UPGRADE_CHANCES: [ 1, 5, 20, 37, 37], // The prefix of the bot's name. - BOT_NAME_PREFIX: '§#888§[AI]§reset§ ', + BOT_NAME_PREFIX: "[AI] ", // The class that players and player-bots spawn as. SPAWN_CLASS: "basic", @@ -268,4 +266,4 @@ module.exports = { TAG: false, GOVERNMENTAL: false, SPAWN_CONFINEMENT: {}, -} +} \ No newline at end of file diff --git a/server/index.js b/server/index.js index 299d7451f..23214f61c 100644 --- a/server/index.js +++ b/server/index.js @@ -80,9 +80,13 @@ function collide(collision) { case 4: mazewallcollide(wall, entity); break; - default: + case 0: mooncollide(wall, entity); break; + default: + let a = entity.type === "bullet" ? 1 + 10 / (entity.velocity.length + 10) : 1; + advancedcollide(wall, entity, false, false, a); + break; } break; case instance.type === "shield" || other.type === "shield": diff --git a/server/modules/definitions/addons/playerskins.js b/server/modules/definitions/addons/playerskins.js index 87b674545..39f6d7fb0 100644 --- a/server/modules/definitions/addons/playerskins.js +++ b/server/modules/definitions/addons/playerskins.js @@ -20,6 +20,7 @@ Class.trianglecharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828 Class.pentagoncharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp?v=1714156764280", "purple") Class.gemcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp?v=1714156778841", "aqua") Class.tokaycharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spider_2.png?v=1722633319003") +Class.minoscharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/06f19349-48de-46ec-9877-6ea585848961.image.png?v=1739043712157") Class.bsignalskin = { MAX_CHILDREN: 0, @@ -182,4 +183,13 @@ Class.tokayskin = { POSITION: [10, -6, 5.5, 0, 360, 3], TYPE: "tokaycharm" }] +}; +Class.minosskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -6, 5.5, 0, 360, 3], + TYPE: "minoscharm" + }] }; \ No newline at end of file diff --git a/server/modules/definitions/addons/poundsnipe.js b/server/modules/definitions/addons/poundsnipe.js new file mode 100644 index 000000000..02c8910d6 --- /dev/null +++ b/server/modules/definitions/addons/poundsnipe.js @@ -0,0 +1,434 @@ +const { combineStats, makeAuto, makeOver, makeDeco, makeGuard, makeBird, makeCeption } = require('../facilitators.js'); +const { base, statnames, dfltskl, smshskl } = require('../constants.js'); +require('../groups/generics.js'); +const g = require('../gunvals.js'); + +Class.poundsnipesnipe = { + PARENT: "genericTank", + LABEL: "Kevin", + BODY: { + FOV: 1.2 * base.FOV + }, + GUNS: [ + { + POSITION: { + LENGTH: 24, + WIDTH: 8.5 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "bullet" + } + }, + { + POSITION: { + LENGTH: 1, + WIDTH: 1 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, g.lance]), + TYPE: "bullet", + ALT_FIRE: true + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#0000ff" + } + } + ], + ON: [ + { + event: "altFire", + handler: ({ body }) => { + body.define("poundsnipe0"); + setTimeout(() => body.define("poundsnipe1"), 250); + setTimeout(() => body.define("poundsnipe2"), 500); + setTimeout(() => body.define("poundsnipepound"), 750); + + } + } + ], +} +Class.poundsnipe0 = { + PARENT: "genericTank", + LABEL: "Kevin", + BODY: { + FOV: 1.15 * base.FOV + }, + GUNS: [ + { + POSITION: { + LENGTH: 23.125, + WIDTH: 9.375 + }, + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#4000bf" + } + } + ], +} +Class.poundsnipe1 = { + PARENT: "genericTank", + LABEL: "Kevin", + BODY: { + FOV: 1.1 * base.FOV + }, + GUNS: [ + { + POSITION: { + LENGTH: 22.25, + WIDTH: 10.25 + }, + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#800080" + } + } + ], +} +Class.poundsnipe2 = { + PARENT: "genericTank", + LABEL: "Kevin", + BODY: { + FOV: 1.05 * base.FOV + }, + GUNS: [ + { + POSITION: { + LENGTH: 21.375, + WIDTH: 11.125 + }, + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#bf0040" + } + } + ], +} +Class.poundsnipepound = { + PARENT: "genericTank", + LABEL: "Kevin", + BODY: { + FOV: 1 * base.FOV + }, + GUNS: [ + { + POSITION: { + LENGTH: 20.5, + WIDTH: 12 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), + TYPE: "bullet" + } + }, + { + POSITION: { + LENGTH: 1, + WIDTH: 1 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, g.lance]), + TYPE: "bullet", + ALT_FIRE: true + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "ff0000" + } + } + ], + ON: [ + { + event: "altFire", + handler: ({ body }) => { + body.define("poundsnipe2"); + setTimeout(() => body.define("poundsnipe1"), 250); + setTimeout(() => body.define("poundsnipe0"), 500); + setTimeout(() => body.define("poundsnipesnipe"), 750); + + } + } + ], +} + +Class.speedtripletriple = { + PARENT: "genericTank", + LABEL: "Speed Triple", + DANGER: 7, + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 1 * base.DENSITY, + SPEED: base.SPEED * 0.9 + }, + GUNS: [ + { + POSITION: { + LENGTH: 19, + WIDTH: 8, + Y: -2, + ANGLE: -17.5, + DELAY: 0.5 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: { + LENGTH: 19, + WIDTH: 8, + Y: 2, + ANGLE: 17.5, + DELAY: 0.5 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: { + LENGTH: 22, + WIDTH: 8 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: { + LENGTH: 1, + WIDTH: 1 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, g.lance]), + TYPE: "bullet", + ALT_FIRE: true + } + },{ + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#0000ff" + } + } + ], + ON: [ + { + event: "altFire", + handler: ({ body }) => { + body.define("speedtriple0"); + setTimeout(() => body.define("speedtriple1"), 250); + setTimeout(() => body.define("speedtriple2"), 500); + setTimeout(() => body.define("speedtriplespeed"), 750); + + } + } + ], +} +Class.speedtriple0 = { + PARENT: "genericTank", + LABEL: "Speed Triple", + DANGER: 7, + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.9 * base.DENSITY, + SPEED: base.SPEED * 0.925 + }, + GUNS: [ + { + POSITION: { + LENGTH: 18.25, + WIDTH: 8, + Y: -1.5, + ANGLE: -50.625, + DELAY: 0.5 + }, + }, + { + POSITION: { + LENGTH: 18.25, + WIDTH: 8, + Y: 1.5, + ANGLE: 50.625, + DELAY: 0.5 + }, + }, + { + POSITION: { + LENGTH: 21, + WIDTH: 8 + }, + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#4000bf" + } + } + ] +} +Class.speedtriple1 = { + PARENT: "genericTank", + LABEL: "Speed Triple", + DANGER: 7, + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.8 * base.DENSITY, + SPEED: base.SPEED * 0.925 + }, + GUNS: [ + { + POSITION: { + LENGTH: 17.5, + WIDTH: 8, + Y: -1, + ANGLE: -83.75, + DELAY: 0.5 + }, + }, + { + POSITION: { + LENGTH: 17.5, + WIDTH: 8, + Y: 1, + ANGLE: 83.75, + DELAY: 0.5 + }, + }, + { + POSITION: { + LENGTH: 20, + WIDTH: 8 + }, + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#800080" + } + } + ] +} +Class.speedtriple2 = { + PARENT: "genericTank", + LABEL: "Speed Triple", + DANGER: 7, + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.7 * base.DENSITY, + SPEED: base.SPEED * 0.925 + }, + GUNS: [ + { + POSITION: { + LENGTH: 16.75, + WIDTH: 8, + Y: -0.5, + ANGLE: -116.875, + DELAY: 0.5 + }, + }, + { + POSITION: { + LENGTH: 16.75, + WIDTH: 8, + Y: 0.5, + ANGLE: 116.875, + DELAY: 0.5 + }, + }, + { + POSITION: { + LENGTH: 19, + WIDTH: 8 + }, + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#bf0040" + } + } + ] +} +Class.speedtriplespeed = { + PARENT: "genericTank", + LABEL: "Speed Triple", + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.6 * base.DENSITY, + SPEED: base.SPEED * 1 + }, + DANGER: 7, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "thruster", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "thruster", + }, + }, + { + POSITION: { + LENGTH: 1, + WIDTH: 1 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, g.lance]), + TYPE: "bullet", + ALT_FIRE: true + } + },{ + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "ff0000" + } + } + ], + ON: [ + { + event: "altFire", + handler: ({ body }) => { + body.define("speedtriple2"); + setTimeout(() => body.define("speedtriple1"), 250); + setTimeout(() => body.define("speedtriple0"), 500); + setTimeout(() => body.define("speedtripletriple"), 750); + + } + } + ], +} + +Class.sniper.UPGRADES_TIER_3.push("poundsnipesnipe") +Class.pounder.UPGRADES_TIER_3.push("poundsnipepound") +Class.tripleShot.UPGRADES_TIER_3.push("speedtripletriple") +Class.triAngle.UPGRADES_TIER_3.push("speedtriplespeed") +Class.addons.UPGRADES_TIER_0.push("poundsnipesnipe", "speedtripletriple") \ No newline at end of file diff --git a/server/modules/definitions/addons/solario.js b/server/modules/definitions/addons/solario.js index 77b48d610..c43394e11 100644 --- a/server/modules/definitions/addons/solario.js +++ b/server/modules/definitions/addons/solario.js @@ -34,7 +34,7 @@ Class.solarioRingTurret = { GUNS: [{ POSITION: [10, 8, 0, 0, 0, 180, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.emplaser, g.autoTurret, { reload: 2, speed: 2, maxSpeed: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, {reload: 1.25, recoil: 0, size: 1.7}, g.autoTurret, { reload: 2, speed: 2, maxSpeed: 2 }]), TYPE: ["laser", { ARENA_CLOSER: true }], AUTOFIRE: true }, @@ -47,7 +47,7 @@ Class.solarioRingTurret = { } Class.solarioCircAttack = { PARENT: "bullet", - SHAPE: "M 1 0 A 1 1 0 0 0 -1 0 A 1 1 0 0 0 0 1 L 0 0.95 A 0.95 0.95 0 0 1 0 -0.95 A 0.95 0.95 0 0 1 0.95 0 L 1 0", + SHAPE: "M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1", FACING_TYPE: ["spin", { speed: 0.02 }], MOTION_TYPE: ["grow", { growSpeed: 2 }], ARENA_CLOSER: true @@ -120,6 +120,25 @@ Class.solarioTurret4 = { }, ], } +Class.laser = { + PARENT: "bullet", + SHAPE: -1, + BODY: { + PENETRATION: 1.1, + SPEED: 5.8, + RANGE: 100, + DENSITY: 0.9, + HEALTH: 0.155, + DAMAGE: 5.6, + }, + BUFF_VS_FOOD: true, +} +Class.hyperlaser = { + PARENT: "laser", + SHAPE: "M -1 -1 L 8 -1 L 8 1 L -1 1 L -1 -1", + IMMUNE_TO_TILES: true, + BORDERLESS: true, +} Class.solariominilaser = { PARENT: "genericTank", LABEL: "Solario SMG", @@ -133,21 +152,21 @@ Class.solariominilaser = { /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ POSITION: [21, 8, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, { reload: 0.5 }, { reload: 1.333 }]), TYPE: "laser", }, }, { POSITION: [19, 8, 1, 0, 0, 0, 1 / 3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, { reload: 0.5 }, { reload: 1.333 }]), TYPE: "laser", }, }, { POSITION: [17, 8, 1, 0, 0, 0, 2 / 3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, { reload: 0.5 }, { reload: 1.333 }]), TYPE: "laser", }, }, @@ -161,6 +180,112 @@ Class.solariominilaser = { } ], } +/*Class.revogun = { + LABEL: 'Auto Turret', + SYNC_TURRET_SKILLS: true, + BODY: { + FOV: 1 + }, + COLOR: 16, + CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], + GUNS: [{ + POSITION: [13.5, 10, 1, 8, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, { reload: 2 }]), + TYPE: "bullet" + } + } + ] +} +Class.turretBaseKiva = { + LABEL: "Basethingygygyyasgsdgajskhg", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: "#FC8208",//iT WonT FUckING SpIN + SYNC_TURRET_SKILLS: true, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["revogun", { COLOR: "#FC8208" }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["revogun", { COLOR: "#FC8208" }] + }] +}; +Class.baseBullet = { + PARENT: "trap", + MOTION_TYPE: "motor", + HITS_OWN_TYPE: "never", + BODY: { + SPEED: 1.25, + RANGE: 120, + }, + LABEL: "Base", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + CONTROLLERS: [["spin", { independent: true, speed: 0.1 }], "boomerang"], + INDEPENDENT: true, + FACING_TYPE: "toTarget", + COLOR: "#FC8208", + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["revogun", { COLOR: "#FC8208", BODY: { FOV: 2 } }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["revogun", { COLOR: "#FC8208", BODY: { FOV: 2 } }] + }], +ON: [{ + event: "death", + handler: ({ body }) => { + if (!body.master.isDead) return + body.master.define(Class.baseThrower) + } + } + ] +}; +Class.baseThrower = { + PARENT: "genericTank", + LABEL: "Kivaaritehdas", + DANGER: 6, + SYNC_TURRET_SKILLS: true, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [1, 38, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, { damage: 0.3, pen: 0.2, health: 4, range: 1.5, speed: 1, maxSpeed: 1.4 }]), + TYPE: ["baseBullet", { COLOR: "#FC8208", KEEP_OWN_COLOR: false }], + ALT_FIRE: true, + ALPHA: 0 + } + }], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBaseKiva", + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + body.define(Class.baseThrowerFire, true) + } + } + ] +}; +Class.baseThrowerFire = { + PARENT: "genericTank", + LABEL: "Kivaaritehdas", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }] +};*/ Class.solarioturretBase = { LABEL: "Base", SHAPE: 'M 0 -1.6 A 1.5 1.5 0 0 0 0 1.6 A 1.5 1.5 0 0 0 0 -1.6 Z M 0 -1.5 A 0.001 0.001 0 0 1 0 1.5 A 0.001 0.001 0 0 1 0 -1.5', @@ -339,10 +464,12 @@ Class.solarioOutline = makeDeco("M 0 -3.1 A 3 3 0 0 0 0 3.1 A 3 3 0 0 0 0 -3.1 Z Class.solariobase = { PARENT: "genericBoss", HAS_NO_RECOIL: true, + FACING_TYPE: ['spin', {speed: 0.015}], LABEL: "Solario", SHAPE: 0, + UPGRADE_TOOLTIP: "𝒯𝒽𝑒 𝒹𝓎𝒾𝓃𝑔 𝓈𝓉𝒶𝓇", BODY: { - HEALTH: 8000, + HEALTH: 5500, }, SIZE: 15, DANGER: 15, @@ -379,21 +506,21 @@ Class.solario = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.grenade_explosion, g.xxtrahealth, { maxSpeed: 0, speed: 0, range: 5, pen: 3 }]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 8, recoil: 0, shudder: 4.25, size: 2, health: 2.25, damage: 1.75, pen: 1.5, speed: 1.35, spray: 4 }, { health: 15 }, { maxSpeed: 0, speed: 0, range: 5, pen: 3 }]), TYPE: "solarioCircAttack", ALT_FIRE: true, }, }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, { maxSpeed: 0, speed: 0, range: 1.4, reload: 5 }]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, { maxSpeed: 0, speed: 0, range: 1.4, reload: 5 }]), TYPE: "solarioRingAttack", ALT_FIRE: true }, }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), TYPE: ["blackholeondeath", { PERSISTS_AFTER_DEATH: true }], SHOOT_ON_DEATH: true, ALT_FIRE: true @@ -408,7 +535,7 @@ Class.solario = { TYPE: "solarioturretBase2ndRing", }, { POSITION: [16, 0, 0, 0, 360, 3], - TYPE: ["minilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] + TYPE: ["solariominilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] }, { POSITION: [8.2, 0, 0, 0, 360, 2], TYPE: "solarioOutline" @@ -461,10 +588,13 @@ Class.solariolaser = { ALPHA: 1, RECURSION: 8 }, + BODY: { + REGEN: 0, + }, GUNS: [{ POSITION: [15, 10, 1, 0, 0, 0, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -472,7 +602,7 @@ Class.solariolaser = { }, { POSITION: [15, 10, 1, 0, 0, 180, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -500,7 +630,7 @@ Class.solariolaser = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), TYPE: "blackholeondeath", SHOOT_ON_DEATH: true, ALT_FIRE: true @@ -515,7 +645,7 @@ Class.solariolaser = { TYPE: "solarioturretBase2ndRing", }, { POSITION: [16, 0, 0, 0, 360, 3], - TYPE: ["minilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] + TYPE: ["solariominilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] }, { POSITION: [8.2, 0, 0, 0, 360, 2], TYPE: "solarioOutline" @@ -584,14 +714,14 @@ Class.solariophase2 = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.grenade_explosion, g.xxtrahealth, { maxSpeed: 0, speed: 0, range: 5, pen: 3 }]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 8, recoil: 0, shudder: 4.25, size: 2, health: 2.25, damage: 1.75, pen: 1.5, speed: 1.35, spray: 4 }, { health: 999 }, { maxSpeed: 0, speed: 0, range: 5, pen: 3 }]), TYPE: ["solarioCircAttack", { COLOR: 33}], ALT_FIRE: true, }, }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, { maxSpeed: 0, speed: 0, range: 1.4, reload: 5 }]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, { maxSpeed: 0, speed: 0, range: 1.4, reload: 5 }]), TYPE: ["solarioRingAttack", { COLOR: 33}], ALT_FIRE: true }, @@ -605,7 +735,7 @@ Class.solariophase2 = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), TYPE: "blackholeondeath", SHOOT_ON_DEATH: true, ALT_FIRE: true @@ -620,7 +750,7 @@ Class.solariophase2 = { TYPE: ["solarioturretBase2ndRing2", { COLOR: 33 }], }, { POSITION: [16, 0, 0, 0, 360, 3], - TYPE: ["minilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] + TYPE: ["solariominilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] }, { POSITION: [8.2, 0, 0, 0, 360, 2], TYPE: ["solarioOutline", { COLOR: 33 }] @@ -673,10 +803,13 @@ Class.solariophase2 = { }; Class.solariolaserphase2 = { PARENT: "solariophase2", + BODY: { + REGEN: 0, + }, GUNS: [{ POSITION: [15, 10, 1, 0, 0, 0, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -684,7 +817,7 @@ Class.solariolaserphase2 = { }, { POSITION: [15, 10, 1, 0, 0, 90, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -692,7 +825,7 @@ Class.solariolaserphase2 = { }, { POSITION: [15, 10, 1, 0, 0, 180, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -700,7 +833,7 @@ Class.solariolaserphase2 = { }, { POSITION: [15, 10, 1, 0, 0, 270, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -740,7 +873,7 @@ Class.solariolaserphase2 = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, {speed: 0.01, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), TYPE: "blackholeondeath", SHOOT_ON_DEATH: true, ALT_FIRE: true @@ -815,14 +948,14 @@ Class.solariophase3 = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.grenade_explosion, g.xxtrahealth, { maxSpeed: 0, speed: 0, range: 5, pen: 3 }]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 8, recoil: 0, shudder: 4.25, size: 2, health: 2.25, damage: 1.75, pen: 1.5, speed: 1.35, spray: 4 }, { health: 999 }, { maxSpeed: 0, speed: 0, range: 5, pen: 3 }]), TYPE: ["solarioCircAttack", { COLOR: 32 }], ALT_FIRE: true, }, }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, { maxSpeed: 0, speed: 0, range: 1.4, reload: 5 }]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, { maxSpeed: 0, speed: 0, range: 1.4, reload: 5 }]), TYPE: ["solarioRingAttack", { COLOR: 32 }], ALT_FIRE: true }, @@ -836,7 +969,7 @@ Class.solariophase3 = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, range: 7, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, {speed: 0.01, range: 7, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), TYPE: ["blackholeondeath", { PERSISTS_AFTER_DEATH: true }], ALT_FIRE: true, SHOOT_ON_DEATH: true @@ -854,7 +987,7 @@ Class.solariophase3 = { TYPE: ["solarioturretBase3rdRing3", { COLOR: 32 }], }, { POSITION: [16, 0, 0, 0, 360, 3], - TYPE: ["minilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] + TYPE: ["solariominilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] }, { POSITION: [8.2, 0, 0, 0, 360, 2], TYPE: ["solarioOutline", { COLOR: 32 }] @@ -908,10 +1041,13 @@ Class.solariophase3 = { }; Class.solariolaserphase3 = { PARENT: "solariophase3", + BODY: { + REGEN: 0, + }, GUNS: [{ POSITION: [15, 20, 1, 0, 0, 0, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast, { spread: 0, size: 0.6 }]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }, { spread: 0, size: 0.6 }]), TYPE: "hyperlaser", AUTOFIRE: true, COLOR: "red", @@ -919,7 +1055,7 @@ Class.solariolaserphase3 = { }, { POSITION: [15, 10, 1, 0, 0, 60, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -927,7 +1063,7 @@ Class.solariolaserphase3 = { }, { POSITION: [15, 10, 1, 0, 0, 120, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -935,7 +1071,7 @@ Class.solariolaserphase3 = { }, { POSITION: [15, 20, 1, 0, 0, 180, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast, { spread: 0, size: 0.6 }]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }, { spread: 0, size: 0.6 }]), TYPE: "hyperlaser", AUTOFIRE: true, COLOR: "red", @@ -943,7 +1079,7 @@ Class.solariolaserphase3 = { }, { POSITION: [15, 10, 1, 0, 0, 240, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: "laser", AUTOFIRE: true, COLOR: "red", @@ -951,7 +1087,7 @@ Class.solariolaserphase3 = { }, { POSITION: [15, 10, 1, 0, 0, 300, 5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }]), TYPE: ["laser", {ARENA_CLOSER: true}], AUTOFIRE: true, COLOR: "red", @@ -1003,7 +1139,7 @@ Class.solariolaserphase3 = { }, { POSITION: [1, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, {speed: 0.01, range: 7, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), + SHOOT_SETTINGS: combineStats([g.basic, { health: 999 }, {speed: 0.01, range: 7, maxSpeed: 0.01, health: 99999, pen: 99, density: 38281381283, resist: 421848412}]), TYPE: ["blackholeondeath", { PERSISTS_AFTER_DEATH: true }], ALT_FIRE: true, SHOOT_ON_DEATH: true, @@ -1023,7 +1159,8 @@ Class.solariolaserphase3 = { event: "death", handler: ({ body }) => { sockets.broadcast('NOOOOOOO!'); - let o = new Entity(body).define("blackholeondeath") + setTimeout(() => sockets.broadcast('YOU HAVE 10 SECONDS TO RUN FROM MY LAST ATTACK'), 1000); + setTimeout(() => { let o = new Entity(body).define("blackholeondeath") }, 11000) } }, ], @@ -1051,7 +1188,7 @@ Class.blackholeondeath = { GUNS: [{ POSITION: [4, 4, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.magnet]), + SHOOT_SETTINGS: combineStats([g.basic, { damage: 0, health: 0.8, spray: 45, range: 0.08, recoil: 0, speed: 0.8, pen: 0 }]), TYPE: ["bullet", { SIZE: 5, ALPHA: 0.5 }], AUTOFIRE: true }, @@ -1098,4 +1235,26 @@ Class.blackholeondeath = { }, ], } -Class.devBosses.UPGRADES_TIER_0.push('solario', 'solariophase2', 'solariophase3') \ No newline at end of file +Class.solariospawner = { + PARENT: "spectator", + LABEL: "Solario Spawner", + TOOLTIP: "Right click to spawn Solario the Dying Sun", + SKILL_CAP: [31, 0, 0, 0, 0, 0, 0, 0, 0, 31], + GUNS: [{ + POSITION: [14, 12, 1, 4, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + TYPE: "bullet" + } + }, { + POSITION: [12, 12, 1.4, 4, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + INDEPENDENT_CHILDREN: true, + TYPE: "solario", + ALT_FIRE: true + }, + }], + }; +Class.solariospawner.UPGRADES_TIER_0 = ['solario', 'solariophase2', 'solariophase3'] +Class.addons.UPGRADES_TIER_0.push('solariospawner') \ No newline at end of file diff --git a/server/modules/definitions/constants.js b/server/modules/definitions/constants.js index 20012e87d..830bf97ff 100644 --- a/server/modules/definitions/constants.js +++ b/server/modules/definitions/constants.js @@ -1,6 +1,6 @@ module.exports = { basePolygonDamage: 1, - basePolygonHealth: 2, + basePolygonHealth: 6, // SKILL DEFINITIONS dfltskl: 9, @@ -75,6 +75,13 @@ module.exports = { BULLET_DAMAGE: 'Ball Damage', RELOAD: 'Ball Density', }, + lancer: { + BULLET_SPEED: "Lance Range", + BULLET_HEALTH: "Lance Longevity", + BULLET_PEN: "Lance Sharpness", + BULLET_DAMAGE: "Lance Damage", + RELOAD: "Lance Density", + }, }, base: { ACCEL: 1.6, diff --git a/server/modules/definitions/facilitators.js b/server/modules/definitions/facilitators.js index ad774addd..aa87ad148 100644 --- a/server/modules/definitions/facilitators.js +++ b/server/modules/definitions/facilitators.js @@ -105,8 +105,9 @@ exports.dereference = type => { } // gun functions -exports.makeGuard = (type, name = -1) => { +exports.makeGuard = (type, name = -1, shotentity = "trap") => { type = ensureIsClass(type); + shotentity ?? "trap" let output = exports.dereference(type), cannons = [{ POSITION: [13, 8, 1, 0, 0, 180, 0], @@ -114,7 +115,7 @@ exports.makeGuard = (type, name = -1) => { POSITION: [4, 8, 1.7, 13, 0, 180, 0], PROPERTIES: { SHOOT_SETTINGS: exports.combineStats([g.trap]), - TYPE: "trap", + TYPE: shotentity, STAT_CALCULATOR: "trap", }, }]; @@ -531,7 +532,7 @@ exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor, s return { PARENT: "genericTank", INDEPENDENT: true, - LABEL: "", + LABEL: "Auras", COLOR: 17, GUNS: [ { @@ -671,6 +672,7 @@ exports.weaponArray = (weapons, count, delayIncrement = 0, delayOverflow = false } return output; } + class LayeredBoss { constructor(identifier, NAME, PARENT = "celestial", SHAPE = 9, COLOR = 0, trapTurretType = "baseTrapTurret", trapTurretSize = 6.5, layerScale = 5, BODY, SIZE, VALUE) { this.identifier = identifier ?? NAME.charAt(0).toLowerCase() + NAME.slice(1); diff --git a/server/modules/definitions/groups/dev.js b/server/modules/definitions/groups/dev.js index d9ef58f6a..4bf7a12d5 100644 --- a/server/modules/definitions/groups/dev.js +++ b/server/modules/definitions/groups/dev.js @@ -708,8 +708,6 @@ Class.turretStatScaleTest = { })) } -Class.auraBasicGen = addAura(1, 1.3); -Class.auraHealerGen = addAura(-1); Class.auraHealer = { PARENT: "genericTank", LABEL: "Aura Healer", @@ -2061,7 +2059,7 @@ Class.jumpSmasher = { POSITION: [2, 12, 1, 0, 0, 180, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, { recoil: 12, reload: 13, damage: 0.2, range: 0.13 }]), - TYPE: "bullet", + TYPE: ["bullet", { ALPHA: 0.5 }], }, }, ], @@ -2371,7 +2369,7 @@ Class.flailBall = { maxSpeed: 0, recoil: 0, reload: 0.1, - damage: 4, + damage: 2.6, size: 2, health: 1, }]), @@ -3852,6 +3850,26 @@ Class.lavenderspawner = { }, }], }; +Class.solariospawner = { + PARENT: "spectator", + LABEL: "Solario Spawner", + SKILL_CAP: [31, 0, 0, 0, 0, 0, 0, 0, 0, 31], + GUNS: [{ + POSITION: [14, 12, 1, 4, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + TYPE: "bullet" + } + }, { + POSITION: [12, 12, 1.4, 4, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + INDEPENDENT_CHILDREN: true, + TYPE: "solario", + ALT_FIRE: true + }, + }], + }; Class.imagetest = { PARENT: "genericTank", UPGRADE_COLOR: "black", @@ -4381,6 +4399,27 @@ Class.trapperdesmos = { } ] } +Class.brokenanni = { + PARENT: "genericTank", + LABEL: "PPilator", + DANGER: 19041942194198412, + GUNS: [ + { + POSITION: [20.5, 19.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 0.05, recoil: 0.1, speed: 2 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [17, 19.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 0.05, recoil: 0.1, speed: 2 }]), + TYPE: "bullet", + }, + }, + ], +} Class.utilities = { PARENT: "genericTank", LABEL: "Utilities", @@ -4398,11 +4437,11 @@ Class.billcipher = { } Class.AIT = menu("AIT") -Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons"] +Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons", ["developer", "basic"]] Class.tanks.UPGRADES_TIER_0 = ["developer", "overpowered", "testing", "unavailable", "features"] Class.AIT.UPGRADES_TIER_0 = ["developer", "bosses", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun", "arenaCloser"] - Class.utilities.UPGRADES_TIER_0 = ["developer", "levels", "teams", "eggGenerator", "spectator", "wallPlacer", "lavenderspawner"] - Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "doubleFlail", "mace", "flangle", "winsor0", "volute", "tetraGunner", "sidewinder", "marksman", "basicCeption", "mirrorBackShield"] + Class.utilities.UPGRADES_TIER_0 = ["developer", "levels", "teams", "eggGenerator", "spectator", "wallPlacer", "lavenderspawner", "solariospawner"] + Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "doubleFlail", "mace", "flangle", "winsor0", "volute", "tetraGunner", "sidewinder", "marksman", "basicCeption", "mirrorBackShield", "auto2", "bascrid", "autoBasic", "auraBasic"] Class.sidewinder.UPGRADES_TIER_3 = ["coil", "oroboros", "cocci", "ranch", "python"] Class.marksman.UPGRADES_TIER_3 = ["deadeye", "nimrod", "revolver", "fork"] Class.volute.UPGRADES_TIER_3 = ["sidewinderOld"] @@ -4415,7 +4454,7 @@ Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons Class.whirlwind.UPGRADES_TIER_3 = ["hexaWhirl", "munition", "whirl3", "whirlGuard",/* "prophet",*/ "vortex"] Class.tornado.UPGRADES_TIER_3 = ["megaTornado", "tempest", "thunderbolt"] Class.hurricane.UPGRADES_TIER_3 = ["typhoon", "blizzard"] - Class.testing.UPGRADES_TIER_0 = ["tanks", "vanquisher", "mummifier", "tracker3", ["grappletest", "basic"], "grappletest2", "dasher"] + Class.testing.UPGRADES_TIER_0 = ["tanks", "vanquisher", "mummifier", "tracker3", ["grappletest", "basic"], "grappletest2", "dasher", "ak47"] Class.dominators.UPGRADES_TIER_0 = ["AIT", "destroyerDominator", "gunnerDominator", "trapperDominator"] Class.sanctuaries.UPGRADES_TIER_0 = ["AIT", "sanctuaryTier1", "sanctuaryTier2", "sanctuaryTier3", "sanctuaryTier4", "sanctuaryTier5", "sanctuaryTier6"] @@ -4432,7 +4471,7 @@ Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons Class.devBosses.UPGRADES_TIER_0 = ["taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss", "AEMKShipBoss", "helenaBoss"] Class.features.UPGRADES_TIER_0 = ["tanks", "diamondShape", "rotatedTrap", "colorMan", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "radialAutoTest", "makeAutoTest", "imageShapeTest", "turretStatScaleTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "gunBenchmark", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] - Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight", "rayofdeath", "biggerCheese", "kivaship", "blaster", "trapperdesmos"] + Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight", "rayofdeath", "biggerCheese", "kivaship", "blaster", "trapperdesmos","brokenanni"] Class.goofytanks.UPGRADES_TIER_0 = ["overpowered", "pisseroo", "papyrus", "Trapper_guy", "watertank", "piszerbeam", "baseThrowerDelta", "pouner", "adsfoipuasdfiopu", "goofywhirlwind", "gettingoverit", "alchem", "stupidpony", "billcipher"] //the "winsor" tank needs this to function, it worked before the "ON" thing was added diff --git a/server/modules/definitions/groups/generics.js b/server/modules/definitions/groups/generics.js index 4476a5fa3..6385fb609 100644 --- a/server/modules/definitions/groups/generics.js +++ b/server/modules/definitions/groups/generics.js @@ -1,4 +1,4 @@ -const { skillSet } = require('../facilitators.js'); +const { skillSet, addAura } = require('../facilitators.js'); const { base, statnames, dfltskl, smshskl } = require('../constants.js'); Class.genericEntity = { @@ -372,6 +372,14 @@ Class.healAura = { DAMAGE: 0.4 / 3, }, }; +Class.auraBasicGen = addAura(1, 1.3); +Class.auraHealerGen = addAura(-1); +Class.auraDamageGen = addAura(2, 1.3, 0.3, "red"); +Class.auraRangeGen = addAura(2, 1.8, 0.3, "teal", "rangeAuraSymbol"); +Class.auraDamageRangeGen = addAura(2, 1.8, 0.3, "red", "rangeAuraSymbol"); +Class.auraMoreDamageGen = addAura(3, 1.3, 0.3, "orange"); +Class.auraMoreRangeGen = addAura(1, 2.3, 0.3, "aqua", "rangeAuraSymbol"); +Class.auraSmasherGen = addAura(11, 1.3); Class.auraSymbol = { PARENT: "genericTank", CONTROLLERS: [["spin", {speed: -0.04}]], diff --git a/server/modules/definitions/groups/projectiles.js b/server/modules/definitions/groups/projectiles.js index 527e50711..3176dc9d3 100644 --- a/server/modules/definitions/groups/projectiles.js +++ b/server/modules/definitions/groups/projectiles.js @@ -10,7 +10,7 @@ Class.splitterBullet = { { POSITION: [8, 8, 1, 0, 0, 90, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), + SHOOT_SETTINGS: combineStats([g.basic, g.repeater]), TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], SHOOT_ON_DEATH: true, } @@ -18,7 +18,7 @@ Class.splitterBullet = { { POSITION: [8, 8, 1, 0, 0, 270, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), + SHOOT_SETTINGS: combineStats([g.basic, g.repeater]), TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], SHOOT_ON_DEATH: true, } @@ -32,7 +32,7 @@ Class.superSplitterBullet = { { POSITION: [8, 8, 1, 0, 0, 90, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), + SHOOT_SETTINGS: combineStats([g.basic, g.repeater]), TYPE: ["splitterBullet", { PERSISTS_AFTER_DEATH: true }], SHOOT_ON_DEATH: true, } @@ -40,7 +40,7 @@ Class.superSplitterBullet = { { POSITION: [8, 8, 1, 0, 0, 270, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), + SHOOT_SETTINGS: combineStats([g.basic, g.repeater]), TYPE: ["splitterBullet", { PERSISTS_AFTER_DEATH: true }], SHOOT_ON_DEATH: true, } @@ -1106,6 +1106,44 @@ Class.empBullet = { } }] } +Class.icetrap = { + PARENT: "trap", + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + TURRETS: [{ + POSITION: [5.5, 0, 0, 0, 0, 1], + TYPE: ["effectBulletDeco", { color: "#28B1DE" }] + }], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + iceOnTick(body, damageTool[0], 1, 1, true); + } + }] +} +Class.setIceTrap = { + PARENT: "setTrap", + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + TURRETS: [{ + POSITION: [5.5, 0, 0, 0, 0, 1], + TYPE: ["effectBulletDeco", { color: "#28B1DE" }] + }], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + iceOnTick(body, damageTool[0], 1, 1, true); + } + }] +} Class.ceptionistbullet = { PARENT: "bullet", GUNS: [{ @@ -1146,6 +1184,7 @@ Class.surgeempBullet = { PARENT: "bullet", HITS_OWN_TYPE: "never", COLOR: "spaceGem", + ALPHA: 0.8, BODY: { }, BORDERLESS: true, @@ -1156,6 +1195,21 @@ Class.surgeempBullet = { RECURSION: 1, } }; +Class.flashfireBullet = { + PARENT: "bullet", + HITS_OWN_TYPE: "never", + COLOR: "#de2410", + ALPHA: 0.8, + BODY: { + }, + BORDERLESS: true, + GLOW: { + RADIUS: 1, + COLOR: "#de2410", + ALPHA: 1, + RECURSION: 1, + } +}; Class.lineEMP = { PARENT: "bullet", LABEL: 'Line', @@ -1231,4 +1285,53 @@ Class.katanaparticle = { POSITION: [25, 15, 0.001, 0, 0, 0, 0] } ], -} \ No newline at end of file +} +Class.shadowparticle = { + LABEL: "kpartic", + ACCEPTS_SCORE: false, + BODY: { + PENETRATION: 1, + SPEED: 3.75, + RANGE: 90, + DENSITY: 1.25, + HEALTH: 10, + DAMAGE: 6, + PUSHABILITY: 0.3, + }, + COLOR: 'mirror', + FACING_TYPE: "toTarget", + CAN_GO_OUTSIDE_ROOM: true, + HITS_OWN_TYPE: "never", + DIE_AT_RANGE: true, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + }, + { + POSITION: [16, 8, 1, 0, 0, 180, 0.1], + } + ], +} +Class.polygunMinion = { + PARENT: "minion", + LABEL: 'Protectorate', + SHAPE: 4, + AI: { + FARMER: true + }, + INDEPENDENT: true, + GUNS: [], + TURRETS: [{ + POSITION: [9, 8, 0, 0, 170, 0], + TYPE: "autoTurret3" + }, { + POSITION: [9, 8, 0, 90, 170, 0], + TYPE: "autoTurret3" + }, { + POSITION: [9, 8, 0, 180, 170, 0], + TYPE: "autoTurret3" + }, { + POSITION: [9, 8, 0, 270, 170, 0], + TYPE: "autoTurret3" + }] +}; \ No newline at end of file diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 72fb47ed2..38dd8e69d 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -7,7 +7,7 @@ const g = require('../gunvals.js'); Class.basic = { PARENT: "genericTank", LABEL: "Basic", - DANGER: 4, + DANGER: 4, SKILL_CAP: Array(10).fill(10), SKILL: Array(10).fill(10), /*BODY: { @@ -20,7 +20,7 @@ Class.basic = { REGEN: base.REGEN * 1, FOV: base.FOV * 1, DENSITY: base.DENSITY * 1, - PUSHABILITY: 1, + PUSHABILITY: 1,3 HETERO: 3 },*/ GUNS: [ @@ -3198,7 +3198,7 @@ Class.repeater = { { POSITION: [20, 10, 0.8, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.repeater]), TYPE: ["splitterBullet", {MOTION_TYPE: "desmos"}] } }, @@ -3536,7 +3536,7 @@ Class.iterator = { { POSITION: [22, 10, 0.8, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.repeater]), TYPE: ["superSplitterBullet", {MOTION_TYPE: "desmos"}] } }, @@ -3997,7 +3997,7 @@ Class.firecracker = { GUNS: [{ POSITION: [17, 13, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, g.halfspeed, { reload: 2.5 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, g.halfspeed, { damage: 0.85, reload: 2.2 }]), TYPE: "firecrackerbomb" } } @@ -4011,7 +4011,7 @@ Class.firecracker = { Class.inception = { PARENT: "genericTank", LABEL: "Inception", - DANGER: 4, + DANGER: 5, GUNS: [ { POSITION: [18, 8, 1, 0, 0, 0, 0], @@ -4030,7 +4030,7 @@ Class.inception = { Class.inceptionist = { PARENT: "genericTank", LABEL: "Ceptionist", - DANGER: 4, + DANGER: 6, GUNS: [ { POSITION: [18, 8, 1, 0, 0, 0, 0], @@ -4049,7 +4049,7 @@ Class.inceptionist = { Class.twinceptionist = { PARENT: "genericTank", LABEL: "Twinceptionist", - DANGER: 4, + DANGER: 7, GUNS: [ { POSITION: [20, 8, 1, 0, 5.5, 0, 0], @@ -4094,7 +4094,7 @@ Class.machinception = { Class.machceptionist = { PARENT: "genericTank", LABEL: "Machceptionist", - DANGER: 4, + DANGER: 7, GUNS: [ { POSITION: [12, 10, 1.4, 8, 0, 0, 0], @@ -4113,6 +4113,7 @@ Class.machceptionist = { Class.flankinception = { PARENT: "genericTank", LABEL: "Flankceptioner", + DANGER: 6, BODY: { SPEED: 1.1 * base.SPEED }, @@ -4131,6 +4132,7 @@ Class.flankinception = { Class.flankceptionist = { PARENT: "genericTank", LABEL: "Flankceptionist", + DANGER: 7, BODY: { SPEED: 1.1 * base.SPEED }, @@ -4149,7 +4151,7 @@ Class.flankceptionist = { Class.flankdue = { PARENT: "genericTank", LABEL: "Flankduer", - DANGER: 5, + DANGER: 6, BODY: { ACCELERATION: base.ACCEL * 0.9, SPEED: base.SPEED * 1.1, @@ -4171,7 +4173,7 @@ Class.flankdue = { Class.tailgator = { PARENT: "genericTank", LABEL: "Tailgator", - DANGER: 4, + DANGER: 6, GUNS: [ { POSITION: [20.5, 12, 1, 0, 0, 0, 0], @@ -4190,7 +4192,7 @@ Class.tailgator = { Class.poundceptionist = { PARENT: "genericTank", LABEL: "PoundCeptionist", - DANGER: 4, + DANGER: 7, GUNS: [ { POSITION: [20.5, 12, 1, 0, 0, 0, 0], @@ -4209,7 +4211,7 @@ Class.poundceptionist = { Class.interceptor = { PARENT: "genericTank", LABEL: "Interceptor", - DANGER: 4, + DANGER: 7, GUNS: [ { POSITION: [21, 14, 1, 0, 0, 0, 0], @@ -4246,7 +4248,10 @@ Class.revolutionist = { Class.proton = { PARENT: "genericTank", LABEL: "Proton", - DANGER: 6, + DANGER: 7, + BODY: { + SPEED: 4 * base.SPEED + }, GUNS: [{ POSITION: [20, 8, 1, 0, 0, 0, 0], PROPERTIES: { @@ -4264,7 +4269,7 @@ Class.proton = { Class.baseThrower = { PARENT: "genericTank", LABEL: "Kivaaritehdas", - DANGER: 6, + DANGER: 7, SYNC_TURRET_SKILLS: true, GUNS: [{ POSITION: [20, 8, 1, 0, 0, 0, 0.2], @@ -4296,7 +4301,7 @@ Class.baseThrower = { Class.baseThrowerFire = { PARENT: "genericTank", LABEL: "Kivaaritehdas", - DANGER: 6, + DANGER: 7, GUNS: [{ POSITION: [20, 8, 1, 0, 0, 0, 0.2], PROPERTIES: { @@ -4308,7 +4313,7 @@ Class.baseThrowerFire = { Class.subverter = { PARENT: "genericTank", LABEL: "Subverter", - DANGER: 6, + DANGER: 7, GUNS: [{ POSITION: [20, 8, 1, 0, 0, 0, 0], PROPERTIES: { @@ -4326,7 +4331,7 @@ Class.subverter = { Class.pion = { PARENT: "genericSmasher", LABEL: "Pion", - DANGER: 6, + DANGER: 7, BODY: { SPEED: 2.5 * base.SPEED }, @@ -4342,7 +4347,7 @@ Class.pion = { Class.equilibrium = { PARENT: "genericTank", LABEL: "Equilibrium", - DANGER: 6, + DANGER: 7, GUNS: [ { POSITION: [20, 8, 1, 0, 5.5, 0, 0], @@ -4368,7 +4373,7 @@ Class.equilibrium = { Class.hadron = { PARENT: "genericTank", LABEL: "Hadron", - DANGER: 6, + DANGER: 7, GUNS: [{ POSITION: [20, 8, 1, 0, 0, 0, 0], PROPERTIES: { @@ -4386,6 +4391,8 @@ Class.hadron = { Class.hivemind = { PARENT: "genericTank", LABEL: "Hivemind", + DANGER: 7, + STAT_NAMES: statnames.mixed, //CONTROLLERS: ['nearestDifferentMaster'], GUNS: [ { @@ -4408,7 +4415,7 @@ Class.hivemind = { { POSITION: [0, 20, 1, 0, 0, 270, 3.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 5 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 10 }]), TYPE: "hiveprobe", MAX_CHILDREN: 1, WAIT_TO_CYCLE: true @@ -4424,22 +4431,22 @@ Class.hivemind = { ] }; Class.cloner = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Cloner", - //CONTROLLERS: ['nearestDifferentMaster'], + STAT_NAMES: statnames.mixed, GUNS: [ { /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ POSITION: [18, 8, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.cloner, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.cloner]), TYPE: "bullet" } }, { - POSITION: [0, 20, 1, 0, 0, 180, 3], + POSITION: [0, 20, 1, 0, 0, 270, 3.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 5 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 10 }]), TYPE: "clonerprobe", MAX_CHILDREN: 1, WAIT_TO_CYCLE: true @@ -4455,10 +4462,10 @@ Class.cloner = { ] }; Class.dictator = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Dictator", STAT_NAMES: statnames.drone, - DANGER: 5, + DANGER: 7, SHAPE: 8, BODY: { ACCELERATION: base.ACCEL * 0.75, @@ -4500,7 +4507,7 @@ Class.littleHunter = { }; Class.subway = makeBird({ PARENT: "genericTank", - DANGER: 5, + DANGER: 7, BODY: { ACCELERATION: base.ACCEL * 0.9, FOV: 1.05 @@ -4521,7 +4528,8 @@ Class.subway = makeBird({ }, "Subway") Class.cockatiel = makeBird({ PARENT: "genericTank", - DANGER: 5, + DANGER: 7, + STAT_NAMES: statnames.mixed, BODY: { ACCELERATION: base.ACCEL * 0.9, FOV: 1.05 @@ -4582,6 +4590,7 @@ Class.twincontagion = { PARENT: "genericTank", LABEL: "Contagiwark", DANGER: 7, + STAT_NAMES: statnames.mixed, GUNS: [{ POSITION: [19, 5.5, 1, 0, -5.5, -8, 0.2], PROPERTIES: { @@ -4665,7 +4674,7 @@ Class.bigSubduer = { LABEL: 'Mitochondrion', DANGER: 7, BODY: { - ACCELERATION: base.ACCEL * .9, + ACCELERATION: base.ACCEL * 0.9, FOV: 1.1 }, GUNS: [{ @@ -4693,7 +4702,7 @@ Class.clubbin = { LABEL: "Clubbin", DANGER: 7, BODY: { - ACCELERATION: base.ACCEL * .9, + ACCELERATION: base.ACCEL * 0.9, FOV: 1.1 }, GUNS: weaponArray([{ @@ -4792,7 +4801,7 @@ Class.accelminigun = { } Class.railgun = { PARENT: "genericTank", - DANGER: 6, + DANGER: 7, LABEL: "Railgun", BODY: { SPEED: 0.9 * base.SPEED, @@ -4837,11 +4846,10 @@ Class.railgun = { Class.skater = { PARENT: "genericSmasher", LABEL: "Skater", - DANGER: 6, + DANGER: 7, BODY: { SPEED: base.SPEED * 2.3, }, - TURRETS: [ { POSITION: [21.5, 0, 0, 0, 360, 0], @@ -5115,7 +5123,7 @@ Class.wyrm = { LABEL: "Wyrm", DANGER: 7, FACING_TYPE: "locksFacing", - STAT_NAMES: statnames.swarm, + STAT_NAMES: statnames.mixed, BODY: { FOV: 1.2 * base.FOV, }, @@ -5323,7 +5331,7 @@ Class.icegun = { Class.frostbite = { PARENT: "genericTank", LABEL: 'Frostbite', - DANGER: 6, + DANGER: 7, GLOW: { RADIUS: 2, COLOR: "#28dead", @@ -5382,7 +5390,7 @@ Class.chiller = { }; Class.freezer = { PARENT: "genericTank", - DANGER: 6, + DANGER: 7, LABEL: "Freezer", GLOW: { RADIUS: 2, @@ -5416,7 +5424,7 @@ Class.helecopter = { PARENT: "genericTank", LABEL: "Attack Helicopter", BODY: { - SPEED: 6, + SPEED: 7, PUSHABILITY: 0, ACCELERATION: 0.8, }, @@ -5469,12 +5477,10 @@ Class.helecopter = { Class.twinsniper = { PARENT: "genericTank", LABEL: "Twiper", - DANGER: 7, + DANGER: 6, BODY: { FOV: 1.1 * base.FOV }, - CONTROLLERS: ["zoom"], - TOOLTIP: "Hold right click to zoom.", GUNS: [ { POSITION: [24, 8.5, 1, 0, 5.5, 0, 0], @@ -5495,6 +5501,9 @@ Class.twinsniper = { Class.backShield = { PARENT: "genericTank", LABEL: 'BackShield', + BODY: { + SPEED: 2 * base.SPEED + }, DANGER: 6, GUNS: [{ POSITION: [18, 8, 1, 0, 0, 0, 0], @@ -5513,6 +5522,9 @@ Class.bigBackShield = { PARENT: "genericTank", LABEL: 'Mega BackShield', DANGER: 7, + BODY: { + SPEED: 2 * base.SPEED + }, GUNS: [{ POSITION: [18, 8, 1, 0, 0, 0, 0], PROPERTIES: { @@ -5543,10 +5555,24 @@ Class.mirrorBackShield = { VULNERABLE: true }] }; +Class.attacker = { + PARENT: "twin", + LABEL: "Attacker", + DANGER: 7, + BODY: { + SPEED: 2 * base.SPEED + }, + TURRETS: [{ + POSITION: [18, 18, 0, 180, 360, 1], + TYPE: ["backshieldturret", { SHAPE: 12 }], + VULNERABLE: true + }] +} Class.wark = { PARENT: "genericTank", LABEL: "Wark", DANGER: 6, + STAT_NAMES: statnames.trap, GUNS: [{ POSITION: [13, 8, 1, 0, -5.5, -8, 0] }, { @@ -5570,7 +5596,7 @@ Class.wark = { Class.waterfall = { PARENT: "genericTank", LABEL: "Waterfall", - DANGER: 6, + DANGER: 7, GUNS: [ { POSITION: [21, 14, 1, 0, 0, 0, 0], @@ -5614,7 +5640,7 @@ Class.auto2 = { Class.swivel2 = { PARENT: "genericTank", LABEL: "Swivel-2", - DANGER: 5, + DANGER: 6, FACING_TYPE: ["spin", {speed: 0.02}], TURRETS: [{ POSITION: [9, 7, 0, 0, 360, 1], @@ -5627,7 +5653,7 @@ Class.swivel2 = { Class.swivel3 = { PARENT: "genericTank", LABEL: "Swivel-3", - DANGER: 5, + DANGER: 7, FACING_TYPE: ["spin", {speed: 0.02}], TURRETS: [{ POSITION: [9, 7, 0, 0, 360, 1], @@ -5640,6 +5666,25 @@ Class.swivel3 = { TYPE: "swivelAutoGun" }] } +Class.axis4 = { + PARENT: "genericTank", + LABEL: "Axis-4", + DANGER: 7, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [{ + POSITION: [9, 7, 0, 0, 360, 1], + TYPE: "swivelAutoGun" + }, { + POSITION: [9, 7, 0, 180, 360, 1], + TYPE: "swivelAutoGun" + }, { + POSITION: [11, 8, 0, 90, 190, 0], + TYPE: "autoTankGun" + }, { + POSITION: [11, 8, 0, 270, 190, 0], + TYPE: "autoTankGun" + }] +} const timer = (run, duration) => { let timer = setInterval(() => run(), 31.25); setTimeout(() => { @@ -5670,7 +5715,7 @@ const iceOnTick = (body, instance, multiplier, duration, hitsOwnTeam) => { Class.acidsmasher = { PARENT: "genericSmasher", LABEL: "Injector", - DANGER: 6, + DANGER: 7, TURRETS: [ { POSITION: [21.8, 0, 0, 0, 360, 0], @@ -5759,7 +5804,7 @@ Class.surge = { break; case 3: body.guns[0].recoilVelocity = 0; - body.guns[0].shootSettings = combineStats([g.basic, { health: 2, pen: 2.5, speed: 3, maxSpeed: 3, size: 1.2, range: 0.5, recoil: 5 }, g.tonsmorerecoil, g.noSpread]); + body.guns[0].shootSettings = combineStats([g.basic, { health: 2, pen: 2.5, speed: 3, maxSpeed: 3, size: 1.2, range: 0.5, recoil: 5, damage: 0.3 }, g.tonsmorerecoil, g.noSpread]); body.guns[0].setBulletType('lineEMP'); body.guns[0].fire(); body.variables.firingStage++; @@ -5783,6 +5828,109 @@ Class.surge = { RECURSION: 3, } } +Class.flashfire = { + PARENT: "genericTank", + LABEL: 'Flashfire', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 0.6, + SPEED: base.SPEED * 0.95, + FOV: 1.2 + }, + GUNS: [{ + POSITION: [24, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "bullet", + IGNORES_CANSHOOT_CHECKS: true + } + }, { + POSITION: [0, 0, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, g.lance]), + TYPE: "bullet", + ALT_FIRE: true + } + }], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: ["surgeDeco", { COLOR: "#de2410", MIRROR_MASTER_ANGLE: true }], + }, + ], + VARIABLES: { + surgeMax: 88, + surgeTimer: 0, + firingStage: 1 + }, + ON: [{ + event: "altFire", + handler: ({ body, gun }) => { + if (body.variables.firingStage === 1) body.variables.firingStage = 2 + } + }, { + event: "tick", + handler: ({ body, gun }) => { + //setTimeout(() => sockets.broadcast(body.guns[0].shootSettings.toString()), 500); + switch(body.variables.firingStage) { + case 2: + body.guns[0].canShoot = false; + body.guns[0].shootSettings = combineStats([g.lance, g.emplaser, { health: 0.1, recoil: 0 }]); + body.guns[0].setBulletType('flashfireBullet'); + body.guns[0].fire(); + + body.variables.surgeTimer++; + if (body.variables.surgeTimer === body.variables.surgeMax) { + body.variables.firingStage++; + } + break; + case 3: + body.guns[0].shootSettings = combineStats([g.basic, g.pelleter, { speed: 6, maxSpeed: 6, damage: 1.2, size: 0.65, spray: 2.3, recoil: 1 }]); + body.guns[0].setBulletType('bullet'); + body.guns[0].fire(), + body.guns[0].recoilVelocity = 56; + setTimeout(() => body.guns[0].fire(), 15); + setTimeout(() => body.guns[0].fire(), 30); + setTimeout(() => body.guns[0].fire(), 45); + setTimeout(() => body.guns[0].fire(), 60); + setTimeout(() => body.guns[0].fire(), 75); + setTimeout(() => body.guns[0].fire(), 90); + setTimeout(() => body.guns[0].fire(), 105); + setTimeout(() => body.guns[0].fire(), 120); + setTimeout(() => body.guns[0].fire(), 135); + setTimeout(() => body.guns[0].fire(), 150); + setTimeout(() => body.guns[0].fire(), 165); + setTimeout(() => body.guns[0].fire(), 180); + setTimeout(() => body.guns[0].fire(), 195); + setTimeout(() => body.guns[0].fire(), 210); + setTimeout(() => body.guns[0].fire(), 225); + setTimeout(() => body.guns[0].fire(), 240); + setTimeout(() => body.guns[0].fire(), 255); + setTimeout(() => body.guns[0].fire(), 270); + setTimeout(() => body.guns[0].fire(), 285); + setTimeout(() => body.guns[0].fire(), 300); + body.variables.firingStage++; + break; + case 4: + body.variables.surgeTimer--; + if (body.variables.surgeTimer === 0) { + body.variables.firingStage = 1; + body.guns[0].shootSettings = combineStats([g.basic, g.sniper]); + body.guns[0].setBulletType('bullet'); + body.guns[0].recoilVelocity = 0; + body.guns[0].canShoot = true; + } + break; + } + } + }], + GLOW: { + RADIUS: 1.2, + COLOR: "#de2410", + ALPHA: 1, + RECURSION: 3, + } +} Class.brella = { PARENT: "genericTank", LABEL: "Nero-Brella", @@ -5835,6 +5983,19 @@ Class.lancer = { } ] } +Class.slasher = { + PARENT: "lancer", + LABEL: "Slasher", + DANGER: 7, + BODY: { + SPEED: 2.3 * base.SPEED + }, + TURRETS: [{ + POSITION: [18, 18, 0, 180, 360, 1], + TYPE: ["backshieldturret", { SHAPE: 12 }], + VULNERABLE: true + }] +} Class.lancebrid = makeOver('lancer', "Lancebrid", {count: 1, independent: true, cycle: false}); Class.autolancer = makeAuto('lancer', "Auto-Lancer"); Class.autolancebrid = makeAuto('lancebrid', "Auto-Lancebrid"); @@ -5966,6 +6127,72 @@ Class.katana = { } }] } +Class.shadow = { + PARENT: "propel", + LABEL: "Shadow", + DANGER: 7, + VARIABLES: { + dashes: 3 + }, + BODY: { + HEALTH: 0.9 * base.HEALTH, + SHIELD: 0.9 * base.SHIELD, + DENSITY: 0.7 * base.DENSITY, + }, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 180, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "thruster", + }, + }, { + POSITION: [1, 15, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { size: 1.4, range: 0.09, speed: 0, maxSpeed: 0 }]), + TYPE: "shadowparticle", + ALT_FIRE: true, + IDENTIFIER: "dash" + } + } + ], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "katanaDeco", + }, + ], + ON: [{ + event: "altFire", + handler: ({ body, gun }) => { + if (gun.identifier = "dash") { + if (body.variables.dashes > 0) { + body.variables.dashes -= 1; + if (body.variables.dashes < 1) body.guns[2].canShoot = false; + body.sendMessage(`Dashes: ${body.variables.dashes.toString()}`) + body.x += 200 * Math.cos(body.facing); + body.y += 200 * Math.sin(body.facing); + setTimeout(() => { + if (body.guns[2] !== undefined) { + body.variables.dashes += 1; + body.sendMessage(`Dashes: ${body.variables.dashes.toString()}`) + body.guns[2].canShoot = true; + } + }, 5000); + } + } + } + }] +} Class.dasher = { PARENT: "genericLancer", LABEL: "Dasher", @@ -6024,16 +6251,17 @@ Class.bayonet = { PARENT: "genericLancer", LABEL: "Bayonet", DANGER: 6, + STAT_NAMES: statnames.mixed, BODY: { SPEED: base.SPEED * 1.3, DAMAGE: base.DAMAGE * 0.9 }, - HAS_NO_RECOIL: true, + HAS_NO_RECOIL: false, GUNS: [ { POSITION: [20, 15, 0.001, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + SHOOT_SETTINGS: combineStats([g.basic, g.lance, {recoil: 0}]), TYPE: ["bullet", { ALPHA: 0 }], AUTOFIRE: true, STAT_CALCULATOR: "lancer" @@ -6044,7 +6272,7 @@ Class.bayonet = { }, { POSITION: [13, 7, 1, 0, 0, 0, 0.2], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 1.3, recoil: 0 }]), TYPE: "bullet" } } @@ -6053,7 +6281,7 @@ Class.bayonet = { Class.wakizashi = { PARENT: "genericLancer", LABEL: "Wakizashi", - DANGER: 6, + DANGER: 7, BODY: { SPEED: base.SPEED * 1.3, DAMAGE: base.DAMAGE * 1.1 @@ -6074,7 +6302,7 @@ Class.wakizashi = { }, { POSITION: [13, 7, 1, 0, 0, 0, 0.2], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 1.3, recoil: 0}]), TYPE: "bullet" } } @@ -6089,6 +6317,7 @@ Class.propel = { SHIELD: 0.9 * base.SHIELD, DENSITY: 0.7 * base.DENSITY, }, + DANGER: 5, GUNS: [ { POSITION: [18, 8, 1, 0, 0, 0, 0], @@ -6160,7 +6389,7 @@ Class.assblaster = { POSITION: [17, 12, 1.5, 0, 0, 180, 2.5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster, { reload: 0.4, spray: 2, recoil: 2.8, damage: 0.6, range: 0.35, size: 1.5 }]), - TYPE: "bullet", + TYPE: ["bullet", { ALPHA: 0.5 }], LABEL: "thruster", }, }, @@ -6174,7 +6403,7 @@ Class.rocker = { SHIELD: 0.5 * base.SHIELD, DENSITY: 0.4 * base.DENSITY, }, - DANGER: 6, + DANGER: 7, GUNS: [ { POSITION: [18, 8, 1, 0, 0, 0, 0], @@ -6211,6 +6440,7 @@ Class.jouster = { SHIELD: 0.7 * base.SHIELD, DENSITY: 0.7 * base.DENSITY, }, + STAT_NAMES: statnames.mixed, HAS_NO_RECOIL: false, GUNS: [ { @@ -6245,6 +6475,7 @@ Class.knight = { DENSITY: 0.7 * base.DENSITY, ACCELERATION: 1.8 * base.ACCEL, }, + STAT_NAMES: statnames.mixed, HAS_NO_RECOIL: false, GUNS: [ { @@ -6272,13 +6503,14 @@ Class.knight = { Class.fencer = { PARENT: "genericLancer", LABEL: "Fencer", - DANGER: 6, + DANGER: 7, BODY: { HEALTH: 0.7 * base.HEALTH, SHIELD: 0.7 * base.SHIELD, DENSITY: 0.7 * base.DENSITY, DAMAGE: base.DAMAGE * 1.1 }, + STAT_NAMES: statnames.mixed, HAS_NO_RECOIL: false, GUNS: [ { @@ -6306,13 +6538,14 @@ Class.fencer = { Class.arisaka = { PARENT: "genericLancer", LABEL: "Arisaka", - DANGER: 6, + DANGER: 7, BODY: { HEALTH: 0.7 * base.HEALTH, SHIELD: 0.7 * base.SHIELD, DENSITY: 0.7 * base.DENSITY, DAMAGE: base.DAMAGE * 1.1 }, + STAT_NAMES: statnames.mixed, HAS_NO_RECOIL: false, GUNS: [ { @@ -6329,7 +6562,7 @@ Class.arisaka = { }, { POSITION: [13, 7, 1, 0, 0, 0, 0.2], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + SHOOT_SETTINGS: combineStats([g.basic, { reload: 1.3, recoil: 0 }]), TYPE: "bullet" } }, @@ -6364,10 +6597,11 @@ Class.saturn = { } ], } - Class.choker = { - PARENT: "genericTank", - LABEL: "Choker", - DANGER: 6, +Class.choker = { + PARENT: "genericTank", + LABEL: "Choker", + DANGER: 7, + STAT_NAMES: statnames.mixed, GUNS: [ { POSITION: [14, 12, 0.8, 0, 0, 0, 0], @@ -6481,104 +6715,1368 @@ Class.radon = { PARENT: "directdrive", LABEL: "Radon", DANGER: 7, - BODY: { - ACCELERATION: base.ACCEL * 2, - SPEED: base.SPEED * 1.8 - }, - TURRETS: [{ - POSITION: [14, 0, 0, 0, 360, 2], - TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + BODY: { + ACCELERATION: base.ACCEL * 2, + SPEED: base.SPEED * 1.8 + }, + TURRETS: [{ + POSITION: [14, 0, 0, 0, 360, 2], + TYPE: ["turretBasenoguns", { COLOR: "#a2c4fc" }], + }, { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "overdriveDeco", + }, + ], +} +Class.accelmachinegun = { + PARENT: "genericTank", + LABEL: "Machine Gun", + GUNS: [ + { + POSITION: [8, .1, -54, 19, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.fake]), + TYPE: "bullet", + COLOR: 12 + } + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.rainmaker]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + } + } + ] +} +Class.gatlinggun = { + PARENT: "genericTank", + LABEL: "Gatling Gun", + DANGER: 6, + GUNS: [{ + POSITION: [14, 10, 1.3, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal]), + TYPE: "bullet", + }, + }, + ], +} +Class.accelgatlinggun = { + PARENT: "genericTank", + LABEL: "Charger", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2 + }, + GUNS: [ + { + POSITION: [8, .1, -54, 21, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal, g.fake]), + TYPE: "bullet", + COLOR: 12 + } + }, + { + POSITION: [14, 10, 1.3, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal, g.rainmaker]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + }, + }, + ] +} +Class.Gatlinception = { + PARENT: "genericTank", + LABEL: "Gatceptioner", + DANGER: 7, + GUNS: [ +{ + POSITION: [14, 10, 1.3, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal]), + TYPE: "autobullet", + }, + }, + ], + TURRETS: [{ + POSITION: [6.5, 22, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.Sprayinception = { + PARENT: "genericTank", + LABEL: "Sprayceptioner", + DANGER: 7, + GUNS: [ + { + POSITION: [23, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.lowPower, g.pelleter, { recoil: 1.15 }]), + TYPE: "bullet" + } + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "autobullet" + } + }, + ], + TURRETS: [{ + POSITION: [6.5, 20, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.polygun = { + PARENT: "genericTank", + LABEL: 'Software', + SHAPE: 8, + DANGER: 7, + STAT_NAMES: statnames.mixed, + BODY: { + SPEED: base.SPEED * 0.8, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [5, 16.5, 1, 10.5, 0, 180, 0] + }, { + POSITION: [2, 19.5, 1.01, 15.5, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { health: 0.9 }]), + TYPE: "polygunMinion", + STAT_CALCULATOR: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + MAX_CHILDREN: 1 + } + }, { + POSITION: [12, 19.5, 1, 0, 0, 180, 0] + }] +}; +Class.ak47 = { + PARENT: "genericTank", + LABEL: "AK-47", + DANGER: 7, + GUNS: [ + { + POSITION: [22, 2, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.power, { reload: 1.25, speed: 1.1, maxSpeed: 1.1, damage: 0.5, health: 1.3, pen: 1.4 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [5.5, 7, -1.8, 6.5, 0, 0, 0], + }, + ], +} +Class.icetrapper = { + PARENT: "genericTank", + LABEL: "Ice Trapper", + STAT_NAMES: statnames.trap, + DANGER: 6, + GUNS: [ + { + POSITION: { + LENGTH: 15, + WIDTH: 7 + } + }, + { + POSITION: { + LENGTH: 3, + WIDTH: 7, + ASPECT: 1.7, + X: 15 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "icetrap", + STAT_CALCULATOR: "trap" + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + } + ] +} +Class.icebuilder = { + PARENT: "genericTank", + LABEL: "Igloo", + STAT_NAMES: statnames.trap, + DANGER: 7, + BODY: { + SPEED: 0.7 * base.SPEED, + FOV: 1.15 * base.FOV + }, + GUNS: [ + { + POSITION: [18, 12, 1, 0, 0, 0, 0], + }, + { + POSITION: [2, 12, 1.1, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), + TYPE: "setIceTrap", + STAT_CALCULATOR: "block" + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + } + ] +} +Class.icetriTrapper = { + PARENT: "genericTank", + LABEL: "Winter", + DANGER: 7, + STAT_NAMES: statnames.trap, + GUNS: weaponArray([ + { + POSITION: [15, 7, 1, 0, 0, 0, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: "icetrap", + STAT_CALCULATOR: "trap" + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + } + ], 3) +} +Class.icetrapGuard = makeGuard({ + PARENT: "genericTank", + LABEL: "Trap", + STAT_NAMES: statnames.mixed, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + } + ] +}, "Ice Guard", "icetrap") + +Class.icewark = { + PARENT: "genericTank", + LABEL: "Ice Wark", + DANGER: 7, + STAT_NAMES: statnames.trap, + GUNS: [{ + POSITION: [13, 8, 1, 0, -5.5, -8, 0] + }, { + POSITION: [4, 8, 1.7, 13, -5.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.halfrange]), + TYPE: "icetrap", + STAT_CALCULATOR: "trap", + } + }, { + POSITION: [13, 8, 1, 0, 5.5, 8, 0.5] + }, { + POSITION: [4, 8, 1.7, 13, 5.5, 8, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.halfrange]), + TYPE: "icetrap", + STAT_CALCULATOR: "trap", + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + }] +} + +Class.icecontagion = { + PARENT: "genericTank", + LABEL: 'Hypothermia', + DANGER: 7, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [13, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [4, 8, 1.7, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "icetrap", + STAT_CALCULATOR: "trap", + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + }] +}; +Class.miniVulc = { + PARENT: "genericTank", + LABEL: 'Submachine', + DANGER: 6, + GUNS: [{ + POSITION: [30, 1.5, 1, 0, 2.5, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, -2.5, 0, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, g.doublereload]), + TYPE: "bullet" + } + }, { + POSITION: [12, 10, 1, 0, 0, 0, 0] + }, { + POSITION: [5, 10, 1, 20, 0, 0, 0] + }] +}; +Class.miniVulcTrap = makeGuard("miniVulc", "Holster") +Class.vulcan = { + PARENT: "genericTank", + LABEL: 'Vulcan', + DANGER: 7, + GUNS: [{ + POSITION: [30, 1.5, 1, 0, -4.5, 0, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, -4.5, 0, 0.9], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, 4.5, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, 4.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, -2.5, 0, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, 2.5, 0, 0.3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, 2.5, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, -2.5, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [30, 1.5, 1, 0, 0, 0, 0.7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.vulc, { reload: 1.25, damage: 0.76 }]), + TYPE: "bullet" + } + }, { + POSITION: [12, 16, 1, 0, 0, 0, 0] + }, { + POSITION: [5, 16, 1, 20, 0, 0, 0] + }] +}; + +Class.littleArtillery = { + PARENT: "genericTank", + LABEL: "Minishot", + DANGER: 5, + GUNS: [{ + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + } + }] +}; +// minishot upgrades +Class.littleMortar = { + PARENT: "genericTank", + LABEL: "Biggie-Shot", + DANGER: 6, + GUNS: [{ + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + } + }] +}; +Class.littleTwinArtillery = { + PARENT: "genericTank", + LABEL: "Hewn/2", + DANGER: 6, + GUNS: [{ + POSITION: [17, 3, 1, 0, -8, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 8, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1.05, 0, 5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet", + } + }, { + POSITION: [20, 8, 1.05, 0, -5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet", + } + }] +}; +Class.littleSnipeArtillery = { + PARENT: "genericTank", + LABEL: "Shredder", + DANGER: 6, + GUNS: [{ + POSITION: [19, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [22, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper/*, {damage: 0.75, pen: 0.7, health: 0.9, speed: 0.85, maxSpeed: 0.9}*/]), + TYPE: "bullet", + } + }] +}; +Class.littleMachArtillery = { + PARENT: "genericTank", + LABEL: "Machshot", + DANGER: 6, + GUNS: [{ + POSITION: [17, 3, 1, 0, -5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.35, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "bullet", + } + }] +}; +Class.littleFlankArtillery = { + PARENT: "genericTank", + LABEL: "Trishot", + DANGER: 6, + GUNS: weaponArray([{ + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + } + }], 3) +}; +Class.littleDirectArtillery = { + PARENT: "genericTank", + LABEL: "CEO", + DANGER: 6, + STAT_NAMES: statnames.drone, + GUNS: [{ + POSITION: [12, 3, 1, 0, -5, -8, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [12, 3, 1, 0, 5, 8, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: { + LENGTH: 6, + WIDTH: 11, + ASPECT: 1.3, + X: 7 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: "drone", + MAX_CHILDREN: 4, + WAIT_TO_CYCLE: true + } + }] +}; +Class.littleTrapArtillery = { + PARENT: "genericTank", + LABEL: "Executionist", + DANGER: 6, + STAT_NAMES: statnames.trap, + GUNS: [{ + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: { + LENGTH: 15, + WIDTH: 7 + } + }, { + POSITION: { + LENGTH: 3, + WIDTH: 7, + ASPECT: 1.7, + X: 15 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: "trap" + } + }] +}; +Class.littleSineArtillery = { + PARENT: "genericTank", + LABEL: "CosLock", + DANGER: 6, + STAT_NAMES: statnames.desmos, + GUNS: [{ + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, -4/3, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + TYPE: ["bullet", {CONTROLLERS: ['snake']}] + } + }, { + POSITION: [3.75, 10, 2.125, 1.5, -6.25, 90, 0] + }, { + POSITION: [3.75, 10, 2.125, 1.5, 6.25, -90, 0] + }] +}; +Class.littleSubArtillery = { + PARENT: "genericTank", + LABEL: "Sub-Shot", + DANGER: 6, + GUNS: [{ + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter]), + TYPE: "bullet" + } + }] +}; +Class.littleIncepArtillery = { + PARENT: "genericTank", + LABEL: "Catalyst", + DANGER: 6, + GUNS: [{ + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "autobullet", + } + } + ], + TURRETS: [{ + POSITION: [5.5, 18, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + }] +}; +Class.littlePropArtillery = { + PARENT: "genericTank", + LABEL: "Speedrun", + DANGER: 6, + GUNS: [{ + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + } + }, { + POSITION: [16, 8, 1, 0, 0, 180, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "thruster", + }, + }] +}; +Class.littleLanceArtillery = { + PARENT: "genericTank", + LABEL: "Knife", + STAT_NAMES: statnames.lancer, + DANGER: 6, + GUNS: [{ + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance, { recoil: 0 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true, + STAT_CALCULATOR: "lancer" + } + }, { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }] +}; +// biggie shot upgrades +Class.littleSheller = { + PARENT: "genericTank", + LABEL: "Biggier-Shot", + DANGER: 7, + GUNS: [{ + POSITION: [13, 2, 1, 0, -8, -9, 5/6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [13, 2, 1, 0, 8, 9, 4/6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, -6.5, -8, 3/6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, 2/6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 1/6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + } + }] +} +Class.littleTwinMortar = { + PARENT: "genericTank", + LABEL: "Skewn/2", + DANGER: 7, + GUNS: [{ + POSITION: [15, 2.5, 1, 0, -8.5, -11, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 8.5, 11, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -8, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 8, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1.05, 0, 5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet", + } + }, { + POSITION: [20, 8, 1.05, 0, -5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet", + } + }] +}; +Class.littleSnipeMortar = { + PARENT: "genericTank", + LABEL: "Chainsaw", + DANGER: 7, + GUNS: [{ + POSITION: [17, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [22, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper/*, {damage: 0.75, pen: 0.7, health: 0.9, speed: 0.85, maxSpeed: 0.9}*/]), + TYPE: "bullet", + } + }] +}; +Class.littleMachMortar = { + PARENT: "genericTank", + LABEL: "Machtillery", + DANGER: 7, + GUNS: [{ + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.35, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, {shudder: 1.3, spray: 0.95}]), + TYPE: "bullet", + } + }] +}; +Class.littleFlankMortar = { + PARENT: "genericTank", + LABEL: "Tri-Tillery", + DANGER: 7, + GUNS: weaponArray([{ + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + } + }], 3) +}; +Class.littleDirectMortar = { + PARENT: "genericTank", + LABEL: "MoneyBags", + DANGER: 7, + STAT_NAMES: statnames.drone, + GUNS: [{ + POSITION: [10.5, 2.5, 1, 0, -6.5, -9, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [10.5, 2.5, 1, 0, 6.5, 9, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [12, 3, 1, 0, -5, -8, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [12, 3, 1, 0, 5, 8, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: { + LENGTH: 6, + WIDTH: 11, + ASPECT: 1.3, + X: 7 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: "drone", + MAX_CHILDREN: 4, + WAIT_TO_CYCLE: true + } + }] +}; +Class.littleTrapMortar = { + PARENT: "genericTank", + LABEL: "Vile", + DANGER: 7, + STAT_NAMES: statnames.trap, + GUNS: [{ + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: { + LENGTH: 15, + WIDTH: 7 + } + }, { + POSITION: { + LENGTH: 3, + WIDTH: 7, + ASPECT: 1.7, + X: 15 + }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: "trap" + } + }] +}; +Class.littleDesmosMortar = { + PARENT: "genericTank", + LABEL: "SineLock", + DANGER: 7, + STAT_NAMES: statnames.desmos, + GUNS: [{ + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } }, { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: "overdriveDeco", - }, - ], -} -Class.gatlinggun = { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, -4/3, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + TYPE: ["bullet", {CONTROLLERS: ['snake']}] + } + }, { + POSITION: [3.75, 10, 2.125, 1.5, -6.25, 90, 0] + }, { + POSITION: [3.75, 10, 2.125, 1.5, 6.25, -90, 0] + }] +}; +Class.littleSubMortar = { PARENT: "genericTank", - LABEL: "Gatling Gun", - DANGER: 6, + LABEL: "Mega Sub-Shot", + DANGER: 7, GUNS: [{ - POSITION: [14, 10, 1.3, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal]), - TYPE: "bullet", - }, - }, - ], -} -Class.accelgatlinggun = { + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter]), + TYPE: "bullet" + } + }] +}; +Class.littleIncepMortar = { PARENT: "genericTank", - LABEL: "Charger", + LABEL: "Mechanism", DANGER: 7, - BODY: { - FOV: base.FOV * 1.2 - }, - GUNS: [ - { - POSITION: [8, .1, -54, 21, 0, 0, 0], + GUNS: [{ + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal, g.fake]), + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "autobullet", + } + }] +}; +Class.littlePropMortar = { + PARENT: "genericTank", + LABEL: "Nascar", + DANGER: 7, + GUNS: [{ + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [19, 9, 1.05, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), TYPE: "bullet", - COLOR: 12 - } - }, - { - POSITION: [14, 10, 1.3, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal, g.rainmaker]), - TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] - }, + } + }, { + POSITION: [16, 8, 1, 0, 0, 180, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "thruster", }, - ] -} -Class.Gatlinception = { + }] +}; +Class.littleLanceMortar = { PARENT: "genericTank", - LABEL: "Gatceptioner", + LABEL: "Exacto", DANGER: 7, - GUNS: [ -{ - POSITION: [14, 10, 1.3, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal]), - TYPE: "autobullet", + STAT_NAMES: statnames.lancer, + GUNS: [{ + POSITION: [15, 2.5, 1, 0, -6.5, -8, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [15, 2.5, 1, 0, 6.5, 8, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, -4.5, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 4.5, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance, { recoil: 0 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true, + STAT_CALCULATOR: "lancer" + } + }, { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }] +}; +// hewn/2 upgrades +/*Class.littleTwinArtillery = { + PARENT: "genericTank", + LABEL: "Hewn/2", + DANGER: 6, + GUNS: [{ + POSITION: [17, 3, 1, 0, -8, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: [17, 3, 1, 0, 8, 7, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet" + } + }, { + POSITION: { + LENGTH: 19, + WIDTH: 8, + Y: -2, + ANGLE: -17.5, + DELAY: 0.5 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } }, - ], - TURRETS: [{ - POSITION: [6.5, 22, 0, 0, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.Sprayinception = { - PARENT: "genericTank", - LABEL: "Sprayceptioner", - DANGER: 7, - GUNS: [ { - POSITION: [23, 7, 1, 0, 0, 0, 0], + POSITION: { + LENGTH: 19, + WIDTH: 8, + Y: 2, + ANGLE: 17.5, + DELAY: 0.5 + }, PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.lowPower, g.pelleter, { recoil: 1.15 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), TYPE: "bullet" } }, { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], + POSITION: { + LENGTH: 22, + WIDTH: 8 + }, PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), - TYPE: "autobullet" + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" } - }, - ], - TURRETS: [{ - POSITION: [6.5, 20, 0, 0, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} - - + } + ] +};*/ // Auto tanks Class.autoBasic = makeAuto("basic", "Auto-Basic"); Class.autoTwin = makeAuto("twin", "Auto-Twin"); @@ -6593,6 +8091,7 @@ Class.autolittleHunter = makeAuto("littleHunter", "Duelist") Class.autoinception = makeAuto("inception", "Deployer"); Class.autoauto2 = makeAuto("auto2", "Auto²-2"); Class.autoPropel = makeAuto("propel", "Grazer"); +Class.autolittleArtillery = makeAuto("littleArtillery", "Quesadilla" /* delta wanted this name lmaoo */) Class.autoCloner = makeAuto({ PARENT: "genericTank", GUNS: [ @@ -6652,26 +8151,6 @@ Class.autoUnderseer = makeAuto("underseer", "Plauge"); Class.autoDestroy = makeAuto("destroyer", "Executer"); Class.autoArtillery = makeAuto("artillery", "Bombarder"); Class.autoLaunch = makeAuto("launcher", "Harbinger"); -Class.autoTriTrapper = makeAuto({ - PARENT: "genericTank", - LABEL: "Mini Defender", - DANGER: 6, - SHAPE: 3, - STAT_NAMES: statnames.trap, - GUNS: weaponArray([ - { - POSITION: [12, 7, 1, 0, 0, 60, 0], - }, - { - POSITION: [3, 7, 1.7, 12, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: "trap", - STAT_CALCULATOR: "trap", - } - } - ], 3) -}, "Mini Defender"); Class.autoTrapGuard = makeAuto("trapGuard", "Ducker"); Class.autoSidewinder = makeAuto("sidewinder", "Auto-Sidewinder"); Class.autoHelix = makeAuto("helix", "DNA"); @@ -6687,6 +8166,20 @@ Class.autochasseur = makeAuto('chasseur', "Auto-Chasseur"); Class.autobayonet = makeAuto('bayonet', "Auto-Bayonet"); Class.autoGatlinggun = makeAuto("gatlinggun", "A-Gatling Gun"); Class.autowark = makeAuto("wark", "WaWark"); +Class.autoIcetrapper = makeAuto("icetrapper", "Auto Ice Trapper"); +Class.autolittleMortar = makeAuto("littleMortar"); +Class.autolittleTwinArtillery = makeAuto("littleTwinArtillery"); +Class.autolittleSnipeArtillery = makeAuto("littleSnipeArtillery"); +Class.autolittleMachArtillery = makeAuto("littleMachArtillery"); +Class.autolittleFlankArtillery = makeAuto("littleFlankArtillery"); +Class.autolittleDirectArtillery = makeAuto("littleDirectArtillery"); +Class.autolittleTrapArtillery = makeAuto("littleTrapArtillery"); +Class.autolittleSineArtillery = makeAuto("littleSineArtillery"); +Class.autolittleSubArtillery = makeAuto("littleSubArtillery"); +Class.autolittleIncepArtillery = makeAuto("littleIncepArtillery"); +Class.autolittlePropArtillery = makeAuto("littlePropArtillery"); +Class.autolittleLanceArtillery = makeAuto("littleLanceArtillery"); +Class.autominiVulc = makeAuto("miniVulc", "M-61"); Class.autoSmasher = makeAuto({ PARENT: "genericSmasher", DANGER: 6, @@ -6771,7 +8264,7 @@ Class.sidewinderbrid = makeOver('sidewinder', "Sidewinderbrid", {count: 1, indep Class.undertowbrid = makeOver('undertow', "Pullist", {count: 1, independent: true, cycle: false}) Class.repeaterbrid = makeOver('repeater', "Comparator", {count: 1, independent: true, cycle: false}) Class.inceptionistbrid = makeOver('inceptionist', "Inceptionistbrid", {count: 1, independent: true, cycle: false}) -Class.machinceptionbrid = makeOver('machinception', "Machinceptibrid", {count: 1, independent: true, cycle: false}) +Class.machinceptionbrid = makeOver('machinception', "MachinceptibriDd", {count: 1, independent: true, cycle: false}) Class.tailgatorbrid = makeOver('tailgator', "Tailgatorbrid", {count: 1, independent: true, cycle: false}) Class.flankinceptionbrid = makeOver('flankinception', "Flankinceptibrid", {count: 1, independent: true, cycle: false}) Class.bateaubrid = makeOver('bateau', "Kayak", {count: 1, independent: true, cycle: false}) @@ -6782,7 +8275,20 @@ Class.chasseubrid = makeOver('chasseur', "Chasseubrid", {count: 1, independent: Class.backshieldbrid = makeOver('backShield', "Fireblanket", {count: 1, independent: true, cycle: false}) Class.gatlinggunbrid = makeOver('gatlinggun', "H-Gatling Gun", {count: 1, independent: true, cycle: false}) Class.warkbrid = makeOver('wark', "Waarrk", {count: 1, independent: true, cycle: false}) - +Class.icetrapbrid = makeOver('icetrapper', "Ice Trapper Brid", {count: 1, independent: true, cycle: false}) +Class.littleArtillerybrid = makeOver('littleArtillery', "Minishotbrid", {count: 1, independent: true, cycle: false}) +Class.littleMortarbrid = makeOver('littleMortar', "Biggieshotbrid", {count: 1, independent: true, cycle: false}) +Class.littleTwinArtillerybrid = makeOver('littleTwinArtillery', "Hewn/2brid", {count: 1, independent: true, cycle: false}) +Class.littleSnipeArtillerybrid = makeOver('littleSnipeArtillery', "Shredderbrid", {count: 1, independent: true, cycle: false}) +Class.littleMachArtillerybrid = makeOver('littleMachArtillery', "Machshotbrid", {count: 1, independent: true, cycle: false}) +Class.littleFlankArtillerybrid = makeOver('littleFlankArtillery', "Trishotbrid", {count: 1, independent: true, cycle: false}) +Class.littleTrapArtillerybrid = makeOver('littleTrapArtillery', "Executionistbrid", {count: 1, independent: true, cycle: false}) +Class.littleSineArtillerybrid = makeOver('littleSineArtillery', "Coslockbrid", {count: 1, independent: true, cycle: false}) +Class.littleSubArtillerybrid = makeOver('littleSubArtillery', "Sub-shotbrid", {count: 1, independent: true, cycle: false}) +Class.littleIncepArtillerybrid = makeOver('littleIncepArtillery', "Catalystbrid", {count: 1, independent: true, cycle: false}) +Class.littlePropArtillerybrid = makeOver('littlePropArtillery', "Speedrunbrid", {count: 1, independent: true, cycle: false}) +Class.littleLanceArtillerybrid = makeOver('littleLanceArtillery', "Knifebrid", {count: 1, independent: true, cycle: false}) +Class.miniVulcbrid = makeOver('miniVulc', "Crowd Control", {count: 1, independent: true, cycle: false}) //auto hybrid tanks Class.autotwinbrid = makeOver('autoTwin', "Auto-Twinbrid", {count: 1, independent: true, cycle: false}) @@ -6796,6 +8302,7 @@ Class.autobascrid = makeOver('autoBasic', "Auto-Basebrid", {count: 1, independen Class.autoinceptionbrid = makeOver('autoinception', "Deployerbrid", {count: 1, independent: true, cycle: false}) Class.autolittleHunterbrid = makeOver('autolittleHunter', "Auto-Subbrid", {count: 1, independent: true, cycle: false}) Class.autopropelbrid = makeOver('autoPropel', "Grazerbrid", {count: 1, independent: true, cycle: false}) +Class.autolittleArtillerybrid = makeOver('autolittleArtillery', "Quessadilabrid", {count: 1, independent: true, cycle: false}) Class.autoauto2brid = makeOver('autoauto2', "Auto²-2brid", {count: 1, independent: true, cycle: false}) //hybrid drive tanks @@ -6813,6 +8320,7 @@ Class.audi = makeOver('inception', "Audi", {count: 1, independent: true, cycle: Class.mustang = makeOver('propel', "Mustang", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) Class.ferrari = makeOver('auto2', "Ferrari", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) Class.ram = makeOver('lancer', "Ram", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.chrysler = makeOver('littleArtillery', "Chrysler", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) //Ceptions Class.basicCeption = makeCeption('basic', "Basiception"); @@ -6831,6 +8339,7 @@ Class.propelCeption = makeCeption('propel', "Propeleception"); Class.lancerception = makeAuto('lancer', "Lanceception"); Class.auto2Ception = makeCeption('auto2', "Auto-2²"); Class.revoception = makeCeption('revolutionist', "revonception"); +Class.littleArtilleryCeption = makeCeption('littleArtillery', "Shotception") //Trackers Class.trackerSmasher = makeAuto('smasher', "Scanner", {type: 'tracker3gun'}); @@ -6841,8 +8350,9 @@ Class.trackerMini = makeAuto('minigun', "Scout", {type: 'tracker3gun'}); Class.trackerRifle = makeAuto('rifle', "DMR", {type: 'tracker3gun'}); Class.trackerTwinsniper = makeAuto('twinsniper', "Bolt Action", {type: 'tracker3gun'}); Class.trackerSniperHybrid = makeAuto('snipebrid', "Camper", {type: 'tracker3gun'}); -Class.trackerAcid = makeAuto('acid', "Acidilizer", {type: 'tracker3gun'}); -Class.trackerChill = makeAuto('chiller', "Icilizer", {type: 'tracker3gun'}); +Class.trackerAcid = makeAuto('acid', "Arsenic", {type: 'tracker3gun'}); +Class.trackerChill = makeAuto('chiller', "Devils Breath", {type: 'tracker3gun'}); +Class.trackerSnipeArtillery = makeAuto('littleSnipeArtillery', "U.A.V.", {type: 'tracker3gun'}); //Homing Auto Tanks Class.homingautoBasic = makeAuto("basic", "Homing Auto-Basic", {type: 'homingAutoTurret'}); @@ -6860,6 +8370,7 @@ Class.homingautoinception = makeAuto("inception", "Homing Deployer", {type: 'hom Class.homingautopropel = makeAuto("propel", "Homing Grazer", {type: 'homingAutoTurret'}); Class.homingautoauto2 = makeAuto("auto2", "Homing Auto²-2", {type: 'homingAutoTurret'}); Class.homingautolancer = makeAuto("lancer", "Homing Lancer", {type: 'homingAutoTurret'}); +Class.homingautolittleArtillery = makeAuto("littleArtillery", "Taco", {type: 'homingAutoTurret'}) //Auras Class.auraBasic = makeAura(Class.basic); @@ -6877,6 +8388,7 @@ Class.auraInception = makeAura(Class.inception); Class.auraPropel = makeAura(Class.propel); Class.auraDesmos = makeAura(Class.desmos); Class.auraAuto2 = makeAura(Class.auto2); +Class.auraLittleArtillery = makeAura(Class.littleArtillery); Class.auraSmasher = makeAura(Class.smasher); Class.damageAuraBasic = makeAura(Class.basic, "Omen Basic", {type: 'auraDamageGen'}); @@ -6891,10 +8403,11 @@ Class.damageAuraAutoBasic = makeAura(Class.autoBasic, "Omen Auto-Basic", {type: Class.damageAuraBascrid = makeAura(Class.bascrid, "Omen Basebrid", {type: 'auraDamageGen'}); Class.damageAuraLittleHunter = makeAura(Class.littleHunter, "Omen Subduer", {type: 'auraDamageGen'}); Class.damageAuraInception = makeAura(Class.inception, "Omen Inception", {type: 'auraDamageGen'}); -Class.damageAuraPropel = makeAura(Class.propel, "Omen Subduer", {type: 'auraDamageGen'}); -Class.damageAuraDesmos = makeAura(Class.desmos, "Omen Propeller", {type: 'auraDamageGen'}); +Class.damageAuraPropel = makeAura(Class.propel, "Omen Propeller", {type: 'auraDamageGen'}); +Class.damageAuraDesmos = makeAura(Class.desmos, "Omen Desmos", {type: 'auraDamageGen'}); Class.damageAuraAuto2 = makeAura(Class.auto2, "Omen Auto-2", {type: 'auraDamageGen'}); Class.damageAuraLancer = makeAura(Class.lancer, "Omen Lancer", {type: 'auraDamageGen'}); +Class.damageAuraLittleArtillery = makeAura(Class.littleArtillery, "Omen Minishot", {type: 'auraDamageGen'}); Class.rangeAuraBasic = makeAura(Class.basic, "Mega-Aura Basic", {type: 'auraRangeGen'}); Class.rangeAuraTwin = makeAura(Class.twin, "Mega-Aura Twin", {type: 'auraRangeGen'}); @@ -6912,14 +8425,17 @@ Class.rangeAuraPropel = makeAura(Class.propel, "Mega-Aura Propeller", {type: 'au Class.rangeAuraDesmos = makeAura(Class.desmos, "Mega-Aura Desmos", {type: 'auraRangeGen'}); Class.rangeAuraAuto2 = makeAura(Class.auto2, "Mega-Aura Auto-2", {type: 'auraRangeGen'}); Class.rangeAuraLancer = makeAura(Class.lancer, "Mega-Aura Lancer", {type: 'auraRangeGen'}); +Class.rangeAuraLittleArtillery = makeAura(Class.littleArtillery, "Mega-Aura Minishot", {type: 'auraRangeGen'}); Class.damagerangeAuraBasic = makeAura(Class.basic, "Mega-Omen Basic", {type: 'auraDamageRangeGen'}); Class.moredamageAuraBasic = makeAura(Class.basic, "X-Omen Basic", {type: 'auraMoreDamageGen'}); Class.morerangeAuraBasic = makeAura(Class.basic, "X-Mega-Aura Basic", {type: 'auraMoreRangeGen'}); +//Twin Class.auraDoubleTwin = makeAura(Class.doubleTwin); Class.auraTripleShot = makeAura(Class.tripleShot); +//Snipe Class.auraAssassin = makeAura(Class.assassin); Class.auraHunter = makeAura(Class.hunter); Class.auraRifle = makeAura(Class.rifle); @@ -6928,16 +8444,20 @@ Class.auraTwinSniper = makeAura(Class.twinsniper); Class.auraAcid = makeAura(Class.acid); Class.auraChiller = makeAura(Class.chiller); +//Mach Class.auraMinigun = makeAura(Class.minigun); Class.auraGunner = makeAura(Class.gunner); Class.auraSprayer = makeAura(Class.sprayer); Class.auraGatlinggun = makeAura(Class.gatlinggun); +Class.auraMiniVulc = makeAura(Class.miniVulc); +//Flank Class.auraHexaTank = makeAura(Class.hexaTank); Class.auraTriAngle = makeAura(Class.triAngle); Class.auraAuto3 = makeAura(Class.auto3); Class.auraBackShield = makeAura(Class.backShield); +//drone Class.auraOverseer = makeAura(Class.overseer); Class.auraCruiser = makeAura(Class.cruiser); Class.auraUnderseer = makeAura(Class.underseer); @@ -6945,15 +8465,19 @@ Class.auraSpawner = makeAura(Class.spawner); Class.auraDirectdrive = makeAura(Class.directdrive); Class.auraNoble = makeAura(Class.noble); +//pound Class.auraDestroyer = makeAura(Class.destroyer); Class.auraArtillery = makeAura(Class.artillery); Class.auraLauncher = makeAura(Class.launcher); +//trap Class.auraBuilder = makeAura(Class.builder); Class.auraTriTrapper = makeAura(Class.triTrapper); Class.auraTrapGuard = makeAura(Class.trapGuard); Class.auraWark = makeAura(Class.wark); +Class.auraIceTrapper = makeAura(Class.icetrapper); +//Auto Class.auraAutoTwin = makeAura(Class.autoTwin); Class.auraAutoSniper = makeAura(Class.autoSniper); Class.auraAutoMach = makeAura(Class.autoMach); @@ -6967,10 +8491,12 @@ Class.auraAutoLittleHunter = makeAura(Class.autolittleHunter); Class.auraAutoInception = makeAura(Class.autoinception); Class.auraAutoAuto2 = makeAura(Class.autoauto2); Class.auraAutoLancer = makeAura(Class.autolancer); -Class.auraAutoPropel = makeAura(Class.propel); +Class.auraAutoPropel = makeAura(Class.autoPropel); +Class.auraAutoLittleArtillery = makeAura(Class.autolittleArtillery); Class.auraBasicCeption = makeAura(Class.basicCeption); Class.auraHomingautoBasic = makeAura(Class.homingautoBasic); +//Brid Class.auratwinbrid = makeAura(Class.twinbrid); Class.aurasnipebrid = makeAura(Class.snipebrid); Class.auramachbrid = makeAura(Class.machbrid); @@ -6984,72 +8510,95 @@ Class.aurainceptionbrid = makeAura(Class.inceptionbrid); Class.aurapropelbrid = makeAura(Class.auto2brid); Class.auraauto2brid = makeAura(Class.auto2brid); Class.auralancebrid = makeAura(Class.lancebrid); +Class.auralittleartillerybrid = makeAura(Class.littleArtillerybrid) Class.jeep = makeAura(Class.car, "Jeep"); +//Sub Class.auraBinary = makeAura(Class.binary); Class.auraContagion = makeAura(Class.contagion); Class.auraGundirector = makeAura(Class.gundirector); Class.auraBigSubduer = makeAura(Class.bigSubduer); Class.auraFlankdue = makeAura(Class.flankdue); +//Incep Class.auraInceptionist = makeAura(Class.inceptionist) Class.auraMachinception = makeAura(Class.machinception); Class.auraTailgator = makeAura(Class.tailgator); Class.auraFlankinception = makeAura(Class.flankinception); +//Desmos Class.auraSidewinder = makeAura(Class.sidewinder); Class.auraHelix = makeAura(Class.helix); Class.auraUndertow = makeAura(Class.undertow); Class.auraRepeater = makeAura(Class.repeater); +//Swivel Class.auraSwivel2 = makeAura(Class.swivel2); +//Lance Class.auraLancer = makeAura(Class.lancer); Class.auraChasseur = makeAura(Class.chasseur); Class.auraBayonet = makeAura(Class.bayonet); +//Prop Class.auraBateau = makeAura(Class.bateau); Class.auraJouster = makeAura(Class.jouster); +Class.auraLittleMortar = makeAura(Class.littleMortar); +Class.auraLittleTwinArtillery = makeAura(Class.littleTwinArtillery); +Class.auraLittleSnipeArtillery = makeAura(Class.littleSnipeArtillery); +Class.auraLittleMachArtillery = makeAura(Class.littleMachArtillery); +Class.auraLittleFlankArtillery = makeAura(Class.littleFlankArtillery); +Class.auraLittleDirectArtillery = makeAura(Class.littleDirectArtillery); +Class.auraLittleTrapArtillery = makeAura(Class.littleTrapArtillery); +Class.auraLittleSineArtillery = makeAura(Class.littleSineArtillery); +Class.auraLittleSubArtillery = makeAura(Class.littleSubArtillery); +Class.auraLittleIncepArtillery = makeAura(Class.littleIncepArtillery); +Class.auraLittlePropArtillery = makeAura(Class.littlePropArtillery); +Class.auraLittleLanceArtillery = makeAura(Class.littleLanceArtillery); + // TANK UPGRADE PATHS -Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", /*"autoBasic", */"desmos", /*"bascrid", */"littleHunter", "inception", "propel", "lancer", "auto2", /*"auraBasic", */"whirlwind"] +Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", /*"autoBasic", */"desmos", /*"bascrid", */"littleHunter", "inception", "propel", "lancer", /*"auto2", "auraBasic", */"whirlwind", "littleArtillery"] Class.basic.UPGRADES_TIER_2 = ["smasher", "cloner"] + Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "landmine", "pion", "trackerSmasher", "saturn", "skater", "acidsmasher", "flail", "autoSmasher", "auraSmasher", "jumpSmasher"] Class.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] Class.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner", "clonebrid"] - Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "helix", "wark", "binary", "twinsniper", "autoTwin", "twinbrid", "auraTwin"] + Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "helix", "wark", "binary", "twinsniper", "littleTwinArtillery", "autoTwin", "twinbrid", "auraTwin"] + Class.twin.UPGRADES_TIER_3 = ["attacker"] Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "bulwark", "autoDouble", "bentDouble", "doubletwinbrid", "auraDoubleTwin"] Class.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentDouble", "triplet", "autoTripleShot", "triplex", "bentHybrid", "trinary", "auraTripleShot"] - Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "twinsniper", "autoSniper", "snipebrid", "trackerSniper", "acid", "chiller", "chasseur", "auraSniper"] - Class.sniper.UPGRADES_TIER_3 = ["bushwhacker"] + Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "twinsniper", "autoSniper", "snipebrid", "trackerSniper", "acid", "chiller", "chasseur", "littleSnipeArtillery", "auraSniper"] + Class.sniper.UPGRADES_TIER_3 = ["bushwhacker", "flashfire"] Class.assassin.UPGRADES_TIER_3 = ["ranger", "xHunter", "falcon", "stalker", "autoAssassin", "assbrid", "trackerAssassin", "disintegrator", "freezer", "auraAssassin", "single"] Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "railgun", "dual", "wakizashi", "autoHunter", "trackerHunter", 'auraHunter'] Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman", "autoRifle", "trackerRifle", "auraRifle"] - Class.trackerSniper.UPGRADES_TIER_3 = ["trackerAssassin", "trackerHunter", "trackerMini", "trackerRifle", "trackerTwinsniper", "trackerSniperHybrid", "trackerAcid", "trackerChill", "auraTrackerSniper"] + Class.trackerSniper.UPGRADES_TIER_3 = ["trackerAssassin", "trackerHunter", "trackerMini", "trackerRifle", "trackerTwinsniper", "trackerSniperHybrid", "trackerAcid", "trackerChill", "trackerSnipeArtillery", "auraTrackerSniper"] Class.twinsniper.UPGRADES_TIER_3 = ["dual", "musket", "autoTwinsniper", "twipebrid", "trackerTwinsniper", "auraTwinSniper"] Class.acid.UPGRADES_TIER_3 = ["disintegrator", "acidsmasher", "formaldehyde", "frostbite", "autoAcid", "acidbrid", "trackerAcid", "auraAcid"] Class.chiller.UPGRADES_TIER_3 = ["freezer", "icegun", "frostbite", "autoChill", "chillbrid", "trackerChill", "auraChiller", "surge"] - Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "gatlinggun", "autoMach", "machbrid", "machinception", "auraMachineGun"] + Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "gatlinggun", "accelmachinegun", "autoMach", "machbrid", "machinception", "miniVulc", "littleMachArtillery", "auraMachineGun"] Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture", "minilaser", "formaldehyde", "icegun", "autoMini", "trackerMini", "accelminigun", "auraMinigun"] Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner", "waterfall", "helecopter", "auraGunner"] Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "Sprayinception", "autoSprayer", "spraybrid", "auraSprayer"] Class.gatlinggun.UPGRADES_TIER_3 = ["focal", "Gatlinception", "accelgatlinggun", "autoGatlinggun", "gatlinggunbrid", "auraGatlinggun"] + Class.miniVulc.UPGRADES_TIER_3 = ["nailgun", "vulcan", "miniVulcTrap", "autominiVulc", "miniVulcbrid", "auraMiniVulc"] - Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank", "flankbrid", "flankdue", /*"flankinception", */"backShield", "auraFlankGuard"] + Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank", "flankbrid", "flankdue", /*"flankinception", */"backShield", "littleFlankArtillery", "auraFlankGuard"] Class.flankGuard.UPGRADES_TIER_3 = ["tripleTwin", "quadruplex"] Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper", "autoHexaTank", "hexatankbrid", "auraHexaTank", "hexaWhirl"] Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "trianglebrid", "surfer", "eagle", "phoenix", "vulture", "subway", "helecopter", "trailblazer", "rocker", "cockatiel", "auraTriAngle"] - Class.backShield.UPGRADES_TIER_3 = ["bigBackShield", "brella", "autoBackShield", "backshieldbrid", "auraBackShield"] + Class.backShield.UPGRADES_TIER_3 = ["bigBackShield", "brella", "slasher", "attacker", "autoBackShield", "backshieldbrid", "auraBackShield"] - Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "gundirector", "spawner", "directdrive", "noble", "autoDirector", "auraDirector"] + Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "gundirector", "spawner", "directdrive", "noble", "autoDirector", "littleDirectArtillery", "auraDirector"] Class.director.UPGRADES_TIER_3 = ["manager", "bigCheese"] Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "trojan", "overdrive", "commander", "helium", "auraOverseer"] Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "surfer", "wyrm", "autoCruiser", "commander", "neon", "auraCruiser"] Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor", "autoUnderseer", "argon", "auraUnderseer"/* "prophet",*/] - Class.spawner.UPGRADES_TIER_3 = ["factory", "protist", "autoSpawner", "xenon", "auraSpawner"] + Class.spawner.UPGRADES_TIER_3 = ["factory", "protist", "polygun", "autoSpawner", "xenon", "auraSpawner"] Class.directdrive.UPGRADES_TIER_3 = ["overdrive", "cruiserdrive", "revodirector", "honda", "dictator", "radon", "autoMotor", "auraDirectdrive"] Class.noble.UPGRADES_TIER_3 = ["helium", "neon", "argon", "krypton", "xenon", "radon", "oganesson", "auraNoble"] @@ -7059,97 +8608,115 @@ Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "di Class.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun", "autoArtillery", "artilbrid", "auraArtillery", "munition"] Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun", "shrapnelgun", "firecracker", "autoLaunch", "launchbrid", "auraLauncher", "vortex"] - Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "wark", "contagion", "autoTrap", "trapbrid", "auraTrapper"] + Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "wark", "contagion", "icetrapper", "autoTrap", "trapbrid", "littleTrapArtillery", "auraTrapper"] Class.trapper.UPGRADES_TIER_3 = ["barricade"] - Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "builderbrid", "auraBuilder"] - Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "triContagion", "autoTriTrapper", "tritrapperbrid", "auraTriTrapper"] - Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "autoTrapGuard", "trapguardbrid", "auraTrapGuard", "whirlGuard"] - Class.wark.UPGRADES_TIER_3 = ["bulwark", "twincontagion", "autowark", "warkbrid", "auraWark"] + Class.builder.UPGRADES_TIER_3 = ["construct", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "icebuilder", "autoBuilder", "builderbrid", "auraBuilder"] + Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "triContagion", "icetriTrapper", "tritrapperbrid", "auraTriTrapper"] + Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "icetrapGuard", "miniVulcTrap", "autoTrapGuard", "trapguardbrid", "auraTrapGuard", "whirlGuard"] + Class.wark.UPGRADES_TIER_3 = ["bulwark", "twincontagion", "icewark", "autowark", "warkbrid", "auraWark"] + Class.icetrapper.UPGRADES_TIER_3 = ["icebuilder", "icetriTrapper", "icetrapGuard", "icewark", "icecontagion", "autoIcetrapper", "icetrapbrid", "auraIceTrapper"] - Class.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "autoDesmos", "autobascrid", "autolittleHunter", "autoinception", "autoPropel", "autolancer", "autoauto2", "auraAutoBasic", "homingautoBasic"] + Class.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "autoDesmos", "autobascrid", "autolittleHunter", "autoinception", "autoPropel", "autolancer", "autoauto2", "autolittleArtillery", "auraAutoBasic", "homingautoBasic"] Class.autoBasic.UPGRADES_TIER_3 = ["autoSmasher", "autoCloner"] - Class.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "equilibrium", "autoBinary", "autoTwinsniper", "autotwinbrid", "auraAutoTwin", "homingautoTwin"] - Class.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "autoTwinsniper", "autoAcid", "autoChill", "autosnipebrid", "autochasseur", "auraAutoSniper", "homingautoSniper"] - Class.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "autoGatlinggun", "automachbrid", "automachinception", "auraAutoMach", "homingautoMach"] - Class.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "autoTriTrapper", "autoflankbrid", "autoFlankdue", "autoflankinception", "auraAutoFlank", "homingautoFlank"] - Class.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoGundirector", "autoSpawner", "auraAutoDirector", "homingautoDirector"] + Class.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "autoHelix", "autowark", "equilibrium", "autoBinary", "autoTwinsniper", "autolittleTwinArtillery", "autotwinbrid", "auraAutoTwin", "homingautoTwin"] + Class.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "autoTwinsniper", "autoAcid", "autoChill", "autosnipebrid", "autochasseur", "autolittleSnipeArtillery", "auraAutoSniper", "homingautoSniper"] + Class.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "autoGatlinggun", "automachbrid", "automachinception", "autolittleMachArtillery", "auraAutoMach", "homingautoMach"] + Class.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "hexaTrapper", "autoflankbrid", "autoFlankdue", "autoflankinception", "autolittleFlankArtillery", "auraAutoFlank", "homingautoFlank"] + Class.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoGundirector", "autoSpawner", "autolittleDirectArtillery", "auraAutoDirector", "homingautoDirector"] Class.autoPound.UPGRADES_TIER_3 = ["autoDestroy", "autoBuilder", "autoArtillery", "autoLaunch", "autopoundbrid", "autotailgator", "auraAutoPound", "homingautoPound"] - Class.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "autoTriTrapper", "autoTrapGuard", "autoContagion", "autotrapbrid", "auraAutoTrap", "homingautoTrap"] - Class.autoDesmos.UPGRADES_TIER_3 = ["autoHelix", "autoUndertow", "autoRepeater", "autodesmosbrid", "auraAutoDesmos", "homingautoDesmos"] - Class.autolittleHunter.UPGRADES_TIER_3 = ["autoMini", "autoBinary", "autoHunter", "autoSprayer", "autoContagion", "autoGundirector", "autoBigSubduer", "autoFlankdue", "autobayonet", "autolittleHunterbrid", "auraAutoLittleHunter", "homingautolittleHunter"] - Class.autoinception.UPGRADES_TIER_3 = ["autoinceptionist", "automachinception", "autotailgator", "autoflankinception", "autoinceptionbrid", "auraAutoInception", "homingautoinception"] - Class.autoPropel.UPGRADES_TIER_3 = ["autoTriAngle", "autoBateau", "autoJouster", "autopropelbrid", "auraAutoPropel", "homingautopropel"] + Class.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "hexaTrapper", "autoTrapGuard", "autoContagion", "autowark", "autoIcetrapper", "autolittleTrapArtillery", "autotrapbrid", "auraAutoTrap", "homingautoTrap", "trapCeption"] + Class.autoDesmos.UPGRADES_TIER_3 = ["autoHelix", "autoUndertow", "autoRepeater", "autodesmosbrid", "autolittleSineArtillery", "auraAutoDesmos", "homingautoDesmos"] + Class.autolittleHunter.UPGRADES_TIER_3 = ["autoMini", "autoBinary", "autoHunter", "autoSprayer", "autoContagion", "autoGundirector", "autoBigSubduer", "autoFlankdue", "autobayonet", "autolittleHunterbrid", "autolittleSubArtillery", "auraAutoLittleHunter", "homingautolittleHunter"] + Class.autoinception.UPGRADES_TIER_3 = ["autoinceptionist", "automachinception", "autotailgator", "autoflankinception", "autoinceptionbrid", "autolittleIncepArtillery", "auraAutoInception", "homingautoinception"] + Class.autoPropel.UPGRADES_TIER_3 = ["autoTriAngle", "autoBateau", "autoJouster", "autopropelbrid", "autolittlePropArtillery", "auraAutoPropel", "homingautopropel"] Class.autoauto2.UPGRADES_TIER_3 = ["autoAuto3", "autoRevolutionist", "autoSwivel2", "autoauto2brid", "auraAutoAuto2", "homingautoauto2"] - Class.autolancer.UPGRADES_TIER_3 = ["autochasseur", "autoJouster", "autobayonet", "autolancebrid", "auraAutoLancer", "homingautolancer"] + Class.autolancer.UPGRADES_TIER_3 = ["autochasseur", "autoJouster", "autobayonet", "autolancebrid", "autolittleLanceArtillery", "auraAutoLancer", "homingautolancer"] Class.basicCeption.UPGRADES_TIER_3 = ["twinCeption", "snipeCeption", "machCeption", "flankCeption", "directCeption", "poundCeption", "trapCeption", "desmosCeption", "bascridCeption", "littleHunterCeption", "inceptCeption", "propelCeption", "lancerception", "auto2Ception", "auraBasicCeption"] - Class.homingautoBasic.UPGRADES_TIER_3 = ["homingautoTwin", "homingautoSniper", "homingautoMach", "homingautoFlank", "homingautoDirector", "homingautoPound", "homingautoTrap", "homingautoDesmos", "homingautobascrid", "homingautolittleHunter", "homingautoinception", "homingautopropel", "homingautolancer", "homingautoauto2", "auraHomingautoBasic"] + Class.homingautoBasic.UPGRADES_TIER_3 = ["homingautoTwin", "homingautoSniper", "homingautoMach", "homingautoFlank", "homingautoDirector", "homingautoPound", "homingautoTrap", "homingautoDesmos", "homingautobascrid", "homingautolittleHunter", "homingautoinception", "homingautopropel", "homingautolancer", "homingautoauto2", "homingautolittleArtillery", "auraHomingautoBasic"] Class.bascrid.UPGRADES_TIER_2 = ["twinbrid", "snipebrid", "machbrid", "flankbrid", "overseer", "poundbrid", "trapbrid", "autobascrid", "desmosbrid", "littleHunterbrid", "inceptionbrid", "lancebrid", "auto2brid", "car", "auraBascrid"] Class.bascrid.UPGRADES_TIER_3 = ["clonebrid"] - Class.twinbrid.UPGRADES_TIER_3 = ["doubletwinbrid", "bentHybrid", "overgunner", "hexatankbrid", "autotwinbrid", "helixbrid", "binarybrid", "twipebrid", "mercedes", "auratwinbrid"] - Class.snipebrid.UPGRADES_TIER_3 = ["assbrid", "poacher", "cropDuster", "armsman", "twipebrid", "autosnipebrid", "trackerSniperHybrid", "acidbrid", "chillbrid", "chasseubrid", "tesla", "aurasnipebrid"] - Class.machbrid.UPGRADES_TIER_3 = ["artilbrid", "cropDuster", "overgunner", "spraybrid", "gatlinggunbrid", "automachbrid", "machinceptionbrid", "toyota", "auramachbrid"] - Class.flankbrid.UPGRADES_TIER_3 = ["hexatankbrid", "trianglebrid", "auto3brid", "trapguardbrid", "tritrapperbrid", "autoflankbrid", "flankduebrid", "flankinceptionbrid", "ford", "auraflankbrid"] + Class.twinbrid.UPGRADES_TIER_3 = ["doubletwinbrid", "bentHybrid", "overgunner", "hexatankbrid", "autotwinbrid", "helixbrid", "warkbrid", "binarybrid", "twipebrid", "littleTwinArtillerybrid", "mercedes", "auratwinbrid"] + Class.snipebrid.UPGRADES_TIER_3 = ["assbrid", "poacher", "cropDuster", "armsman", "twipebrid", "autosnipebrid", "trackerSniperHybrid", "acidbrid", "chillbrid", "chasseubrid", "littleSnipeArtillerybrid", "tesla", "aurasnipebrid"] + Class.machbrid.UPGRADES_TIER_3 = ["artilbrid", "cropDuster", "overgunner", "spraybrid", "gatlinggunbrid", "automachbrid", "machinceptionbrid", "littleMachArtillerybrid", "toyota", "auramachbrid"] + Class.flankbrid.UPGRADES_TIER_3 = ["hexatankbrid", "trianglebrid", "auto3brid", "trapguardbrid", "tritrapperbrid", "autoflankbrid", "flankduebrid", "flankinceptionbrid", "littleFlankArtillerybrid", "ford", "auraflankbrid"] Class.poundbrid.UPGRADES_TIER_3 = ["hybrid", "builderbrid", "artilbrid", "launchbrid", "autopoundbrid", "tailgatorbrid", "honda", "aurapoundbrid"] - Class.trapbrid.UPGRADES_TIER_3 = ["builderbrid", "tritrapperbrid", "trapguardbrid", "contagionbrid", "autotrapbrid", "overtrapper", "gmc", "auratrapbrid"] + Class.trapbrid.UPGRADES_TIER_3 = ["builderbrid", "tritrapperbrid", "trapguardbrid", "contagionbrid", "warkbrid", "icetrapbrid", "autotrapbrid", "overtrapper", "littleTrapArtillerybrid", "gmc", "auratrapbrid"] Class.autobascrid.UPGRADES_TIER_3 = ["autotwinbrid", "autosnipebrid", "automachbrid", "autoflankbrid", "autopoundbrid", "autotrapbrid", "autodesmosbrid", "autolittleHunterbrid", "autoinceptionbrid", "autopropelbrid", "autolancebrid", "porsche", "auraautobascrid"] - Class.desmosbrid.UPGRADES_TIER_3 = ["helixbrid", "undertowbrid", "repeaterbrid", "autodesmosbrid", "mazda", "auradesmosbrid"] - Class.littleHunterbrid.UPGRADES_TIER_3 = ["cropDuster", "binarybrid", "poacher", "spraybrid", "contagionbrid", "bigsubduerbrid", "flankduebrid", "bayonetbrid", "autolittleHunterbrid", "volkswagen", "auralittlehunterbrid"] - Class.inceptionbrid.UPGRADES_TIER_3 = ["trianglebrid", "machinceptionbrid", "tailgatorbrid", "flankinceptionbrid", "overdrive", "autoinceptionbrid", "audi", "aurainceptionbrid"] - Class.propelbrid.UPGRADES_TIER_3 = ["trianglebrid", "bateaubrid", "jousterbrid", "autopropelbrid", "mustang", "aurapropelbrid"] + Class.desmosbrid.UPGRADES_TIER_3 = ["helixbrid", "undertowbrid", "repeaterbrid", "autodesmosbrid", "littleSineArtillerybrid", "mazda", "auradesmosbrid"] + Class.littleHunterbrid.UPGRADES_TIER_3 = ["cropDuster", "binarybrid", "poacher", "spraybrid", "contagionbrid", "bigsubduerbrid", "flankduebrid", "bayonetbrid", "autolittleHunterbrid", "littleSubArtillerybrid", "volkswagen", "auralittlehunterbrid"] + Class.inceptionbrid.UPGRADES_TIER_3 = ["trianglebrid", "machinceptionbrid", "tailgatorbrid", "flankinceptionbrid", "overdrive", "autoinceptionbrid", "littleIncepArtillerybrid", "audi", "aurainceptionbrid"] + Class.propelbrid.UPGRADES_TIER_3 = ["trianglebrid", "bateaubrid", "jousterbrid", "autopropelbrid", "littlePropArtillerybrid", "mustang", "aurapropelbrid"] Class.auto2brid.UPGRADES_TIER_3 = ["auto3brid", "revobrid", "swivel2brid", "autoauto2brid", "ferrari", "auraauto2brid"] - Class.lancebrid.UPGRADES_TIER_3 = ["chasseubrid", "jousterbrid", "bayonetbrid", "autolancebrid", "ram", "auralancebrid"] - Class.car.UPGRADES_TIER_3 = ["mercedes", "tesla", "toyota", "ford", "overdrive", "honda", "gmc", "porsche", "mazda", "volkswagen", "audi", "mustang", "ram", "ferrari", "jeep"] + Class.lancebrid.UPGRADES_TIER_3 = ["chasseubrid", "jousterbrid", "bayonetbrid", "autolancebrid", "littleLanceArtillerybrid", "ram", "auralancebrid"] + Class.car.UPGRADES_TIER_3 = ["mercedes", "tesla", "toyota", "ford", "overdrive", "honda", "gmc", "porsche", "mazda", "volkswagen", "audi", "mustang", "ram", "ferrari", "jeep", "chrysler"] - Class.littleHunter.UPGRADES_TIER_2 = ["minigun", "binary", "hunter", "sprayer", "contagion", "gundirector", "bigSubduer", "flankdue", "bayonet", "autolittleHunter", "littleHunterbrid", "auraLittleHunter"] + Class.littleHunter.UPGRADES_TIER_2 = ["minigun", "binary", "hunter", "sprayer", "contagion", "gundirector", "bigSubduer", "flankdue", "bayonet", "autolittleHunter", "littleHunterbrid", "littleSubArtillery", "auraLittleHunter"] Class.binary.UPGRADES_TIER_3 = ["trinary", "dual", "twincontagion", "autoBinary", "binarybrid", "auraBinary"] - Class.contagion.UPGRADES_TIER_3 = ["fort", "triContagion", "twincontagion", "droneTrapper", "cockatiel", "autoContagion", "contagionbrid", "auraContagion"] + Class.contagion.UPGRADES_TIER_3 = ["fort", "triContagion", "twincontagion", "droneTrapper", "cockatiel", "icecontagion", "autoContagion", "contagionbrid", "auraContagion"] Class.gundirector.UPGRADES_TIER_3 = ["trojan", "protist", "wyrm", "gundirectorbig", "droneTrapper", "autoGundirector", "krypton", "auraGundirector"] Class.bigSubduer.UPGRADES_TIER_3 = ["predator", "redistributor", "biggerSubduer", "clubbin", "autoBigSubduer", "bigsubduerbrid", "auraBigSubduer"] Class.flankdue.UPGRADES_TIER_3 = ["subway", "triContagion", "clubbin", "autoFlankdue", "flankduebrid", "auraFlankdue"] - Class.inception.UPGRADES_TIER_2 = ["inceptionist", "machinception", "tailgator", "launcher", /*"flankinception", */"directdrive", "spawner", "autoinception", "inceptionbrid", "auraInception"] + Class.inception.UPGRADES_TIER_2 = ["inceptionist", "machinception", "tailgator", "launcher", /*"flankinception", */"directdrive", "spawner", "autoinception", "inceptionbrid", "littleIncepArtillery", "auraInception"] Class.inceptionist.UPGRADES_TIER_3 = ["twinceptionist", "machceptionist", "poundceptionist", /*"flankceptionist", */"factory", "autoinceptionist", "inceptionistbrid", "auraInceptionist"] Class.machinception.UPGRADES_TIER_3 = ["machceptionist", "Sprayinception", "Gatlinception", "automachinception", "machinceptionbrid", "auraMachinception"] Class.tailgator.UPGRADES_TIER_3 = ["poundceptionist", "interceptor", "engineer", "shrapnelgun", "autotailgator", "tailgatorbrid", "auraTailgator"] Class.flankinception.UPGRADES_TIER_3 = ["flankceptionist", "autoflankinception", "flankinceptionbrid", "auraFlankinception"] - Class.desmos.UPGRADES_TIER_2 = ["helix", "undertow", "repeater", "autoDesmos", "desmosbrid", "auraDesmos"] + Class.desmos.UPGRADES_TIER_2 = ["helix", "undertow", "repeater", "homingautoBasic", "autoDesmos", "desmosbrid", "littleSineArtillery", "auraDesmos"] Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "duplicator", "autoHelix", "helixbrid", "auraHelix"] Class.undertow.UPGRADES_TIER_3 = ["riptide", "choker", "autoUndertow", "undertowbrid", "auraUndertow"] Class.repeater.UPGRADES_TIER_3 = ["iterator", "duplicator", "autoRepeater", "repeaterbrid", "auraRepeater"] Class.auraBasic.UPGRADES_TIER_2 = ["auraTwin", "auraSniper", "auraMachineGun", "auraFlankGuard", "auraDirector", "auraPounder", "auraTrapper", "auraAutoBasic", "auraDesmos", "auraBascrid", "auraLittleHunter", "auraInception", "auraLancer", "auraAuto2", "damageAuraBasic", "rangeAuraBasic"] Class.auraBasic.UPGRADES_TIER_3 = ["auraSmasher"] - Class.auraTwin.UPGRADES_TIER_3 = ["auraDoubleTwin", "auraTripleShot", "auraGunner", "auraHexaTank", "auraAutoTwin", "auraHelix", "auratwinbrid", "auraBinary", "auraTwinSniper", "damageAuraTwin", "rangeAuraTwin"] - Class.auraSniper.UPGRADES_TIER_3 = ["auraAssassin", "auraHunter", "auraMinigun", "auraRifle", "auraTwinSniper", "auraAutoSniper", "aurasnipebrid", "auraTrackerSniper", "auraAcid", "auraChiller", "auraChasseur", "damageAuraSniper", "rangeAuraSniper"] - Class.auraMachineGun.UPGRADES_TIER_3 = ["auraArtillery", "auraMinigun", "auraGunner", "auraSprayer", "auraGatlinggun", "auraAutoMach", "auramachbrid", "auraMachinception", "damageAuraMachineGun", "rangeAuraMachineGun"] - Class.auraFlankGuard.UPGRADES_TIER_3 = ["auraHexaTank", "auraTriAngle", "auraAuto3", "auraTrapGuard", "auraTriTrapper", "auraAutoFlank", "auraflankbrid", "auraFlankdue", "auraFlankinception", "auraBackShield", "damageAuraFlankGuard", "rangeAuraFlankGuard"] - Class.auraDirector.UPGRADES_TIER_3 = ["auraOverseer", "auraCruiser", "auraUnderseer", "auraSpawner", "auraDirectdrive", "auraAutoDirector", "auraNoble", "damageAuraDirector", "rangeAuraDirector"] - Class.auraPounder.UPGRADES_TIER_3 = ["auraBuilder", "auraArtillery", "auraLauncher", "auraAutoPound", "aurapoundbrid", "auraTailgator", "damageAuraPounder", "rangeAuraPounder"] - Class.auraTrapper.UPGRADES_TIER_3 = ["auraBuilder", "auraTriTrapper", "auraTrapGuard", "auraContagion", "auraAutoTrap", "auratrapbrid", "damageAuraTrapper", "rangeAuraTrapper"] + Class.auraTwin.UPGRADES_TIER_3 = ["auraDoubleTwin", "auraTripleShot", "auraGunner", "auraHexaTank", "auraAutoTwin", "auraHelix", "auraWark", "auratwinbrid", "auraBinary", "auraTwinSniper", "auraLittleTwinArtillery", "damageAuraTwin", "rangeAuraTwin"] + Class.auraSniper.UPGRADES_TIER_3 = ["auraAssassin", "auraHunter", "auraMinigun", "auraRifle", "auraTwinSniper", "auraAutoSniper", "aurasnipebrid", "auraTrackerSniper", "auraAcid", "auraChiller", "auraChasseur", "auraLittleSnipeArtillery", "damageAuraSniper", "rangeAuraSniper"] + Class.auraMachineGun.UPGRADES_TIER_3 = ["auraArtillery", "auraMinigun", "auraGunner", "auraSprayer", "auraGatlinggun", "auraAutoMach", "auramachbrid", "auraMachinception", "auraLittleMachArtillery", "damageAuraMachineGun", "rangeAuraMachineGun"] + Class.auraFlankGuard.UPGRADES_TIER_3 = ["auraHexaTank", "auraTriAngle", "auraAuto3", "auraTrapGuard", "auraTriTrapper", "auraAutoFlank", "auraflankbrid", "auraFlankdue", "auraFlankinception", "auraBackShield", "auraLittleFlankArtillery", "damageAuraFlankGuard", "rangeAuraFlankGuard"] + Class.auraDirector.UPGRADES_TIER_3 = ["auraOverseer", "auraCruiser", "auraUnderseer", "auraSpawner", "auraDirectdrive", "auraAutoDirector", "auraNoble", "auraLittleDirectArtillery", "damageAuraDirector", "rangeAuraDirector"] + Class.auraPounder.UPGRADES_TIER_3 = ["auraDestroyer", "auraBuilder", "auraArtillery", "auraLauncher", "auraAutoPound", "aurapoundbrid", "auraTailgator", "damageAuraPounder", "rangeAuraPounder"] + Class.auraTrapper.UPGRADES_TIER_3 = ["auraBuilder", "auraTriTrapper", "auraTrapGuard", "auraContagion", "auraWark", "auraIceTrapper", "auraAutoTrap", "auratrapbrid", "auraLittleTrapArtillery", "damageAuraTrapper", "rangeAuraTrapper"] Class.auraAutoBasic.UPGRADES_TIER_3 = ["auraAutoTwin", "auraAutoSniper", "auraAutoMach", "auraAutoFlank", "auraAutoDirector", "auraAutoPound", "auraAutoTrap", "auraAutoDesmos", "auraautobascrid", "auraAutoLittleHunter", "auraAutoInception", "auraHomingautoBasic", "damageAuraAutoBasic", "rangeAuraAutoBasic"] Class.auraBascrid.UPGRADES_TIER_3 = ["auratwinbrid", "aurasnipebrid", "auramachbrid", "auraflankbrid", "aurapoundbrid", "auratrapbrid", "auradesmosbrid", "auraautobascrid", "auralittlehunterbrid", "aurainceptionbrid", "jeep", "damageAuraBascrid", "rangeAuraBascrid"] - Class.auraDesmos.UPGRADES_TIER_3 = ["auraHelix", "auraUndertow", "auraRepeater", "auraAutoDesmos", "auradesmosbrid", "damageAuraDesmos", "rangeAuraDesmos"] - Class.auraLittleHunter.UPGRADES_TIER_3 = ["auraMinigun", "auraBinary", "auraHunter", "auraSprayer", "auraContagion", "auraGundirector", "auraBigSubduer", "auraFlankdue", "auraBayonet", "auraAutoLittleHunter", "auralittlehunterbrid", "damageAuraLittleHunter", "rangeAuraLittleHunter"] - Class.auraInception.UPGRADES_TIER_3 = ["auraInceptionist", "auraMachinception", "auraTailgator", "auraFlankinception", "auraAutoInception", "aurainceptionbrid", "damageAuraInception", "rangeAuraInception"] - Class.auraPropel.UPGRADES_TIER_3 = ["auraTriAngle", "auraBateau", "auraJouster", "auraAutoPropel", "aurapropelbrid", "damageAuraPropel", "rangeAuraPropel"] + Class.auraDesmos.UPGRADES_TIER_3 = ["auraHelix", "auraUndertow", "auraRepeater", "auraAutoDesmos", "auradesmosbrid", "auraLittleSineArtillery", "damageAuraDesmos", "rangeAuraDesmos"] + Class.auraLittleHunter.UPGRADES_TIER_3 = ["auraMinigun", "auraBinary", "auraHunter", "auraSprayer", "auraContagion", "auraGundirector", "auraBigSubduer", "auraFlankdue", "auraBayonet", "auraAutoLittleHunter", "auralittlehunterbrid", "auraLittleSubArtillery", "damageAuraLittleHunter", "rangeAuraLittleHunter"] + Class.auraInception.UPGRADES_TIER_3 = ["auraInceptionist", "auraMachinception", "auraTailgator", "auraFlankinception", "auraAutoInception", "aurainceptionbrid", "auraLittleIncepArtillery", "damageAuraInception", "rangeAuraInception"] + Class.auraPropel.UPGRADES_TIER_3 = ["auraTriAngle", "auraBateau", "auraJouster", "auraAutoPropel", "aurapropelbrid", "auraLittlePropArtillery", "damageAuraPropel", "rangeAuraPropel"] Class.auraAuto2.UPGRADES_TIER_3 = ["auraAuto3", "auraRevolutionist", "auraAutoAuto2", "auraauto2brid", "damageAuraAuto2", "rangeAuraAuto2"] - Class.auraLancer.UPGRADES_TIER_3 = ["auraChasseur", "auraJouster", "auraBayonet", "auraAutoLancer", "auralancebrid", "damageAuraLancer", "rangeAuraLancer"] + Class.auraLancer.UPGRADES_TIER_3 = ["auraChasseur", "auraJouster", "auraBayonet", "auraAutoLancer", "auralancebrid", "auraLittleLanceArtillery", "damageAuraLancer", "rangeAuraLancer"] Class.damageAuraBasic.UPGRADES_TIER_3 = ["damageAuraTwin", "damageAuraSniper", "damageAuraMachineGun", "damageAuraFlankGuard", "damageAuraDirector", "damageAuraPounder", "damageAuraTrapper", "damageAuraAutoBasic", "damageAuraBascrid", "damageAuraDesmos", "damageAuraLittleHunter", "damageAuraInception", "damageAuraPropel", "damageAuraAuto2", "damageAuraLancer", "moredamageAuraBasic", "damagerangeAuraBasic"] Class.rangeAuraBasic.UPGRADES_TIER_3 = ["rangeAuraTwin", "rangeAuraSniper", "rangeAuraMachineGun", "rangeAuraFlankGuard", "rangeAuraDirector", "rangeAuraPounder", "rangeAuraTrapper", "rangeAuraAutoBasic", "rangeAuraBascrid", "rangeAuraDesmos", "rangeAuraLittleHunter", "rangeAuraInception", "rangeAuraPropel", "rangeAuraAuto2", "rangeAuraLancer", "morerangeAuraBasic", "damagerangeAuraBasic"] Class.auto2.UPGRADES_TIER_2 = ["auto3", "revolutionist", "swivel2", "autoauto2", "auto2brid", "auraAuto2"] - Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee", "autoAuto3", "auto3brid", "auraAuto3", "whirl3"] + Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee", "homingautoauto2", "autoAuto3", "auto3brid", "auraAuto3", "whirl3"] Class.revolutionist.UPGRADES_TIER_3 = ["subverter", "autoRevolutionist", "proton", "pion", "hadron", "equilibrium", "revobrid", "baseThrower", "revodirector", "saturn", "auraRevolutionist"] - Class.swivel2.UPGRADES_TIER_3 = ["swivel3", "autoSwivel2", "swivel2brid", "auraSwivel2"] + Class.swivel2.UPGRADES_TIER_3 = ["swivel3", "axis4", "autoSwivel2", "swivel2brid", "auraSwivel2"] - Class.lancer.UPGRADES_TIER_2 = ["chasseur", "jouster", "bayonet", "autolancer", "lancebrid", "auraLancer"] - Class.lancer.UPGRADES_TIER_3 = ["katana"] + Class.lancer.UPGRADES_TIER_2 = ["chasseur", "jouster", "bayonet", "autolancer", "lancebrid", "littleLanceArtillery", "auraLancer"] + Class.lancer.UPGRADES_TIER_3 = ["slasher", "katana"] Class.chasseur.UPGRADES_TIER_3 = ["flail", "fencer", "wakizashi", "autochasseur", "chasseubrid", "auraChasseur"] Class.bayonet.UPGRADES_TIER_3 = ["choker", "arisaka", "wakizashi", "autobayonet", "bayonetbrid", "auraBayonet"] - Class.propel.UPGRADES_TIER_2 = ["triAngle", "bateau", "jouster", "autoPropel", "propelbrid", "auraPropel"] - Class.propel.UPGRADES_TIER_3 = ["jumpSmasher"] + Class.propel.UPGRADES_TIER_2 = ["triAngle", "bateau", "jouster", "autoPropel", "propelbrid", "littlePropArtillery", "auraPropel"] + Class.propel.UPGRADES_TIER_3 = ["jumpSmasher", "shadow"] Class.bateau.UPGRADES_TIER_3 = ["assblaster", "rocker", "knight", "autoBateau", "bateaubrid", "auraBateau"] - Class.jouster.UPGRADES_TIER_3 = ["trailblazer", "knight", "fencer", "arisaka", "autoJouster", "jousterbrid", "auraJouster"] \ No newline at end of file + Class.jouster.UPGRADES_TIER_3 = ["trailblazer", "knight", "fencer", "arisaka", "autoJouster", "jousterbrid", "auraJouster"] + + Class.littleArtillery.UPGRADES_TIER_2 = ["littleMortar", "littleTwinArtillery", "littleSnipeArtillery", "littleMachArtillery", "littleFlankArtillery", "littleDirectArtillery", "artillery", "littleTrapArtillery", "littleSineArtillery", "littleSubArtillery", "littleIncepArtillery", "littlePropArtillery", "littleLanceArtillery", "tripleShot", "autolittleArtillery", "littleArtillerybrid", "auraLittleArtillery"] + Class.littleMortar.UPGRADES_TIER_3 = ["littleSheller", "littleTwinMortar", "littleSnipeMortar", "littleMachMortar", "littleFlankMortar", "littleDirectMortar", "mortar", "littleTrapMortar", "littleDesmosMortar", "littleSubMortar", "littleIncepMortar", "littlePropMortar", "littleLanceMortar", "pentaShot", "machineGunner", "autolittleMortar", "littleMortarbrid", "auraLittleMortar"] + Class.littleTwinArtillery.UPGRADES_TIER_3 = ["littleTwinMortar", "autolittleTwinArtillery", "littleTwinArtillerybrid", "auraLittleTwinArtillery"] + Class.littleSnipeArtillery.UPGRADES_TIER_3 = ["crossbow", "littleSnipeMortar", "autolittleSnipeArtillery", "littleSnipeArtillerybrid", "trackerSnipeArtillery", "auraLittleSnipeArtillery"] + Class.littleMachArtillery.UPGRADES_TIER_3 = ["littleMachMortar", "autolittleMachArtillery", "littleMachArtillerybrid", "auraLittleMachArtillery"] + Class.littleFlankArtillery.UPGRADES_TIER_3 = ["littleFlankMortar", "autolittleFlankArtillery", "littleFlankArtillerybrid", "auraLittleFlankArtillery"] + Class.littleDirectArtillery.UPGRADES_TIER_3 = ["littleDirectMortar", "autolittleDirectArtillery", "auraLittleDirectArtillery"] + Class.littleTrapArtillery.UPGRADES_TIER_3 = ["littleTrapMortar", "autolittleTrapArtillery", "littleTrapArtillerybrid", "auraLittleTrapArtillery"] + Class.littleSineArtillery.UPGRADES_TIER_3 = ["littleDesmosMortar", "autolittleSineArtillery", "littleSineArtillerybrid", "auraLittleSineArtillery"] + Class.littleSubArtillery.UPGRADES_TIER_3 = ["littleSubMortar", "autolittleSubArtillery", "littleSubArtillerybrid", "auraLittleSubArtillery"] + Class.littleIncepArtillery.UPGRADES_TIER_3 = ["littleIncepMortar", "autolittleIncepArtillery", "littleIncepArtillerybrid", "auraLittleIncepArtillery"] + Class.littlePropArtillery.UPGRADES_TIER_3 = ["littlePropMortar", "autolittlePropArtillery", "littlePropArtillerybrid", "auraLittlePropArtillery"] + Class.littleLanceArtillery.UPGRADES_TIER_3 = ["littleLanceMortar", "autolittleLanceArtillery", "littleLanceArtillerybrid", "auraLittleLanceArtillery"] + Class.autolittleArtillery.UPGRADES_TIER_3 = ["autolittleTwinArtillery", "autolittleSnipeArtillery", "autolittleMachArtillery", "autolittleFlankArtillery", "autolittleDirectArtillery", "autoArtillery", "autolittleTrapArtillery", "autolittleSineArtillery", "autolittleSubArtillery", "autolittleIncepArtillery", "autolittlePropArtillery", "autolittleLanceArtillery", "autoTripleShot", "autolittleArtillerybrid", "auraAutoLittleArtillery", /*"littleArtilleryCeption",*/ "homingautolittleArtillery"] + Class.littleArtillerybrid.UPGRADES_TIER_3 = ["littleMortarbrid", "littleTwinArtillerybrid", "littleSnipeArtillerybrid", "littleMachArtillerybrid", "littleFlankArtillerybrid", "artilbrid", "littleTrapArtillerybrid", "littleSineArtillerybrid", "littleSubArtillerybrid", "littleIncepArtillerybrid", "littlePropArtillerybrid", "littleLanceArtillerybrid", "bentHybrid", "autolittleArtillerybrid", "chrysler", "auralittleartillerybrid"] + Class.auraLittleArtillery.UPGRADES_TIER_3 = ["auraLittleMortar", "auraLittleTwinArtillery", "auraLittleSnipeArtillery", "auraLittleMachArtillery", "auraLittleFlankArtillery", "auraLittleDirectArtillery", "auraArtillery", "auraLittleTrapArtillery", "auraLittleSineArtillery", "auraLittleSubArtillery", "auraLittleIncepArtillery", "auraLittlePropArtillery", "auraLittleLanceArtillery", "auraTripleShot", "auraAutoLittleArtillery", "auralittleartillerybrid", "damageAuraLittleArtillery", "rangeAuraLittleArtillery"] \ No newline at end of file diff --git a/server/modules/definitions/groups/turrets.js b/server/modules/definitions/groups/turrets.js index 3ac6eba2b..eacfb1df5 100644 --- a/server/modules/definitions/groups/turrets.js +++ b/server/modules/definitions/groups/turrets.js @@ -1088,7 +1088,7 @@ Class.revogun = { GUNS: [{ POSITION: [13.5, 10, 1, 8, 0, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.halfreload]), + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret]), TYPE: "bullet" } } @@ -1249,17 +1249,25 @@ Class.jumpsmashBody = { PARENT: "smasherBody", SHAPE: 7 } +Class.autoTurret3 = { + LABEL: 'Auto Turret', + BODY: { + FOV: 0.9 + }, + COLOR: 16, + GUNS: [{ + POSITION: [21.5, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.lesspower, g.bitlessreload]), + TYPE: "bullet" + } + }] +}; Class.skaterDeco = makeDeco("M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1"); Class.skaterDeco.STROKE_WIDTH = 2; Class.switcherDeco = makeDeco('M 0 0 M 2 -1 L -2 -1 L -2 8 L -1 8 L 1 8 L 2 8') Class.effectBulletDeco = makeDeco(0) Class.firecrackerDeco = makeDeco(-6) -Class.auraDamageGen = addAura(2, 1.3, 0.3, "red"); -Class.auraRangeGen = addAura(2, 1.8, 0.3, "teal", "rangeAuraSymbol"); -Class.auraDamageRangeGen = addAura(2, 1.8, 0.3, "red", "rangeAuraSymbol"); -Class.auraMoreDamageGen = addAura(3, 1.3, 0.3, "orange"); -Class.auraMoreRangeGen = addAura(1, 2.3, 0.3, "aqua", "rangeAuraSymbol"); -Class.auraSmasherGen = addAura(11, 1.3); Class.surgeDeco = makeDeco(-1, "spaceGem"); Class.katanaDeco = makeDeco('M 0 2 L 0 -1 L 1 0 L 0 -1 L -1 0 L 0 -1', "#add6f7"); Class.brellaDeco = makeDeco('M -0 2.2587 L 0.9 0.905 L 0.9 -0.9 L -0 -2.2537 L -0.9 -2.5245 L -0.9 2.5295 L -0 2.2587', "gray") \ No newline at end of file diff --git a/server/modules/definitions/gunvals.js b/server/modules/definitions/gunvals.js index 6261074d5..225d79c33 100644 --- a/server/modules/definitions/gunvals.js +++ b/server/modules/definitions/gunvals.js @@ -3,7 +3,7 @@ module.exports = { basic: { reload: 10.5, recoil: 1.4, shudder: 0.1, damage: 0.75, speed: 4.5, spray: 15 }, drone: { reload: 36, recoil: 0.25, shudder: 0.1, size: 0.6, speed: 2, spray: 0.1 }, trap: { reload: 23, shudder: 0.25, size: 0.6, damage: 0.75, speed: 5, spray: 15, resist: 3 }, - swarm: { reload: 23, recoil: 0.25, shudder: 0.05, size: 0.4, damage: 0.75, speed: 4, spray: 5 }, + swarm: { reload: 23, recoil: 0.25, shudder: 0.05, size: 0.4, damage: 1.2, speed: 4, spray: 5 }, factory: { reload: 48, shudder: 0.1, size: 0.7, damage: 0.75, speed: 3, spray: 0.1 }, productionist: { reload: 56, recoil: 0.25, shudder: 0.05, size: 0.7, damage: 0.75, speed: 4, range: 1.5, spray: 5 }, @@ -68,13 +68,13 @@ module.exports = { babyfactory: { reload: 1.5, maxSpeed: 1.25 }, bigCheese: { reload: 1.5, size: 1.8, health: 2.5, speed: 1.25 }, mothership: { reload: 1.25, pen: 1.1, speed: 0.775, maxSpeed: 0.8, range: 15, resist: 1.15 }, - satellite: { size: 0.8, reload: 3, damage: 1.875 }, + satellite: { size: 0.8, reload: 3, damage: 4 }, contagi: { reload: 1, recoil: 0.5, shudder: 1.5, size: 1, health: 0.6, damage: 0.6, pen: 0.75, speed: 1.05, maxSpeed: 1, range: 1, density: 0.9, spray: 0.75, resist: 0.7 }, // Heavy cannons pounder: { reload: 2, recoil: 1.6, damage: 2, speed: 0.85, maxSpeed: 0.8, density: 1.5, resist: 1.15 }, - destroyer: { reload: 2.2, recoil: 1.8, shudder: 0.5, health: 2, damage: 2, pen: 1.2, speed: 0.65, maxSpeed: 0.5, density: 2, resist: 3 }, - annihilator: { reload: 0.8, recoil: 1.25 }, + destroyer: { reload: 2.2, recoil: 1.8, shudder: 0.5, health: 2, damage: 1.4, pen: 1.2, speed: 0.65, maxSpeed: 0.5, density: 2, resist: 3 }, + annihilator: { reload: 0.8, recoil: 1.25, damage: 1.43 }, hive: { reload: 1.5, recoil: 0.8, size: 0.8, health: 0.7, damage: 0.3, maxSpeed: 0.6 }, artillery: { reload: 1.2, recoil: 0.7, size: 0.9, speed: 1.15, maxSpeed: 1.1, density: 1.5 }, mortar: { reload: 1.2, health: 1.1, speed: 0.8, maxSpeed: 0.8 }, @@ -155,9 +155,9 @@ module.exports = { lesspower: { health: 0.9, damage: 0.9, pen: 0.9 }, grenade_explosion: { reload: 8, recoil: 0, shudder: 4.25, size: 2, health: 2.25, damage: 1.75, pen: 1.5, speed: 1.35, spray: 4 }, literallyamachinegun: { reload: 0.2, speed: 5, maxSpeed: 5, spray: 0.3, shudder: 0.6 }, - rainmaker: { speed: 0.03, maxSpeed: 0.5, health: 0.9, damage: 0.85, range: 0.25 }, + rainmaker: { speed: 0.03, maxSpeed: 0.5, health: 0.98, damage: 0.88, range: 0.25 }, acceltospeedoflight: { speed: 0.001, maxSpeed: 1000 }, - explosion: { speed: 0.01, maxSpeed: 0.01, health: 5, damage: 4, pen: 5, density: 3.7, resist: 3 }, + explosion: { speed: 0.01, maxSpeed: 0.01, health: 5, damage: 3, pen: 4.6, density: 3.6, resist: 3 }, brella: { reload: 2.5, health: 35, pen: 0, damage: 0.2, maxSpeed: 0.8, spray: 0, range: 2.25, size: 2.4, shudder: 0.1 }, magnet: { damage: 0, health: 0.8, spray: 45, range: 0.08, recoil: 0, speed: 0.8, pen: 0 }, solarioblast: { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.6 }, @@ -165,4 +165,6 @@ module.exports = { empbullet: { reload: 1.25, recoil: 0, size: 2.5, speed: 1.1, maxSpeed: 1.1, spray: 0.2 }, cloner: { damage: 0.78, pen: 0.85 }, sidewinder2: { shudder: 0, spray: 0, size: 0.8, speed: 0.001, damage: 5 }, + repeater: { damage: 0.6 }, + vulc: {reload: 1.25, recoil: 0.1, shudder: 0, size: 0.8, health: 0.6, damage: 0.27, pen: 1, speed: 1.3, maxSpeed: 1.3, range: 1, density: 1.25, spray: 0.001, resist: 1.1}, } \ No newline at end of file diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index 65e84cff2..d90cef15e 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -1811,12 +1811,12 @@ class Entity extends EventEmitter { this.damp = this.motionTypeArgs.damp ?? -0.025; break; case "accelerate": - this.velocity.x = this.velocity.x + (4.5 * Math.cos(this.facing)) - this.velocity.y = this.velocity.y + (4.5 * Math.sin(this.facing)) + this.velocity.x += 4.5 * Math.cos(this.facing) + this.velocity.y += 4.5 * Math.sin(this.facing) this.topSpeed += 30; this.maxSpeed += 30; this.damp = -0.0125; - this.damage += 1.3 + //this.damage += 0.45 for now... break; case "acceleratetothespeedoflight": this.velocity.x = this.velocity.x + ((1 * this.maxSpeed + 0.5) * Math.cos(this.facing)) diff --git a/server/modules/network/sockets.js b/server/modules/network/sockets.js index 45c86a30e..e2602d286 100644 --- a/server/modules/network/sockets.js +++ b/server/modules/network/sockets.js @@ -439,9 +439,9 @@ function incoming(message, socket) { return 1; } // cheatingbois - if (player.body != null && socket.permissions && socket.permissions.class) { + if (player.body != null && ((socket.permissions && socket.permissions.class) || Config.GAME_MODES[0] == 'sandbox')) { player.body.define({ RESET_UPGRADES: true, BATCH_UPGRADES: false }); - player.body.define(socket.permissions.class); + Config.GAME_MODES[0] == 'sandbox' ? player.body.define("developer") : player.body.define(socket.permissions.class); if (player.body.color.base == '-1' || player.body.color.base == 'mirror') { player.body.color.base = getTeamColor((Config.GROUPS || (Config.MODE == 'ffa' && !Config.TAG)) ? TEAM_RED : player.body.team); } @@ -460,60 +460,60 @@ function incoming(message, socket) { } break; case "testTeleport": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.x = player.body.x + player.target.x; player.body.y = player.body.y + player.target.y; } break; case "smallerTank": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.SIZE *= 4/5; player.body.RECOIL_MULTIPLIER *= 4/5; } break; case "biggerTank": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.SIZE *= 5/4; player.body.RECOIL_MULTIPLIER *= 5/4; } break; case "smallerFOV": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.FOV *= 4/5 } break; case "biggerFOV": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.FOV *= 5/4 } break; case "godmodeButton": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.godmode = !player.body.godmode; player.body.sendMessage((player.body.godmode ? "Godmode enabled." : "Godmode disabled.")); } break; case "invisibility": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.alpha = !player.body.alpha; player.body.invisible = [player.body.alpha, !player.body.alpha] } break; case "canBeOnLeaderboard": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.settings.leaderboardable = !player.body.settings.leaderboardable; player.body.sendMessage((player.body.settings.leaderboardable ? "You have been added to the leaderboard" : "You have been removed from the leaderboard.")); } break; case "keyStrong"://keyStrong - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.skill.raw = Array(10).fill(12); player.body.skill.setCaps(Array(10).fill(12)); player.body.refreshBodyAttributes(); } break; case "drag": { // drag - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { if (!player.pickedUpInterval) { let tx = player.body.x + player.target.x; let ty = player.body.y + player.target.y; @@ -548,7 +548,7 @@ function incoming(message, socket) { } } break; case "watchThis": { // Kill what your mouse is over //watchThis - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { entities.forEach(o => { if (o !== player.body != null && util.getDistance(o, { x: player.target.x + player.body.x, @@ -562,7 +562,7 @@ function incoming(message, socket) { } break; case "heal": { // Kill what your mouse is over - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { entities.forEach(o => { if (o !== player.body != null && util.getDistance(o, { x: player.target.x + player.body.x, @@ -576,7 +576,7 @@ function incoming(message, socket) { } break; case "randomTestKey": { // Spawn entities at mouse - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { let loc = { x: (30 * Math.round((player.target.x + player.body.x - 15)/30))+15, y: (30 * Math.round((player.target.y + player.body.y - 15)/30))+15, @@ -589,7 +589,7 @@ function incoming(message, socket) { } } break;} break; case "spawnWall": { // Spawn entities at mouse -if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { entities.forEach(o => { if (o !== player.body != null /*&& global.canKill != false*/ && o.label === "Wall" && util.getDistance(o, { x: player.target.x + player.body.x, @@ -620,7 +620,7 @@ if (player.body != null && socket.permissions) { } break; } break; case "nullallalallalala": - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { player.body.sendMessage("turi ip ip ip") } break; case "A": @@ -716,7 +716,11 @@ if (player.body != null && socket.permissions) { player.body.sendMessage("There are no special tanks in this mode that you can control."); } break; - + case "setclass": + if (player.body !== null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { + player.body.define(m[0].replace("setclass", "")); + } + break; case "M": if (player.body == null) return 1; let abort, message = m[0], original = m[0]; @@ -748,7 +752,7 @@ if (player.body != null && socket.permissions) { chats[id] = []; } - if (player.body != null && socket.permissions) { + if (player.body != null && (socket.permissions || Config.GAME_MODES[0] == 'sandbox')) { if (message.includes("/broadcast ")) { if (message.replace("/broadcast ", "") != "") sockets.broadcast(player.body.name + ": " + message.replace("/broadcast ", "")); } diff --git a/server/modules/network/webServer.js b/server/modules/network/webServer.js index 1e6153abb..3c108f105 100644 --- a/server/modules/network/webServer.js +++ b/server/modules/network/webServer.js @@ -37,9 +37,9 @@ server = require('http').createServer((req, res) => { //if this file does not exist, return the default; if (!fs.existsSync(fileToGet)) { - fileToGet = path.join(sharedRoot, Config.DEFAULT_FILE); + fileToGet = path.join(publicRoot, Config.DEFAULT_FILE); } else if (!fs.lstatSync(fileToGet).isFile()) { - fileToGet = path.join(sharedRoot, Config.DEFAULT_FILE); + fileToGet = path.join(publicRoot, Config.DEFAULT_FILE); } //return the file @@ -75,9 +75,26 @@ server = require('http').createServer((req, res) => { } // CORS? res.setHeader('Access-Control-Allow-Origin', '*'); + + const zlib = require("zlib"); + res.setHeader("Access-Control-Allow-Origin", "*"); + let acceptEncoding = req.headers['accept-encoding']; + if (!acceptEncoding) { + acceptEncoding = ''; + }; + if (acceptEncoding.match(/\bdeflate\b/)) { + res.writeHead(200, { 'content-encoding': 'deflate' }); + zlib.createDeflate().end(resStr).pipe(res); + } else if (acceptEncoding.match(/\bgzip\b/)) { + res.writeHead(200, { 'content-encoding': 'gzip' }); + zlib.createGzip().end(resStr).pipe(res); + } else { + res.writeHead(200, {}); + res.end(resStr); + } - res.writeHead(200); - res.end(resStr); + //res.writeHead(200); + //res.end(resStr); }); server.on('upgrade', (req, socket, head) => wsServer.handleUpgrade(req, socket, head, ws => sockets.connect(ws, req))); diff --git a/server/modules/setup/gamemodeconfigs/sandbox.js b/server/modules/setup/gamemodeconfigs/sandbox.js new file mode 100644 index 000000000..a09954537 --- /dev/null +++ b/server/modules/setup/gamemodeconfigs/sandbox.js @@ -0,0 +1 @@ +module.exports = {}; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_blank3.js b/server/modules/setup/rooms/map_neroio_blank3.js new file mode 100644 index 000000000..495fc4c1e --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_blank3.js @@ -0,0 +1,26 @@ +let { rock } = require('../tiles/decoration.js'), + { wall: WALL, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf, water: watr, fovwall: FWAL } = require('../tiles/misc.js'), + +room = [ + [rock,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,rock], + [F___,FWAL,F___,____,F___,____,WALL,WALL,WALL,____,WALL,rock,F___,____,F___,WALL,F___,FWAL,F___], + [____,F___,____,F___,WALL,F___,WALL,F___,____,F___,____,WALL,WALL,WALL,____,WALL,____,F___,____], + [F___,____,F___,WALL,F___,rock,F___,____,WALL,____,F___,WALL,F___,____,F___,____,WALL,____,WALL], + [WALL,WALL,____,WALL,____,F___,____,F___,WALL,F___,____,F___,____,F___,____,WALL,rock,F___,WALL], + [F___,rock,F___,rock,F___,WALL,F___,WALL,WALL,WALL,WALL,____,WALL,WALL,F___,WALL,F___,rock,F___], + [____,F___,rock,F___,____,WALL,rock,F___,rock,F___,rock,F___,rock,WALL,____,F___,rock,F___,____], + [F___,rock,F___,rock,F___,WALL,F___,nest,nesf,nest,nesf,nest,F___,WALL,WALL,____,WALL,WALL,F___], + [____,F___,____,WALL,WALL,WALL,rock,nesf,nest,nesf,nest,nesf,rock,WALL,watr,watr,watr,WALL,____], + [WALL,____,F___,____,F___,____,F___,nest,nesf,nest,nesf,nest,F___,____,watr,watr,watr,____,F___], + [WALL,F___,WALL,F___,____,WALL,rock,nesf,nest,nesf,nest,nesf,rock,WALL,watr,watr,watr,WALL,____], + [F___,____,WALL,____,F___,WALL,F___,nest,nesf,nest,nesf,nest,F___,WALL,WALL,____,WALL,WALL,F___], + [____,WALL,____,WALL,____,WALL,rock,F___,rock,F___,rock,F___,rock,WALL,____,F___,____,F___,rock], + [F___,____,F___,WALL,F___,WALL,WALL,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,____,WALL], + [____,F___,rock,F___,____,F___,____,F___,____,WALL,____,F___,____,F___,____,F___,____,F___,____], + [WALL,rock,F___,WALL,F___,____,F___,____,F___,____,F___,____,F___,WALL,WALL,WALL,F___,WALL,F___], + [____,F___,____,F___,WALL,F___,watr,watr,____,F___,rock,F___,____,WALL,____,F___,____,F___,____], + [F___,FWAL,F___,____,WALL,____,watr,watr,F___,____,WALL,rock,F___,WALL,F___,____,F___,FWAL,F___], + [rock,F___,____,F___,____,F___,____,F___,____,WALL,WALL,WALL,____,F___,____,WALL,____,F___,rock] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_mazearena2.js b/server/modules/setup/rooms/map_neroio_mazearena2.js new file mode 100644 index 000000000..495fc4c1e --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_mazearena2.js @@ -0,0 +1,26 @@ +let { rock } = require('../tiles/decoration.js'), + { wall: WALL, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf, water: watr, fovwall: FWAL } = require('../tiles/misc.js'), + +room = [ + [rock,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,rock], + [F___,FWAL,F___,____,F___,____,WALL,WALL,WALL,____,WALL,rock,F___,____,F___,WALL,F___,FWAL,F___], + [____,F___,____,F___,WALL,F___,WALL,F___,____,F___,____,WALL,WALL,WALL,____,WALL,____,F___,____], + [F___,____,F___,WALL,F___,rock,F___,____,WALL,____,F___,WALL,F___,____,F___,____,WALL,____,WALL], + [WALL,WALL,____,WALL,____,F___,____,F___,WALL,F___,____,F___,____,F___,____,WALL,rock,F___,WALL], + [F___,rock,F___,rock,F___,WALL,F___,WALL,WALL,WALL,WALL,____,WALL,WALL,F___,WALL,F___,rock,F___], + [____,F___,rock,F___,____,WALL,rock,F___,rock,F___,rock,F___,rock,WALL,____,F___,rock,F___,____], + [F___,rock,F___,rock,F___,WALL,F___,nest,nesf,nest,nesf,nest,F___,WALL,WALL,____,WALL,WALL,F___], + [____,F___,____,WALL,WALL,WALL,rock,nesf,nest,nesf,nest,nesf,rock,WALL,watr,watr,watr,WALL,____], + [WALL,____,F___,____,F___,____,F___,nest,nesf,nest,nesf,nest,F___,____,watr,watr,watr,____,F___], + [WALL,F___,WALL,F___,____,WALL,rock,nesf,nest,nesf,nest,nesf,rock,WALL,watr,watr,watr,WALL,____], + [F___,____,WALL,____,F___,WALL,F___,nest,nesf,nest,nesf,nest,F___,WALL,WALL,____,WALL,WALL,F___], + [____,WALL,____,WALL,____,WALL,rock,F___,rock,F___,rock,F___,rock,WALL,____,F___,____,F___,rock], + [F___,____,F___,WALL,F___,WALL,WALL,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,____,WALL], + [____,F___,rock,F___,____,F___,____,F___,____,WALL,____,F___,____,F___,____,F___,____,F___,____], + [WALL,rock,F___,WALL,F___,____,F___,____,F___,____,F___,____,F___,WALL,WALL,WALL,F___,WALL,F___], + [____,F___,____,F___,WALL,F___,watr,watr,____,F___,rock,F___,____,WALL,____,F___,____,F___,____], + [F___,FWAL,F___,____,WALL,____,watr,watr,F___,____,WALL,rock,F___,WALL,F___,____,F___,FWAL,F___], + [rock,F___,____,F___,____,F___,____,F___,____,WALL,WALL,WALL,____,F___,____,WALL,____,F___,rock] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_zerolag.js b/server/modules/setup/rooms/map_neroio_zerolag.js index 98a468b89..128da7021 100644 --- a/server/modules/setup/rooms/map_neroio_zerolag.js +++ b/server/modules/setup/rooms/map_neroio_zerolag.js @@ -1,4 +1,4 @@ -let { normalNoFood: F___, hookpoint: hook } = require('../tiles/misc.js'), +let { normalNoFood: F___, hookpoint: hook, water: watr } = require('../tiles/misc.js'), room = [ [F___,F___,F___,F___,F___,F___,F___,F___], @@ -6,8 +6,8 @@ room = [ [F___,F___,F___,F___,F___,F___,F___,F___], [F___,F___,F___,F___,F___,F___,F___,F___], [F___,F___,F___,F___,F___,F___,F___,F___], - [F___,F___,F___,F___,F___,F___,F___,F___], - [F___,F___,F___,F___,F___,F___,F___,F___], + [F___,F___,F___,F___,F___,watr,watr,F___], + [F___,F___,F___,F___,F___,watr,watr,F___], [F___,F___,F___,F___,F___,F___,F___,F___] ]; diff --git a/server/modules/setup/tiles/misc.js b/server/modules/setup/tiles/misc.js index ca4b17337..5166ae3ea 100644 --- a/server/modules/setup/tiles/misc.js +++ b/server/modules/setup/tiles/misc.js @@ -39,6 +39,24 @@ normalNoFood = new Tile({ }, init: tile => room.spawnableDefault.push(tile), }), + +water = new Tile({ + color: "aqua", + data: { + allowMazeWallSpawn: true, + }, + init: tile => room.spawnableDefault.push(tile), + tick: tile => { + for (let i = 0; i < tile.entities.length; i++) { + let entity = tile.entities[i]; + if (entity.pushability && !entity.immuneToTiles && !entity.master.immuneToTiles) { + let dirToCenter = Math.atan2(room.center.y - entity.y, room.center.x - entity.x); + entity.velocity.x /= 1.05; + entity.velocity.y /= 1.05; + } + } + } +}), dancefloor = new Tile({ color: "rainbow", @@ -49,35 +67,35 @@ dancefloor = new Tile({ }), dancefloor1 = new Tile({ - color: 20, + color: "flashBlueRed", data: { allowMazeWallSpawn: false, }, init: tile => room.spawnableDefault.push(tile), }), dancefloor2 = new Tile({ - color: 21, + color: "flashBlueGray", data: { allowMazeWallSpawn: false, }, init: tile => room.spawnableDefault.push(tile), }), dancefloor3 = new Tile({ - color: 22, + color: "flashGreyBlue", data: { allowMazeWallSpawn: false, }, init: tile => room.spawnableDefault.push(tile), }), dancefloor4 = new Tile({ - color: 23, + color: "flashRedGrey", data: { allowMazeWallSpawn: false, }, init: tile => room.spawnableDefault.push(tile), }), dancefloor5 = new Tile({ - color: 24, + color: "flashGreyRed", data: { allowMazeWallSpawn: false, }, @@ -193,4 +211,4 @@ hookpoint = new Tile({ } }); -module.exports = { normal, normalNoFood, nest, nestNoFood, wall, nestNoBoss, blacktile, dancefloor, dancefloor1, dancefloor2, dancefloor3, dancefloor4, dancefloor5, dfxwall, hookpoint, fovwall }; \ No newline at end of file +module.exports = { normal, normalNoFood, nest, nestNoFood, wall, nestNoBoss, blacktile, dancefloor, dancefloor1, dancefloor2, dancefloor3, dancefloor4, dancefloor5, dfxwall, hookpoint, fovwall, water }; \ No newline at end of file diff --git a/server/permissions.js b/server/permissions.js index 9dd56f5c4..0f58cbf71 100644 --- a/server/permissions.js +++ b/server/permissions.js @@ -15,23 +15,32 @@ module.exports = [ "nameColor": "#ffffff", "class": "developer", "infiniteLevelUp": true, - "name": "unnamed#0000", - "note": "note here" + "name": "Beta tester", + "note": "Beta testing token" }, { "key": process.env.TOKEN_3, "discordID": "0", - "nameColor": "#ffffff", + "nameColor": "#348feb", "class": "developer", "infiniteLevelUp": true, - "name": "unnamed#0000", - "note": "note here" + "name": "anguish", + "note": "angishes token" }, { "key": process.env.TOKEN_4, "discordID": "0", "nameColor": "#ffffff", "class": "developer", + "infiniteLevelUp": false, + "name": "Lesscool", + "note": "note here" + }, + { + "key": process.env.TOKEN_5, + "discordID": "0", + "nameColor": "#ffffff", + "class": "developer", "infiniteLevelUp": true, "name": "unnamed#0000", "note": "note here" diff --git a/shit/randomstuff/aasfsdgsdg b/shit/randomstuff/aasfsdgsdg index f04fd8d80..39fb9ed99 100644 --- a/shit/randomstuff/aasfsdgsdg +++ b/shit/randomstuff/aasfsdgsdg @@ -1 +1,2 @@ -qwertyuiop \ No newline at end of file +qwertyuiop +oli was here \ No newline at end of file diff --git a/shit/secret.html b/shit/secret.html new file mode 100644 index 000000000..7dc32d6c0 --- /dev/null +++ b/shit/secret.html @@ -0,0 +1,8 @@ + + + AAAAAAAAAAAAAAAAAAAAAAAAAA + + +

    Penis explosion chamber

    + + \ No newline at end of file From bf37339dce4d6f5a5796fe3dcd670e8b0e2cc539 Mon Sep 17 00:00:00 2001 From: "Glitch (neroio2)" Date: Fri, 23 May 2025 02:04:24 +0000 Subject: [PATCH 15/15] rip glitch --- .glitch-assets | 1 + changelog preview | 1 + public/app.js | 3 +- public/changelog.html | 6 +- public/main.css | 2 +- server/config.js | 2 +- server/modules/definitions/groups/food.js | 1 - .../modules/definitions/groups/projectiles.js | 59 +++++++++- server/modules/definitions/groups/tanks.js | 106 ++++++++++++++++-- server/modules/live/entity.js | 3 + server/permissions.js | 5 +- 11 files changed, 174 insertions(+), 15 deletions(-) diff --git a/.glitch-assets b/.glitch-assets index 048535638..04e75a069 100644 --- a/.glitch-assets +++ b/.glitch-assets @@ -272,3 +272,4 @@ {"name":"78ef256e-6586-43e1-9028-b0d3e8e829f6.image.png","date":"2025-04-30T21:56:55.645Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/78ef256e-6586-43e1-9028-b0d3e8e829f6.image.png","type":"image/png","size":5139345,"imageWidth":2880,"imageHeight":1800,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F78ef256e-6586-43e1-9028-b0d3e8e829f6.image.png","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"1LTYT8YpDR2YN6JL"} {"name":"adacb81f-a679-413e-8499-6005e1cc4b05.image.png","date":"2025-04-30T21:59:45.838Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/adacb81f-a679-413e-8499-6005e1cc4b05.image.png","type":"image/png","size":100807,"imageWidth":162,"imageHeight":230,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/adacb81f-a679-413e-8499-6005e1cc4b05.image.png","thumbnailWidth":162,"thumbnailHeight":230,"uuid":"NJEBu3CqFufkB37c"} {"name":"43e3e1ea-297c-435c-8198-04760b9427f7.image.png","date":"2025-04-30T22:03:01.478Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/43e3e1ea-297c-435c-8198-04760b9427f7.image.png","type":"image/png","size":665522,"imageWidth":720,"imageHeight":946,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F43e3e1ea-297c-435c-8198-04760b9427f7.image.png","thumbnailWidth":252,"thumbnailHeight":330,"uuid":"5wmKnV6rum0h1RL6"} +{"name":"nero-logo-text.png","date":"2025-05-08T22:09:22.513Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nero-logo-text.png","type":"image/png","size":251897,"imageWidth":1920,"imageHeight":1080,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fnero-logo-text.png","thumbnailWidth":330,"thumbnailHeight":186,"uuid":"5IM9a5dDHFvQ4Qqa"} diff --git a/changelog preview b/changelog preview index 472a5ee98..ba4c8af40 100644 --- a/changelog preview +++ b/changelog preview @@ -38,6 +38,7 @@
  • bayonet reload nerfed from 1 to 1.3
  • fixed cloner not cloning
  • nerfed probe cloning reload
  • +
  • buffed cloner branch cloning speed
  • Ay, Anguish on that beat ho'

    diff --git a/public/app.js b/public/app.js index c8b7661df..d2bb5bfe8 100644 --- a/public/app.js +++ b/public/app.js @@ -1054,6 +1054,7 @@ window.onload = async () => { tdMode = document.createElement("td"), tdIp = document.createElement("td"), tr = document.createElement("tr"); + tdMode.textContent = "Loading"; tdPlayers.textContent = `${server.players} Players`; tdPlayers.classList.add("tdLeft"); @@ -3283,7 +3284,7 @@ function drawMinimapAndDebug(spacing, alcoveSize, GRAPHDATA) { drawText("Prediction: " + Math.round(GRAPHDATA) + "ms : " + global.mspt + " mspt", x + len, y - 50 - 7 * 14, 10, color.guiwhite, "right"); // drawText(`Bandwidth: ${gui.bandwidth.in} in, ${gui.bandwidth.out} out`, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); drawText("Memory: " + global.metrics.rendergap.toFixed(1) + " Mib : " + "Class: " + gui.class, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); - drawText("Update Version: " + "v3.515", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); + drawText("Update Version: " + "v3.52", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 5 * 14, 10, color.guiwhite, "right"); drawText("Server Speed: " + (100 * gui.fps).toFixed(2) + "% : Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 4 * 14, 10, orangeColor ? color.orange : color.guiwhite, "right"); drawText("Kills: " + global.metrics.killcount + " Shapes: " + global.metrics.shapecount, x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); diff --git a/public/changelog.html b/public/changelog.html index 56d41e81d..ba4c8af40 100644 --- a/public/changelog.html +++ b/public/changelog.html @@ -32,9 +32,13 @@

    Update 3.5

  • added numbers for health bar
  • buffed swarm tank damage by a multiplier of 2
  • nerfed flail damage from 3 to 1.95
  • -
  • buffed whirlwind damage from 1.875 to 8
  • +
  • buffed whirlwind damage from 1.875 to 4
  • buffed revolutionist turrets reload from 0.45 to 0.9
  • made jump smashers bullets half opacity
  • +
  • bayonet reload nerfed from 1 to 1.3
  • +
  • fixed cloner not cloning
  • +
  • nerfed probe cloning reload
  • +
  • buffed cloner branch cloning speed
  • Ay, Anguish on that beat ho'

    diff --git a/public/main.css b/public/main.css index 4ed2d3906..5593d0ac3 100644 --- a/public/main.css +++ b/public/main.css @@ -41,7 +41,7 @@ body { body { font-family: Ubuntu; font-size: 14px; - background-image: url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png?v=1713356636170"); + background-image: url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nero-logo-text.png?v=1746742162513"); background-repeat: repeat; background-color: #484848; } diff --git a/server/config.js b/server/config.js index 547a2aed2..08bb738d2 100644 --- a/server/config.js +++ b/server/config.js @@ -113,7 +113,7 @@ module.exports = { }, // Default skill caps. - MAX_SKILL: 9, + MAX_SKILL: 9, //9 // Amount of tank tiers. MAX_UPGRADE_TIER: 9, diff --git a/server/modules/definitions/groups/food.js b/server/modules/definitions/groups/food.js index 221d29251..e86298d02 100644 --- a/server/modules/definitions/groups/food.js +++ b/server/modules/definitions/groups/food.js @@ -127,7 +127,6 @@ Class.pentagon = { DENSITY: 80, HEALTH: 10 * basePolygonHealth, RESIST: 1, - //PENETRATION: 0.7, PENETRATION: 0.7, ACCELERATION: 0.0035 }, diff --git a/server/modules/definitions/groups/projectiles.js b/server/modules/definitions/groups/projectiles.js index 3176dc9d3..45db2cade 100644 --- a/server/modules/definitions/groups/projectiles.js +++ b/server/modules/definitions/groups/projectiles.js @@ -623,6 +623,17 @@ Class.shotTrapBox = { PARENT: 'unsetTrap', MOTION_TYPE: "glide", } +Class.ramrodTrap = { + PARENT: "setTrap", + INDEPENDENT: true, + FACING_TYPE: "withMaster", + CONTROLLERS: ["nearestDifferentMaster"], + GUNS: [ + { + POSITION: [30, 10, 1, 0, 0, 90, 0] + } + ] +} // Pillboxes Class.pillbox = { @@ -1334,4 +1345,50 @@ Class.polygunMinion = { POSITION: [9, 8, 0, 270, 170, 0], TYPE: "autoTurret3" }] -}; \ No newline at end of file +}; + Class.undertowBlock = { + PARENT: 'setTrap', + ON: [ + { + event: "tick", + handler: ({ body }) => { + for (let instance of entities) { + let diffX = instance.x - body.x, + diffY = instance.y - body.y, + dist2 = diffX ** 2 + diffY ** 2; + if (dist2 <= ((body.size / 12)*250) ** 1.9) { + if ((instance.team != body.team || (instance.type == "undertowEffect" && instance.master.id == body.master.id)) && instance.type != "wall" && instance.isTurret != true) { + if (instance.type == "undertowEffect") { + forceMulti = 1 + } + else if (instance.type == "food") { + forceMulti = (6 / instance.size) + } + else { + forceMulti = (2 / instance.size) + } + instance.velocity.x += util.clamp(body.x - instance.x, -90, 90) * instance.damp * forceMulti;//0.05 + instance.velocity.y += util.clamp(body.y - instance.y, -90, 90) * instance.damp * forceMulti;//0.05 + if (instance.type != "undertowEffect" && instance.type != "bullet" && instance.type != "swarm" && instance.type != "drone" && instance.type != "trap" && instance.type != "dominator") { + let o = new Entity({x: instance.x, y: instance.y}) + o.define('undertowEffect') + o.team = body.team; + o.color = instance.color; + o.alpha = 0.3; + o.master = body.master; + } + } + } + if (dist2 < body.size ** 3 + instance.size ** 3) { + if (instance.master.id == body.master.id) { + if (instance.type == "undertowEffect") + { + instance.kill(); + } + } + } + } + } + } + ], + } \ No newline at end of file diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 38dd8e69d..cc63b7b8d 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -2841,6 +2841,47 @@ Class.assembler = { } ] } +Class.ramrod = { + PARENT: "genericTank", + LABEL: "RamRod (BETA)", + DANGER: 6, + STAT_NAMES: statnames.trap, + MAX_CHILDREN: 1, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.2 * base.FOV + }, + GUNS: [ + { + POSITION: [18, 12, 1, 0, 0, 0, 0], + }, { + POSITION: [2, 12, 1.1, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, {size: 2, health: 1.5, damage: 0.7}]), + TYPE: "ramrodTrap", + STAT_CALCULATOR: "block" + } + } + ] +} + +for (let i = 0; i < 2; i++) { + Class.ramrod.GUNS.push( + { + POSITION: [3, 3, 0.001, -5, 14 - (i * 3), -90, 0] + }, { + POSITION: [3, 3, 0.001, -5, -14 + (i * 3), 90, 0] + } + ) +} + +Class.ramrod.GUNS.push( + { + POSITION: [15, 2, 1, 0, -6, 0, 0] + }, { + POSITION: [15, 2, 1, 0, 6, 0, 0] + } +) // Tri-Trapper upgrades Class.hexaTrapper = makeAuto({ @@ -4404,7 +4445,7 @@ Class.hivemind = { } }, { - POSITION: [0, 20, 1, 0, 0, 90, 3], + POSITION: [0, 20, 1, 0, 0, 90, 1], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 5 }]), TYPE: "hiveprobe", @@ -4413,9 +4454,9 @@ Class.hivemind = { } }, { - POSITION: [0, 20, 1, 0, 0, 270, 3.5], + POSITION: [0, 20, 1, 0, 0, 270, 1], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 10 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 5 }]), TYPE: "hiveprobe", MAX_CHILDREN: 1, WAIT_TO_CYCLE: true @@ -4444,9 +4485,9 @@ Class.cloner = { } }, { - POSITION: [0, 20, 1, 0, 0, 270, 3.5], + POSITION: [0, 20, 1, 0, 0, 270, 1], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 10 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 5 }]), TYPE: "clonerprobe", MAX_CHILDREN: 1, WAIT_TO_CYCLE: true @@ -6730,7 +6771,8 @@ Class.radon = { } Class.accelmachinegun = { PARENT: "genericTank", - LABEL: "Machine Gun", + LABEL: "Watt", + DANGER: 6, GUNS: [ { POSITION: [8, .1, -54, 19, 0, 0, 0], @@ -6749,6 +6791,55 @@ Class.accelmachinegun = { } ] } +Class.accelArtillery = { + PARENT: "genericTank", + LABEL: "Cannon", + DANGER: 7, + GUNS: [ + { + POSITION: [8, .1, -37, 19, -6, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.fake]), + TYPE: "bullet", + COLOR: 12 + } + }, + { + POSITION: [8, .1, -37, 19, 6, 7, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.fake]), + TYPE: "bullet", + COLOR: 12 + } + }, + { + POSITION: [17, 3, 1, 0, -6, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.rainmaker]), + TYPE: "bullet", + LABEL: "Secondary", + MOTION_TYPE: "accelerate" + }, + }, + { + POSITION: [17, 3, 1, 0, 6, 7, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.rainmaker]), + TYPE: "bullet", + LABEL: "Secondary", + MOTION_TYPE: "accelerate" + }, + }, + { + POSITION: [19, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), + TYPE: "bullet", + LABEL: "Heavy", + }, + }, + ], +} Class.gatlinggun = { PARENT: "genericTank", LABEL: "Gatling Gun", @@ -8585,6 +8676,7 @@ Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "di Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner", "waterfall", "helecopter", "auraGunner"] Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "Sprayinception", "autoSprayer", "spraybrid", "auraSprayer"] Class.gatlinggun.UPGRADES_TIER_3 = ["focal", "Gatlinception", "accelgatlinggun", "autoGatlinggun", "gatlinggunbrid", "auraGatlinggun"] + Class.accelmachinegun.UPGRADES_TIER_3 = ["accelArtillery", "accelminigun", "accelgatlinggun"] Class.miniVulc.UPGRADES_TIER_3 = ["nailgun", "vulcan", "miniVulcTrap", "autominiVulc", "miniVulcbrid", "auraMiniVulc"] Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank", "flankbrid", "flankdue", /*"flankinception", */"backShield", "littleFlankArtillery", "auraFlankGuard"] @@ -8610,7 +8702,7 @@ Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "di Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "wark", "contagion", "icetrapper", "autoTrap", "trapbrid", "littleTrapArtillery", "auraTrapper"] Class.trapper.UPGRADES_TIER_3 = ["barricade"] - Class.builder.UPGRADES_TIER_3 = ["construct", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "icebuilder", "autoBuilder", "builderbrid", "auraBuilder"] + Class.builder.UPGRADES_TIER_3 = ["construct", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "icebuilder", "ramrod", "autoBuilder", "builderbrid", "auraBuilder"] Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "triContagion", "icetriTrapper", "tritrapperbrid", "auraTriTrapper"] Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "icetrapGuard", "miniVulcTrap", "autoTrapGuard", "trapguardbrid", "auraTrapGuard", "whirlGuard"] Class.wark.UPGRADES_TIER_3 = ["bulwark", "twincontagion", "icewark", "autowark", "warkbrid", "auraWark"] diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index d90cef15e..f649430ca 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -1976,6 +1976,9 @@ class Entity extends EventEmitter { case "locksFacing": if (!this.control.alt) this.facing = Math.atan2(t.y, t.x); break; + case "withMaster": + if (this.master.independent) this.facing = this.master.facing + break; case "looseWithTarget": case "looseToTarget": case "smoothToTarget": diff --git a/server/permissions.js b/server/permissions.js index 0f58cbf71..b79f2cf96 100644 --- a/server/permissions.js +++ b/server/permissions.js @@ -39,10 +39,11 @@ module.exports = [ { "key": process.env.TOKEN_5, "discordID": "0", - "nameColor": "#ffffff", + "nameColor": "rainbow", "class": "developer", "infiniteLevelUp": true, "name": "unnamed#0000", - "note": "note here" + "note": "note here", + "administrator": true }, ] \ No newline at end of file
    +
    -
    This Arras.io Private Server runs on Open Source Arras.
    For more info, visit the GitHub Repository.

    Not an official Arras.io project. We are not associated with Arras.io or Momentum Studios.
    + + +
    +

    view notes ▸

    +
    +
    + +
    +
    Nero.io runs on Open Source Arras. For more info,
    visit the APS++ GitHub Repository by Taureon And Join The Nero.io Discord With The Widget In The Top Right
    +
    +

    Date Since Creation

    +
    +
    -
    -

    Open Source Arras

    -
    -

    Connecting...

    -
    + - +

    -

    view options ▸

    +

    view options ▸ ≡


    - Advanced Controls:
    - +
    AppearanceOptionsControlsLinks
    +
    +
    All Controls
    +
    + + - + - - - + + + +
    W - move up A - move left
    S - move down D - move right
    E - auto-fire C - auto-spin
    R - disable AI N - level up
    V - reverse tank F - auto-alt
    V - reverse tank G - auto-alt
    B - reverse mouse O - self-destruct
    T - show tank treeM - maximize stat
    X - spin lock P - developer tank*
    * = requires valid token
    T - show tank treeL - stats for nerds
    X - spin lock H - take control
    - - placeholder - - placeholder
    - - placeholder - - placeholder
    - Options: +
    +
    +
    Themes
    + + + + + +
    +
    +
    UI Stuff
    - + +
    +
    +
    +
    Performance & Optimization
    + + - - + + + + + +
    +
    Miscellaneous
    + - +
    +
    +
    -
    - +
    +
    -
    +
    +
    +
    +
    +
    + + +
    +
    +
    +

    Achievements

    +
    +
    + +
    + +
    + +
    +
    +
    +

    Skins

    +
    +
    +

    Default

    +
    + + +
    + +
    ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○
    +
    + + + +
    @@ -139,9 +557,10 @@

    view options ▸

    + - + \ No newline at end of file diff --git a/public/lib/canvas.js b/public/lib/canvas.js index d12f84314..10e5c5ca9 100644 --- a/public/lib/canvas.js +++ b/public/lib/canvas.js @@ -7,7 +7,7 @@ class Canvas { this.target = global.target; this.socket = global.socket; this.directions = []; - + this.wikiInput = document.getElementById("wikiTankThing"); this.chatInput = document.getElementById('chatInput'); this.chatInput.addEventListener('keydown', event => { if (![global.KEY_ENTER, global.KEY_ESC].includes(event.keyCode)) return; @@ -18,6 +18,17 @@ class Canvas { if (event.keyCode === global.KEY_ENTER) this.socket.talk('M', this.chatInput.value); this.chatInput.value = ""; }); + this.wikiInput.addEventListener('keydown', event => { + if (global.wiki && global.gameStart) { + if (event.keyCode === global.KEY_ENTER) { + if (this.wikiInput.value != "") { + global.wikidisplaytank = this.wikiInput.value; + this.wikiInput.value = ""; + } + this.cv.focus(); + } + } + }); this.cv = document.getElementById('gameCanvas'); this.cv.addEventListener('mousemove', event => this.mouseMove(event), false); @@ -64,13 +75,21 @@ class Canvas { if (global.showTree) this.treeScrollSpeedMultiplier = 5; else this.socket.cmd.set(6, true); break; - + case global.KEY_PING: + global.showDebug = !0; + break; case global.KEY_ENTER: + global.killsoundready = true // Enter to respawn if (global.died) { - this.socket.talk('s', global.playerName, 0, 1 * settings.game.autoLevelUp); + this.socket.talk('s', global.playerName, 0, 1 * settings.game.autoLevelUp, global.skin); global.died = false; - break; + break; + } + + if (global.wiki && global.gameStart) { + this.wikiInput.focus(); + break; } // or to talk instead @@ -94,11 +113,19 @@ class Canvas { case global.KEY_LEFT_ARROW: if (!global.died && global.showTree) return global.scrollVelocityX = -this.treeScrollSpeed * this.treeScrollSpeedMultiplier; case global.KEY_LEFT: + if (global.wiki && global.gameStart) { + global.wikidisplaytank = parseInt(global.wikidisplaytank) - 1; + break; + } this.socket.cmd.set(2, true); break; case global.KEY_RIGHT_ARROW: if (!global.died && global.showTree) return global.scrollVelocityX = +this.treeScrollSpeed * this.treeScrollSpeedMultiplier; case global.KEY_RIGHT: + if (global.wiki && global.gameStart) { + global.wikidisplaytank = parseInt(global.wikidisplaytank) + 1; + break; + } this.socket.cmd.set(3, true); break; case global.KEY_MOUSE_0: @@ -125,6 +152,61 @@ class Canvas { case global.KEY_SUICIDE: this.socket.talk('1'); break; + case global.KEY_TELEPORT: + this.socket.talk('testTeleport'); + break; + case global.KEY_SMALLER_TANK: + this.socket.talk('smallerTank'); + break; + case global.KEY_BIGGER_TANK: + this.socket.talk('biggerTank'); + break; + case global.KEY_SMALLER_FOV: + this.socket.talk('smallerFOV'); + break; + case global.KEY_BIGGER_FOV: + this.socket.talk('biggerFOV'); + break; + case global.KEY_GOD_MODE: + this.socket.talk('godmodeButton'); + break; + case global.KEY_INVISIBLE: + this.socket.talk('invisibility'); + break; + case global.KEY_CAN_BE_ON_LEADERBOARD: + this.socket.talk('canBeOnLeaderboard'); + break; + case global.KEY_STRONG: + this.socket.talk('keyStrong'); + break; + case global.KEY_WATCH_THIS: + this.socket.talk('watchThis'); + break; + case global.KEY_DRAG: + this.socket.talk('drag'); + break; + case global.KEY_SPAWN_WALL: + this.socket.talk('spawnWall'); + break; + case global.KEY_RANDOM_TEST: + this.socket.talk('randomTestKey'); + break; + case global.KEY_HEAL: + this.socket.talk('heal'); + break; + case global.KEY_WIKI: + global.wiki = true; + document.querySelector("#wikiTankThing").style.display = 'block'; + break; + case global.KEY_ESC: + global.wiki = false; + document.querySelector("#wikiTankThing").style.display = 'none'; + case global.KEY_CHANGE_SONG: + const pmusic = ["https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3?v=1705287022417", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav?v=1705286889038", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3?v=1705807057028", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3?v=1708218475743", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3?v=1708218464295", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.wav?v=1713352428783", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"]; + var randmusic = pmusic[~~(Math.random() * pmusic.length)]; + global.music2.src = (randmusic); + global.music2.load(); + global.music2.play(); } if (!event.repeat) { switch (event.keyCode) { @@ -202,6 +284,9 @@ class Canvas { case global.KEY_UP: this.socket.cmd.set(0, false); break; + case global.KEY_PING: + global.showDebug = !1; + break; case global.KEY_DOWN_ARROW: global.scrollVelocityY = 0; case global.KEY_DOWN: diff --git a/public/lib/color.js b/public/lib/color.js index 9293836ab..8447c71e7 100644 --- a/public/lib/color.js +++ b/public/lib/color.js @@ -1,32 +1,32 @@ var color = { - "normal": { - "teal": "#7ad3db", - "lgreen": "#b9e87e", - "orange": "#e7896d", - "yellow": "#fdf380", - "lavender": "#b58efd", - "aqua": "#7adbba", - "pink": "#ef99c3", - "vlgrey": "#e8ebf7", - "lgrey": "#a4a4ad", //"#aa9f9e", - "guiwhite": "#ffffff", - "black": "#484848", - "blue": "#3ca4cb", - "green": "#8abc3f", - "red": "#e03e41", - "gold": "#efc74b", - "purple": "#8d6adf", - "magenta": "#cc669c", - "grey": "#a7a7af", - "dgrey": "#726f6f", - "white": "#dbdbdb", - "guiblack": "#000000", - "mustard": "#c49608", - "tangerine": "#ec7b0f", - "brown": "#895918", - "cyan": "#13808e", - "paletteSize": 20, - "border": 0.6509803921568628 + "nero": { + "teal": "#9EFFE0", + "lgreen": "#87FF8D", + "orange": "#FFB675", + "yellow": "#FDF380", + "lavender": "#b58efd", + "aqua": "#7adbba", + "pink": "#FFBDDD", + "vlgrey": "#E8EBF7", + "lgrey": "#b6b7ba", + "guiwhite": "#F0F0F0", + "black": "#484848", + "blue": "#52A8EB", + "green": "#8ABC3F", + "red": "#FC4E51", + "gold": "#EFC74B", + "purple": "#8D6ADF", + "magenta": "#ED2891", + "grey": "#A7A7AF", + "dgrey": "#726F6F", + "white": "#F0F8FA", + "guiblack": "#000000", + "mustard": "#c49608", + "tangerine": "#ec7b0f", + "brown": "#895918", + "cyan": "#13808e", + "paletteSize": 10, + "border": 0.65 }, "dark": { "teal": "#6ecedc", @@ -609,4 +609,4 @@ var color = { "border": 0 } }; -export { color } +export { color } \ No newline at end of file diff --git a/public/lib/gameDraw.js b/public/lib/gameDraw.js index 776c88d91..b2000f1a2 100644 --- a/public/lib/gameDraw.js +++ b/public/lib/gameDraw.js @@ -94,10 +94,10 @@ var gameDraw = { //TODO: somehow move the calculation to these in reanimateColors to improve performance colorCache: {}, modifyColor: (color, base = "16 0 1 0 false") => { - // Split into array + // Split into array let colorDetails = color.split(" "), baseDetails = base.split(" "); - + // Color mirroring if (colorDetails[0] == "-1" || colorDetails[0] == "mirror") { colorDetails[0] = baseDetails[0]; @@ -156,21 +156,26 @@ var gameDraw = { lesbian: "", gay: "", bi: "", + nero: "", trans: "", magenta: "", blue_red: "", blue_grey: "", grey_blue: "", red_grey: "", - grey_red: "" + grey_red: "", + sans: "", + epilepsy: "" }, reanimateColors: () => { let now = Date.now(), - //six_gradient = Math.floor((now / 200) % 6), + six_gradient = Math.floor((now / 200) % 6), five_bars = Math.floor((now % 2000) / 400), three_bars = Math.floor((now % 2000) * 3 / 2000), + fourtyfive_bars = Math.floor((now % 4000) * 45 / 4000), blinker = 150 > now % 300, + seizure = 5 > now % 10, lesbian_magenta = "#a50062", lesbian_oredange = "#d62900", @@ -178,7 +183,7 @@ var gameDraw = { lesbian_useSecondSet = five_bars < 2, gay_transition = (now / 2000) % 1, - + ratio = (Math.sin(now / 2000 * Math.PI)) / 2 + 0.5, light_purple = { h: 258/360, s: 1, l: 0.84 }, purple = { h: 265/360, s: 0.69, l: 0.47 }, @@ -186,6 +191,16 @@ var gameDraw = { bi_pink = "#D70071", bi_purple = "#9C4E97", bi_blue = "#0035AA", + + nero_blue1 = "#4287F5", + nero_blue2 = "#3CA2F0", + nero_blue3 = "#70B5FF", + nero_blue4 = "#4B90DB", + nero_blue5 = "#355BBD", + nero_blue6 = "#1F4199", + nero_blue7 = "#242bbd", + nero_blue8 = "#1814E0", + nero_blue9 = "#2668d1", trans_pink = "#f7a8b8", trans_blue = "#55cdfc", @@ -206,6 +221,9 @@ var gameDraw = { gameDraw.animatedColor.grey_blue = blinker ? gameDraw.color.grey : gameDraw.color.blue; gameDraw.animatedColor.red_grey = blinker ? gameDraw.color.red : gameDraw.color.grey; gameDraw.animatedColor.grey_red = blinker ? gameDraw.color.grey : gameDraw.color.red; + gameDraw.animatedColor.epilepsy = seizure ? gameDraw.color.guiblack : gameDraw.color.guiwhite; + + gameDraw.animatedColor.nero = [nero_blue1, "#418CF4", "#4092F3", "#3E97F2", "#3D9DF1", nero_blue2, "#46A6F3", "#51AAF6", "#5BADF9", "#66B1FC", nero_blue3, "#69AEF8", "#61A6F1", "#5A9FE9", "#5297E2", nero_blue4, "#4785D5", "#427BCF", "#3E70C9", "#3966C3", nero_blue5, "#3156B6", "#2C51AF", "#284BA7", "#2346A0", nero_blue6, "#203DA0", "#2138A7", "#2234AF", "#232FB6", nero_blue7, "#2226C4", "#1F22CB", "#1D1DD2", "#1A19D9", nero_blue8, "#1B25DD", "#1E36DA", "#2046D7", "#2357D4", nero_blue9, "#2C6ED8", "#3174DF", "#377BE7", "#3C81EE", "#4287F5"][fourtyfive_bars]; }, animatedColors: { // police @@ -243,10 +261,18 @@ var gameDraw = { // bi 38: true, bi: true, - + // magenta 42: true, animatedMagenta: true, + + // nero + 43: true, + animatednero: true, + + // epil + 44: true, + animatedepilepsy: true }, getColor: (colorNumber) => { if (colorNumber[0] == '#') return colorNumber; @@ -413,6 +439,16 @@ var gameDraw = { case "42": case "animatedMagenta": return gameDraw.animatedColor.magenta; + + // nero shit + case "43": + case "animatednero": + case "nero": + return gameDraw.animatedColor.nero; + case "44": + case "animatedepilepsy": + case "epilepsy": + return gameDraw.animatedColor.epilepsy; } }, getColorDark: (givenColor) => { diff --git a/public/lib/global.js b/public/lib/global.js index 36d861af3..083df3af6 100644 --- a/public/lib/global.js +++ b/public/lib/global.js @@ -48,61 +48,79 @@ let Region = (size) => { }; const global = { - // Keys and other mathematical constants. You can find the list here: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode - KEY_ESC: 27,// Escape - KEY_ENTER: 13,// Enter - KEY_SHIFT: 16,// Shift - KEY_BECOME: 70,// F - KEY_CHAT: 13,// Enter - KEY_FIREFOOD: 119,// F8 - KEY_SPLIT: 32,// Space + // Keys and other mathematical constants + KEY_ESC: 27, + KEY_ENTER: 13, + KEY_SHIFT: 16, + KEY_BECOME: 70, + KEY_CHAT: 13, + KEY_FIREFOOD: 119, + KEY_SPLIT: 32, - KEY_LEFT: 65,// A - KEY_UP: 87,// W - KEY_RIGHT: 68,// D - KEY_DOWN: 83,// S - KEY_LEFT_ARROW: 37,// ArrowLeft - KEY_UP_ARROW: 38,// ArrowUp - KEY_RIGHT_ARROW: 39,// ArrowRight - KEY_DOWN_ARROW: 40,// ArrowDown + KEY_LEFT: 65, + KEY_UP: 87, + KEY_RIGHT: 68, + KEY_DOWN: 83, + KEY_LEFT_ARROW: 37, + KEY_UP_ARROW: 38, + KEY_RIGHT_ARROW: 39, + KEY_DOWN_ARROW: 40, - KEY_AUTO_SPIN: 67,// C - KEY_AUTO_FIRE: 69,// E - KEY_AUTO_ALT: 71,// G - KEY_OVER_RIDE: 82,// R - KEY_REVERSE_TANK: 86,// V - KEY_REVERSE_MOUSE: 66,// B - KEY_SPIN_LOCK: 88,// X + KEY_AUTO_SPIN: 67, + KEY_AUTO_FIRE: 69, + KEY_AUTO_ALT: 71, + KEY_OVER_RIDE: 82, + KEY_REVERSE_TANK: 86, + KEY_REVERSE_MOUSE: 66, + KEY_SPIN_LOCK: 88, KEY_LEVEL_UP: 78, - KEY_FUCK_YOU: 80,// P - KEY_CLASS_TREE: 84,// T - KEY_MAX_STAT: 77,// M - KEY_SUICIDE: 79,// O - KEY_ZOOM_OUT: 45,// ?? - KEY_ZOOM_IN: 61,// ?? + KEY_FUCK_YOU: 192, + KEY_PING: 76, + KEY_CLASS_TREE: 84, + KEY_MAX_STAT: 77, + KEY_SUICIDE: 79, + KEY_ZOOM_OUT: 45, + KEY_ZOOM_IN: 61, + KEY_TELEPORT: 80, + KEY_SMALLER_TANK: 188, + KEY_BIGGER_TANK: 190, + KEY_SMALLER_FOV: 187, + KEY_BIGGER_FOV: 189, + KEY_GOD_MODE: 186, + KEY_INVISIBLE: 222, + KEY_CAN_BE_ON_LEADERBOARD: 113, + KEY_STRONG: 191, + KEY_HEAL: 220, + KEY_WATCH_THIS: 219, + KEY_DRAG: 221, + KEY_SPAWN_WALL: 90, + KEY_RANDOM_TEST: 81, + KEY_CHANGE_SONG: 112, - KEY_UPGRADE_ATK: 49,// 1 - KEY_UPGRADE_HTL: 50,// 2 - KEY_UPGRADE_SPD: 51,// 3 - KEY_UPGRADE_STR: 52,// 4 - KEY_UPGRADE_PEN: 53,// 5 - KEY_UPGRADE_DAM: 54,// 6 - KEY_UPGRADE_RLD: 55,// 7 - KEY_UPGRADE_MOB: 56,// 8 - KEY_UPGRADE_RGN: 57,// 9 - KEY_UPGRADE_SHI: 48,// 0 - KEY_MOUSE_0: 32,// 32 - KEY_MOUSE_1: 86,// V - KEY_MOUSE_2: 16,// ShiftLeft - KEY_CHOOSE_1: 89,// Y - KEY_CHOOSE_2: 85,// U - KEY_CHOOSE_3: 73,// I - KEY_CHOOSE_4: 72,// H - KEY_CHOOSE_5: 74,// J - KEY_CHOOSE_6: 75,// K + KEY_UPGRADE_ATK: 49, + KEY_UPGRADE_HTL: 50, + KEY_UPGRADE_SPD: 51, + KEY_UPGRADE_STR: 52, + KEY_UPGRADE_PEN: 53, + KEY_UPGRADE_DAM: 54, + KEY_UPGRADE_RLD: 55, + KEY_UPGRADE_MOB: 56, + KEY_UPGRADE_RGN: 57, + KEY_UPGRADE_SHI: 48, + KEY_MOUSE_0: 32, + KEY_MOUSE_1: 86, + KEY_MOUSE_2: 16, + KEY_CHOOSE_1: 89, + KEY_CHOOSE_2: 85, + KEY_CHOOSE_3: 73, + KEY_CHOOSE_4: 72, + KEY_CHOOSE_5: 74, + KEY_CHOOSE_6: 75, + KEY_WIKI: 118, showTree: false, + showDebug: !1, scrollX: 0, realScrollX: 0, // Canvas @@ -119,6 +137,7 @@ const global = { died: false, kicked: false, continuity: false, + wiki: false, startPingTime: 0, toggleMassState: 0, backgroundColor: '#f2fbff', @@ -148,7 +167,18 @@ const global = { lastrender: 0, rendergap: 0, lastuplink: 0, + killcount: 0, + shapecount: 0, }, + emojiloaded: false, + wikidisplaytank: 999, + ISTHEGODAMNFUCKINGGAMEON: "no", + killsoundready: true, + skin: "", + skinpage: 0, + savedkillcount: 0, + savedshapecount: 0, + lockedornot: 0, mouse: { x: 0, y: 0}, target: { x: 0, y: 0 }, reverseTank: 1, @@ -157,6 +187,12 @@ const global = { ratio: window.devicePixelRatio, mockupLoading: { then: cb => cb() }, treeScale: 1, - chats: {} + chats: {}, + music2: { + src: "", + songname: "", + }, + stopthefuckingkillsoundyouprick: false, + }; export { global } diff --git a/public/lib/json/color.json b/public/lib/json/color.json index 6c64942c4..d201cdd04 100644 --- a/public/lib/json/color.json +++ b/public/lib/json/color.json @@ -1,4 +1,33 @@ { + "nero": { + "teal": "#9EFFE0", + "lgreen": "#87FF8D", + "orange": "#FFB675", + "yellow": "#FDF380", + "lavender": "#b58efd", + "aqua": "#7adbba", + "pink": "#FFBDDD", + "vlgrey": "#E8EBF7", + "lgrey": "#b6b7ba", + "guiwhite": "#F0F0F0", + "black": "#484848", + "blue": "#52A8EB", + "green": "#8ABC3F", + "red": "#FC4E51", + "gold": "#EFC74B", + "purple": "#8D6ADF", + "magenta": "#ED2891", + "grey": "#A7A7AF", + "dgrey": "#726F6F", + "white": "#F0F8FA", + "guiblack": "#000000", + "mustard": "#c49608", + "tangerine": "#ec7b0f", + "brown": "#895918", + "cyan": "#13808e", + "paletteSize": 10, + "border": 0.65 + }, "normal": { "teal": "#7ad3db", "lgreen": "#b9e87e", diff --git a/public/lib/json/manifest.json b/public/lib/json/manifest.json index edb615004..8d9cdc749 100644 --- a/public/lib/json/manifest.json +++ b/public/lib/json/manifest.json @@ -1,15 +1,15 @@ { - "name": "Open Source Arras", - "theme_color": "#454b7f", + "name": "Nero.io 2", + "theme_color": "#000000", "background_color": "#484948", - "description": "This server runs on Open Source Arras.", + "description": "Nero.io 2 runs on Open Source Arras.", "orientation": "landscape", "start_url": "/", "scope": "/", "display": "fullscreen", "icons": [{ - "src": "round.png", + "src": "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png?v=1701910145704", "sizes": "96x96", "type": "image/png" }] -} +} \ No newline at end of file diff --git a/public/lib/settings.js b/public/lib/settings.js index 5991c0fe4..ac519ff62 100644 --- a/public/lib/settings.js +++ b/public/lib/settings.js @@ -7,7 +7,7 @@ const settings = { deathBlurAmount: 3, darkBorders: false, fancyAnimations: true, - colors: 'normal', + colors: 'nero', pointy: true, fontSizeBoost: 1.4, fontStrokeRatio: 4.5, diff --git a/public/lib/socketInit.js b/public/lib/socketInit.js index 8d841f31f..1b12c3ec2 100644 --- a/public/lib/socketInit.js +++ b/public/lib/socketInit.js @@ -809,6 +809,11 @@ const socketInit = port => { if (socket.cmd.check()) socket.cmd.talk(); }); }; + var KillSound = new Audio(); + function PlaySoundKS() { + KillSound.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Voicy_Slap%20Battles%20Killstreak%20Kill.mp3?v=1714045643190"); + KillSound.play(); + } // Handle incoming messages socket.onmessage = async function socketMessage(message) { await new Promise(Resolve => setTimeout(Resolve, window.fakeLagMS)); @@ -822,7 +827,7 @@ const socketInit = port => { case 'w': // welcome to the game if (m[0]) { // Ask to spawn console.log('The server has welcomed us to the game room. Sending spawn request.'); - socket.talk('s', global.playerName, 1, 1 * settings.game.autoLevelUp); + socket.talk('s', global.playerName, 1, 1 * settings.game.autoLevelUp, global.skin); global.message = ''; } break; @@ -845,6 +850,24 @@ const socketInit = port => { global.message = m[0]; console.log(m[0]); break; + case "achieve": + const achievementTable = ['killachievement', 'killachievement2', 'tokenachievement'] // lookup table of achievements and their ids + util.submitAchievementToLocalStorage(achievementTable[m[0]]) // whatever code to actually give the player the achievement + break; + case "killgained": + PlaySoundKS() + global.metrics.killcount += 1; + global.savedkillcount = (Number(localStorage.getItem("savedkills")) + 1); + localStorage.setItem("savedkills", global.savedkillcount.toString()); + break; + case "shapegained": + global.metrics.shapecount += 1; + global.savedshapecount = (Number(localStorage.getItem("savedshapes")) + 1); + localStorage.setItem("savedshapes", global.savedshapecount.toString()); + break; + case "killstreakreset": + global.metrics.killcount = 0; + break; case 'c': // force camera move global.player.renderx = global.player.cx = m[0]; global.player.rendery = global.player.cy = m[1]; @@ -891,6 +914,7 @@ const socketInit = port => { global.gameStart = true; global.entities = []; global.message = ''; + global.stopthefuckingkillsoundyouprick = true; }); } break; @@ -1033,4 +1057,4 @@ const socketInit = port => { return socket; }; -export { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow }; +export { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow }; \ No newline at end of file diff --git a/public/lib/tankdesc.js b/public/lib/tankdesc.js new file mode 100644 index 000000000..d6926f36b --- /dev/null +++ b/public/lib/tankdesc.js @@ -0,0 +1,545 @@ +const tankdescs = { +/* + template: { + type: "", + desc: "", + tier: "", + weapons: "", + abilities: "", + weak: "", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "", + origin: "", + updateadded: "", + } +*/ + basic: { + type: "Catalyst", + desc: "The Starting Tank Of Nero.io, The Beginning Of Nero.io, The Catalyst Of Nero.io, It Starts It All.", + tier: "1", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: Twin, Sniper, Machine Gun, Flank Guard, Director, Pounder, Trapper, Auto-Basic, Desmos, Basic-Hybrid, Subduer, Inception.", + "Tier 3: Smasher, Cloner.", + "Misc: Daily Tank", + "---"], + upgradesfrom: "N/A", + origin: "diep.io", + updateadded: "1.0", + }, + twin: { + type: "Assaulter", + desc: "Basic With An Extra Front Barrel. Good If You Like More Barrels Without Losing Too Much Penetration. Excels In Mid To Long-ish Range Combat.", + tier: "2", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 3: Double Twin, Triple Shot, Gunner, Hexa Tank, Auto Twin, Helix, Twin Hybrid, Binary", + "Tier 4: Bulwark, Musket", + "---", + "---"], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + sniper: { + type: "Ranger", + desc: "Longer and more Powerful Basic. Good for Long Range, Dont Get Too Close To Your Enemy Though As Snipers Are Meant For Long Range Combat Afterall...", + tier: "2", + weapons: "Bullets", + abilities: "N/A", + weak: "Drones, Close Range", + upgradesto: ["Tier 2: Assassin, Hunter", + "Tier 3: ", + "Tier 4: ", + "Misc: N/A"], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + machineGun: { + type: "Spammer", + desc: "Easy To Play As, Fun To Use. Good For Spamming, Not The Best Idea To Go Up Against High Penetration Tanks Though!", + tier: "2", + weapons: "Bullets", + abilities: "N/A", + weak: "Drones, Snipers", + upgradesto: ["Tier 2: Gunner", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + flankGuard: { + type: "Assaulter", + desc: "Guards Your Back From Sneaky People. Great At Getting More Bullet Coverage. Well Balanced And Serves Its Perpose", + tier: "2", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: Hexa Tank, Tri-Angle", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + director: { + type: "Controller", + desc: "Instead Of Bullets, Try Drones! Control Them With The Cursor. Beware Though, The Drones May Not Go As Fast As You Want Them To.", + tier: "2", + weapons: "Drones", + abilities: "N/A", + weak: "Assaulters, Fast Tanks", + upgradesto: ["Tier 2: Overseer", + "Tier 3: ", + "Tier 4: ", + "Misc: N/A"], + upgradesfrom: "Basic", + origin: "arras.io", + updateadded: "1.0", + }, + pounder: { + type: "Lobber", + desc: "Heavier Bullets With More Of A Kick To Them. Great For Close Combat, Just Dont Let The Slower Fire Rate And Bullet Speed Kill You!", + tier: "2", + weapons: "Bullet", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: Destroyer", + "Tier 3: ", + "Tier 4: ", + "Misc: N/A"], + upgradesfrom: "Basic", + origin: "arras.io", + updateadded: "1.0", + }, + trapper: { + type: "Defender", + desc: "Deploys Traps Instead Of Bullets, These Act Like Shields To Protect You From Things. They Arent Invincible Though!", + tier: "2", + weapons: "Traps", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.6", + }, + desmos: { + type: "Siner", + desc: "Gives Bullets The Ability To Act Like Waves, Helpful For Getting Around High Bullet Health Coming Straight At You", + tier: "2", + weapons: "Sine-Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "arras.io", + updateadded: "2.8", + }, + smasher: { + type: "Banger", + desc: "No Guns, Only Melee Damage. For People Who Like Agressive Playstyles Or Just Want Something More In Your Control", + tier: "3", + weapons: "Armour", + abilities: "N/A", + weak: "Anything Faster", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + healer: { + type: "Supporter", + desc: "", + tier: "3", + weapons: "Healer-Bullets", + abilities: "Healing", + weak: "", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic?Siege", + origin: "arras.io", + updateadded: "2.8", + }, + doubleTwin: { + type: "Assaulter", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Twin, Flank Guard", + origin: "diep.io", + updateadded: "1.0", + }, + tripleShot: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "", + origin: "diep.io", + updateadded: "1.0", + }, + tripleTwin: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "", + origin: "diep.io", + updateadded: "1.0", + }, + hewnDouble: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Double Twin", + origin: "arras.io", + updateadded: "1.0", + }, + pentaShot: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Triple Shot", + origin: "diep.io", + updateadded: "1.0", + }, + spreadshot: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Triple Shot", + origin: "diep.io", + updateadded: "1.0", + }, + bentDouble: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Penta Shot, Double Twin", + origin: "arras.io", + updateadded: "1.0", + }, + triplet: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Triple Shot", + origin: "diep.io", + updateadded: "1.0", + }, + assassin: { + type: "Ranger", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper", + origin: "diep.io", + updateadded: "1.0", + }, + hunter: { + type: "Ranger-Stacker", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "Scope", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper", + origin: "diep.io", + updateadded: "1.0", + }, + rifle: { + type: "Ranger", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper", + origin: "arras.io", + updateadded: "2.2", + }, + ranger: { + type: "Ranger", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Assassin", + origin: "diep.io", + updateadded: "1.0", + }, + stalker: { + type: "Ranger-Ghoster", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "Invisibility", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Assassin", + origin: "diep.io", + updateadded: "2.3", + }, + single: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Assassin", + origin: "arras.io", + updateadded: "1.0", + }, + predator: { + type: "Ranger-Stacker", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "Scope", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Hunter", + origin: "diep.io", + updateadded: "1.0", + }, + xHunter: { + type: "Ranger-Stacker", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "Heavy Scope", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Hunter", + origin: "arras.io", + updateadded: "2.7", + }, + dual: { + type: "Ranger-Stacker", + desc: "Hunter With Dual Barrels Similar To Twin", + tier: "4", + weapons: "Bullets", + abilities: "Scope", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Hunter", + origin: "arras.io", + updateadded: "1.2", + }, + musket: { + type: "Ranger-Assaulter", + desc: "Rifle With Dual Barrels Similar To Twin", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Rifle, Twiper", + origin: "arras.io", + updateadded: "2.2", + }, + crossbow: { + type: "Ranger-Assaulter", + desc: "Rifle With Added Mini Barrels", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Rifle", + origin: "arras.io", + updateadded: "2.2", + }, + minigun: { + type: "Spammer", + desc: "3 Stacked Barrels Firing Very Fast", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper, Machine Gun, Subduer", + origin: "arras.io", + updateadded: "1.0", + }, + gunner: { + type: "Spammer", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Twin, Machine Gun", + origin: "diep.io", + updateadded: "1.0", + }, + sprayer: { + type: "Spammer", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Machine Gun, Subduer", + origin: "diep.io", + updateadded: "1.0", + }, + streamliner: { + type: "Spammer", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Minigun", + origin: "diep.io", + updateadded: "1.0", + }, + barricade: { + type: "Defense-Spammer", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Trapper, Minigun", + origin: "arras.io", + updateadded: "2.6", + } +}; +export { tankdescs } \ No newline at end of file diff --git a/public/lib/util.js b/public/lib/util.js index d0b93dad3..2e26ececb 100644 --- a/public/lib/util.js +++ b/public/lib/util.js @@ -11,6 +11,17 @@ const util = { document.getElementById(name).checked = localStorage.getItem(name + 'Checked') === 'true'; return false; }, + submitAchievementToLocalStorage: achive => { + localStorage.setItem(achive, "YOUDIDIT:D!!!"); + return false; + }, + resetAchievementFromLocalStorage: achive => { + localStorage.setItem(achive, "noachievement"); + return false; + }, + getTankWikiStats: name => { + return name; + }, handleLargeNumber: (a, cullZeroes = false) => { if (cullZeroes && a == 0) { return ''; @@ -199,6 +210,7 @@ const util = { facing: mainMockup.facing, shape: mainMockup.shape, name: name.substring(1), + className: mainMockup.className, upgradeTooltip: upgradeTooltip.substring(1), upgradeName: mainMockup.upgradeName, score: 0, @@ -246,9 +258,8 @@ const util = { }), }; }, - sizeMultipleMockups: (positionData) => { + sizeMultipleMockups: (positionData) => { let endPoints = []; - function rounder(val) { if (Math.abs(val) < 0.00001) val = 0; return +val.toPrecision(6); @@ -290,7 +301,6 @@ const util = { // Check point is on the line with a small margin return Math.abs(checkPoint[1] - predictedY) <= 1e-5; } - // Find circumcircle and circumcenter function constructCircumcirle(point1, point2, point3) { // Rounder to avoid floating point nonsense @@ -300,7 +310,6 @@ const util = { let y2 = rounder(point2[1]); let x3 = rounder(point3[0]); let y3 = rounder(point3[1]); - // Invalid math protection if (x3 == x1 || x3 == x2) { x3 += 1e-5; @@ -315,7 +324,6 @@ const util = { let y = (numer1 * factorX1 - numer2 * factorX2) / (factorY1 * factorX2 - factorY2 * factorX1); let x = ((y - y3) ** 2 - (y - y1) ** 2 - x1 ** 2 + x3 ** 2) / factorX2; let r = Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2)); - return {x, y, r}; } @@ -327,7 +335,6 @@ const util = { endPoints.push([middle.x + Math.cos(theta) * axis / 2, middle.y + Math.sin(theta) * axis / 2]); } } - // Convert to useful info endPoints.sort((a, b) => (b[0] ** 2 + b[1] ** 2 - a[0] ** 2 - a[1] ** 2)); let point1 = getFurthestFrom(0, 0), @@ -337,7 +344,6 @@ const util = { while (point1[0] == 0 && point2[0] == 0 || point1[1] == 0 && point2[1] == 0) { point2 = getFurthestFrom(...point1); } - let avgX = (point1[0] + point2[0]) / 2, avgY = (point1[1] + point2[1]) / 2, point3 = getFurthestFrom(avgX, avgY); @@ -348,7 +354,6 @@ const util = { } let {x, y, r} = constructCircumcirle(point1, point2, point3); - return { axis: r * 2, middle: {x, y}, diff --git a/public/main.css b/public/main.css index 43bd90677..18ecb7be6 100644 --- a/public/main.css +++ b/public/main.css @@ -1,6 +1,8 @@ :root { font-family: Ubuntu; font-size: 14px; + --backgroundColor: #DDE6EB; + --menuTextColor: #000000; } .conceal { @@ -8,7 +10,7 @@ } #mainBody { - background-color: #dbdbdb; + background-color: #484848; } ::-webkit-scrollbar { @@ -36,29 +38,51 @@ body { -moz-user-select: none; user-select: none; } - body { font-family: Ubuntu; font-size: 14px; - background-image: url('./osa_background_tile.png'); - background-repeat: repeat; - background-color: gray; + background-image: url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png?v=1713356636170"); + background-color: #484848; } html, body, -canvas { +canvas[id=gameCanvas] { width: 100%; height: 100%; margin: 0; padding: 0; } -canvas { +canvas[id=gameCanvas] { image-rendering: optimizeSpeed; image-rendering: pixelated; } +#content { + position: absolute; + top: 0; + left: 0; + background: #000000; + width: 100%; + height: 100%; +} + +canvas[id=musiccanvas] { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +audio { + position: fixed; + left: 10px; + bottom: 10px; + width: calc(100% - 20px); +} + #gameName { padding: 0; margin-top: 5px; @@ -67,7 +91,15 @@ canvas { font-size: xx-large; font-weight: bolder; } - +#gameName:active { + padding: 0; + margin-top: 5px; + margin-bottom: 10px; + text-align: center; + font-size: xx-large; + font-weight: bolder; + animation:pfpDefault 800ms linear both; +} h2 { font-size: small; color: #000000; @@ -85,10 +117,24 @@ options_header { text-align: center; } +miniupdate { + font-size: medium; + color: #000000; + font-weight: bold; + text-align: center; + font-size: 16px; + animation:pfpDefault 800ms linear both; +} + h3 { font-size: small; color: #484848; text-align: center; + animation:pfpDefault 800ms linear both; +} + +h3:hover { + animation:pfpDefault 800ms linear both; } h4 { @@ -139,14 +185,20 @@ input { } input.checkbox { - width: 13px; - height: 13px; + width: 15px; + height: 15px; padding: 0; margin: 0; vertical-align: bottom; position: relative; - top: -2px; + top: -1px; overflow: hidden; + font-family: Ubuntu; +} +input.checkbox:focus, +input.checkbox.focus { + border: none; + box-shadow: 0 0 0px 0px #DDDDDD; } #playerNameInput { @@ -157,6 +209,7 @@ input.checkbox { #playerKeyInput { padding: 3px; color: gray; + } input:focus, @@ -205,7 +258,7 @@ div { margin: auto; width: 1150px; padding: 10px; - margin-top: 100px; + margin-top: 74px; margin-bottom: 100px; border-radius: 5px; -moz-border-radius: 5px; @@ -223,14 +276,121 @@ div { .startMenuHolder { width: 350px; - height: 380px; + height: 365px; padding: 10px; overflow: hidden; display: inline-block; vertical-align: text-top; } +.replace1 { +right: 0; +} +.replace2 { +right: -50; +} +a.menuTab { + float: right; + height: 13px; + font: 13px Ubuntu; + border-radius: 0px 0px 5px 5px; + padding: 6px 10px 7px 10px; + color: #FFFFFF !important; + text-decoration: none; + margin-right: 10px; +} +a.menuTab.discordbutton { + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #6175ba; + box-shadow: inset 0 -2px #6175ba; + -webkit-box-shadow: inset 0 -2px #6175ba; + animation:pfpDefault 800ms linear both; + background: #7289DA url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/svg0.svg") 4px 3px/21px no-repeat; +} +a.menuTab.discordbutton:active, +a.menuTab.discordbutton:hover { + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} +a.menuTab.catto { + background: #FF0000 url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/coder.png") 8px 6px no-repeat; + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #c91a1a; + box-shadow: inset 0 -2px #c91a1a; + -webkit-box-shadow: inset 0 -2px #c91a1a; + animation:pfpDefault 800ms linear both; +} +a.menuTab.catto:active, +a.menuTab.catto:hover { + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} +a.menuTab.ach { + background: #2bab2f url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png?v=1708025693434") 3px 2px/23px no-repeat; + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #2a802d; + box-shadow: inset 0 -2px #2a802d; + -webkit-box-shadow: inset 0 -2px #2a802d; + animation:pfpDefault 800ms linear both; +} +a.menuTab.ach:active, +a.menuTab.ach:hover { + top: 1px; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +a.menuTab.skin { + background: #9900FF url("https://cdn.glitch.global/9b9522e6-a4f4-4511-8978-4c190b6759bd/stick.png?v=1708440293253") 3px 2px/23px no-repeat; + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #7b11c2; + box-shadow: inset 0 -2px #7b11c2; + -webkit-box-shadow: inset 0 -2px #7b11c2; + animation:pfpDefault 800ms linear both; +} +a.menuTab.skin:active, +a.menuTab.skin:hover { + top: 1px; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +a.menuTab.stat { + background: #1E8449 url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/play.png") 3px 2px/23px no-repeat; + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #156637; + box-shadow: inset 0 -2px #156637; + -webkit-box-shadow: inset 0 -2px #156637; + animation:pfpDefault 800ms linear both; +} +a.menuTab.stat:active, +a.menuTab.stat:hover { + top: 1px; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +a.menuTab.??? { + background: #FFFFFF url("https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/2022_06_23_11e_Kleki.png?v=1675997243695") 3px 2px/23px no-repeat; + padding: 6px 10px 7px 28px; + animation:pfpDefault 800ms linear both; +} +a.menuTab:link:hover, a.menuTab:visited:hover { + text-decoration: underline; + animation:pfpHoverOn 800ms linear both; +} .sliderHolder { + width: 350px; + height: 323px; + overflow: hidden; +} + +.sliderHolder2 { width: 350px; height: 325px; overflow: hidden; @@ -248,6 +408,7 @@ td { table { width: 100%; + color: black; } .slider { @@ -258,23 +419,97 @@ table { -moz-transition: top 500ms; -o-transition: top 500ms; transition: top 500ms; + animation:pfpDefault 800ms linear both; + transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1.2) +} + +.slider2 { + position: relative; + right: 0px; + width: 100%; + z-index: 0; + display: inline-block; + -webkit-transition: right 1000ms; + -moz-transition: right 1000ms; + -o-transition: right 1000ms; + transition: right 1000ms; + animation:pfpDefault 800ms linear both; + transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1) +} +.slider3 { + position: absolute; + z-index: -6; + right: 400px; + width: 100%; + display: inline-block; + -webkit-transition: right 1000ms; + -moz-transition: right 1000ms; + -o-transition: right 1000ms; + transition: right 1000ms; + animation:pfpDefault 800ms linear both; + transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1) +} + +.slidingtrigger3 { + position: relative; + top: 0px; + width: 100%; + -webkit-transition: top 500ms; + -moz-transition: top 500ms; + -o-transition: top 500ms; + transition: top 500ms; } #startMenuSlidingContent { - height: 305px; + height: 300px; } #startMenuSlidingTrigger { cursor: pointer; height: 15px; } - #startMenuSlidingTrigger:hover { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); } +#startMenuSlidingTrigger:active > h3 { + color: #323232; + animation:pfpDefault 800ms linear both; +} + +#startMenuSlidingTrigger:hover > h3 > i.arrow { + border-color: #323232; +} + +#startMenuSlidingTrigger2 { + cursor: pointer; +} +#startMenuSlidingTrigger2:hover { + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); +} +#startMenuSlidingTrigger2:active > h3 { + color: #323232; + animation:pfpDefault 800ms linear both; +} +#startMenuSlidingTrigger2:hover > h3 > i.arrow { + border-color: #323232; +} +#startMenuSlidingTrigger3 { + cursor: pointer; + height: 15px; +} + +#startMenuSlidingTrigger3:hover { + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); +} +.menuTabs { + height: 26px; + margin: 0 8px; +} update { color: #D83848; + animation:pfpDefault 800ms linear both; + font-weight: bold; } @@ -282,16 +517,56 @@ update { padding-left: 10px; font-size: x-large; font-weight: bold; - text-align: center; + text-align: justify; } .shrinkable { padding-left: 0px; width: 360px; } +#credits { + max-width: 330px; + /*animation:pfpDefault 800ms linear both;*/ + height: calc(100% - 100px); + padding: 5px 20px 10px; + overflow: hidden auto; + scrollbar-width: thin; + scrollbar-color: rgba(0, 0, 0, 0.3) rgba(0, 0, 0, 0.15); +} + +#credits div { + > .title { + margin: 0; + font-size: 1.5em; + font-weight: bold; + } + + > date { + color: rgba(0, 0, 0, 0.45); + font-style: italic; + } + + > ul li { + margin-left: 1em; + margin-bottom: .5em; + } + + position: relative; + /*animation:pfpDefault 800ms linear both;*/ + + &::before { + content: ''; + position: absolute; + bottom: 0; + width: 100%; + height: .1em; + background-color: gray; + } +} #patchNotes { max-width: 330px; + /*animation:pfpDefault 800ms linear both;*/ height: calc(100% - 100px); padding: 5px 20px 10px; overflow: hidden auto; @@ -304,8 +579,8 @@ update { margin: 0; font-size: 1.5em; font-weight: bold; - } - + } + > date { color: rgba(0, 0, 0, 0.45); font-style: italic; @@ -317,6 +592,7 @@ update { } position: relative; + /*animation:pfpDefault 800ms linear both;*/ &::before { content: ''; @@ -351,10 +627,12 @@ update { height: 40px; box-sizing: border-box; font-size: larger; + line-height: 0; color: white; + animation:pfpDefault 800ms linear both; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); - background: #336699; + background: #335099; /*background: #A9D86D;*/ border: 0; border-bottom: 2px solid #1B3353; @@ -369,14 +647,79 @@ update { -webkit-border-radius: 5px; } +#hideongamestart { + position: relative; + z-index: 3; + } + +#resetachievementsbutton { + font-family: Ubuntu; + line-height: 0; + top: 30px; + width: 100%; + height: 40px; + max-height: 100px; + top: 443px; + z-index: 3; + color: white; + animation:pfpDefault 800ms linear both; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); + background: #70b5ff; + font-family: Ubuntu; + position: relative; + border: 0; + border-bottom: 2px solid #1B3353; + cursor: pointer; + -webkit-box-shadow: inset 0 -2px #1B3353; + box-shadow: inset 0 -2px #1B3353; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + float: left; +} + +.icon { + animation:pfpDefault 800ms linear both; +} + +.icon:hover { + animation:pfpHoverOn 800ms linear both; +} + +.icon:active { + animation:pfpDefault 400ms linear both; +} + #startButton:active, #startButton:hover { top: 1px; - background: #1B3353; + background: #335099; + /*background: #A9D86D;*/ + border: 0; + border-bottom: 3px solid #1B3353; + /*background: #1B3353;*/ /*background: #8ABC3F;*/ + line-height: 25px; + text-align: center; outline: none; -webkit-box-shadow: none; box-shadow: none; + height: 39px; +} + +#resetachievementsbutton:active, +#resetachievementsbutton:hover { + line-height: 25px; + text-align: center; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; + height: 39px; + border: 0; + border-bottom: 3px solid #1B3353; + top: 444px; + } #bottomHolder { @@ -404,108 +747,132 @@ a.link { } .discord { + top: 2px; + animation:pfpDefault 800ms linear both; background: #7289da; + line-height: 15px; border-bottom: 2px solid #6175ba; box-shadow: inset 0 -2px #6175ba; -webkit-box-shadow: inset 0 -2px #6175ba; } .discord:active, .discord:hover { - top: 1px; - background: #6175ba; - outline: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -.revolt { - background: #fd6671; - border-bottom: 2px solid #ed4245; - box-shadow: inset 0 -2px #ed4245; - -webkit-box-shadow: inset 0 -2px #ed4245; -} -.revolt:active, -.revolt:hover { - top: 1px; - background: #ed4245; + top: 3px; + background: #7289da; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #6175ba; + box-shadow: inset 0 -2px #6175ba; + -webkit-box-shadow: inset 0 -2px #6175ba; } .reddit { + top: 2px; + animation:pfpDefault 800ms linear both; background: #f75401; + line-height: 15px; border-bottom: 2px solid #d24a01; box-shadow: inset 0 -2px #d24a01; -webkit-box-shadow: inset 0 -2px #d24a01; } + .reddit:active, .reddit:hover { - top: 1px; - background: #d24a01; + top: 3px; + background: #f75401; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #d24a01; + box-shadow: inset 0 -2px #d24a01; + -webkit-box-shadow: inset 0 -2px #d24a01; } .original { + top: 2px; + animation:pfpDefault 800ms linear both; background: #77bf79; + line-height: 15px; border-bottom: 2px solid #679c68; box-shadow: inset 0 -2px #679c68; -webkit-box-shadow: inset 0 -2px #679c68; } + .original:active, .original:hover { - top: 1px; - background: #679c68; + top: 3px; + background: #77bf79; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #679c68; + box-shadow: inset 0 -2px #679c68; + -webkit-box-shadow: inset 0 -2px #679c68; } .developer { + top: 2px; + animation:pfpDefault 800ms linear both; background: #454b7f; + line-height: 15px; border-bottom: 2px solid #313454; box-shadow: inset 0 -2px #313454; -webkit-box-shadow: inset 0 -2px #313454; } .developer:active, .developer:hover { - top: 1px; - background: #313454; + top: 3px; + background: #454b7f; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #313454; + box-shadow: inset 0 -2px #313454; + -webkit-box-shadow: inset 0 -2px #313454; } .youtube { + top: 2px; + animation:pfpDefault 800ms linear both; background: #f71701; + line-height: 15px; border-bottom: 2px solid #d21401; box-shadow: inset 0 -2px #d21401; -webkit-box-shadow: inset 0 -2px #d21401; } + .youtube:active, .youtube:hover { - top: 1px; - background: #d21401; + top: 3px; + background: #f71701; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #d21401; + box-shadow: inset 0 -2px #d21401; + -webkit-box-shadow: inset 0 -2px #d21401; } .github { + top: 2px; + animation:pfpDefault 800ms linear both; background: #666666; + line-height: 15px; border-bottom: 2px solid #333333; - -webkit-box-shadow: inset 0 -2px #333333; box-shadow: inset 0 -2px #333333; + -webkit-box-shadow: inset 0 -2px #333333; } .github:active, .github:hover { - top: 1px; - background: #333333; + top: 3px; + background: #666666; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #333333; + box-shadow: inset 0 -2px #333333; + -webkit-box-shadow: inset 0 -2px #333333; } #startMenuWrapper { @@ -565,6 +932,17 @@ a.link { color: black; background-color: #ffffff88; } +p.vsaucereference { + animation:pfpHoverOn 400ms linear both; + font-size: 13px; +} +p.vsaucereference:hover { + animation:pfpHoverOn 400ms linear both; +} + +p.vsaucereference:active { + animation: pfpDefault 800ms linear both; +} input [type="image"]:focus { border: none; @@ -575,4 +953,700 @@ input [type="image"]:focus { *:focus { outline: 1px solid transparent; border-style: none; +} +.popup { + position: absolute; + display: block; + width: auto; + max-width: 42%; + height: auto; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 3; + border-radius: 10px; + background: var(--backgroundColor); + padding: 10px; + font-size: larger; + text-align: center; + border-style: solid; + border-color: #c1cfd8; + color: var(--menuTextColor); +} + +.popup button { + margin: 15px; + padding: 10px 50px 10px 50px; + width: auto; + box-sizing: border-box; + color: white; + text-align: center; + text-shadow: 0 0 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.2); + background: #A9D86D; + border: 0; + border-bottom: 2px solid #8ABC3F; + cursor: pointer; + box-shadow: inset 0 -2px #8ABC3F; + border-radius: 5px; + font: 18px Ubuntu; +} + +.popup button:hover { + border-bottom: 1px solid #8ABC3F; +} + +.popup button:active { + background: #FFFFFF; + border-bottom: 0; + outline: none; + box-shadow: none; +} + +.popup span.small { + font-size: xx-large; + font-weight: bold; + color: black; + white-space: pre-line; +} + +.popup span { + font-size: x-large; + white-space: pre-line; + font-weight: light; + color: black; +} +.achievementsHolder { + position: absolute; + display: block; + width: 700px; + height: 550px; + padding-top: 50px; + top: 47.5%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 3; + background: var(--backgroundColor); + padding: 10px; + font-size: larger; + text-align: center; + border-style: solid; + border-color: #c1cfd8; + color: black; + display: none; +} + +.achievementsHolder span.small { + font-size: xx-large; + font-weight: bold; + color: black; + animation:pfpDefault 800ms linear both; +} + +.achievementsHolder span { + font-size: x-large; + font-weight: lighter; + color: black; + animation:pfpDefault 800ms linear both; +} + +#achievementsClose { + height: 45px; + width: 50px; + float: right; + position: relative; + opacity: .8; + background-image: url('data:image/svg+xml,%3Csvg xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" fill%3D"%23DD0000" viewBox%3D"0 0 16 16" width%3D"30" height%3D"30"%3E%3Cpath d%3D"M3 0 0 3 6 8 0 13 3 16 8 10 13 16 16 13 10 8 16 3 13 0 8 6 3 0Z"%3E%3C%2Fpath%3E%3C%2Fsvg%3E'); + background-repeat: no-repeat; + background-position: center; +} + +#achievementsClose:hover { + cursor: pointer; + opacity: 1; +} + +#achievementsDisplay { + height: 450px; + margin-top: -20px; + position: absolute; + animation:pfpDefault 800ms linear both; + width: 96.5%; + border-style: solid; + border-color: #c1cfd8; + background-color: rgba(0, 0, 0, 0.2); + background: url("https://cdn.glitch.global/ded4b664-3b74-4a3b-9282-9796baafc60b/41R6Ok5aeKL.jpg?v=1713446403687") 0px -550px/100% repeat; +} + +.achievementsItem { + margin: 16px 16px 12px 16px; + border-radius: 14px; + animation:pfpDefault 800ms linear both; + padding: 6px; + +} + +.achievementsItem h1 { + font-size: 22px; + animation:pfpDefault 800ms linear both; + font-weight: bold; + color: #22160b; +} + +.achievementsItem span { + font-size: 17px; + font-weight: bold; + animation:pfpDefault 800ms linear both; + color: #22160b; +} + +.greenachievement { + background-color: rgb(138, 187, 68); +} + +.greyachievement { + background-color: rgb(159, 159, 159); +} + +.bleenachievement { + background-color: rgb(125, 195, 235); +} + +.grueachievement { + background-color: rgb(160, 170, 180); +} + +#achievementsStatsTable td { + animation:pfpDefault 800ms linear both; + font-size: 18px; +} + +#achievementsStatsTable tr b { + animation:pfpDefault 800ms linear both; + font-size: 22px; +} +.autoBorder { + display: block; + border: 3.5px solid rgba(0, 0, 0, 0.35); +} +.metasip { + height: 10px; + width: 10px; + background-image: "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/svg0.svg" +} +#wikiTankThing { + display: none; + position: absolute; + top: 58.5vh; + left: 40%; + z-index: 5; + width: 20%; +} +.skinHolder { + position: absolute; + display: block; + width: 650px; + height: 600px; + top: 47.5%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 3; + background: var(--backgroundColor); + padding: 10px; + font-size: larger; + text-align: center; + border-style: solid; + border-color: #c1cfd8; + color: black; + display: none; +} + +.skinHolder span.small { + font-size: xx-large; + font-weight: bold; + color: black; + animation:pfpDefault 800ms linear both; +} + +.skinHolder span { + font-size: x-large; + font-weight: light; + color: black; + animation:pfpDefault 800ms linear both; +} + +#skinClose { + height: 45px; + width: 50px; + float: right; + position: relative; + opacity: .8; + background-image: url('data:image/svg+xml,%3Csvg xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" fill%3D"%23DD0000" viewBox%3D"0 0 16 16" width%3D"30" height%3D"30"%3E%3Cpath d%3D"M3 0 0 3 6 8 0 13 3 16 8 10 13 16 16 13 10 8 16 3 13 0 8 6 3 0Z"%3E%3C%2Fpath%3E%3C%2Fsvg%3E'); + background-repeat: no-repeat; + background-position: center; +} + +#skinClose:hover { + cursor: pointer; + opacity: 1; +} + +#skinDisplay { + height: 448px; + margin-top: -20px; + position: absolute; + animation:pfpDefault 800ms linear both; + width: 96.5%; + border-style: solid; + border-color: #c1cfd8; + background-color: rgba(0, 0, 0, 0.2); +} + +.skinItem { + margin: 16px 16px 12px 16px; + border-radius: 14px; + animation:pfpDefault 800ms linear both; + padding: 6px; + +} + +.skinItem h1 { + font-size: 22px; + animation:pfpDefault 800ms linear both; + font-weight: light; + color: #22160b; +} + +.skinItem span { + font-size: 17px; + font-weight: bold; + animation:pfpDefault 800ms linear both; + color: #22160b; +} + +#leftarrowbutton { + position: relative; + float: left; + height: 20%; + width: 20%; +} +#rightarrowbutton { + position: relative; + float: right; + height: 20%; + width: 20%; +} +#leftarrowbutton:active { + animation:pfpDefault 800ms linear both; +} +#rightarrowbutton:active { + animation:pfpDefault 800ms linear both; +} +.displaytest { + top: 0; + position: relative; + text-align: center; + margin-left: auto; + margin-right: auto; + margin-top: auto; +} +.displayskinname { + top: -2%; + position: relative; +} +#skinpdiv { + top: -3%; + position: relative; + margin-left: auto; + margin-right: auto; + width: 50%; +} +#skinpreview { + vertical-align: bottom; + width: 100%; + height: 100%; + z-index: 3; + +} +#selectskin { + vertical-align: bottom; + float: center; + margin-left: auto; + margin-right: auto; + height: 130px; + width: 260px; + z-index: 3; +} +#lockedskin { + display: none; + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + z-index: 3; +} +#lockbg { + display: inline-block; + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0.4; + z-index: -5; +} +#eventtitle { + position: absolute; + float: center; + top: 10%; + left: 50%; + color: white; + outline: #000000 solid; + z-index: 0; + cursor: pointer; + text-shadow: -1px -1px 0 #000000, 1px -1px 0 #000000, -1px 1px 0 #000000, 1px 1px 0 #000000; + background: #202020 url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/channels4_profile.jpg?v=1709324207088") 0px 0px/100px repeat; +} +.horizontalSelector { + padding: 4px 0; + margin-bottom: 4px; + font: bold 12px Ubuntu; + text-align: center; +} +.horizontalSelector span { + padding: 4px 10px; + color: #343434; + cursor: pointer; +} +.horizontalSelector span:hover { + color: #5f5f5f; +} +.horizontalSelector span.active { + background: #335099; + color: #ffffff; + border-radius: 5px; + cursor: default; +} +.tabappearance { + display: block; +} +.taboptions { + display: none; +} +.tabcontrols { + display: none; +} +.tablinks { + display: none; +} +#controls { + height: 200px; +} +.animpop { + animation:pfpDefault 800ms linear both; +} +.animinvert { + animation:invertation 2s linear both; + -webkit-animation-timing-function: linear; + animation-timing-function: linear; +} +.incog:active { + animation:wack2 2s linear 3; + -webkit-animation-timing-function: linear; + animation-timing-function: linear +} +.popuptaskbar { + display: block; + position: relative; + height: 50px; + width: 102.8%; + left: -10px; + top: -32px; + background: #2bab2f url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png?v=1708025693434") 0px 0px/50px no-repeat; +} +#achievementsHeader { + padding: 5px; + text-align: left; + margin-left: 50px; + color: #FFFFFF +} +.popuptaskbar2 { + display: block; + position: relative; + height: 50px; + width: 102.8%; + left: -10px; + top: -32px; + background: #9900FF url("https://cdn.glitch.global/9b9522e6-a4f4-4511-8978-4c190b6759bd/stick.png?v=1708440293253") 0px 0px/50px no-repeat; +} +#skinHeader { + padding: 5px; + text-align: left; + margin-left: 50px; + color: #FFFFFF +} +.atthebottom { + position: relative; + top: 425px; +} + +@keyframes pfpHoverOn { + 0% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 3.4% { transform: matrix3d(1.032, 0, 0, 0, 0, 1.041, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 4.7% { transform: matrix3d(1.045, 0, 0, 0, 0, 1.06, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 6.81% { transform: matrix3d(1.066, 0, 0, 0, 0, 1.089, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 9.41% { transform: matrix3d(1.088, 0, 0, 0, 0, 1.117, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 10.21% { transform: matrix3d(1.094, 0, 0, 0, 0, 1.123, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 13.61% { transform: matrix3d(1.112, 0, 0, 0, 0, 1.133, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 14.11% { transform: matrix3d(1.114, 0, 0, 0, 0, 1.133, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 17.52% { transform: matrix3d(1.121, 0, 0, 0, 0, 1.124, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 18.72% { transform: matrix3d(1.121, 0, 0, 0, 0, 1.119, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 21.32% { transform: matrix3d(1.12, 0, 0, 0, 0, 1.107, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 24.32% { transform: matrix3d(1.115, 0, 0, 0, 0, 1.096, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 25.23% { transform: matrix3d(1.113, 0, 0, 0, 0, 1.094, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 29.03% { transform: matrix3d(1.106, 0, 0, 0, 0, 1.09, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 29.93% { transform: matrix3d(1.105, 0, 0, 0, 0, 1.09, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 35.54% { transform: matrix3d(1.098, 0, 0, 0, 0, 1.096, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 36.74% { transform: matrix3d(1.097, 0, 0, 0, 0, 1.098, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 41.04% { transform: matrix3d(1.096, 0, 0, 0, 0, 1.102, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 44.44% { transform: matrix3d(1.097, 0, 0, 0, 0, 1.103, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 52.15% { transform: matrix3d(1.099, 0, 0, 0, 0, 1.101, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 59.86% { transform: matrix3d(1.101, 0, 0, 0, 0, 1.099, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 63.26% { transform: matrix3d(1.101, 0, 0, 0, 0, 1.099, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 75.28% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 85.49% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 90.69% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 100% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } +} + +@keyframes pfpDefault { + 0% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 3.4% { transform: matrix3d(1.068, 0, 0, 0, 0, 1.059, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 4.7% { transform: matrix3d(1.055, 0, 0, 0, 0, 1.04, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 6.81% { transform: matrix3d(1.034, 0, 0, 0, 0, 1.011, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 9.41% { transform: matrix3d(1.012, 0, 0, 0, 0, 0.983, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 10.21% { transform: matrix3d(1.006, 0, 0, 0, 0, 0.977, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 13.61% { transform: matrix3d(0.988, 0, 0, 0, 0, 0.967, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 14.11% { transform: matrix3d(0.986, 0, 0, 0, 0, 0.967, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 17.52% { transform: matrix3d(0.979, 0, 0, 0, 0, 0.976, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 18.72% { transform: matrix3d(0.979, 0, 0, 0, 0, 0.981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 21.32% { transform: matrix3d(0.98, 0, 0, 0, 0, 0.993, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 24.32% { transform: matrix3d(0.985, 0, 0, 0, 0, 1.004, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 25.23% { transform: matrix3d(0.987, 0, 0, 0, 0, 1.006, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 29.03% { transform: matrix3d(0.994, 0, 0, 0, 0, 1.01, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 29.93% { transform: matrix3d(0.995, 0, 0, 0, 0, 1.01, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 35.54% { transform: matrix3d(1.002, 0, 0, 0, 0, 1.004, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 36.74% { transform: matrix3d(1.003, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 41.04% { transform: matrix3d(1.004, 0, 0, 0, 0, 0.998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 44.44% { transform: matrix3d(1.003, 0, 0, 0, 0, 0.997, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 52.15% { transform: matrix3d(1.001, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 59.86% { transform: matrix3d(0.999, 0, 0, 0, 0, 1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 63.26% { transform: matrix3d(0.999, 0, 0, 0, 0, 1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 75.28% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 85.49% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 90.69% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 100% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } +} +@keyframes invertation { + 0% { + background-color: black; + color: white; + } + + 50% { + background-color: white; + -webkit-filter: invert(1); + filter: invert(1); + } +} +@keyframes wack { + 25% { + transform: scale(1, 5); + } + 75% { + transform: scale(5, 1) + } +} +@keyframes wack2 { + 20% { + transform: scale(100, 5); + } + 40% { + transform: scale(2, 10) + } + 60% { + transform: scale(0.2, 15); + } + 80% { + transform: scale(-10, 6) + } + 100% { + transform: scale(-3, -1) + } +} +@keyframes flashing { + 0% { + background-color: black; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + } + 5% { + background-color: black; + -webkit-filter: invert(1); + filter: invert(1); + } + 10% { + background-color: red; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + } + 15% { + background-color: red; + -webkit-filter: invert(1); + filter: invert(1); + } + 20% { + background-color: black; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + } + 25% { + background-color: black; + -webkit-filter: invert(1); + filter: invert(1); + } + 30% { + background-color: white; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + } + 35% { + background-color: white; + -webkit-filter: invert(1); + filter: invert(1); + } + 40% { + background-color: red; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + + } + 45% { + background-color: black; + } + 50% { + background-color: orange; + color: white; + } + 55% { + background-color: white; + } + 60% { + background-color: yellow; + } + 65% { + background-color: black; + } + 70% { + background-color: green; + } + + 75% { + background-color: white; + } + 80% { + background-color: blue; + } + 85% { + background-color: black; + } + 90% { + background-color: purple; + } + 95% { + background-color: white; + } +} +@keyframes pop { + 0% { + transform: scale(1, 1); + } + 5% { + transform: scale(0.9, 0.9); + } + 10% { + transform: scale(0.8, 0.8); + } + 15% { + transform: scale(0.7, 0.7); + } + 20% { + transform: scale(0.6, 0.6); + } + 25% { + transform: scale(0.5, 0.5); + } + 30% { + transform: scale(0.4, 0.4); + } + 35% { + transform: scale(0.3, 0.3); + } + 40% { + transform: scale(0.2, 0.2); + } + 45% { + transform: scale(0.1, 0.1); + } + 50% { + transform: scale(0, 0); + } + 55% { + transform: scale(0.1, 0.1); + } + 60% { + transform: scale(0.2, 0.2); + } + 65% { + transform: scale(0.3, 0.3); + } + 70% { + transform: scale(0.4, 0.4); + } + 75% { + transform: scale(0.5, 0.5); + } + 80% { + transform: scale(0.6, 0.6); + } + 85% { + transform: scale(0.7, 0.7); + } + 90% { + transform: scale(0.8, 0.8); + } + 95% { + transform: scale(0.9, 0.9); + } +} +@keyframes movedown { + 0% { + padding: 6px 10px 7px 28px; + } + 100% { + padding: 6px 10px 70px 28px; + } +} +@keyframes moveup { + 0% { + transform: translatey(100px); + } + 100% { + transform: translatey(0px); + } } \ No newline at end of file diff --git a/public/osa_background_tile.png b/public/osa_background_tile.png deleted file mode 100644 index 1266bc53d30cd59b94ef59271561b93664c7634d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 748 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 LBMqdQGyMMm(j~<0 diff --git a/run.bat b/public/run.bat similarity index 100% rename from run.bat rename to public/run.bat diff --git a/server/config.js b/server/config.js index 893ebd919..03c7fe9aa 100644 --- a/server/config.js +++ b/server/config.js @@ -3,10 +3,10 @@ module.exports = { // Game server domain. // If 'localhost:NUMBER', the port must equal the port setting. - host: "localhost:26301", + host: "neroio2.glitch.me", // Which port to run the web server on. - port: 26301, + port: 3000, // How often to update the list of the entities that players can see. // Has effects of when entities are activated. @@ -17,25 +17,25 @@ module.exports = { // Flatten entity definition, which gets rid of PARENT attributes and applies the parents' attributes to the entity definition, if they're not set in the entity already. flattenDefintions: false, - + // Log speed loop warnings LOGS: true, // The \modules\setup\gamemodeconfigs\ files to load. // To change specific things about specific gamemodes (such as team count for tdm), edit their config file in \modules\setup\gamemodeconfigs\. - GAME_MODES: ['tdm', 'domination'], + GAME_MODES: ['ffa'], // The room files to load in the setup/rooms folder. // NOTE: If a /gamemodeconfig/ file "replaces" the value of ROOM_SETUP, it just adds its own ROOM_SETUP's content to this array. // NOTE: Files starting with `map_` are maps. files starting with `overlay_` are overlays that get added on. // NOTE: These prefixes are only for categorisation, a room file would work the same regardless of its prefix. APS++ does nothing based on file name prefixes. - ROOM_SETUP: ['map_apspp_default'], + ROOM_SETUP: ['map_neroio_mazearena'], // The dimensions of a single tile on the map. - TILE_WIDTH: 400, - TILE_HEIGHT: 400, - - + TILE_WIDTH: 200, //400 + TILE_HEIGHT: 200, //400 + + // Miscellaneous @@ -45,43 +45,43 @@ module.exports = { // If you don't want your players to color their messages. // They get sanitized after addons interpret them, but before they're added to the chat message dictionary. - SANITIZE_CHAT_MESSAGE_COLORS: true, + SANITIZE_CHAT_MESSAGE_COLORS: false, // If someone tries to get a file that does not exist, send them this instead. DEFAULT_FILE: 'index.html', // Window name of the server terminal. - WINDOW_NAME: 'OSA Game Server Instance', + WINDOW_NAME: 'Nero Game Server Instance', // Allows you to type and run javascript code in the terminal. REPL_WINDOW: false, // Welcome message once a player spawns. - WELCOME_MESSAGE: "You have spawned! Welcome to the game.\n" - +"You will be invulnerable until you move or shoot.\n" - +"Please report any bugs you encounter!", + WELCOME_MESSAGE: "You have spawned! Welcome to the game, Hold N To Level Up.\n" + +"You will be invulnerable until you move or shoot OR ACCIDENTALLY PRESS THE FUCKING SPACE BAR.\n" + +"Please report any bugs you encounter on our discord! :)", + // How long a popup message lasts before fading out in milliseconds. MESSAGE_DISPLAY_TIME: 10_000, - // Physics // General multiplier for acceleration and max speeds. - runSpeed: 1.5, + runSpeed: 1.5, //1.5 // General damage multiplier everytime damage is dealt. - DAMAGE_CONSTANT: 0.5, + DAMAGE_CONSTANT: 0.5, // 0.5 // General knockback multiplier everytime knockback is applied. - KNOCKBACK_CONSTANT: 1.5, + KNOCKBACK_CONSTANT: 1.5, //1.5 // TODO: Figure out how the math behind this works. GLASS_HEALTH_FACTOR: 2, // How strong the force is that confines entities to the map and portals apply to entities. - ROOM_BOUND_FORCE: 0.01, + ROOM_BOUND_FORCE: 0.01, //0.01 @@ -111,20 +111,20 @@ module.exports = { LEVEL_CHEAT_CAP: 45, // Amount of player-bots to spawn. - BOTS: 0, + BOTS: 6, // How much XP player-bots get per second until they reach LEVEL_CAP. BOT_XP: 125, - + // How much XP player-bots will receive when first created. - BOT_START_XP: 0, + BOT_START_XP: 26302, // The chances of a player-bot upgrading a specific skill when skill upgrades are available. BOT_SKILL_UPGRADE_CHANCES: [ 1, 1, 3, 4, 4, 4, 4, 2, 1, 1], // The chances of a player-bot upgrading a specific amount of times before it stops upgrading. BOT_CLASS_UPGRADE_CHANCES: [ 1, 5, 20, 37, 37], - + // The prefix of the bot's name. BOT_NAME_PREFIX: "[AI] ", @@ -133,22 +133,22 @@ module.exports = { - // Natural Spawns + // Natural Spawns - FOOD_CAP: 3, // Max normal food per normal tile. - FOOD_SPAWN_CHANCE: 0.875, // Likeliness of normal food spawn attempts succeeding. - FOOD_SPAWN_COOLDOWN: 30, // Cooldown (in game ticks) of food spawn attempts being made. + FOOD_CAP: 1, // Max normal food per normal tile. 3 + FOOD_SPAWN_CHANCE: 0.1, // Likeliness of normal food spawn attempts succeedingg. 0.875 + FOOD_SPAWN_COOLDOWN: 60, // Cooldown (in game ticks) of food spawn attempts being made. 30 - FOOD_CAP_NEST: 3, // Max nest food per nest tile. - FOOD_SPAWN_CHANCE_NEST: 0.25, // Likeliness of nest food spawn attempts succeeding. - FOOD_SPAWN_COOLDOWN_NEST: 45, // Cooldown (in game ticks) of nest food spawn attempts being made. + FOOD_CAP_NEST: 1, // Max nest food per nest tile. 3 + FOOD_SPAWN_CHANCE_NEST: 0.1, // Likeliness of nest food spawn attempts succeeding. 0.25 + FOOD_SPAWN_COOLDOWN_NEST: 120, // Cooldown (in game ticks) of nest food spawn attempts being made. 45 - ENEMY_CAP_NEST: 1, // Max nest enemies per nest tile. - ENEMY_SPAWN_CHANCE_NEST: 0.9, // Likeliness of nest enemies spawn attempts succeeding. + ENEMY_CAP_NEST: 0, // Max nest enemies per nest tile. 1 + ENEMY_SPAWN_CHANCE_NEST: 0.9, // Likeliness of nest enemies spawn attempts succeeding. 0.9 ENEMY_SPAWN_COOLDOWN_NEST: 60, // Cooldown (in game ticks) of nest enemies spawn attempts being made. // Cooldown (in seconds) of boss spawns being announced. - BOSS_SPAWN_COOLDOWN: 60, + BOSS_SPAWN_COOLDOWN: 1800, //120 // The delay (in seconds) between the boss spawns being announced and the bosses actually spawning. // NOTE: The spawn message (ex. "A strange trembling...") takes half as long to appear than the boss. BOSS_SPAWN_DURATION: 5, diff --git a/server/index.js b/server/index.js index 5c69a0a34..f565ea784 100644 --- a/server/index.js +++ b/server/index.js @@ -67,6 +67,7 @@ function collide(collision) { if (instance.type === "wall" && other.type === "wall") return; if (instance.type === "aura" || other.type === "aura") return; if (instance.type === "satellite" || other.type === "satellite") return; + if (instance.type === "shield" || other.type === "shield" || instance.type === "brella" || other.type === "brella") return; let wall = instance.type === "wall" ? instance : other; let entity = instance.type === "wall" ? other : instance; if (entity.ac || entity.master.ac) return; @@ -84,6 +85,29 @@ function collide(collision) { break; } break; + case instance.type === "shield" || other.type === "shield": + if (instance.type === "aura" || other.type === "aura" || instance.type === "satellite" || other.type === "satellite" || instance.type === "satellite" || other.type === "satellite" || instance.team === other.team) return; + let shield = instance.type === "shield" ? instance : other; + let nonshield = instance.type === "shield" ? other : instance; + switch (true) { + case (shield.shapeData == "m -0.7020 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099"): + mirrorcollide(shield, nonshield); + break; + default: + reflectcollide(shield, nonshield); + break; + } + break; + case instance.type === "brella" || other.type === "brella": + if (instance.type === "aura" || other.type === "aura" || instance.type === "satellite" || other.type === "satellite" || instance.type === "satellite" || other.type === "satellite" || instance.team === other.team) return; + let brella = instance.type === "brella" ? instance : other; + let nonbrella = instance.type === "brella" ? other : instance; + switch (true) { + default: + reflectcollide(brella, nonbrella); + break; + } + break; case instance.team === other.team && (instance.settings.hitsOwnType === "pushOnlyTeam" || other.settings.hitsOwnType === "pushOnlyTeam"): @@ -367,4 +391,4 @@ setInterval(() => { } syncedDelaysLoop(); -}, room.cycleSpeed); +}, room.cycleSpeed); \ No newline at end of file diff --git a/server/lib/random.js b/server/lib/random.js index 0308c8fa1..c1dc0672e 100644 --- a/server/lib/random.js +++ b/server/lib/random.js @@ -104,4 +104,4 @@ exports.chooseBossName = code => { case "legion": return exports.choose([ "Vesta", "Juno", "Orcus", "Janus", "Minerva", "Ceres" ]); } -} +} \ No newline at end of file diff --git a/server/modules/debug/speedLoop.js b/server/modules/debug/speedLoop.js index c24120637..6abacf94b 100644 --- a/server/modules/debug/speedLoop.js +++ b/server/modules/debug/speedLoop.js @@ -13,6 +13,9 @@ const speedcheckloop = () => { active = logs.entities.count(); global.fps = (1000 / sum).toFixed(2); if (sum > 1000 / c.runSpeed / 30) { + for (let entity of entities) { + util.warn(...entity.defs) + } //fails++; if (c.LOGS) { util.warn('~~ LAST SERVER TICK TOOK TOO LONG TO CALCULATE ~~'); diff --git a/server/modules/definitions/addons/amongus.js b/server/modules/definitions/addons/amongus.js new file mode 100644 index 000000000..7f675df15 --- /dev/null +++ b/server/modules/definitions/addons/amongus.js @@ -0,0 +1,108 @@ + //UNCOMMENT LINE 11 TO DISABLE + //return + console.log('[AMONG US CREWMATE] Addon running'); + + Class.OSAmongus_basebody = { + PARENT: ["genericTank"], + LABEL: "", + SHAPE: "M -0.731 1.979 Q -1.279 -2.215 -0.005 -2.244 Q 1.635 -2.31 1.485 0 Q 1.415 1.801 0.992 1.822 Q 0.599 1.847 0.591 1.342 Q 0.888 1.29 1.078 1.056 Q 0.551 1.132 0.03 1.073 L -0.008 1.871 Q -0.304 2.162 -0.727 1.982", + } + Class.OSAmongus_basebodyshadow = { + PARENT: ["genericTank"], + LABEL: "", + BORDERLESS: true, + SHAPE: "M 0.431 0.765 C -0.809 0.861 -0.8 -0.981 -0.573 -1.968 C -0.451 -2.449 1.348 -2.396 1.331 -1.051 C 1.829 0.495 0.85 0.826 0.423 0.774", + } + Class.OSAmongus_backpack= { + PARENT: ["genericTank"], + LABEL: "", + SHAPE: "M-.6.9-1 1Q-1.615 1.258-1.567-.014-1.581-1.214-1.094-1.014L-1.095-1.009-.7-.9", + } + Class.OSAmongus_backpackshadow= { + PARENT: ["genericTank"], + BORDERLESS: true, + LABEL: "", + SHAPE: "M -1.11 -0.781 C -1.125 -0.812 -1.481 -0.806 -1.532 -0.734 C -1.507 -0.874 -1.517 -1.033 -1.316 -1.033 C -1.073 -1.069 -1.053 -1.028 -1.11 -0.791", + } + Class.OSAmongus_visor= { + PARENT: ["genericTank"], + LABEL: "", + SHAPE: "M 0.004 -1.131 C -0.007 -0.231 1.655 -0.524 1.649 -1.097 C 1.741 -1.807 0.027 -1.962 -0.001 -1.131", + } + Class.OSAmongus_visorshadow= { + PARENT: ["genericTank"], + BORDERLESS: true, + LABEL: "", + SHAPE: "M 0.178 -1.402 C 0.05 -0.851 1.667 -0.668 1.642 -1.374 C 1.654 -1.609 0.251 -1.785 0.175 -1.411", + } + Class.OSAmongus_visorhighlight= { + PARENT: ["genericTank"], + BORDERLESS: true, + LABEL: "", + SHAPE: "M 0.178 -1.402 C 0.05 -0.851 1.667 -0.668 1.642 -1.374 C 1.654 -1.609 0.251 -1.785 0.175 -1.411", + } + Class.OSAmongus_crewmatebase= { + PARENT: ["genericTank"], + LABEL: "AMONG US", + SHAPE: "M 0.178", + COLOR: 12, + TURRETS:[ + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_backpack", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_backpackshadow", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 0,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_basebody", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_basebodyshadow", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: -1, BRIGHTNESS_SHIFT: 0,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_visor", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 10, BRIGHTNESS_SHIFT: -15,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_visorshadow", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 10, BRIGHTNESS_SHIFT: 0,}}], + }, + { + POSITION: [5, 2.75, -4, 0, 0, 1], + TYPE: ["OSAmongus_visorhighlight", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 8, BRIGHTNESS_SHIFT: 0,}}], + }, + ], + } + Class.addons.UPGRADES_TIER_0.push("OSAmongus_crewmatebase"); + Class.OSAmongus_crewmatebase.UPGRADES_TIER_0 = []; + const colors = [ + "red", + "orange", + "gold", + "brown", + "green", + "blue", + "cyan", + "teal", + "pink", + "purple", + "magenta", + "veryLightGray", + "darkGray", + "animatedLesbian", + "animatedTrans", + "rainbow", + ] + for (let i = 0; i < colors.length; i++) { + Class["OSAmongus_" + colors[i] + "crewmate"] = { + PARENT: ["OSAmongus_crewmatebase"], + COLOR: colors[i] + + }; + + Class.OSAmongus_crewmatebase.UPGRADES_TIER_0.push("OSAmongus_" + colors[i] + "crewmate"); +} \ No newline at end of file diff --git a/server/modules/definitions/addons/basicChatModeration.js b/server/modules/definitions/addons/basicChatModeration.js index 5f2c04fe1..4e1ae4f20 100644 --- a/server/modules/definitions/addons/basicChatModeration.js +++ b/server/modules/definitions/addons/basicChatModeration.js @@ -47,5 +47,4 @@ module.exports = ({ Events }) => { }); console.log('[basicChatModeration] Loaded spam prevention!'); -}; - +}; \ No newline at end of file diff --git a/server/modules/definitions/addons/cooper.js b/server/modules/definitions/addons/cooper.js new file mode 100644 index 000000000..53af0685a --- /dev/null +++ b/server/modules/definitions/addons/cooper.js @@ -0,0 +1,30 @@ +const { combineStats, makeAuto, makeHybrid, makeHybridDrive, makeOver, makeDeco, makeGuard, makeBird, makeMulti, makeCeption, makeCeptionNerf, makeTracker } = require('../facilitators.js'); +const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); +require('../groups/generics.js'); +const g = require('../gunvals.js'); + +Class.sandwichdeco = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg?v=1708356424097"); + +Class.A = { + PARENT: "genericTank", + LABEL: "ChickenSandwichTank", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single, g.op]), + TYPE: "bullet" + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ], + TURRETS: [{ + POSITION: [11, 0, 0, 0, 0, 99], + TYPE: "sandwichdeco" + }] +}; + +Class.addons.UPGRADES_TIER_0.push("A") \ No newline at end of file diff --git a/server/modules/definitions/addons/dailyTanks.js b/server/modules/definitions/addons/dailyTanks.js new file mode 100644 index 000000000..e50edb19a --- /dev/null +++ b/server/modules/definitions/addons/dailyTanks.js @@ -0,0 +1,1687 @@ +const { dereference, combineStats, makeMulti, makeDeco, makeAuto, makeHybrid, makeCeptionNerf } = require('../facilitators.js'); +const { base, gunCalcNames, statnames, dfltskl, smshskl } = require('../constants.js'); +const g = require('../gunvals.js'); + +const addToMain = true + +// Bullets +Class.masterBullet = { + PARENT: "missile", + FACING_TYPE: "veryfastspin", + MOTION_TYPE: "motor", + HAS_NO_RECOIL: false, + DIE_AT_RANGE: false, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), + TYPE: "bullet", + LABEL: "Front", + AUTOFIRE: true, + }, + }, + { + POSITION: [13, 8, 1, 0, -1, 140, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "Thruster", + AUTOFIRE: true, + }, + }, + { + POSITION: [13, 8, 1, 0, 1, 220, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "Thruster", + AUTOFIRE: true, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "Thruster", + AUTOFIRE: true, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "Thruster", + AUTOFIRE: true, + }, + }, + ], +} + +Class.squareSatellite = { + PARENT: "satellite", + SHAPE: 4 +} + +// Turrets +Class.lamgSpinnerTurret = makeMulti({ + PARENT: "genericTank", + LABEL: "Spinner Turret", + GUNS: [ + { + POSITION: [15, 3.5, 1, 0, 0, 0, 0] + } + ] +}, 10) + +// Decorations +Class.tornadoDeco = makeDeco(4); +Class.tornadoDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.megaTornadoDeco = makeDeco([[0,-1],[0.5,0],[0,1],[-0.5,0]]) +Class.megaTornadoDeco.CONTROLLERS = [["spin", { independent: true }]]; +Class.tempestDeco1 = makeDeco(3); +Class.tempestDeco1.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.tempestDeco2 = makeDeco(3); +Class.tempestDeco2.CONTROLLERS = [["spin", { independent: true, speed: -0.128 }]]; +Class.thunderboltDeco = makeDeco(4); +Class.thunderboltDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.16 }]]; +Class.hurricaneDeco = makeDeco(8); +Class.hurricaneDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.typhoonDeco = makeDeco(10); +Class.typhoonDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.blizzardDeco1 = makeDeco(5); +Class.blizzardDeco1.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.blizzardDeco2 = makeDeco(5); +Class.blizzardDeco2.CONTROLLERS = [["spin", { independent: true, speed: -0.128 }]]; + +// Whirlwind upgrades +Class.dlywhirlwind = { + PARENT: "genericTank", + LABEL: "Whirlwind", + //UPGRADE_TOOLTIP: "Daily Tank!", + //UPGRADE_COLOR: "rainbow", + ANGLE: 60, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "whirlwindDeco" + } + ], + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 6; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 60}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.tornado = { + PARENT: "genericTank", + LABEL: "Tornado", + DANGER: 6, + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + ANGLE: 90, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 4; i++) { + output.push({ + POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), + TYPE: ["satellite", {ANGLE: i * 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.hurricane = { + PARENT: ["genericTank"], + LABEL: "Hurricane", + DANGER: 6, + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "hurricaneDeco", + }, + ], + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 8; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 45}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.hexaWhirl = { + PARENT: ["genericTank"], + LABEL: "Hexa Whirl", + DANGER: 7, + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 300, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} +Class.munition = { + PARENT: ["genericTank"], + DANGER: 7, + LABEL: "Munition", + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + POSITION: [17, 3, 1, 0, -6, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [17, 3, 1, 0, 6, 7, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [19, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), + TYPE: "bullet", + LABEL: "Heavy", + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} +Class.whirl3 = { + PARENT: "genericTank", + LABEL: "Whirl-3", + DANGER: 7, + FACING_TYPE: "autospin", + ANGLE: 90, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + { + POSITION: [11, 8, 0, 0, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 120, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 240, 190, 0], + TYPE: "autoTankGun", + }, + ], + GUNS: (() => { + let output = [] + for (let i = 0; i < 4; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }) + } + return output + })() +} +Class.whirlGuard = { + PARENT: ["genericTank"], + LABEL: "Whirl Guard", + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + DANGER: 7, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [13, 8, 1, 0, 0, 180, 0], + }, + { + POSITION: [4, 8, 1.7, 13, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} +Class.prophet = { + PARENT: ["genericTank"], + LABEL: "Prophet", + DANGER: 7, + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + BODY: { + SPEED: 0.9 * base.SPEED, + }, + AI: { + SPEED: 2, + }, + SHAPE: 4, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + POSITION: [5.25, 12, 1.2, 8, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + MAX_CHILDREN: 7, + }, + }, + { + POSITION: [5.25, 12, 1.2, 8, 0, 270, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + MAX_CHILDREN: 7, + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["squareSatellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["squareSatellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["squareSatellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["squareSatellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} +Class.vortex = { + PARENT: ["genericTank"], + LABEL: "Vortex", + BODY: { + FOV: base.FOV * 1.1, + }, + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + DANGER: 7, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [10, 9, 1, 9, 0, 0, 0], + }, + { + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery]), + TYPE: "minimissile", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} + +// Tornado upgrades +Class.megaTornado = { + PARENT: "genericTank", + LABEL: "Mega Tornado", + DANGER: 7, + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: "megaTornadoDeco", + }, + ], + ANGLE: 180, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 2; i++) { + output.push({ + POSITION: {WIDTH: 16, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder, g.destroyer]), + TYPE: ["satellite", {ANGLE: i * 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.tempest = { + PARENT: "genericTank", + LABEL: "Tempest", + DANGER: 7, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tempestDeco1", + }, + { + POSITION: [4, 0, 0, 180, 360, 1], + TYPE: "tempestDeco2", + }, + ], + ANGLE: 120, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 3; i++) { + output.push({ + POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), + TYPE: ["satellite", {ANGLE: i * 120}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + for (let i = 0; i < 3; i++) { + output.push({ + POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), + TYPE: ["satellite", { ANGLE: i * 120, CONTROLLERS: [['orbit', {invert: true}]] }], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.thunderbolt = { + PARENT: ["genericTank"], + LABEL: "Thunderbolt", + DANGER: 7, + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "thunderboltDeco", + }, + ], + ANGLE: 90, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2.5, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 4; i++) { + output.push({ + POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), + TYPE: ["satellite", {ANGLE: i * 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} + +// Hurricane upgrades +Class.typhoon = { + PARENT: ["genericTank"], + LABEL: "Typhoon", + DANGER: 7, + ANGLE: 36, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "typhoonDeco", + }, + ], + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 10; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 36}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.blizzard = { + PARENT: "genericTank", + LABEL: "Blizzard", + DANGER: 7, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "blizzardDeco1", + }, + { + POSITION: [6, 0, 0, 180, 360, 1], + TYPE: "blizzardDeco2", + }, + ], + ANGLE: 72, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 5; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 72}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + for (let i = 0; i < 5; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", { ANGLE: i * 72, CONTROLLERS: [['orbit', {invert: true}]] }], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} + +// Whirlwind upgrade paths +Class.dlywhirlwind.UPGRADES_TIER_2 = ["tornado", "hurricane"] + Class.dlywhirlwind.UPGRADES_TIER_3 = ["hexaWhirl", "munition", "whirl3", "whirlGuard", "prophet", "vortex"] + Class.tornado.UPGRADES_TIER_3 = ["megaTornado", "tempest", "thunderbolt"] + Class.hurricane.UPGRADES_TIER_3 = ["typhoon", "blizzard"] + +// December 14th - Master +Class.master = { + PARENT: "genericTank", + LABEL: "Master", + UPGRADE_TOOLTIP: "Daily Tank!", + UPGRADE_COLOR: "rainbow", + BODY: { + HEALTH: base.HEALTH * 0.4, + SHIELD: base.SHIELD * 0.4, + DENSITY: base.DENSITY * 0.3, + }, + DANGER: 8, + GUNS: [ + { + POSITION: [18, 16, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "masterBullet", + MAX_CHILDREN: 4, + DESTROY_OLDEST_CHILD: true, + }, + }, + { + POSITION: [13, 8, 1, 0, -1, 140, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [13, 8, 1, 0, 1, 220, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + ], +} + +// December 16th - Literally a Machine Gun +Class.literallyAMachineGun = { + PARENT: "genericTank", + LABEL: "Literally a Machine Gun", + UPGRADE_TOOLTIP: "Daily Tank!", + UPGRADE_COLOR: "rainbow", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2 + }, + TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + TURRETS: [ + { + POSITION: [10, 14, 0, 0, 0, 1], + TYPE: "lamgSpinnerTurret" + } + ], + GUNS: [ + { + POSITION: [22, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [2, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + } + ] +} + +// Dev shit +Class.dailyTanks = { + PARENT: "genericTank", + LABEL: "Daily Tanks!", + UPGRADE_COLOR: "rainbow", + UPGRADES_TIER_0: [ + "dlywhirlwind", + "master", + "literallyAMachineGun", + "literallyATank", + "crayon", + "jumpSmasher", + "dlylancer", + ] +} + +// December 19th-20th - Jump Smasher +Class.jumpsmasherBody = { + LABEL: "", + CONTROLLERS: [["spin", { independent: true, speed: 0.3 }]], + COLOR: "black", + SHAPE: 8, + INDEPENDENT: true +} +Class.jumpSmasher = { + PARENT: "genericSmasher", + LABEL: "Jump Smasher", + //UPGRADE_TOOLTIP: "Daily Tank!", + //UPGRADE_COLOR: "rainbow", + DANGER: 7, + GUNS: [ + { + POSITION: [2, 10, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.tonsmorerecoil, g.tonsmorerecoil, g.halfreload, g.halfreload, g.halfreload, g.halfreload, g.norange]), + TYPE: "bullet", + ALT_FIRE: true + } + } + ], + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "jumpsmasherBody" + } + ] +} + +// *InsertCorrectDateHereCuzIdk* - Literally A Tank +class io_turretWithMotion extends IO { + constructor(b, opts = {}) { + super(b) + } + think(input) { + return { + target: this.body.master.velocity, + main: true, + }; + } +} +ioTypes.turretWithMotion = io_turretWithMotion +Class.latTop = makeDeco(0) +Class.latDeco1 = { + PARENT: "genericTank", + LABEL: "Tank Deco", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#5C533F", + SHAPE: "M -1 -2 C -1 -2 -1 -3 0 -3 C 1 -3 1 -2 1 -2 V 2 C 1 2 1 3 0 3 C -1 3 -1 2 -1 2 V -2", + MIRROR_MASTER_ANGLE: true, +} +Class.latDeco2 = { + PARENT: "genericTank", + LABEL: "Tank Deco", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#5C533F", + SHAPE: "M -2 0 H 2 L 0 1 L -2 0", + MIRROR_MASTER_ANGLE: true, +} +Class.latDeco3 = { + PARENT: "genericTank", + LABEL: "Tank Deco", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#3F3B2D", + SHAPE: "M -10 -1 L 10 -1 L 10 1 L -10 1 L -10 -1", + MIRROR_MASTER_ANGLE: true, +} +Class.latRight = { + PARENT: "genericTank", + LABEL: "Tank Side", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#96794E", + SHAPE: "M -6 0 H 5 V 1 C 5 2 4 2 4 2 H -5 C -6 2 -6 1 -6 1 V 0", + MIRROR_MASTER_ANGLE: true, + TURRETS: [ + { + POSITION: [4.8, 31, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 24, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 17, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -42, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -35, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -28, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [18, -5, 0, 0, 0, 1], + TYPE: "latDeco2", + }, + ] +} +Class.latLeft = { + PARENT: "genericTank", + LABEL: "Tank Side", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#96794E", + SHAPE: "M -5 0 H 6 V 1 C 6 2 5 2 5 2 H -4 C -5 2 -5 1 -5 1 V 0", + MIRROR_MASTER_ANGLE: true, + TURRETS: [ + { + POSITION: [4.8, -31, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -24, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -17, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 42, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 35, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 28, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [18, 5, 0, 0, 0, 1], + TYPE: "latDeco2", + }, + ] +} +Class.latBase = { + PARENT: "genericTank", + LABEL: "Tank Base", + CONTROLLERS: ["turretWithMotion"], + COLOR: "#96794E", + SHAPE: [ + [1.1, 1], + [1.4, 0], + [1.1, -1], + [-1.1, -1], + [-0.8, 0], + [-1.1, 1] + ], + GUNS: [ + { + POSITION: [16, 5.5, 1, 1, 6.5, 0, 0] + }, + { + POSITION: [14.5, 5.5, 1, 1, 6.5, 0, 0] + }, + { + POSITION: [13, 5.5, 1, 1, 6.5, 0, 0] + }, + { + POSITION: [16, 5.5, 1, 1, -6.5, 0, 0] + }, + { + POSITION: [14.5, 5.5, 1, 1, -6.5, 0, 0] + }, + { + POSITION: [13, 5.5, 1, 1, -6.5, 0, 0] + }, + { + POSITION: [13, 5.5, 1, 1, 6.5, 180, 0] + }, + { + POSITION: [11.5, 5.5, 1, 1, 6.5, 180, 0] + }, + { + POSITION: [10, 5.5, 1, 1, 6.5, 180, 0] + }, + { + POSITION: [8.5, 5.5, 1, 1, 6.5, 180, 0] + }, + { + POSITION: [13, 5.5, 1, 1, -6.5, 180, 0] + }, + { + POSITION: [11.5, 5.5, 1, 1, -6.5, 180, 0] + }, + { + POSITION: [10, 5.5, 1, 1, -6.5, 180, 0] + }, + { + POSITION: [8.5, 5.5, 1, 1, -6.5, 180, 0] + }, + ], + TURRETS: [ + { + POSITION: [5.3, 0, -10, 0, 0, 1], + TYPE: "latLeft", + }, + { + POSITION: [5.3, 0, -10, 180, 0, 1], + TYPE: "latRight", + }, + { + POSITION: [2, 0, -1.4, 90, 0, 1], + TYPE: "latDeco3", + }, + ] +} +Class.literallyATank = { + PARENT: "genericTank", + UPGRADE_TOOLTIP: "Daily Tank!", + UPGRADE_COLOR: "rainbow", + DANGER: 6, + BODY: { + HEALTH: base.HEALTH * 1.2, + }, + LABEL: "Literally a Tank", + SHAPE: "M -1 -1 H 0 C 1 -1 1 0 1 0 C 1 0 1 1 0 1 H -1 V -1", + GUNS: [ + { + POSITION: [30, 8, 1, 0, 0, 0, 0] + }, + { + POSITION: [4, 8, -1.4, 8, 0, 0, 0] + }, + { + POSITION: [12, 8, 1.3, 30, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "developerBullet" + } + }, + { + POSITION: [2, 11, 1, 34, 0, 0, 0] + } + ], + TURRETS: [ + { + POSITION: [15, 0, 0, 0, 360, 1], + TYPE: [ "latTop", { COLOR: "#5C533F" } ], + }, + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: [ "latTop", { COLOR: "#736245" } ], + }, + { + POSITION: [35, 0, 0, 0, 360, 0], + TYPE: [ "latBase", { COLOR: "#96794E" } ], + }, + ] +} + +Class.dlylancer = { + PARENT: "genericLancer", + LABEL: "Lancer", + //UPGRADE_TOOLTIP: "Daily Tank!", + //UPGRADE_COLOR: "rainbow", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + } + ] +} +Class.dlylancebrid = makeHybrid(Class.dlylancer, "Lancebrid"); +Class.dlyautolancer = makeAuto(Class.dlylancer, "Auto-Lancer"); +Class.dlyautolancebrid = makeAuto(Class.dlylancebrid, "Auto-Lancebrid"); +Class.dlytrilancer = { + PARENT: "genericLancer", + LABEL: "Tri-Lancer", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 120, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 240, 0] + } + ] +} +Class.dlyhexalancer = { + PARENT: "genericLancer", + LABEL: "Hexa Lancer", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 60, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 120, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 180, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 240, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 300, 0] + } + ] +} +Class.dlychasseur = { + PARENT: "genericLancer", + LABEL: "Chasseur", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true, + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + } + ] +} +Class.dlyautochasseur = makeAuto(Class.dlychasseur, "Auto-Chasseur"); +Class.dlylancerception = makeAuto(Class.dlylancer, "Lancer-Ception"); +Class.dlyautotrilancer = makeAuto(Class.dlytrilancer, "Auto-Trilancer"); +Class.dlychasseubrid = makeHybrid(Class.dlychasseur, "Chasseubrid"); +Class.dlytrilancebrid = makeHybrid(Class.dlytrilancer, "Trilancebrid"); +Class.dlytrichasseur = { + PARENT: "genericLancer", + LABEL: "Tri-Chasseur", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [25, 15, 0.001, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 120, 0] + }, + { + POSITION: [25, 15, 0.001, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 240, 0] + } + ] +} +Class.dlytripleur = { + PARENT: "genericLancer", + LABEL: "Tripleur", + BODY: { + SPEED: base.SPEED * 1.1, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, -30, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, -30, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 30, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 30, 0] + } + ] +} +Class.dlytrailblazer = { + PARENT: "genericLancer", + LABEL: "Trailblazer", + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.6 * base.DENSITY, + }, + HAS_NO_RECOIL: false, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + } + ] +} + +Class.dlylancer.UPGRADES_TIER_2 = [ + "dlychasseur", // + "dlylancebrid", // + "dlytrilancer", // + "dlyautolancer", // +]; +Class.dlychasseur.UPGRADES_TIER_3 = [ + "dlytripleur", // + "flail", + "dlyautochasseur", // + "dlytrichasseur", // + "dlychasseubrid", // +]; +Class.dlytrilancer.UPGRADES_TIER_3 = [ + "dlyhexalancer", // + "dlytrailblazer", // + "dlytrichasseur", // + "dlytrilancebrid", // + "dlyautotrilancer", // +]; +Class.dlyautolancer.UPGRADES_TIER_3 = [ + "dlyautochasseur", // + "dlyautolancebrid", // + "dlyautotrilancer", // + "dlylancerception", // +]; +Class.dlylancebrid.UPGRADES_TIER_3 = [ + "dlychasseubrid", // + "dlyautolancebrid", // + "dlytrilancebrid", // +]; +Class.crayon = { + PARENT: "genericTank", + LABEL: "Crayon", + UPGRADE_COLOR: "rainbow", + UPGRADE_TOOLTIP: "Daily Tank!", + SIZE: 12, + SHAPE: 0, + GUNS: [{ + POSITION: [16.615, 6.4, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet" + } + }, { + POSITION: [16.615, 6.4, 1, 0, -5.538, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet" + }, + }, + { + POSITION: [16.615, 6.4, 1, 0, 5.538, 0, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet" + }, + }, + ], +}; +Class.autocrayon = makeAuto(Class.crayon, 'Auto Crayon'); + +Class.crayon.UPGRADES_TIER_3 = ["autocrayon"]; + +let dlytanks = ["master", "dlywhirlwind", "literallyATank", "jumpSmasher", "dlylancer", "literallyAMachineGun", "crayon"]; +dailytank = dlytanks[global.dayofweek]; + +if (addToMain == true) { +Class.basic.UPGRADES_TIER_1.push("dlylancer", "dlywhirlwind") +Class.smasher.UPGRADES_TIER_3.push("jumpSmasher") +Class.hexaTank.UPGRADES_TIER_3.push("hexaWhirl") +Class.artillery.UPGRADES_TIER_3.push("munition") +Class.auto3.UPGRADES_TIER_3.push("whirl3") +Class.trapGuard.UPGRADES_TIER_3.push("whirlGuard") +Class.underseer.UPGRADES_TIER_3.push("prophet") +Class.launcher.UPGRADES_TIER_3.push("vortex") +} else { +//Class.basic.UPGRADES_TIER_3 = [dailytank] +} +Class.addons.UPGRADES_TIER_3 = ["dailyTanks"]; \ No newline at end of file diff --git a/server/modules/definitions/addons/dreadv1.js b/server/modules/definitions/addons/dreadv1.js index 42b43463e..3df30c13b 100644 --- a/server/modules/definitions/addons/dreadv1.js +++ b/server/modules/definitions/addons/dreadv1.js @@ -41,7 +41,7 @@ const enableHealers = true; // Misc Class.genericDreadnought1 = { - PARENT: "genericTank", + PARENT: ["genericTank"], BODY: dreadnoughtBody, SHAPE: 6, COLOR: 'hexagon', @@ -50,7 +50,7 @@ Class.genericDreadnought1 = { REROOT_UPGRADE_TREE: "dreadOfficialV1", }; Class.mechanismMainTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", CONTROLLERS: ["nearestDifferentMaster"], INDEPENDENT: true, @@ -67,7 +67,7 @@ Class.mechanismMainTurret = { }] }; Class.automationMainTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", CONTROLLERS: ["onlyAcceptInArc", "nearestDifferentMaster"], INDEPENDENT: true, @@ -84,7 +84,7 @@ Class.automationMainTurret = { }] }; Class.automationSecondaryTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", CONTROLLERS: ["onlyAcceptInArc", "nearestDifferentMaster"], INDEPENDENT: true, @@ -101,7 +101,7 @@ Class.automationSecondaryTurret = { }] }; Class.medicareTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", CONTROLLERS: [ ["spin", {speed: 0.04}] ], INDEPENDENT: true, @@ -126,7 +126,7 @@ for(let i = 0; i < 3; i++) { }) } Class.medicaidTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", CONTROLLERS: [ ["spin", {speed: 0.04}] ], INDEPENDENT: true, @@ -150,7 +150,7 @@ for(let i = 0; i < 5; i++) { }, }) } -Class.turretedTrap = makeAuto("trap", "Auto-Trap", {size: 7.5, type: 'droneAutoTurret'}); +Class.turretedTrap = makeAuto(Class.trap, "Auto-Trap", {size: 7.5, type: 'droneAutoTurret'}); Class.turretedTrap.BODY.RECOIL_MULTIPLIER = 0; Class.weakMinion = { PARENT: "minion", @@ -168,7 +168,7 @@ Class.weakMinion = { // T0 Class.dreadOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Dreadnought", UPGRADE_LABEL: "Dreads V1", LEVEL: 150, @@ -177,7 +177,7 @@ Class.dreadOfficialV1 = { // T1 Class.swordOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Sword", UPGRADE_TOOLTIP: "Snipers", GUNS: [], @@ -193,7 +193,7 @@ for (let i = 0; i < 3; i++) { } Class.pacifierOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Pacifier", UPGRADE_TOOLTIP: "Bullet Spam", GUNS: [], @@ -209,7 +209,7 @@ for (let i = 0; i < 3; i++) { } Class.invaderOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Invader", UPGRADE_TOOLTIP: "Drones", GUNS: [], @@ -230,7 +230,7 @@ for (let i = 0; i < 3; i++) { } Class.centaurOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Centaur", UPGRADE_TOOLTIP: "Traps", GUNS: [], @@ -249,7 +249,7 @@ for (let i = 0; i < 3; i++) { } Class.automationOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Automation", UPGRADE_TOOLTIP: "Auto Turrets", TURRETS: [], @@ -266,7 +266,7 @@ Class.automationOfficialV1.TURRETS.push({ }); Class.juggernautOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Juggernaut", UPGRADE_TOOLTIP: "Health Buff", BODY: { @@ -281,7 +281,7 @@ Class.juggernautOfficialV1 = { }] } Class.medicareOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Medicare", UPGRADE_TOOLTIP: "Healing", TURRETS: [{ @@ -292,7 +292,7 @@ Class.medicareOfficialV1 = { // T2 Class.sabreOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Sabre", UPGRADE_TOOLTIP: "Assassins", GUNS: [], @@ -309,7 +309,7 @@ for (let i = 0; i < 3; i++) { }); } Class.gladiusOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Gladius", UPGRADE_TOOLTIP: "Rifles", GUNS: [], @@ -327,7 +327,7 @@ for (let i = 0; i < 3; i++) { } Class.appeaserOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Appeaser", UPGRADE_TOOLTIP: "Machine Guns", GUNS: [], @@ -348,7 +348,7 @@ for (let i = 0; i < 3; i++) { }); } Class.peacekeeperOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Peacekeeper", UPGRADE_TOOLTIP: "Heavy Bullets", GUNS: [], @@ -363,7 +363,7 @@ for (let i = 0; i < 3; i++) { }); } Class.diplomatOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Diplomat", UPGRADE_TOOLTIP: "Triplets", GUNS: [], @@ -391,7 +391,7 @@ for (let i = 0; i < 3; i++) { } Class.inquisitorOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Inquisitor", UPGRADE_TOOLTIP: "Drones", GUNS: [], @@ -411,7 +411,7 @@ for (let i = 0; i < 3; i++) { }); } Class.assailantOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Assailant", UPGRADE_TOOLTIP: "Minions", GUNS: [], @@ -434,7 +434,7 @@ for (let i = 0; i < 3; i++) { }); } Class.infiltratorOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Infiltrator", UPGRADE_TOOLTIP: "Swarms", GUNS: [], @@ -465,7 +465,7 @@ for (let i = 0; i < 3; i++) { } Class.cerberusOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Cerberus", UPGRADE_TOOLTIP: "Trap Spam", GUNS: [], @@ -501,7 +501,7 @@ for (let i = 0; i < 3; i++) { }); } Class.minotaurOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Minotaur", UPGRADE_TOOLTIP: "Blocks", GUNS: [], @@ -519,7 +519,7 @@ for (let i = 0; i < 3; i++) { }); } Class.sirenOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Siren", GUNS: [], } @@ -537,7 +537,7 @@ for (let i = 0; i < 3; i++) { } Class.mechanismOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Mechanism", UPGRADE_TOOLTIP: "Auto Turrets", TURRETS: [], @@ -554,7 +554,7 @@ Class.mechanismOfficialV1.TURRETS.push({ }) Class.behemothOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Behemoth", UPGRADE_TOOLTIP: "Health Buff", BODY: { @@ -569,7 +569,7 @@ Class.behemothOfficialV1 = { }], } Class.medicaidOfficialV1 = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], LABEL: "Medicaid", UPGRADE_TOOLTIP: "Healing", TURRETS: [{ @@ -635,7 +635,7 @@ for (let primary of Class.dreadOfficialV1.UPGRADES_TIER_1) { // Actually make that guy Class[definitionName] = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], UPGRADES_TIER_2: [], BODY, LABEL, UPGRADE_TOOLTIP, GUNS, TURRETS, }; @@ -682,11 +682,11 @@ for (let primary of Class.dreadOfficialV1.UPGRADES_TIER_1) { // Actually make that guy Class[definitionName2] = { - PARENT: "genericDreadnought1", + PARENT: ["genericDreadnought1"], BODY, LABEL, UPGRADE_TOOLTIP, GUNS, TURRETS }; Class[definitionName].UPGRADES_TIER_2.push(definitionName2); } } } -} +} \ No newline at end of file diff --git a/server/modules/definitions/addons/dreadv2.js b/server/modules/definitions/addons/dreadv2.js index 3cc2dcda4..2ad820da2 100644 --- a/server/modules/definitions/addons/dreadv2.js +++ b/server/modules/definitions/addons/dreadv2.js @@ -62,12 +62,12 @@ const hexnoughtScaleFactor = 0.9; // Misc Class.genericDreadnoughtOfficialV2 = { - PARENT: "genericTank", + PARENT: ["genericTank"], SKILL_CAP: Array(10).fill(smshskl), REROOT_UPGRADE_TREE: ["dreadWeaponOfficialV2", "dreadBodyOfficialV2"], } Class.genericEggnought = { - PARENT: "genericDreadnoughtOfficialV2", + PARENT: ["genericDreadnoughtOfficialV2"], BODY: eggnoughtBody, SHAPE: 0, COLOR: 'egg', @@ -75,7 +75,7 @@ Class.genericEggnought = { DANGER: 8, } Class.genericSquarenought = { - PARENT: "genericDreadnoughtOfficialV2", + PARENT: ["genericDreadnoughtOfficialV2"], BODY: squarenoughtBody, SHAPE: 4, COLOR: 'square', @@ -83,7 +83,7 @@ Class.genericSquarenought = { DANGER: 9, } Class.genericTrinought = { - PARENT: "genericDreadnoughtOfficialV2", + PARENT: ["genericDreadnoughtOfficialV2"], BODY: trinoughtBody, SHAPE: 3.5, COLOR: 'triangle', @@ -91,7 +91,7 @@ Class.genericTrinought = { DANGER: 10, } Class.genericPentanought = { - PARENT: "genericDreadnoughtOfficialV2", + PARENT: ["genericDreadnoughtOfficialV2"], BODY: pentanoughtBody, SHAPE: 5.5, COLOR: 'pentagon', @@ -99,7 +99,7 @@ Class.genericPentanought = { DANGER: 11, } Class.genericHexnought = { - PARENT: "genericDreadnoughtOfficialV2", + PARENT: ["genericDreadnoughtOfficialV2"], BODY: hexnoughtBody, SHAPE: 6, COLOR: 'hexagon', @@ -108,7 +108,7 @@ Class.genericHexnought = { } Class.spamAutoTurret = { - PARENT: "autoTankGun", + PARENT: ["autoTankGun"], INDEPENDENT: true, GUNS: [ { @@ -121,7 +121,7 @@ Class.spamAutoTurret = { ], } Class.supermissile = { - PARENT: "bullet", + PARENT: ["bullet"], LABEL: "Missile", INDEPENDENT: true, BODY: { @@ -157,7 +157,7 @@ Class.supermissile = { ], }; Class.betadrone = { - PARENT: "drone", + PARENT: ["drone"], TURRETS: [ { POSITION: [10, 0, 0, 180, 0, 1], @@ -168,9 +168,9 @@ Class.betadrone = { // T0 Class.dreadOfficialV2 = { - PARENT: "genericEggnought", - LABEL: "Dreadnought", - UPGRADE_LABEL: "Dreads V2", + PARENT: ["genericEggnought"], + LABEL: "Dreadnought", + UPGRADE_LABEL: "Dreads V2", LEVEL: 90, EXTRA_SKILL: 18, } @@ -187,7 +187,7 @@ Class.dreadBodyOfficialV2 = { // T1 Weapons Class.swordOfficialV2 = { - PARENT: "genericEggnought", + PARENT: ["genericEggnought"], LABEL: "Sword", GUNS: [], } @@ -207,7 +207,7 @@ Class.sword2OfficialV2 = { BATCH_UPGRADES: true, } Class.pacifierOfficialV2 = { - PARENT: "genericEggnought", + PARENT: ["genericEggnought"], LABEL: "Pacifier", GUNS: [], } @@ -227,7 +227,7 @@ Class.pacifier2OfficialV2 = { BATCH_UPGRADES: true, } Class.peacekeeperOfficialV2 = { - PARENT: "genericEggnought", + PARENT: ["genericEggnought"], LABEL: "Peacekeeper", GUNS: [], } @@ -247,7 +247,7 @@ Class.peacekeeper2OfficialV2 = { BATCH_UPGRADES: true, } Class.invaderOfficialV2 = { - PARENT: "genericEggnought", + PARENT: ["genericEggnought"], LABEL: "Invader", GUNS: [], } @@ -272,7 +272,7 @@ Class.invader2OfficialV2 = { BATCH_UPGRADES: true, } Class.centaurOfficialV2 = { - PARENT: "genericEggnought", + PARENT: ["genericEggnought"], LABEL: "Centaur", GUNS: [], } @@ -298,7 +298,7 @@ Class.centaur2OfficialV2 = { // T1 Bodies Class.byteTurretOfficialV2 = { - PARENT: "autoTankGun", + PARENT: ["autoTankGun"], INDEPENDENT: true, GUNS: [ { @@ -311,7 +311,7 @@ Class.byteTurretOfficialV2 = { ], } Class.byteOfficialV2 = { - PARENT: "genericEggnought", + PARENT: ["genericEggnought"], LABEL: "Byte", TURRETS: [ { @@ -326,7 +326,7 @@ Class.byteOfficialV2 = { } Class.atmosphereAuraOfficialV2 = addAura(1, 1, 0.15); Class.atmosphereOfficialV2 = { - PARENT: "genericEggnought", + PARENT: ["genericEggnought"], LABEL: "Atmosphere", TURRETS: [ { @@ -340,7 +340,7 @@ Class.atmosphereOfficialV2 = { ], } Class.juggernautOfficialV2 = { - PARENT: "genericEggnought", + PARENT: ["genericEggnought"], LABEL: "Juggernaut", BODY: { HEALTH: 1.6, @@ -362,7 +362,7 @@ Class.juggernautOfficialV2 = { // T2 Weapons Class.sabreOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Sabre", GUNS: [], } @@ -381,7 +381,7 @@ for (let i = 0; i < 4; i++) { ) } Class.gladiusOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Gladius", GUNS: [], } @@ -400,7 +400,7 @@ for (let i = 0; i < 4; i++) { ) } Class.mediatorOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Mediator", GUNS: [], } @@ -423,7 +423,7 @@ for (let i = 0; i < 4; i++) { ) } Class.negotiatorOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Negotiator", GUNS: [], } @@ -439,7 +439,7 @@ for (let i = 0; i < 4; i++) { ) } Class.enforcerOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Enforcer", GUNS: [], } @@ -455,7 +455,7 @@ for (let i = 0; i < 4; i++) { ) } Class.executorOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Executor", GUNS: [], } @@ -475,7 +475,7 @@ for (let i = 0; i < 4; i++) { ) } Class.inquisitorOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Inquisitor", GUNS: [], } @@ -496,7 +496,7 @@ for (let i = 0; i < 4; i++) { ) } Class.assailantMinionOfficialV2 = { - PARENT: "minion", + PARENT: ["minion"], BODY: { SPEED: 0.5, }, @@ -517,7 +517,7 @@ for (let i = 0; i < 4; i++) { ) } Class.assailantOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Assailant", GUNS: [], } @@ -544,7 +544,7 @@ for (let i = 0; i < 4; i++) { ) } Class.daemonOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Daemon", GUNS: [], } @@ -575,7 +575,7 @@ for (let i = 0; i < 4; i++) { ) } Class.minotaurOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Minotaur", GUNS: [], } @@ -597,7 +597,7 @@ for (let i = 0; i < 4; i++) { // T2 Bodies Class.automationOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Automation", TURRETS: [ { @@ -615,7 +615,7 @@ for (let i = 0; i < 4; i++) { ) } Class.kilobyteTurretOfficialV2 = { - PARENT: "autoTankGun", + PARENT: ["autoTankGun"], INDEPENDENT: true, GUNS: [ { @@ -628,7 +628,7 @@ Class.kilobyteTurretOfficialV2 = { ], } Class.kilobyteOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Kilobyte", TURRETS: [ { @@ -643,7 +643,7 @@ Class.kilobyteOfficialV2 = { } Class.coronaAuraOfficialV2 = addAura(1.5, 0.8, 0.15); Class.coronaOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Corona", TURRETS: [ { @@ -658,7 +658,7 @@ Class.coronaOfficialV2 = { } Class.thermosphereAuraOfficialV2 = addAura(-1, 1.5); Class.thermosphereOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Thermosphere", TURRETS: [ { @@ -672,7 +672,7 @@ Class.thermosphereOfficialV2 = { ], } Class.jumboOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "Jumbo", BODY: { HEALTH: 2.4, @@ -692,7 +692,7 @@ Class.jumboOfficialV2 = { ], } Class.colossusTopOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], GUNS: [], } for (let i = 0; i < 4; i++) { @@ -704,7 +704,7 @@ for (let i = 0; i < 4; i++) { ) } Class.colossusBottomOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], GUNS: [], } for (let i = 0; i < 4; i++) { @@ -724,7 +724,7 @@ for (let i = 0; i < 4; i++) { ) } Class.colossusOfficialV2 = { - PARENT: "genericSquarenought", + PARENT: ["genericSquarenought"], LABEL: "colossus", BODY: { SPEED: 1.75, @@ -744,7 +744,7 @@ Class.colossusOfficialV2 = { } // T3 Weapons Class.bayonetOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Bayonet", GUNS: [], } @@ -763,7 +763,7 @@ for (let i = 0; i < 3; i++) { ) } Class.bladeOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Blade", GUNS: [], } @@ -792,7 +792,7 @@ for (let i = 0; i < 3; i++) { ) } Class.mitigatorOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Mitigator", GUNS: [], } @@ -815,7 +815,7 @@ for (let i = 0; i < 3; i++) { ) } Class.appeaserOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Appeaser", GUNS: [], } @@ -838,7 +838,7 @@ for (let i = 0; i < 3; i++) { ) } Class.suppressorOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Suppressor", GUNS: [], } @@ -854,7 +854,7 @@ for (let i = 0; i < 3; i++) { ) } Class.inhibitorOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Inhibitor", GUNS: [], } @@ -874,7 +874,7 @@ for (let i = 0; i < 3; i++) { ) } Class.infiltratorOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Infiltrator", GUNS: [], } @@ -919,7 +919,7 @@ for (let i = 0; i < 3; i++) { ) } Class.aggressorMinionOfficialV2 = { - PARENT: "minion", + PARENT: ["minion"], SHAPE: 3.5, COLOR: 2, BODY: { @@ -940,7 +940,7 @@ for (let i = 0; i < 3; i++) { ) } Class.aggressorOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Aggressor", GUNS: [], } @@ -967,7 +967,7 @@ for (let i = 0; i < 3; i++) { ) } Class.hydraOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Hydra", GUNS: [], } @@ -1009,7 +1009,7 @@ for (let i = 0; i < 3; i++) { ) } Class.beelzebubOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Beelzebub", GUNS: [], } @@ -1031,7 +1031,7 @@ for (let i = 0; i < 3; i++) { // T3 Bodies Class.mechanismOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Mechanism", TURRETS: [ { @@ -1054,7 +1054,7 @@ for (let i = 0; i < 3; i++) { } Class.trinoughtBigAura = addAura(2, 1.5); Class.fusionOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Fusion", TURRETS: [ { @@ -1076,7 +1076,7 @@ for (let i = 0; i < 3; i++) { ) } Class.binaryOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Binary", TURRETS: [ { @@ -1101,7 +1101,7 @@ Class.binaryOfficialV2.TURRETS.push( ) Class.trinoughtBigHealAura = addAura(-1.5, 1.5); Class.exosphereOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Exosphere", TURRETS: [ { @@ -1123,7 +1123,7 @@ for (let i = 0; i < 3; i++) { ) } Class.megabyteTurretOfficialV2 = { - PARENT: "autoTankGun", + PARENT: ["autoTankGun"], INDEPENDENT: true, GUNS: [ { @@ -1136,7 +1136,7 @@ Class.megabyteTurretOfficialV2 = { ], } Class.megabyteOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Megabyte", TURRETS: [ { @@ -1151,7 +1151,7 @@ Class.megabyteOfficialV2 = { } Class.trinoughtSmallAura = addAura(1, 2.1, 0.15); Class.trojanOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Trojan", TURRETS: [ { @@ -1176,7 +1176,7 @@ Class.trojanOfficialV2.TURRETS.push( ) Class.trinoughtSmallHealAura = addAura(-2/3, 2.1, 0.15); Class.hardwareOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Hardware", TURRETS: [ { @@ -1200,7 +1200,7 @@ Class.hardwareOfficialV2.TURRETS.push( }, ) Class.chromosphereOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Chromosphere", TURRETS: [ { @@ -1222,7 +1222,7 @@ for (let i = 0; i < 3; i++) { ) } Class.mesosphereOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Mesosphere", TURRETS: [ { @@ -1244,7 +1244,7 @@ for (let i = 0; i < 3; i++) { ) } Class.goliathOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Goliath", BODY: { HEALTH: 3.2, @@ -1264,7 +1264,7 @@ Class.goliathOfficialV2 = { ], } Class.planetOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Planet", BODY: { HEALTH: 2.4, @@ -1292,7 +1292,7 @@ for (let i = 0; i < 3; i++) { ) } Class.moonOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Moon", BODY: { HEALTH: 2.4, @@ -1320,7 +1320,7 @@ for (let i = 0; i < 3; i++) { ) } Class.titanTopOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], GUNS: [], } for (let i = 0; i < 3; i++) { @@ -1332,7 +1332,7 @@ for (let i = 0; i < 3; i++) { ) } Class.titanOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Titan", BODY: { SPEED: 2.15, @@ -1351,7 +1351,7 @@ Class.titanOfficialV2 = { ], } Class.sirenOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Siren", BODY: { SPEED: 1.75, @@ -1378,7 +1378,7 @@ for (let i = 0; i < 3; i++) { ) } Class.harpyOfficialV2 = { - PARENT: "genericTrinought", + PARENT: ["genericTrinought"], LABEL: "Harpy", BODY: { SPEED: 1.75, @@ -1407,7 +1407,7 @@ for (let i = 0; i < 3; i++) { // T4 Weapons Class.javelinOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Javelin", GUNS: [], } @@ -1426,7 +1426,7 @@ for (let i = 0; i < 5; i++) { ) } Class.rapierOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Rapier", GUNS: [], } @@ -1455,7 +1455,7 @@ for (let i = 0; i < 5; i++) { ) } Class.diplomatOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Diplomat", GUNS: [], } @@ -1485,7 +1485,7 @@ for (let i = 0; i < 5; i++) { ) } Class.arbitratorOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Arbitrator", GUNS: [], } @@ -1515,7 +1515,7 @@ for (let i = 0; i < 5; i++) { ) } Class.retardantOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Retardant", GUNS: [], } @@ -1531,7 +1531,7 @@ for (let i = 0; i < 5; i++) { ) } Class.tyrantOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Tyrant", GUNS: [], } @@ -1551,7 +1551,7 @@ for (let i = 0; i < 5; i++) { ) } Class.raiderOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Raider", GUNS: [], } @@ -1596,7 +1596,7 @@ for (let i = 0; i < 5; i++) { ) } Class.gladiatorGenericMinionOfficialV2 = { - PARENT: "minion", + PARENT: ["minion"], BODY: { SPEED: 1, }, @@ -1605,23 +1605,23 @@ Class.gladiatorGenericMinionOfficialV2 = { GUNS: [], } Class.gladiatorTritankMinionOfficialV2 = { - PARENT: "gladiatorGenericMinionOfficialV2", + PARENT: ["gladiatorGenericMinionOfficialV2"], GUNS: [], } Class.gladiatorTritrapMinionOfficialV2 = { - PARENT: "gladiatorGenericMinionOfficialV2", + PARENT: ["gladiatorGenericMinionOfficialV2"], GUNS: [], } Class.gladiatorTriswarmMinionOfficialV2 = { - PARENT: "gladiatorGenericMinionOfficialV2", + PARENT: ["gladiatorGenericMinionOfficialV2"], GUNS: [], } Class.gladiatorAutoMinionOfficialV2 = makeAuto({ - PARENT: "gladiatorGenericMinionOfficialV2", + PARENT: ["gladiatorGenericMinionOfficialV2"], }, "Minion", {size: 12, angle: 0}); Class.gladiatorAuraMinionAuraOfficialV2 = addAura(1, 1.2); Class.gladiatorAuraMinionOfficialV2 = { - PARENT: "gladiatorGenericMinionOfficialV2", + PARENT: ["gladiatorGenericMinionOfficialV2"], TURRETS: [ { POSITION: [12, 0, 0, 0, 360, 1], @@ -1631,7 +1631,7 @@ Class.gladiatorAuraMinionOfficialV2 = { } Class.gladiatorHealAuraMinionAuraOfficialV2 = addAura(-2/3, 1.2); Class.gladiatorHealAuraMinionOfficialV2 = { - PARENT: "gladiatorGenericMinionOfficialV2", + PARENT: ["gladiatorGenericMinionOfficialV2"], TURRETS: [ { POSITION: [12, 0, 0, 0, 360, 1], @@ -1675,7 +1675,7 @@ for (let i = 0; i < 3; i++) { ); } Class.gladiatorOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Gladiator", GUNS: [], } @@ -1707,7 +1707,7 @@ Class.gladiatorOfficialV2.GUNS[7].PROPERTIES.TYPE = "gladiatorTriswarmMinionOffi Class.gladiatorOfficialV2.GUNS[10].PROPERTIES.TYPE = "gladiatorAutoMinionOfficialV2"; Class.gladiatorOfficialV2.GUNS[13].PROPERTIES.TYPE = "gladiatorAuraMinionOfficialV2"; Class.cerberusOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Cerberus", GUNS: [], } @@ -1749,7 +1749,7 @@ for (let i = 0; i < 5; i++) { ) } Class.luciferOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Lucifer", GUNS: [], } @@ -1771,7 +1771,7 @@ for (let i = 0; i < 5; i++) { // T4 Bodies Class.skynetOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Skynet", TURRETS: [ { @@ -1798,7 +1798,7 @@ for (let i = 0; i < 5; i++) { } Class.pentanoughtBigAura = addAura(2.5, 1.45); Class.supernovaOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Supernova", TURRETS: [ { @@ -1820,7 +1820,7 @@ for (let i = 0; i < 5; i++) { ) } Class.cipherOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Cipher", TURRETS: [ { @@ -1845,7 +1845,7 @@ Class.cipherOfficialV2.TURRETS.push( ) Class.pentanoughtBigHealAura = addAura(-2, 1.45); Class.interstellarOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Interstellar", TURRETS: [ { @@ -1867,7 +1867,7 @@ for (let i = 0; i < 5; i++) { ) } Class.gigabyteTurretOfficialV2 = { - PARENT: "autoTankGun", + PARENT: ["autoTankGun"], INDEPENDENT: true, GUNS: [ { @@ -1880,7 +1880,7 @@ Class.gigabyteTurretOfficialV2 = { ], } Class.gigabyteOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Gigabyte", TURRETS: [ { @@ -1894,7 +1894,7 @@ Class.gigabyteOfficialV2 = { ], } Class.malwareOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Malware", TURRETS: [ { @@ -1920,7 +1920,7 @@ Class.malwareOfficialV2.TURRETS.push( ) Class.pentanoughtSmallHealAura = addAura(-2/3, 1.6, 0.15); Class.softwareOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Software", TURRETS: [ { @@ -1948,7 +1948,7 @@ if (useOldPhotosphere) { Class.photosphereBigAuraOfficialV2 = addAura(1.5, 4); } Class.photosphereOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Photosphere", TURRETS: [ { @@ -1991,7 +1991,7 @@ if (useOldPhotosphere) { ) } Class.stratosphereOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Stratosphere", TURRETS: [ { @@ -2013,7 +2013,7 @@ for (let i = 0; i < 5; i++) { ) } Class.behemothOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Behemoth", BODY: { HEALTH: 4, @@ -2033,7 +2033,7 @@ Class.behemothOfficialV2 = { ], } Class.astronomicOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Astronomic", BODY: { HEALTH: 3.2, @@ -2061,7 +2061,7 @@ for (let i = 0; i < 5; i++) { ) } Class.grandioseOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Grandiose", BODY: { HEALTH: 3.2, @@ -2089,13 +2089,13 @@ for (let i = 0; i < 5; i++) { ) } Class.pentagonLeviathanTopOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Leviathan", MIRROR_MASTER_ANGLE: true, GUNS: [], } Class.pentagonLeviathanBottomOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Leviathan", MIRROR_MASTER_ANGLE: true, GUNS: [], @@ -2115,13 +2115,13 @@ for (let i = 0; i < 5; i++) { ); } Class.hexagonLeviathanTopOfficialV2 = { - PARENT: "genericHexnought", + PARENT: ["genericHexnought"], LABEL: "Leviathan", MIRROR_MASTER_ANGLE: true, GUNS: [], } Class.hexagonLeviathanBottomOfficialV2 = { - PARENT: "genericHexnought", + PARENT: ["genericHexnought"], LABEL: "Leviathan", MIRROR_MASTER_ANGLE: true, GUNS: [], @@ -2141,7 +2141,7 @@ for (let i = 0; i < 6; i++) { ) } Class.leviathanOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Leviathan", GUNS: [], BODY: { @@ -2160,7 +2160,7 @@ Class.leviathanOfficialV2 = { ], } Class.valrayvnOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Valrayvn", GUNS: [], BODY: { @@ -2187,7 +2187,7 @@ for (let i = 0; i < 5; i++) { ) } Class.pegasusOfficialV2 = { - PARENT: "genericPentanought", + PARENT: ["genericPentanought"], LABEL: "Pegasus", GUNS: [], BODY: { @@ -2575,4 +2575,4 @@ if(buildHexnoughts) { Class[i].UPGRADES_TIER_0.push(mergeHexnoughtWeaponV2(i, j)); } } -} +} \ No newline at end of file diff --git a/server/modules/definitions/addons/exampleAddon.js b/server/modules/definitions/addons/exampleAddon.js index 3eb655784..8c88557be 100644 --- a/server/modules/definitions/addons/exampleAddon.js +++ b/server/modules/definitions/addons/exampleAddon.js @@ -72,4 +72,4 @@ Class.exampleAddon = { }; Class.addons.UPGRADES_TIER_0.push("exampleAddon"); -console.log('[exampleAddon] The Abomination has been created.'); +console.log('[exampleAddon] The Abomination has been created.'); \ No newline at end of file diff --git a/server/modules/definitions/addons/geometryDashDart.js b/server/modules/definitions/addons/geometryDashDart.js new file mode 100644 index 000000000..99a98d793 --- /dev/null +++ b/server/modules/definitions/addons/geometryDashDart.js @@ -0,0 +1,72 @@ +const { combineStats, makeDeco } = require('../facilitators'); +const g = require('../gunvals'); + + Class.geometryDash_square = makeDeco(4, 'blue'); + Class.geometryDash_square.MIRROR_MASTER_ANGLE = true; + + Class.geometryDash_longRect = { + SHAPE: 'M 0 0 L 5 0 L 5 2 L 0 2 L 0 0', + COLOR: 'blue', + MIRROR_MASTER_ANGLE: true + }; + + Class.geometryDash = { + PARENT: 'genericTank', + LABEL: 'Geometry Dash', + SHAPE: 4, + BODY: { + HEALTH: 1e7, + SHIELD: 0, + DAMAGE: 0, + ACCELERATION: 10, + SPEED: 20, + PUSHABILITY: 0 + }, + COLOR: '#FFFF00', + SIZE: 20, + SKILL_CAP: Array(10).fill(10), + EXTRA_SKILL: 10, + FACING_TYPE: 'autospin', + TURRETS: [ + { + POSITION: { SIZE: 5, X: 4, Y: 5, LAYER: 1 }, + TYPE: 'geometryDash_square' + }, + { + POSITION: { SIZE: 5, X: 4, Y: -5, LAYER: 1 }, + TYPE: 'geometryDash_square' + }, + { + POSITION: { SIZE: 5, X: -6.1, Y: 2, ANGLE: 90, LAYER: 1 }, + TYPE: 'geometryDash_longRect' + } + ], + UPGRADES_TIER_0: ['geometryDashWave'] + } + + Class.geometryDashWave = { + PARENT: 'genericTank', + LABEL: 'Dart', + NAME: 'Wave', + SHAPE: 3, + BODY: { + HEALTH: 1e7, + DAMAGE: 1e7, + SHIELD: 0, + ACCELERATION: 0, + SPEED: 0, + PUSHABILITY: 0 + }, + COLOR: '#FFFF00', + SIZE: 20, + GUNS: [{ + POSITION: { LENGTH: 13, WIDTH: 8, ASPECT: 2, ANGLE: 180 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.tonsmorerecoil, g.tonsmorerecoil, g.veryfast, { reload: 0.05, range: 0.2 }]), + TYPE: 'bullet', + COLOR: 'blue' + } + }] + } + + Class.addons.UPGRADES_TIER_0.push('geometryDash'); \ No newline at end of file diff --git a/server/modules/definitions/addons/labyFood.js b/server/modules/definitions/addons/labyFood.js index 9b412c42b..17760a9aa 100644 --- a/server/modules/definitions/addons/labyFood.js +++ b/server/modules/definitions/addons/labyFood.js @@ -40,4 +40,4 @@ module.exports = ({ Config }) => { ]); console.log('[labyFood.js] Using Labyrinth Food.'); -}; +}; \ No newline at end of file diff --git a/server/modules/definitions/addons/lancer.js b/server/modules/definitions/addons/lancer.js new file mode 100644 index 000000000..0ffcb47c7 --- /dev/null +++ b/server/modules/definitions/addons/lancer.js @@ -0,0 +1,663 @@ +const { + combineStats, + makeAuto, + makeCeption, + makeBiSwarming, + makeSwarming, + makeHybrid, + makeOver, + makeDeco, + makeGuard, + makeBird, + makeMulti, +} = require("../facilitators.js"); +const { + base, + statnames, + gunCalcNames, + dfltskl, + smshskl, +} = require("../constants.js"); +const generics = require("../groups/generics.js"); +const g = require("../gunvals.js"); + +Class.lancer = { + PARENT: "genericTank", + LABEL: "Lancer", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + } + ] +} +Class.autolancer = makeAuto(Class.lancer, "Auto-Lancer"); +Class.trilancer = { + PARENT: "genericTank", + LABEL: "Tri-Lancer", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 120, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 240, 0] + } + ] +} +Class.hexalancer = { + PARENT: "genericTank", + LABEL: "Hexa Lancer", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 60, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 120, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 180, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 240, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 300, 0] + } + ] +} +Class.hedgehog = { + PARENT: "genericTank", + LABEL: "Hedgehog", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, -50, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, -50, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, -100, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, -100, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, -150, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, -150, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 160, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 160, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 105, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 105, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 50, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 50, 0] + } + ] +} +Class.autohedgehog = makeAuto(Class.hedgehog, "Auto-Hedgehog"); +Class.lancebrid = makeHybrid(Class.lancer, "Lancebrid"); +Class.chasseur = { + PARENT: "genericTank", + LABEL: "Chasseur", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 1 }], + AUTOFIRE: true, + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + } + ] +} +Class.autochasseur = makeAuto(Class.chasseur, "Auto-Chasseur"); +Class.trichasseur = { + PARENT: "genericTank", + LABEL: "Tri-Chasseur", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [25, 15, 0.001, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 120, 0] + }, + { + POSITION: [25, 15, 0.001, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 240, 0] + } + ] +} +Class.autotrichasseur = makeAuto(Class.trichasseur, "Auto-Tri-Chasseur"); +Class.spiny = { + PARENT: "genericTank", + LABEL: "Spiny", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 60, 0] + }, + { + POSITION: [25, 15, 0.001, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 120, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 180, 0] + }, + { + POSITION: [25, 15, 0.001, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 240, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 300, 0] + } + ] +} +Class.tripleur = { + PARENT: "genericTank", + LABEL: "Tripleur", + BODY: { + SPEED: base.SPEED * 1.1, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, -30, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, -30, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 30, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 30, 0] + } + ] +} +Class.trailblazer = { + PARENT: "genericTank", + LABEL: "Trailblazer", + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.6 * base.DENSITY, + }, + HAS_NO_RECOIL: false, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + } + ] +} +Class.flazer = { + PARENT: "genericTank", + LABEL: "Flazer", + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.6 * base.DENSITY, + }, + HAS_NO_RECOIL: false, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [12, 10, 1.4, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + } + ] +} +Class.jouster = { + PARENT: "genericTank", + LABEL: "Jouster", + BODY: { + SPEED: base.SPEED * 1.4, + DAMAGE: base.DAMAGE * 0.8 + }, + HAS_NO_RECOIL: true, + STAT_NAMES: { + BULLET_SPEED: 'Lance Range', + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + }, + GUNS: [ + { + POSITION: [15, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0] + } + ] +} +Class.joustebrid = makeHybrid(Class.jouster, "Joustebrid"); +Class.autojoustebrid = makeAuto(Class.joustebrid, "Auto-Joustebrid"); + +Class.jouster.UPGRADES_TIER_2 = [ + "lancer", + "joustebrid", + "smasher", +]; +Class.lancer.UPGRADES_TIER_3 = [ + "chasseur", + "lancebrid", + "trilancer", + "autolancer", +]; +Class.chasseur.UPGRADES_TIER_3 = [ + "tripleur", + "autochasseur", + "trichasseur", +]; +Class.joustebrid.UPGRADES_TIER_3 = [ + "lancebrid", + "autojoustebrid", +]; +Class.trilancer.UPGRADES_TIER_4 = [ + "hexalancer", + "trailblazer", + "trichasseur", +]; +Class.autolancer.UPGRADES_TIER_3 = [ + "autochasseur", +]; +Class.trichasseur.UPGRADES_TIER_5 = [ + "spiny", + "autotrichasseur", +]; +Class.hexalancer.UPGRADES_TIER_5 = [ + "hedgehog", + "spiny", +]; +Class.trailblazer.UPGRADES_TIER_5 = [ + "flazer", +]; +Class.hedgehog.UPGRADES_TIER_6 = [ + "autohedgehog", +]; + +Class.addons.UPGRADES_TIER_0.push("jouster"); \ No newline at end of file diff --git a/server/modules/definitions/addons/playerskins.js b/server/modules/definitions/addons/playerskins.js new file mode 100644 index 000000000..e7a1ad046 --- /dev/null +++ b/server/modules/definitions/addons/playerskins.js @@ -0,0 +1,175 @@ +const { combineStats, makeAuto, makeHybrid, makeHybridDrive, makeOver, makeDeco, makeGuard, makeBird, makeMulti, makeCeption, makeCeptionNerf, makeTracker } = require('../facilitators.js'); +const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); +require('../groups/generics.js'); +const g = require('../gunvals.js'); + + +Class.bsignalcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png?v=1708615075011") +Class.tcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png?v=1708536680813") +Class.dfxcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif?v=1708618924966") +Class.primalcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp?v=1708602763032") +Class.kangaroocharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp?v=1708602765689") +Class.cogcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381") +Class.skypecharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png?v=1708623594494") +Class.coincharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png?v=1708619146196") +Class.discordcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png?v=1701908710293") +Class.incomcharm = makeDeco("https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/1200px-Icon-round-Question_mark.svg.png?v=1699273933044") +Class.eggcharm = makeDeco(0, "veryLightGrey") +Class.squarecharm = makeDeco(4, "gold") +Class.trianglecharm = makeDeco(3, "orange") +Class.pentagoncharm = makeDeco(5, "purple") +Class.gemcharm = makeDeco(6, "aqua") + +Class.bsignalskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "bsignalcharm" + }] +}; +Class.tankcharmskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, 6, 5.5, 0, 360, 3], + TYPE: "tcharm" + }] +}; +Class.dfxskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "dfxcharm" + }] +}; +Class.primalskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [20, 0, 0, 0, 360, 3], + TYPE: "primalcharm" + }] +}; +Class.kangarooskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "kangaroocharm" + }] +}; +Class.cswmskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 0.5], + TYPE: "sandwichdeco" + }] +}; +Class.cogskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "cogcharm" + }] +}; +Class.skypeskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "skypecharm" + }] +}; +Class.coinskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "coincharm" + }] +}; +Class.discordskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "discordcharm" + }] +}; +Class.deltaDecoskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 3], + TYPE: "deltaDeco" + }] +}; +Class.incomskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "incomcharm" + }] +}; +Class.eggskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -5, 5.5, 0, 360, 3], + TYPE: "eggcharm" + }] +}; +Class.squareskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -5, 5.5, 0, 360, 3], + TYPE: "squarecharm" + }] +}; +Class.triangleskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -5, 5.5, 0, 360, 3], + TYPE: "trianglecharm" + }] +}; +Class.pentagonskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -5, 5.5, 0, 360, 3], + TYPE: "pentagoncharm" + }] +}; +Class.gemskin = { + MAX_CHILDREN: 1, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -5, 5.5, 0, 360, 3], + TYPE: "gemcharm" + }] +}; \ No newline at end of file diff --git a/server/modules/definitions/addons/revolutionistPack.js b/server/modules/definitions/addons/revolutionistPack.js new file mode 100644 index 000000000..d421a9d9c --- /dev/null +++ b/server/modules/definitions/addons/revolutionistPack.js @@ -0,0 +1,186 @@ +// An addon is guaranteed to run only after all groups are loaded. +// This is helpful, if your group relies on all other definitions already being loaded. +// Addons that are dependant on other addons should be named something like +// "[PARENT ADDON NAME]-[EXTENSION NAME].js", to make sure that it would run after that addon ran. + +const { combineStats, makeDeco, makeAuto, makeCeption } = require('../facilitators'); +const g = require('../gunvals'); + + + // This addon is enabled by default. + // If you want to disable, uncomment the line below. + return console.log('[revolutionistPack.js] Addon disabled by default'); + + Class.revoautoTurret = { + PARENT: "genericTank", + LABEL: "Turret", + BODY: { + FOV: 0.8, + }, + COLOR: "grey", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), + TYPE: "bullet", + }, + }, + ], +} + Class.solarioTurret1 = { + PARENT: "genericTank", + LABEL: "Turret", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + COLOR: 13, + SHAPE: 0, + BODY: { + FOV: 0.8, + }, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), + TYPE: "bullet", + }, + }, + ], +} + Class.solarioTurret2 = { + PARENT: "genericTank", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + LABEL: "Turret", + COLOR: 13, + SHAPE: 3, + BODY: { + FOV: 0.8, + }, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), + TYPE: "bullet", + }, + }, + ], +} + Class.solarioTurret3 = { + PARENT: "genericTank", + LABEL: "Turret", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + + SHAPE: 4, + COLOR: 13, + BODY: { + FOV: 0.8, + }, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), + TYPE: "bullet", + }, + }, + ], +} + Class.solarioTurret4 = { + PARENT: "genericTank", + LABEL: "Turret", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + COLOR: 13, + SHAPE: 6, + BODY: { + FOV: 0.8, + }, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), + TYPE: "bullet", + }, + }, + ], +} + Class.revoturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: "revoautoTurret", + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: "revoautoTurret", + }] +}; + Class.solarioturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 13, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: "solarioTurret1", + }, { + POSITION: [4.65, 9.85, 0, 180, 220, 1], + TYPE: "solarioTurret2", + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: "solarioTurret3", + }, { + POSITION: [4.65, 9.85, 0, 0, 220, 1], + TYPE: "solarioTurret4", + }] +}; +Class.revolution = { + PARENT: "genericTank", + LABEL: "Revolutionist", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "revoturretBase", + }, + ], +}; +Class.solario = { + PARENT: "genericTank", + LABEL: "Solario", + COLOR: 13, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_05_0sn_Kleki.png?v=1701808881532', + SIZE: 15, + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "solarioturretBase", + }, + ], +}; + Class.autorevol = makeAuto(Class.revolution, "Auto-Revolutionist"); + Class.revoceptionist = makeCeption(Class.revolution, "Revo-Ception"); + Class.revolution.UPGRADES_TIER_0 = []; + Class.addons.UPGRADES_TIER_0.push('revolution'); + Class.revolution.UPGRADES_TIER_0.push('revoceptionist', 'autorevol', 'solario'); \ No newline at end of file diff --git a/server/modules/definitions/addons/woomeraddonmeow.js b/server/modules/definitions/addons/woomeraddonmeow.js new file mode 100644 index 000000000..079863f40 --- /dev/null +++ b/server/modules/definitions/addons/woomeraddonmeow.js @@ -0,0 +1,64 @@ +// An addon is guaranteed to run only after all groups are loaded. +// This is helpful, if your group relies on all other definitions already being loaded. +// Addons that are dependant on other addons should be named something like +// "[PARENT ADDON NAME]-[EXTENSION NAME].js", to make sure that it would run after that addon ran. +module.Class = ({ Class }) => { + +const { base } = require('../constants.js'); + +// This addon is disabled by default. +// You can also disable addons by not making them end with '.js' +// If you want to enable, simply make the line below just not run. +return console.log('[woomeraddonmeow.js] Addon disabled by default'); + + /* + Class.littleHunter = { + PARENT: "genericTank", + LABEL: "Subduer", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.hunter]), + TYPE: "bullet" + } + }] +}; +Class.flankdue = makeMulti({ + PARENT: "genericTank", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.1, + SPEED: base.SPEED * 1.1, + }, + GUNS: [{ + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter]), + TYPE: "bullet" + } + }] +}, 3, "Flankduer") +Class.autolittleHunter = makeAuto(Class.littleHunter, "Auto-Subduer") +Class.littleHunterbrid = makeHybrid('littleHunter', "Subduer-Hybrid") +Class.autolittleHunterbrid = makeHybrid('autolittleHunter', "Auto-Subduer-Hybrid") + +*/ +} \ No newline at end of file diff --git a/server/modules/definitions/combined.js b/server/modules/definitions/combined.js index f8b530de3..cb2cf3a8d 100644 --- a/server/modules/definitions/combined.js +++ b/server/modules/definitions/combined.js @@ -80,4 +80,4 @@ let i = 0; for (let key in Class) { if (!Class.hasOwnProperty(key)) continue; Class[key].index = i++; -} +} \ No newline at end of file diff --git a/server/modules/definitions/constants.js b/server/modules/definitions/constants.js index 25ac48e7f..23182c9e9 100644 --- a/server/modules/definitions/constants.js +++ b/server/modules/definitions/constants.js @@ -75,6 +75,12 @@ module.exports = { BULLET_DAMAGE: 'Ball Damage', RELOAD: 'Ball Density', }, + lancer: { + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + } }, gunCalcNames: { default: 0, diff --git a/server/modules/definitions/facilitators.js b/server/modules/definitions/facilitators.js index c87191003..d90094261 100644 --- a/server/modules/definitions/facilitators.js +++ b/server/modules/definitions/facilitators.js @@ -260,6 +260,30 @@ exports.makeHybrid = (type, name = -1) => { output.LABEL = name == -1 ? "Hybrid " + type.LABEL : name; return output; } +exports.makeHybridDrive = (type, name = -1) => { + type = ensureIsClass(type); + let output = exports.dereference(type); + let spawner = { + POSITION: [6, 12, 1.2, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: exports.combineStats([g.drone, g.weak]), + TYPE: ["turretedDrone", { INDEPENDENT: true }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: false, + MAX_CHILDREN: 3, + }, + }; + let spawnerdeco = { + POSITION: [7, 14, 0, 180, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + output.GUNS = type.GUNS == null ? [spawner] : type.GUNS.concat([spawner]); + output.TURRETS = type.TURRETS == null ? [spawnerdeco] : type.TURRETS.concat([spawnerdeco]); + output.LABEL = name == -1 ? "Hybrid " + type.LABEL : name; + return output; +} exports.makeOver = (type, name = -1) => { type = ensureIsClass(type); let output = exports.dereference(type); @@ -640,6 +664,58 @@ exports.makeAuto = (type, name = -1, options = {}) => { output.DANGER = type.DANGER + 1; return output; } +exports.makeTracker = (type, name = -1, options = {}) => { + let turret = { + type: "tracker3gun", + size: 10, + independent: true, + color: 16, + angle: 180, + }; + if (options.type != null) { + turret.type = options.type; + } + if (options.size != null) { + turret.size = options.size; + } + if (options.independent != null) { + turret.independent = options.independent; + } + if (options.color != null) { + turret.color = options.color; + } + if (options.angle != null) { + turret.angle = options.angle; + } + let output = exports.dereference(type); + let autogun = { + /********* SIZE X Y ANGLE ARC */ + POSITION: [turret.size, 0, 0, turret.angle, 360, 1], + TYPE: [ + turret.type, + { + CONTROLLERS: ["nearestDifferentMaster"], + INDEPENDENT: turret.independent, + COLOR: turret.color, + }, + ], + }; + if (type.GUNS != null) { + output.GUNS = type.GUNS; + } + if (type.TURRETS == null) { + output.TURRETS = [autogun]; + } else { + output.TURRETS = [...type.TURRETS, autogun]; + } + if (name == -1) { + output.LABEL = "Auto-" + type.LABEL; + } else { + output.LABEL = name; + } + output.DANGER = type.DANGER + 1; + return output; +} exports.makeCeption = (type, name = -1, options = {}) => { type = ensureIsClass(type); let turret = { @@ -683,6 +759,91 @@ exports.makeCeption = (type, name = -1, options = {}) => { output.DANGER = type.DANGER + 1; return output; } +exports.makeCeptionNerf = (type, name = -1, options = {}) => { + type = ensureIsClass(type); + let turret = { + type: "autoTurretNerf", + size: 12.5, + independent: true, + }; + if (options.type != null) { + turret.type = options.type; + } + if (options.size != null) { + turret.size = options.size; + } + if (options.independent != null) { + turret.independent = options.independent; + } + let output = exports.dereference(type); + let autogun = { + /********* SIZE X Y ANGLE ARC */ + POSITION: [turret.size, 0, 0, 180, 360, 1], + TYPE: [ + type, + { + CONTROLLERS: ["nearestDifferentMaster"], + INDEPENDENT: turret.independent, + }, + ], + }; + if (type.GUNS != null) { + output.GUNS = type.GUNS; + } + if (type.TURRETS == null) { + output.TURRETS = [autogun]; + } else { + output.TURRETS = [...type.TURRETS, autogun]; + } + if (name == -1) { + output.LABEL = type.LABEL + "-Ception"; + } else { + output.LABEL = name; + } + output.DANGER = type.DANGER + 1; + return output; +} +exports.addBackTurret = (type, name = "", options = {}) => { + type = ensureIsClass(type); + let turret = { + type: "autoTurret", + size: 11, + angle: 180, + }; + if (options.type != null) { + turret.type = options.type; + } + if (options.size != null) { + turret.size = options.size; + } + if (options.color != null) { + turret.color = options.color; + } + if (options.angle != null) { + turret.angle = options.angle; + } + let output = exports.dereference(type); + let autogun = { + POSITION: [turret.size, 8, 0, turret.angle, 190, 1], + TYPE: [ + turret.type, + { + COLOR: turret.color, + }, + ], + }; + if (type.GUNS != null) { + output.GUNS = type.GUNS; + } + if (type.TURRETS == null) { + output.TURRETS = [autogun]; + } else { + output.TURRETS = [...type.TURRETS, autogun]; + } + output.LABEL = name; + output.DANGER = type.DANGER + 1; + return output; +} exports.makeDeco = (shape = 0, color = 16) => { return { PARENT: "genericTank", @@ -690,13 +851,13 @@ exports.makeDeco = (shape = 0, color = 16) => { COLOR: color, }; } -exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor) => { +exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor, symbolType) => { let isHeal = damageFactor < 0; let auraType = isHeal ? "healAura" : "aura"; - let symbolType = isHeal ? "healerSymbol" : "auraSymbol"; + if (symbolType == null) symbolType = isHeal ? "healerSymbol" : "auraSymbol"; auraColor = auraColor ?? (isHeal ? 12 : 0); return { - PARENT: "genericTank", + PARENT: ["genericTank"], INDEPENDENT: true, LABEL: "", COLOR: 17, @@ -720,6 +881,41 @@ exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor) = ] }; } +exports.makeAura = (type, name = -1, options = {}) => { + let turret = { + type: "auraBasicGen", + size: 14, + }; + if (options.type != null) { + turret.type = options.type; + } + if (options.size != null) { + turret.size = options.size; + } + let output = exports.dereference(type); + let aurathing = { + /********* SIZE X Y ANGLE ARC */ + POSITION: [turret.size, 0, 0, 0, 0, 1], + TYPE: [ + turret.type, + ], + }; + if (type.GUNS != null) { + output.GUNS = type.GUNS; + } + if (type.TURRETS == null) { + output.TURRETS = [aurathing]; + } else { + output.TURRETS = [...type.TURRETS, aurathing]; + } + if (name == -1) { + output.LABEL = "Aura " + type.LABEL; + } else { + output.LABEL = name; + } + output.DANGER = type.DANGER + 2; + return output; +} exports.menu = (name = -1, color = -1, shape = 0) => { let gun = { diff --git a/server/modules/definitions/groups/bosses.js b/server/modules/definitions/groups/bosses.js index 29d60ca9f..f7147e97d 100644 --- a/server/modules/definitions/groups/bosses.js +++ b/server/modules/definitions/groups/bosses.js @@ -1,2943 +1,2943 @@ -const { combineStats, skillSet, makeAuto, addAura, LayeredBoss, makeDeco } = require('../facilitators.js'); -const { base, gunCalcNames, smshskl } = require('../constants.js'); -const g = require('../gunvals.js'); -require('./generics.js'); - -Class.miniboss = { - PARENT: "genericBoss", - CONTROLLERS: ["nearestDifferentMaster", "minion", "canRepel"], - AI: { NO_LEAD: true }, -}; -Class.ramMiniboss = { - PARENT: "genericBoss", - CONTROLLERS: ["nearestDifferentMaster", "canRepel", "mapTargetToGoal"], -}; - -// ELITE CRASHERS -Class.elite = { - PARENT: "miniboss", - LABEL: "Elite Crasher", - COLOR: "pink", - SHAPE: 3, - SIZE: 27, - VARIES_IN_SIZE: true, - VALUE: 15e4, - BODY: { - FOV: 1.25, - SPEED: 0.1 * base.SPEED, - HEALTH: 7 * base.HEALTH, - DAMAGE: 2.5 * base.DAMAGE, - }, -}; -Class.eliteDestroyer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Destroyer", - UPGRADE_COLOR: "pink", - GUNS: [ - { - POSITION: [5, 16, 1, 6, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, { - POSITION: [5, 16, 1, 6, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, { - POSITION: [5, 16, 1, 6, 0, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, - ], - TURRETS: [ - { - POSITION: [11, 0, 0, 180, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, 60, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, -60, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: [ "bigauto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.eliteGunner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Gunner", - UPGRADE_COLOR: "pink", - FACING_TYPE: "toTarget", - GUNS: [ - { - POSITION: [14, 16, 1, 0, 0, 180, 0], - }, { - POSITION: [4, 16, 1.5, 14, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: ["unsetPillbox", {MOTION_TYPE: "glide"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [6, 14, -2, 2, 0, 60, 0], - }, { - POSITION: [6, 14, -2, 2, 0, 300, 0], - }, - ], - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 8, 0, 60, 180, 0], - TYPE: ["auto4gun"], - }, { - POSITION: [14, 8, 0, 300, 180, 0], - TYPE: ["auto4gun"], - }, - ], -}; -Class.eliteSprayer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Sprayer", - UPGRADE_COLOR: "pink", - SKILL: [0, 9, 3, 9, 2, 9, 9, 9, 9, 0], - AI: { NO_LEAD: false }, - HAS_NO_RECOIL: true, - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [6, 0, 0, 0, 360, 1], - TYPE: ["machineTripleTurret", { INDEPENDENT: true }], - }, { - POSITION: [9, 6, -5, 180, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, 180, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, 60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, -5, 60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, -60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, -5, -60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, - ], -}; -Class.eliteBattleship = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Battleship", - UPGRADE_COLOR: "pink", - GUNS: [ - { - POSITION: [4, 6, 0.6, 7, -8, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, 60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, -8, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, -8, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, -60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - ], - TURRETS: [ - { - POSITION: [5, 7, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [5, 7, 0, 120, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [5, 7, 0, 240, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.eliteSpawner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Spawner", - UPGRADE_COLOR: "pink", - MAX_CHILDREN: 9, - AI: { STRAFE: false }, - GUNS: [ - { - POSITION: [11, 16, 1, 0, 0, 60, 0], - }, { - POSITION: [11, 16, 1, 0, 0, 180, 0], - }, { - POSITION: [11, 16, 1, 0, 0, 300, 0], - }, { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [2, 18, 1, 11, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentrySwarm", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [2, 18, 1, 11, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentryTrap", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [2, 18, 1, 11, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentryGun", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, - ], - TURRETS: [ - { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: ["auto4gun", { INDEPENDENT: false, COLOR: -1 }], - }, - ], -}; -Class.eliteTrapGuard = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Trap Guard", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false }, - GUNS: [], - TURRETS: [ - { - POSITION: [9.5, 0, 0, 0, 360, 1], - TYPE: "triTrapGuardTurret", - }, - ], -}; -for (let i = 0; i < 3; i++) { - Class.eliteTrapGuard.GUNS.push( - { - POSITION: [10.5, 6, 1, 0, 0, 120*i+60, 0], - }, { - POSITION: [3, 6, 1.7, 10.5, 0, 120*i+60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ) - Class.eliteTrapGuard.TURRETS.push( - { - POSITION: [5, 8, -7, 120*i+60, 160, 0], - TYPE: ["autoTurret", { INDEPENDENT: false }], - }, { - POSITION: [5, 8, 7, 120*i+60, 160, 0], - TYPE: ["autoTurret", { INDEPENDENT: false }], - }, - ) -}; -Class.eliteSpinner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Spinner", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false }, - FACING_TYPE: ["spin", {speed: 0.1}], - GUNS: [], - TURRETS: [ - { - POSITION: [9.5, 0, 0, 0, 360, 1], - TYPE: ["eliteSpinnerCyclone", {COLOR: -1}], - }, - ], -}; -for (let i = 0; i < 3; i++) { - Class.eliteSpinner.GUNS.push( - { - POSITION: [9.5, 2, 1, -1.5, 11.5, 120*i+10, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [9.5, 2, 1, 3.5, 6.5, 120*i+10, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [9.5, 2, 1, 8.5, 1.5, 120*i+10, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [2, 20, 0.75, 8, 0, 120*i+60, 0], - }, - ) -}; - -// OLD ELITE -Class.oldEliteSprayer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Sprayer (Old)", - UPGRADE_COLOR: "pink", - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 6, 0, 180, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, { - POSITION: [14, 6, 0, 60, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, { - POSITION: [14, 6, 0, -60, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, - ], -}; - -// Legionary Crasher -Class.legionaryCrasherTop = { - PARENT: "elite", - AI: { STRAFE: false, NO_LEAD: false }, - CONTROLLERS: [ ["spin", { independent: true, speed: -0.005 }] ], - INDEPENDENT: true, - GUNS: [], - TURRETS: [], -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasherTop.GUNS.push( - { - POSITION: [4, 9.5, 0.7, 7, 5, 120*i+60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), - TYPE: [ "swarm", { INDEPENDENT: true } ], - STAT_CALCULATOR: gunCalcNames.swarm, - AUTOFIRE: true, - - }, - }, { - POSITION: [4, 9.5, 0.7, 7, -5, 120*i+60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), - TYPE: [ "swarm", { INDEPENDENT: true } ], - STAT_CALCULATOR: gunCalcNames.swarm, - AUTOFIRE: true, - }, - }, - ) - Class.legionaryCrasherTop.TURRETS.push( - { - POSITION: [9.5, 10, 0, 120*i, 190, 0], - TYPE: "auto4gun", - }, - ) -} -Class.legionaryCrasher = { - PARENT: "elite", - LABEL: "Legionary Crasher", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false, NO_LEAD: false }, - HAS_NO_RECOIL: true, - VALUE: 5e6, - SIZE: 75, - BODY: { - FOV: 1.5, - SPEED: 0.1 * base.SPEED, - HEALTH: 2000, - DAMAGE: 5 * base.DAMAGE, - }, - GUNS: [], - TURRETS: [ - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: "legionaryCrasherTop", - } - ], -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasher.GUNS.push( - { - POSITION: [14.5, 13, 1, 0, 0, 120*i, 0], - }, { - POSITION: [3, 13, 1.7, 14.5, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, g.destroyer, { speed: 2.5, size: 0.6, maxSpeed: 3 }]), - TYPE: "legionaryPillbox", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ) -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasher.GUNS.push( - { - POSITION: [5, 12, 1.6, -11, 0, 120*i, 0], - } - ) - Class.legionaryCrasher.TURRETS.push( - { - POSITION: [14, 8, 0, 120*i+60, 180, 0], - TYPE: [ "sprayer", { COLOR: -1, } ], - }, - ) -} - -Class.sprayerLegion = { - PARENT: "elite", - UPGRADE_LABEL: "Sprayer Legion", - UPGRADE_COLOR: "pink", - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 6, 0, 180, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, { - POSITION: [14, 6, 0, 60, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, { - POSITION: [14, 6, 0, -60, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, - ], -}; - -// STRANGE BOSSES -Class.sorcerer = { - PARENT: "miniboss", - LABEL: "Sorcerer", - DANGER: 7, - SHAPE: 0, - COLOR: "veryLightGrey", - UPGRADE_COLOR: "veryLightGrey", - SIZE: 26, - MAX_CHILDREN: 50, - VALUE: 2e5, - BODY: { - FOV: 0.5, - SPEED: 0.12 * base.SPEED, - HEALTH: 6 * base.HEALTH, - DAMAGE: 2 * base.DAMAGE, - }, - GUNS: Array(2).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.machineGun, g.machineGunner, { size: 0.4, spray: 150, speed: 2, shudder: 1.75 }]), - TYPE: "minichip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.summoner = { - PARENT: "miniboss", - LABEL: "Summoner", - DANGER: 8, - SHAPE: 4, - COLOR: "gold", - UPGRADE_COLOR: "gold", - SIZE: 26, - MAX_CHILDREN: 28, - VALUE: 3e5, - BODY: { - FOV: 0.5, - SPEED: 0.1 * base.SPEED, - HEALTH: 7 * base.HEALTH, - DAMAGE: 2.6 * base.DAMAGE, - }, - GUNS: Array(4).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.8 }]), - TYPE: ["sunchip"], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.enchantress = { - PARENT: "miniboss", - LABEL: "Enchantress", - DANGER: 8, - SHAPE: 3.5, - COLOR: "orange", - UPGRADE_COLOR: "orange", - SIZE: 26, - MAX_CHILDREN: 28, - VALUE: 4e5, - BODY: { - FOV: 0.5, - SPEED: 0.09 * base.SPEED, - HEALTH: 10 * base.HEALTH, - DAMAGE: 3 * base.DAMAGE, - }, - GUNS: Array(3).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.9 }]), - TYPE: "dorito", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.exorcistor = { - PARENT: "miniboss", - LABEL: "Exorcistor", - DANGER: 8, - SHAPE: 5.5, - COLOR: "purple", - UPGRADE_COLOR: "purple", - SIZE: 26, - MAX_CHILDREN: 20, - VALUE: 5e5, - BODY: { - FOV: 0.5, - SPEED: 0.08 * base.SPEED, - HEALTH: 15 * base.HEALTH, - DAMAGE: 4 * base.DAMAGE, - }, - GUNS: Array(5).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 72, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), - TYPE: "demonchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.shaman = { - PARENT: "miniboss", - LABEL: "Shaman", - DANGER: 8, - SHAPE: 6, - COLOR: "hexagon", - UPGRADE_COLOR: "hexagon", - SIZE: 26, - MAX_CHILDREN: 20, - VALUE: 6e5, - BODY: { - FOV: 0.5, - SPEED: 0.07 * base.SPEED, - HEALTH: 20 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - }, - GUNS: Array(6).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { size: 1.1 }]), - TYPE: "realchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.eliteSkimmer = { - PARENT: "elite", - LABEL: "Elite Skimmer", - COLOR: "orange", - UPGRADE_COLOR: "orange", - TURRETS: [ - { - POSITION: [15, 5, 0, 60, 170, 0], - TYPE: "skimmerTurret", - }, { - POSITION: [15, 5, 0, 180, 170, 0], - TYPE: "skimmerTurret", - }, { - POSITION: [15, 5, 0, 300, 170, 0], - TYPE: "skimmerTurret", - }, - ], -}; - -// Nesters -Class.nestKeeper = { - PARENT: "miniboss", - LABEL: "Nest Keeper", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - MAX_CHILDREN: 15, - VALUE: 3e5, - GUNS: [ - { - POSITION: [3.5, 6.65, 1.2, 8, 0, 35, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, -35, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, 108, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, -108, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, - ], - TURRETS: [ - { - POSITION: [8, 9, 0, 72, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 0, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 144, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 216, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, -72, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "boomerTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.nestWarden = { - PARENT: "miniboss", - LABEL: "Nest Warden", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - VALUE: 3e5, - GUNS: [], - TURRETS: [ - { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "barricadeTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -for(let i = 0; i < 5; i++) { - Class.nestWarden.GUNS.push( - { - POSITION: [10.7, 8, 1, 0, 0, 72*i+36, 0], - }, { - POSITION: [1.5, 8, 1.2, 10.7, 0, 72*i+36, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { speed: 1.2 }, g.setTrap, g.constructor]), - TYPE: "unsetTrap", - STAT_CALCULATOR: gunCalcNames.block - }, - }, - ); - Class.nestWarden.TURRETS.push( - { - POSITION: [8, 9, 0, 72*i, 120, 0], - TYPE: [ "cruiserTurret", { INDEPENDENT: true, COLOR: -1 } ], - } - ); -}; -Class.nestGuardian = { - PARENT: "miniboss", - LABEL: "Nest Guardian", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - VALUE: 3e5, - GUNS: [], - TURRETS: [ - { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "twisterTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -for(let i = 0; i < 5; i++) { - Class.nestGuardian.GUNS.push( - { - POSITION: [5.5, 7, 1, 6, 0, 72*i+36, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, - ); - Class.nestGuardian.TURRETS.push( - { - POSITION: [8, 9, 0, 72*i, 120, 0], - TYPE: [ "swarmerTurret", { INDEPENDENT: true, COLOR: -1 } ], - } - ); -}; - -// Rogues -Class.roguePalisade = { - PARENT: "miniboss", - LABEL: "Rogue Palisade", - COLOR: "darkGrey", - UPGRADE_COLOR: "darkGrey", - SHAPE: 6, - SIZE: 30, - VALUE: 5e5, - CONTROLLERS: ['nearestDifferentMaster', 'onlyAcceptInArc'], - BODY: { - FOV: 1.4, - SPEED: 0.05 * base.SPEED, - HEALTH: 16 * base.HEALTH, - SHIELD: 3 * base.SHIELD, - DAMAGE: 3 * base.DAMAGE, - }, - GUNS: [ - { POSITION: [4, 6, -1.6, 8, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 60, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 120, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 180, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 240, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 300, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - ], - TURRETS: [ - { POSITION: [5, 10, 0, 30, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 90, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 150, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 210, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 270, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 330, 110, 0], TYPE: "baseTrapTurret" }, - ], -}; -Class.rogueArmada = (() => { - let SHAPE = 7, - GUNS = [], - TURRETS = []; - for (let i = 0; i < SHAPE; i++) { - for (let j = 0; j < 8; j++) { - GUNS.push({ - POSITION: [8, 2 + Math.floor(j / 3), 1, 0, j / 2 - 2, (i + 0.5) * (360 / SHAPE), 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), - TYPE: j % SHAPE < 2 ? "bullet" : "casing" - } - }); - } - GUNS.push({ - POSITION: [8.5, 6, 1, 4, 0, (i + 0.5) * (360 / SHAPE), 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), - TYPE: "casing" - } - }, { - POSITION: [7, 6, -1.6, 4, 0, (i + 0.5) * (360 / SHAPE), 0] - }); - } - for (let i = 0; i < SHAPE; i++) { - TURRETS.push({ - POSITION: [5, 10, 0, i * 360 / SHAPE, 160, 0], - TYPE: "shottrapTurret" - }); - } - return { - PARENT: "miniboss", - LABEL: 'Rogue Armada', - COLOR: "darkGrey", - UPGRADE_COLOR: "darkGrey", - SHAPE, - SIZE: 28, - VALUE: 500000, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.1, - HEALTH: base.HEALTH * 16, - SHIELD: base.SHIELD * 3, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 3, - }, - GUNS, TURRETS - }; -})(); - -// Bob. -Class.bob = { - PARENT: "ramMiniboss", - LABEL: "Bob", - SHAPE: 0, - COLOR: "aqua", - UPGRADE_COLOR: "aqua", - SIZE: 18, - BODY: { - FOV: 2, - SPEED: 2 * base.SPEED, - HEALTH: 5 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - REGEN: 8 * base.REGEN, - FOV: 0.5 * base.FOV, - DENSITY: 6 * base.DENSITY, - }, - CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody", - }, { - POSITION: [21.5, 0, 0, 30, 360, 0], - TYPE: "landmineBody", - }, { - POSITION: [23.75, 0, 0, 0, 360, 0], - TYPE: "spikeBody", - }, - ], -}; -Class.nemesis = { - PARENT: "bob", - LABEL: "Nemesis", - COLOR: "red", - UPGRADE_COLOR: "red", - BODY: { - REGEN: 1e5, - HEALTH: 1e6, - DENSITY: 30, - DAMAGE: 1e5, - FOV: 5, - }, -}; - -// DIEP BOSSES -Class.guardian = { - PARENT: "elite", - LABEL: "Guardian of the Pentagons", - UPGRADE_LABEL: "Guardian", - UPGRADE_COLOR: "pink", - FACING_TYPE: "toTarget", - GUNS: [ - { - POSITION: [4, 12, 1.4, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, { size: 0.5 }]), - TYPE: "swarm", - AUTOFIRE: true, - }, - }, - ], - AI: { NO_LEAD: false }, -}; -Class.defenderAutoTankGun = { - PARENT: "autoTankGun", - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret]), - TYPE: ["bullet", {COLOR: "yellow"}], - }, - }, - ], -}; -Class.defender = { - PARENT: "elite", - LABEL: "Defender", - COLOR: "orange", - UPGRADE_COLOR: "orange", - GUNS: [ - { - POSITION: [15, 7, 1, -3, 0, 60, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [15, 7, 1, -3, 0, 180, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [15, 7, 1, -3, 0, 300, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], - TURRETS: [ - { - POSITION: [5, 7, 0, 0, 190, 1], - TYPE: "defenderAutoTankGun", - }, { - POSITION: [5, 7, 0, 120, 190, 1], - TYPE: "defenderAutoTankGun", - }, { - POSITION: [5, 7, 0, 240, 190, 1], - TYPE: "defenderAutoTankGun", - }, - ], - AI: { NO_LEAD: false }, -}; - -// CELESTIALS -Class.terrestrial = { - PARENT: "miniboss", - LABEL: "Terrestrial", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 5e5, - SHAPE: 7, - SIZE: 35, - BODY: { - FOV: 1, - HEALTH: 1000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 9, - }, -}; -Class.celestial = { - PARENT: "miniboss", - LABEL: "Celestial", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 1e6, - SHAPE: 9, - SIZE: 45, - BODY: { - FOV: 1, - HEALTH: 1000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 12, - }, -}; -Class.rogueCelestial = { - PARENT: "celestial", - LABEL: "Rogue Celestial", - COLOR: "darkGrey", -}; -Class.eternal = { - PARENT: "miniboss", - LABEL: "Eternal", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 4e6, - SHAPE: 11, - SIZE: 90, - BODY: { - FOV: 1, - HEALTH: 3000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 18, - }, -}; - -// Terrestrials -let ares = new LayeredBoss(null, "Ares", "terrestrial", 7, "purple", "terrestrialTrapTurret", 7, 5.5); -ares.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["demonchip", { INDEPENDENT: true, }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, false, null, 18); -ares.addLayer({turret: { - POSITION: [10, 8.5, 0, null, 160, 0], - TYPE: ["protoSwarmerTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let gersemi = new LayeredBoss(null, "Gersemi", "terrestrial", 7, "lightGreen", "terrestrialTrapTurret", 7, 5.5); -gersemi.addLayer({turret: { - POSITION: [9, 8, 0, null, 160, 0], - TYPE: ["swarmTurret", { INDEPENDENT: true }], -}}); -gersemi.addLayer({turret: { - POSITION: [9.5, 7.5, 0, null, 160, 0], - TYPE: ["basicTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let ezekiel = new LayeredBoss(null, "Ezekiel", "terrestrial", 7, "orange", "terrestrialTrapTurret", 7, 5.5); -ezekiel.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["dorito", { COLOR: "orange", INDEPENDENT: true, }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 18); -ezekiel.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["skimmerTurret", { COLOR: "grey", INDEPENDENT: true }], -}}, true, 6.5) - -let eris = new LayeredBoss(null, "Eris", "terrestrial", 7, "pink", "terrestrialTrapTurret", 7, 5.5); -eris.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), - TYPE: ["minion", { INDEPENDENT: true, COLOR: "pink", HAS_NO_RECOIL: true }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, false, null, 14); -eris.addLayer({turret: { - POSITION: [10, 8.5, 0, null, 160, 0], - TYPE: ["rocketeerTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let selene = new LayeredBoss(null, "Selene", "terrestrial", 7, "gold", "terrestrialTrapTurret", 7, 5.5); -selene.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["sunchip", { COLOR: "gold", INDEPENDENT: true }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 18); -selene.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["hyperTwisterTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -// PALADIN -let paladin = new LayeredBoss(null, "Paladin", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); -paladin.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: ["demonchip", {INDEPENDENT: true}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 16); -paladin.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: "swarmerTurret", -}}, true, 6); - -// FREYJA -let freyja = new LayeredBoss(null, "Freyja", "celestial", 9, "lightGreen", "baseTrapTurret", 6.5, 5.5); -freyja.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "cruiserTurret", -}}); -freyja.addLayer({turret: { - POSITION: [10.6, 7.5, 0, null, 160, 0], - TYPE: "auto4gun", -}}, true, 6); - -// ZAPHKIEL -let zaphkiel = new LayeredBoss(null, "Zaphkiel", "celestial", 9, "orange", "baseTrapTurret", 6.5, 5.5); -zaphkiel.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: ["drone", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 16); -zaphkiel.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["skimmerTurret", {COLOR: "grey", INDEPENDENT: true}], -}}, true, 6); - -// NYX -let nyx = new LayeredBoss(null, "Nyx", "celestial", 9, "pink", "baseTrapTurret", 6.5, 5.5); -nyx.addLayer({gun: { - POSITION: [3.8, 7, -1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), - TYPE: ["minion", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 16); -nyx.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: "rocketeerTurret", -}}, true, 6); - -// THEIA -let theia = new LayeredBoss(null, "Theia", "celestial", 9, "gold", "baseTrapTurret", 6.5, 5.5); -theia.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, { size: 0.5 }]), - TYPE: ["summonerDrone", {INDEPENDENT: true}], - AUTOFIRE: true, - WAIT_TO_CYCLE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 35); -theia.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["twisterTurret", {COLOR: "grey"}], -}}, true, 6); - -// ATLAS -let atlas = new LayeredBoss(null, "Atlas", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); -atlas.addLayer({turret: { - POSITION: [7, 9, 0, null, 180, 0], - TYPE: "artilleryTurret", -}}); -atlas.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "nailgunTurret", -}}, true, 6); - -// RHEA -let rhea = new LayeredBoss(null, "Rhea", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -rhea.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "wrenchTurret", -}}); -rhea.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "crowbarTurret", -}}, true, 6); - -// JULIUS -let julius = new LayeredBoss(null, "Julius", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -julius.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "juliusLowerTurret", -}}); -julius.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "launcherTurret", -}}, true, 6); - -// GENGHIS -let genghis = new LayeredBoss(null, "Genghis", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -genghis.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "genghisLowerTurret", -}}); -genghis.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "auto4gun", -}}, true, 6); - -// NAPOLEON -let napoleon = new LayeredBoss(null, "Napoleon", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -napoleon.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "napoleonLowerTurret", -}}); -napoleon.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "napoleonUpperTurret", -}}, true, 6) - -// Eternals -let kronos = new LayeredBoss(null, "Kronos", "eternal", 11, "veryLightGrey", "baseTrapTurret", 6, 5.5); -kronos.addLayer({turret: { - POSITION: [6.5, 9, 0, null, 160, 0], - TYPE: "kronosSkimmerTurret", -}}); -kronos.addLayer({turret: { - POSITION: [6.5, 9, 0, null, 160, 0], - TYPE: "carrierTurret", -}}, true, 4); -kronos.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 160, 0], - TYPE: "tripletTurret", -}}, true, 4); - -let odin = new LayeredBoss(null, "Odin", "eternal", 11, "aqua", "baseTrapTurret", 4.5, 3.5); -odin.addLayer({gun: { - POSITION: [2.25, 3.25, -1.6, 9, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }, g.pounder, {size: 1.7}]), - TYPE: ["gemDrone", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 18); -odin.addLayer({turret: { - POSITION: [7, 8, 0, null, 160, 0], - TYPE: "autosmashTurret", -}}, true, 5.5); -odin.addLayer({turret: { - POSITION: [8, 9, 0, null, 160, 0], - TYPE: "gunnerCruiserTurret", -}}, true, 4.5); - -// Developer Bosses -Class.taureonCoreBase = { - SHAPE: 4, - COLOR: '#00A2E8' -}; -Class.taureonCore = { - PARENT: "genericTank", - LABEL: "Core Turret", - SHAPE: 4.5, - COLOR: '#99D9EA', - CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], - INDEPENDENT: true, - GUNS: [{ - POSITION: [10, 14, -0.5, 14, 0, 0, 0] - },{ - POSITION: [21, 15, -1.1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.destroyer, g.sniper]), - TYPE: "snake", - STAT_CALCULATOR: gunCalcNames.sustained - } - }], - TURRETS: [{ - POSITION: [20 * Math.SQRT2, 0, 0, 0, 0, 0], - TYPE: "taureonCoreBase" - }] -}; -Class.taureonBase = { - SHAPE: 4.5, - COLOR: '#161B54', - MIRROR_MASTER_ANGLE: true -}; -let d = 1/4; -Class.taureonStar = { - SHAPE: [[0,1],[d,d],[1,0],[d,-d],[0,-1],[-d,-d],[-1,0],[-d,d]], - COLOR: '#3F48CC', - MIRROR_MASTER_ANGLE: true -}; -Class.taureonRailgunTurret = { - PARENT: "genericTank", - COLOR: "grey", - LABEL: "Railgun Turret", - CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], - INDEPENDENT: true, - GUNS: [{ - POSITION: [20, 7, 1, 0, 0, 0, 0] - },{ - POSITION: [24, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.destroyer, { speed: 5, penetration: 0.8 }]), - TYPE: "bullet" - } - },{ - POSITION: [5, 7.5, -1.6, 8, 0, 0, 0], - }] -}; -Class.taureonThruster = { - PARENT: "genericTank", - COLOR: "grey", - LABEL: "Thruster", - CONTROLLERS: ["onlyAcceptInArc"], - GUNS: [{ - POSITION: [14, 12, 1, 4, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), - TYPE: ["bullet", { ALPHA: 0.5 }] - } - }, { - POSITION: [12, 12, 1.4, 4, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), - TYPE: ["bullet", { ALPHA: 0.5 }] - }, - }] -}; -Class.taureonMissile = { - PARENT: "bullet", - LABEL: "Missile", - FACING_TYPE: "smoothToTarget", - CONTROLLERS: ["nearestDifferentMaster"], - INDEPENDENT: true, - BODY: { - ACCELERATION: 10, - FOV: base.FOV * 2 - }, - TURRETS: [{/** SIZE X Y ANGLE ARC */ - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - }], - GUNS: [{/* LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [6, 12, 1.4, 8, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] - } - },{ - POSITION: [10, 12, 0.8, 8, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] - } - },...Array(32).fill().map((_, i)=>({ - POSITION: [0, (i % 4) + 1, 0, 0, 0, 0, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, { spray: 1e6, range: 0.5, shudder: 1.5, damage: 1 + (i % 4) }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - SHOOT_ON_DEATH: true - }, - }))] -}; -Class.taureonBoss = { - PARENT: "miniboss", - LABEL: "Diamond Marauder", - NAME: "Taureon", - COLOR: '#2B339B', - UPGRADE_COLOR: "spaceGem", - DANGER: 10, - SHAPE: 4.5, - SIZE: 50, - FACING_TYPE: "smoothToTarget", - UPGRADE_TOOLTIP: "With a powerful Gatling Gun on the front, Rocket Launchers as wings, movable Thrusters on the back, " + - "and equipped with Railgun Turrets, it perfectly excells at terminating those who feel its Wrath.\n" + - "An octahedral carbon robot, exclusively designed to eradicate opponents with sheer brutality alone.\n" + - '"NOW YOU FACE MY ULTIMATE CREATION."', - VALUE: 9e6, - BODY: { - FOV: 1, - SPEED: 0.5 * base.SPEED, - HEALTH: 20 * base.HEALTH, - DAMAGE: 3 * base.DAMAGE, - }, - TURRETS: [{ - POSITION: [23.3, 0, 0, 0, 0, 0], - TYPE: "taureonBase" - },{ - POSITION: [5, 10, 0, -45, 180, 0], - TYPE: "taureonRailgunTurret" - },{ - POSITION: [5, 10, 0, 45, 180, 0], - TYPE: "taureonRailgunTurret" - },{ - POSITION: [5, -10, -2, -45, 90, 0], - TYPE: "taureonThruster" - },{ - POSITION: [5, -10, 2, 45, 90, 0], - TYPE: "taureonThruster" - },{ - POSITION: [25, 0, 0, 0, 0, 1], - TYPE: "taureonStar" - },{ - POSITION: [5, 0, 0, 0, 360, 1], - TYPE: "taureonCore" - }], - GUNS: [...Array(6).fill().map((_, i) => ({ - POSITION: [18, 1.75, 1, 0, Math.cos(Math.PI * i / 3) * 2, 0, i / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, { speed: 2, maxSpeed: 2, damage: 0.75, size: 0.8 }]), - TYPE: "bullet" - } - })),{ - POSITION: [4, 5, -0.5, 12, 0, -90, 0] - },{ - POSITION: [10, 5, -1.2, 5, 0, -90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), - TYPE: "taureonMissile", - STAT_CALCULATOR: gunCalcNames.sustained - } - },{ - POSITION: [4, 5, -0.5, 12, 0, 90, 0] - },{ - POSITION: [10, 5, -1.2, 5, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), - TYPE: "taureonMissile", - STAT_CALCULATOR: gunCalcNames.sustained - } - },{ - POSITION: [5.5, 5, -1.5, 5, 0, -45, 0] - },{ - POSITION: [5.5, 5, -1.5, 5, 0, 45, 0] - },{ - POSITION: [2, 7, 1, 8, 0, 0, 0] - },{ - POSITION: [2, 7, 1, 14.5, 0, 0, 0] - }] -}; - -Class.zephiMiscDeco = makeDeco(4, "white") -Class.zephiMiscDeco2 = makeDeco(4, "black") -Class.zephiSunchip = makeAuto({ - PARENT: "drone", - SHAPE: 4, - HITS_OWN_TYPE: "hard", - BODY: { - FOV: 0.5, - }, - AI: { - BLIND: true, - FARMER: true, - }, - TURRETS: [{ - POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], - TYPE: ["overdriveDeco", { MIRROR_MASTER_ANGLE: true }] - },{ - POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], - TYPE: ["shinySquare", { MIRROR_MASTER_ANGLE: true }] - }] -}, "Robo-Sunchip", {type: 'autoSmasherTurret', size: 6}) -Class.zephiEggchip = { - PARENT: "drone", - LABEL: "Guided Missile", - SHAPE: 0, - HITS_OWN_TYPE: "hard", - BODY: { - FOV: 0.5, - }, - AI: { - BLIND: true, - FARMER: true, - }, - GUNS: [ - { - POSITION: [14, 6, 1, 0, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, g.lowPower, { reload: 0.5, recoil: 1.35, speed: 1.3, maxSpeed: 1.3 }]), - TYPE: ["bullet", { COLOR: "black", PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.thruster, - }, - }, - ], - TURRETS: [{ - POSITION: [10, 0, 0, 45, 0, 1], - TYPE: "gem" - }] -} -Class.zephiGearOuter = makeDeco('M 0.5 0.0929 V -0.0908 L 0.3875 -0.1096 C 0.3792 -0.1409 0.3667 -0.1701 0.3521 -0.1952 L 0.4187 -0.2871 L 0.2896 -0.4186 L 0.1958 -0.3539 C 0.1687 -0.3685 0.1396 -0.381 0.1104 -0.3894 L 0.0917 -0.5 H -0.0917 L -0.1104 -0.3873 C -0.1417 -0.3789 -0.1688 -0.3664 -0.1958 -0.3518 L -0.2875 -0.4165 L -0.4188 -0.2871 L -0.3521 -0.1952 C -0.3667 -0.1681 -0.3792 -0.1388 -0.3875 -0.1075 L -0.5 -0.0908 V 0.0929 L -0.3875 0.1117 C -0.3792 0.143 -0.3667 0.1701 -0.3521 0.1973 L -0.4188 0.2912 L -0.2896 0.4207 L -0.1958 0.3539 C -0.1688 0.3685 -0.1396 0.381 -0.1083 0.3894 L -0.0896 0.5 H 0.0938 L 0.1125 0.3873 C 0.1417 0.3789 0.1708 0.3664 0.1979 0.3518 L 0.2917 0.4186 L 0.4208 0.2891 L 0.3542 0.1952 C 0.3688 0.1681 0.3812 0.1409 0.3896 0.1096 L 0.5 0.0929 Z M 0.3333 0 C 0.3333 0.1841 0.1841 0.3333 0 0.3333 C -0.1841 0.3333 -0.3333 0.1841 -0.3333 0 C -0.3333 -0.1841 -0.1841 -0.3333 0 -0.3333 C 0.1841 -0.3333 0.3333 -0.1841 0.3333 0 Z', '#7F7F7F') -Class.zephiGearOuter.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearOuter.BORDERLESS = true -Class.zephiGearCentre = makeDeco(0, '#1F1F1F') -Class.zephiGearCentre.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearCentre.BORDERLESS = true -Class.zephiGearRed = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#FF1F1F') -Class.zephiGearRed.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearRed.BORDERLESS = true -Class.zephiGearGreen = makeDeco('M 0.0771 -0.2552 C 0.0743 -0.2561 0.0691 -0.2576 0.0657 -0.2585 L 0.0607 -0.2597 C 0.0571 -0.2605 0.0514 -0.2617 0.0479 -0.2623 L 0.0428 -0.2632 C 0.0392 -0.2638 0.0334 -0.2646 0.0299 -0.265 L 0.0247 -0.2655 C 0.0211 -0.2659 0.0153 -0.2662 0.0117 -0.2664 L 0.0066 -0.2666 C 0.003 -0.2667 -0.0029 -0.2667 -0.0065 -0.2666 L -0.0116 -0.2664 C -0.0153 -0.2662 -0.0211 -0.2659 -0.0247 -0.2655 L -0.0298 -0.265 C -0.0334 -0.2646 -0.0392 -0.2638 -0.0427 -0.2632 L -0.0478 -0.2623 C -0.0514 -0.2617 -0.0571 -0.2605 -0.0606 -0.2597 L -0.0656 -0.2585 C -0.0691 -0.2576 -0.0747 -0.256 -0.0782 -0.2549 C -0.081 -0.254 -0.0833 -0.2502 -0.0833 -0.2466 V 0.2466 C -0.0833 0.2502 -0.0805 0.2541 -0.0771 0.2552 C -0.0743 0.2561 -0.0691 0.2576 -0.0656 0.2585 L -0.0606 0.2597 C -0.0571 0.2605 -0.0514 0.2617 -0.0478 0.2623 L -0.0427 0.2632 C -0.0392 0.2638 -0.0334 0.2646 -0.0298 0.265 L -0.0247 0.2655 C -0.0211 0.2659 -0.0153 0.2663 -0.0116 0.2664 L -0.0065 0.2666 C -0.0029 0.2667 0.003 0.2667 0.0066 0.2666 L 0.0117 0.2664 C 0.0153 0.2663 0.0211 0.2659 0.0247 0.2655 L 0.0299 0.265 C 0.0334 0.2646 0.0392 0.2638 0.0428 0.2632 L 0.0479 0.2623 C 0.0514 0.2617 0.0571 0.2605 0.0607 0.2597 L 0.0657 0.2585 C 0.0691 0.2576 0.0748 0.256 0.0782 0.2549 C 0.0811 0.254 0.0834 0.2502 0.0834 0.2466 V -0.2466 C 0.0834 -0.2502 0.0806 -0.2541 0.0771 -0.2552 Z', '#1FDF1F') -Class.zephiGearGreen.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearGreen.BORDERLESS = true -Class.zephiGearBlue = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#1F7FDF') -Class.zephiGearBlue.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearBlue.BORDERLESS = true -Class.zephiBoss = { - PARENT: "miniboss", - LABEL: "Shiny Mecha-Thaumaturge", - NAME: "Zephi", - DANGER: 10, - SHAPE: 4, - COLOR: "lightGreen", - UPGRADE_COLOR: "lightGreen", - SIZE: 50, - VALUE: 5e6, - SKILL: skillSet({ - rld: 1, - dam: 1, - pen: 1, - str: 1, - spd: 1, - atk: 1, - hlt: 1, - shi: 1, - rgn: 1, - mob: 1, - }), - BODY: { - FOV: 0.75, - SPEED: 0.05 * base.SPEED, - HEALTH: 15 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - }, - UPGRADE_TOOLTIP: "Good luck.", - GUNS: Array(4).fill().map((_, i) => ([{ - POSITION: [2.5, 3, 1.2, 8, 5, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 50, speed: 1.25, shudder: 1.25 }]), - TYPE: ["zephiEggchip", {COLOR: "black"}], - MAX_CHILDREN: 8, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - COLOR: "black", - } - },{ - POSITION: [2.5, 3, 1.2, 8, -5, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 150, speed: 1.25, shudder: 1.25 }]), - TYPE: ["zephiEggchip", {COLOR: "black"}], - MAX_CHILDREN: 8, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - COLOR: "black", - } - },{ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, g.destroyer, { speed: 2.5 }, { maxSpeed: 3 }]), - TYPE: ["zephiSunchip", {COLOR: "black"}], - MAX_CHILDREN: 4, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true - } - }])).flat(), - TURRETS: [{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearOuter" - },{ - POSITION: [5.375 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearCentre" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearRed" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearGreen" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 180, 360, 2], - TYPE: "zephiGearBlue" - },{ - POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], - TYPE: "overdriveDeco" - },{ - POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], - TYPE: "zephiMiscDeco2" - },{ - POSITION: [20 * Math.SQRT1_2 ** 3, 0, 0, 45, 0, 1], - TYPE: "zephiMiscDeco" - }] -}; - -Class.dogeiscutBody = { - PARENT: "genericTank", - COLOR: "grey", - SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]] -} -Class.dogeiscutTurret = { - PARENT: "genericTank", - COLOR: "grey", - GUNS: [ { - POSITION: [ 50, 5, 2.5, 0, 0, 0, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.minigun, {reload: 0.1}]), - TYPE: "bullet", - }, - }, { - POSITION: [ 18, 8, -2, 0, 0, 0, 0, ], - }, - ], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], - }, - ] -} -function createDogeiscutMissileTurret(color) { - return { - PARENT: "genericTank", - COLOR: "grey", - GUNS: [ { - POSITION: [ 15, 8, 2.5, 0, 0, 180, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ - g.basic, - g.skimmer, - { reload: 0.5 }, - g.lowPower, - { recoil: 1.35 }, - { speed: 1.3, maxSpeed: 1.3 }, - { speed: 1.3, maxSpeed: 1.3 }, - {reload: 0.15, recoil: 1, range: 0.1}]), - TYPE: ["bullet", - { - PERSISTS_AFTER_DEATH: true, - COLOR: color - }, - ], - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - }, - }, - ], - } -} -function createDogeiscutMissile(color) { - return { - PARENT: "bullet", - LABEL: color + " Missile", - COLOR: color, - GUNS: [...Array(11).fill().map((_, i)=>({ - POSITION: [0, 8, 0, 0, 0, ((360) / 11)*i, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, density: 30 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, COLOR: color }], - SHOOT_ON_DEATH: true, - }, - }))], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutMissileTurret_" + color], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - } - ] - } -} -Class.dogeiscutMissileTurret_red = createDogeiscutMissileTurret('red') -Class.dogeiscutMissile_red = createDogeiscutMissile('red') -Class.dogeiscutMissileTurret_orange = createDogeiscutMissileTurret('orange') -Class.dogeiscutMissile_orange = createDogeiscutMissile('orange') -Class.dogeiscutMissileTurret_yellow = createDogeiscutMissileTurret('yellow') -Class.dogeiscutMissile_yellow = createDogeiscutMissile('yellow') -Class.dogeiscutMissileTurret_green = createDogeiscutMissileTurret('green') -Class.dogeiscutMissile_green = createDogeiscutMissile('green') -Class.dogeiscutMissileTurret_cyan = createDogeiscutMissileTurret('cyan') -Class.dogeiscutMissile_cyan = createDogeiscutMissile('cyan') -Class.dogeiscutMissileTurret_blue = createDogeiscutMissileTurret('blue') -Class.dogeiscutMissile_blue = createDogeiscutMissile('blue') -Class.dogeiscutMissileTurret_purple = createDogeiscutMissileTurret('purple') -Class.dogeiscutMissile_purple = createDogeiscutMissile('purple') -Class.dogeiscutBomb = { - PARENT: "trap", - LABEL: "Bomb", - SHAPE: 0, - GUNS: [...Array(32).fill().map((_, i)=>({ - POSITION: [0, 8, 0, 0, 0, ((360) / 32)*i, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, size: 0.5}]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - SHOOT_ON_DEATH: true, - }, - })),...Array(10).fill().map((_,i)=>({ - POSITION: [12, 3.5, 1, 0, 0, (360/10)*i, (i%3)/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ - g.basic, - g.twin, - g.gunner, - g.cyclone, - {reload: 3} - ]), - TYPE: "bullet", - AUTOFIRE: true, - }, - })) - ], - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - } - ] - } -Class.dogeiscutBoss = { - PARENT: "miniboss", - LABEL: "DOG", - NAME: "DogeisCut", - DANGER: 10, - FACING_TYPE: "smoothToTarget", - SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]], - COLOR: "yellow", - UPGRADE_COLOR: "yellow", - SIZE: 50, - VALUE: 5e6, - BODY: { - FOV: 0.75, - SPEED: 0.25 * base.SPEED, - HEALTH: 14 * base.HEALTH, - DAMAGE: 4 * base.DAMAGE, - }, - GUNS: [ { - POSITION: [ 6, 8, 1.5, 3, 0, 180, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, {size: 1, reload: 3, recoil: 5}]), - TYPE: ["dogeiscutBomb"], - STAT_CALCULATOR: gunCalcNames.sustained, - } - }, { - POSITION: [ 4, 4, 1.5, 3, 0, 180, 0, ], - PROPERTIES: { - COLOR: "black" - } - }, - - { - POSITION: [ 1, 2, 1, 4, -8, 68, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_red"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'red' - } - }, { - POSITION: [ 1, 2, 1, 4, -5.333, 68, 1/7, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_orange"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'orange' - } - }, { - POSITION: [ 1, 2, 1, 4, -2.666, 68, (1/7)*2, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_yellow"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'yellow' - } - }, { - POSITION: [ 1, 2, 1, 4, 0, 68, (1/7)*3, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_green"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'green' - } - }, { - POSITION: [ 1, 2, 1, 4, 2.666, 68, (1/7)*4, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_cyan"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'cyan' - } - }, { - POSITION: [ 1, 2, 1, 4, 5.333, 68, (1/7)*5, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_blue"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'blue' - } - }, { - POSITION: [ 1, 2, 1, 4, 8, 68, (1/7)*6, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_purple"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'purple' - } - }, - - - { - POSITION: [ 1, 2, 1, 4, 8, -68, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_red"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'red' - } - }, { - POSITION: [ 1, 2, 1, 4, 5.333, -68, 1/7, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_orange"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'orange' - } - }, { - POSITION: [ 1, 2, 1, 4, 2.666, -68, (1/7)*2, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_yellow"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'yellow' - } - }, { - POSITION: [ 1, 2, 1, 4, 0, -68, (1/7)*3, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_green"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'green' - } - }, { - POSITION: [ 1, 2, 1, 4, -2.666, -68, (1/7)*4, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_cyan"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'cyan' - } - }, { - POSITION: [ 1, 2, 1, 4, -5.333, -68, (1/7)*5, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_blue"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'blue' - } - }, { - POSITION: [ 1, 2, 1, 4, -8, -68, (1/7)*6, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_purple"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'purple' - } - }, - ], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], - }, - { - POSITION: [5, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutTurret", { INDEPENDENT: true, CONTROLLERS: ["nearestDifferentMaster"], COLOR: "yellow" }], - }, - { - POSITION: [1, 10.5, 0, 0, 360, 0], - TYPE: ["genericTank", {COLOR: "black"}], - }, - ] -} -Class.trplnrBossAuraBulletAura = addAura(1, 0.8) -Class.trplnrBossAuraBullet = { - PARENT: 'genericTank', - LABEL: 'Nest', - SHAPE: -4, - PERSISTS_AFTER_DEATH: true, - BODY: { - HEALTH: 100, - }, - SIZE: 25, - COLOR: '#F49EFF', - GLOW: { - STRENGTH: 25, - COLOR: 'mirror', - ALPHA: 1 - }, - DRAW_HEALTH: true, - GUNS: (() => { - let output = [] - for (let i = 0; i < 4; i++) { - output.push({ - POSITION: { ANGLE: (360/4)*i, ASPECT: -0.35, X: -5 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { size: 0.8 }, {reload: 1.6, damage: 1.5}]), - TYPE: 'autoswarm', - AUTOFIRE: true, - }, - }) - } - return output - })(), - TURRETS: [ - { - POSITION: {SIZE: 10, LAYER: 1}, - TYPE: "trplnrBossAuraBulletAura" - } - ] -} -const trplnrBossDecor = { - COLOR: '#F49EFF', - UPGRADE_COLOR: "lavender", - LABEL: 'Lavender', - NAME: 'Trioplane', - SHAPE: 3, - SIZE: 25, - VALUE: 5e7, - DANGER: 10, - GLOW: { - RADIUS: 15, - COLOR: 'mirror', - ALPHA: 1, - RECURSION: 5 - }, - PROPS: [{ - POSITION: { SIZE: 25 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, - TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] - }, { - POSITION: { SIZE: 25 ** Math.SQRT1_2, LAYER: 1 }, - TYPE: ['triangle', { COLOR: -1, MIRROR_MASTER_ANGLE: true }] - }, { - POSITION: { SIZE: 25 }, - TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] - }], -} -Class.trplnrBoss = { - PARENT: "miniboss", - ...trplnrBossDecor, - UPGRADE_TOOLTIP: "\"Heck, even The Guardians are afraid of him, \n" + - "They usually call him the The Light, Victory, Death and Ruler of the Pentagon Race a.k.a Lvndr. \n" + - "We don't know where his teleportation powers came from, \n" + - "He was secretive of it. \n" + - "Though some say there was an old script found at the Neutrality Point \n" + - "at the middle of the nest when it still existed, It had some \n" + - "sort of drawing of a tank going through walls, and this thing that said '6@D M0|)3 \n" + - "Nest Reseachers still haven't been able to decipher it though. \n" + - "One day, The Neutrality Point left and on that same day, \n" + - "A sentry's child went missing, \n" + - "Coincidence? I think not.\"", - BODY: { - HEALTH: 500, - }, - ON: [ - { - event: 'fire', - handler: ({ body, gun }) => { - if (gun.identifier != 'onHandler') return - const messages = [ - 'Attack my little swarms!', - 'Deploying, Attack swarms', - 'You really think you can defeat me? Heres a little challenge for you.', - 'This thing is really gonna annoy you HAHA!', - 'I don\'t know what to say uhhh, die i guess.' - ] - sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) - sockets.broadcast('Lavender will turn into `BULL3T HELL F0rM`, Run!') - for (let i = 0; i < 24; i++) { - i < 12 ? - setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) - : - setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) - } - setTimeout(() => { - let range = 500 - let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - body.x += whereToGoX - body.y += whereToGoY - }, 12 * 50); - setTimeout(() => body.define('trplnrBossBulletHellForm'), 24 * 50) - } - } - ], - GUNS: [], - GUNS: (() => { - let output = [] - for (let i = 0; i<2; i++) { - output.push({ - POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), - TYPE: "trplnrBossAuraBullet", - INDEPENDENT_CHILDREN: true, - } - }) - } - output.push({ - POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * 2) - 180 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), - TYPE: "trplnrBossAuraBullet", - INDEPENDENT_CHILDREN: true, - IDENTIFIER: 'onHandler', - ALPHA: 0, - } - }) - for (let i = 0; i < 3; i++) { - output.push({ - POSITION: { WIDTH: 5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'black' - } - }) - output.push({ - POSITION: { WIDTH: 5, HEIGHT: 5, X: -30, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'black' - } - }, { - POSITION: { WIDTH: 5, HEIGHT: 5, X: -25, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'white' - } - }) - } - return output - })() -} - -Class.trplnrBossBulletHellFormPentagonsAuraBullet = { - PARENT: 'bullet', - PERSISTS_AFTER_DEATH: true, - TURRETS: [{ - POSITION: {SIZE: 13, LAYER: 1}, - TYPE: "trplnrBossAuraBulletAura" - }] -} - -Class.trplnrBossBulletHellFormPentagons = { - PARENT: 'bullet', - LABEL: 'Pentagon', - SHAPE: -5, - PROPS: [{ - POSITION: { SIZE: 40 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, - TYPE: ['pentagon', {COLOR: 'black', MIRROR_MASTER_ANGLE: true}] - }], - GUNS: (() => { - let output = [] - for (let i = 0; i < 5; i++) { - output.push({ - POSITION: { WIDTH: 10, HEIGHT: 10, ANGLE: ((360/5)*i) - 180, DELAY: 11.5 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 0.4}]), - TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', - AUTOFIRE: true, - COLOR: 'white', - } - }) - } - return output - })() -} -Class.trplnrBossBulletHellForm = { - PARENT: "miniboss", - ...trplnrBossDecor, - LABEL: 'Lavender - Bullet Hell Form', - BODY: { - HEALTH: 500, - }, - ON: [ - { - event: "fire", - handler: ({ body, masterStore, gun }) => { - if (gun.identifier != 'onHandler') return - masterStore.shotsFired ??= 0 - masterStore.shotsFired++ - - for (let i = 0; i < 24; i++) { - i < 12 ? - setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) - : - setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) - } - setTimeout(() => { - let range = 500 - let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - body.x += whereToGoX - body.y += whereToGoY - }, 12 * 50) - - if (masterStore.shotsFired > 5) { - body.define('trplnrBossVulnerableForm') - const messages = [ - 'I\'m a little tired right now', - 'Ouch my leg!', - 'i sleep', - 'Bruh my keyboard isn\'t working', - 'Omg bruh I chose the wrong form' - ] - sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) - sockets.broadcast('Lavender is in its `VULN3RABLE F0RM`, Attack!') - } - } - } - ], - GUNS: [], - GUNS: (() => { - let output = [] - for (let i = 0; i<3; i++) { - output.push({ - POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -25 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 1 }]), - TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', - COLOR: 'black' - } - }, { - POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -20 }, - PROPERTIES: { - COLOR: 'white' - } - }, { - POSITION: { WIDTH: 10, HEIGHT: 5, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 3 }]), - TYPE: 'trplnrBossBulletHellFormPentagons', - COLOR: 'white' - } - }, { - POSITION: { WIDTH: 8, HEIGHT: 3, X: -1, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'pureWhite', - } - }, { - POSITION: { WIDTH: 5, HEIGHT: 10, X: 5, ASPECT: 0.2, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: -1, - } - }) - } - output.push({ - POSITION: { WIDTH: 0, HEIGHT: 0 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 2 }, g.fake]), - TYPE: 'bullet', - IDENTIFIER: 'onHandler', - ALPHA: 0 - } - }) - return output - })() -} -Class.trplnrBossVulnerableForm = { - PARENT: "miniboss", - ...trplnrBossDecor, - LABEL: 'Lavender - Vulnerable Form', - BODY: { - HEALTH: 500, - SPEED: 0.1 - }, - ON: [ - { - event: "tick", - handler: ({ body }) => { - body.store.ticks ??= 0 - body.store.ticks++ - const spawnCrashers = body.store.ticks % 3 == 0 - const spawnSentries = body.store.ticks % 60 == 0 - const sentries = ["sentrySwarm", "sentryGun", "sentryTrap"] - if (spawnCrashers) new Entity(body, body).define("crasher") - if (spawnSentries) new Entity(body, body).define(sentries[Math.floor(Math.random() * sentries.length)]) - } - }, - { - event: "fire", - handler: ({ body, gun }) => { - if (gun.identifier != 'onHandler') return - setTimeout(() => { - body.define('trplnrBoss') - sockets.broadcast('im awake') - }, 15000) - setTimeout(() => sockets.broadcast('Lavender will activate in 10 seconds and turn into S4nctuary F0rM'), 5000) - } - } - ], - GUNS: [{ - POSITION: {LENGTH: 0, WIDTH: 0}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, {reload: 500}]), - TYPE: 'bullet', - AUTOFIRE: true, - IDENTIFIER: 'onHandler', - ALPHA: 0 - } - }] -} - -Class.frostAuraSmall = { - PARENT: "aura", - LAYER: 30, - FACING_TYPE: ["spin", {speed: -0.04}], - BORDERLESS: true, - SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraSmallOutline' - }] -} -Class.frostAuraSmallOutline = { - PARENT: "aura", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0" + - "L 0.309 0.951 L -0.809 0.588 L -0.809 -0.588 L 0.309 -0.951 L 1 0" + - "L 0 0 L 0.309 0.951 M 0 0 L -0.809 0.588 M 0 0 L -0.809 -0.588 M 0 0 L 0.309 -0.951", -} -Class.frostAuraLarge = { - PARENT: "aura", - LAYER: 30, - FACING_TYPE: ["spin", {speed: -0.04}], - BORDERLESS: true, - SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraLargeOutline' - }] -} -Class.frostAuraLargeOutline = { - PARENT: "aura", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0" + - "M 0.988 -0.156 L 0.988 0.156 L 0.891 0.454 L 0.707 0.707 L 0.454 0.891 L 0.156 0.988 L -0.156 0.988 L -0.454 0.891 L -0.707 0.707 L -0.891 0.454 L -0.988 0.156 L -0.988 -0.156 L -0.891 -0.454 L -0.707 -0.707 L -0.454 -0.891 L -0.156 -0.988 L 0.156 -0.988 L 0.454 -0.891 L 0.707 -0.707 L 0.891 -0.454 L 0.988 -0.156 L 0.949 0" + - "L 0.988 0.156 L 0.891 0.256 L 0.891 0.454 L 0.739 0.537 L 0.707 0.707 L 0.519 0.769 L 0.454 0.891 L 0.293 0.902 L 0.156 0.988 L 0.032 0.927 L -0.156 0.988 L -0.282 0.869 L -0.454 0.891 L -0.571 0.731 L -0.707 0.707 L -0.768 0.558 L -0.891 0.454 L -0.871 0.317 L -0.988 0.156 L -0.914 0 L -0.988 -0.156 L -0.871 -0.317 L -0.891 -0.454 L -0.768 -0.558 L -0.707 -0.707 L -0.571 -0.731 L -0.454 -0.891 L -0.282 -0.869 L -0.156 -0.988 L 0.032 -0.927 L 0.156 -0.988 L 0.293 -0.902 L 0.454 -0.891 L 0.519 -0.769 L 0.707 -0.707 L 0.739 -0.537 L 0.891 -0.454 L 0.891 -0.256 L 0.988 -0.156 L 0.949 0" + - "L 0.891 0.256 L 0.739 0.537 L 0.519 0.769 L 0.293 0.902 L 0.032 0.927 L -0.282 0.869 L -0.571 0.731 L -0.768 0.558 L -0.871 0.317 L -0.914 0 L -0.871 -0.317 L -0.768 -0.558 L -0.571 -0.731 L -0.282 -0.869 L 0.032 -0.927 L 0.293 -0.902 L 0.519 -0.769 L 0.739 -0.537 L 0.891 -0.256 L 0.949 0" + - "M 0.834 0 L 0.891 0.256 L 0.704 0.291 L 0.739 0.537 L 0.495 0.579 L 0.519 0.769 L 0.258 0.793 L 0.032 0.927 L -0.06 0.759 L -0.282 0.869 L -0.398 0.649 L -0.571 0.731 L -0.674 0.49 L -0.871 0.317 L -0.741 0.178 L -0.914 0 L -0.741 -0.178 L -0.871 -0.317 L -0.674 -0.49 L -0.571 -0.731 L -0.398 -0.649 L -0.282 -0.869 L -0.06 -0.759 L 0.032 -0.927 L 0.258 -0.793 L 0.519 -0.769 L 0.495 -0.579 L 0.739 -0.537 L 0.704 -0.291 L 0.891 -0.256 L 0.834 0" + - "L 0.704 0.291 L 0.495 0.579 L 0.258 0.793 L -0.06 0.759 L -0.398 0.649 L -0.674 0.49 L -0.741 0.178 L -0.741 -0.178 L -0.674 -0.49 L -0.398 -0.649 L -0.06 -0.759 L 0.258 -0.793 L 0.495 -0.579 L 0.704 -0.291 L 0.834 0" + - "M 0.592 0 L 0.704 0.291 L 0.413 0.3 L 0.495 0.579 L 0.183 0.563 L -0.06 0.759 L -0.158 0.485 L -0.398 0.649 L -0.479 0.348 L -0.741 0.178 L -0.51 0 L -0.741 -0.178 L -0.479 -0.348 L -0.398 -0.649 L -0.158 -0.485 L -0.06 -0.759 L 0.183 -0.563 L 0.495 -0.579 L 0.413 -0.3 L 0.704 -0.291 L 0.592 0" + - "L 0.413 0.3 L 0.183 0.563 L -0.158 0.485 L -0.479 0.348 L -0.51 0 L -0.479 -0.348 L -0.158 -0.485 L 0.183 -0.563 L 0.413 -0.3 L 0.592 0" + - "M 0.292 0 L 0.413 0.3 L 0.09 0.277 L -0.158 0.485 L -0.236 0.171 L -0.51 0 L -0.236 -0.171 L -0.158 -0.485 L 0.09 -0.277 L 0.413 -0.3 L 0.292 0 L 0.09 0.277" + - "L -0.236 0.171 L -0.236 -0.171 L 0.09 -0.277 L 0.292 0 M 0 0 L 0.949 0" + - "M 0 0 L 0.293 0.902 M 0 0 L -0.768 0.558 M 0 0 L -0.768 -0.558 M 0 0 L 0.293 -0.902", -} -Class.frostAuraSymbol = { - PARENT: "genericTank", - CONTROLLERS: [["spin", { speed: -0.04 }]], - INDEPENDENT: true, - BORDERLESS: true, - COLOR: 'teal', - SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraSymbolOutline' - }] -} -Class.frostAuraSymbolOutline = { - PARENT: "genericTank", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z" + - "M 0.52 0.3 L 0.52 -0.3 L 0.797 -0.46 M 0.52 -0.3 L 0 -0.6 L 0 -0.92 M 0 -0.6 L -0.52 -0.3 L -0.797 -0.46 M -0.52 -0.3 L -0.52 0.3 L -0.797 0.46 M -0.52 0.3 L 0 0.6 L 0 0.92 M 0 0.6 L 0.52 0.3 L 0.797 0.46" -} - -function addIcosphereAura(damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraSize = "Medium") { - let auraType = "frostAura" + auraSize; - return { - PARENT: "genericTank", - INDEPENDENT: true, - LABEL: "", - COLOR: 17, - GUNS: [ - { - POSITION: [0, 20, 1, 0, 0, 0, 0,], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.aura, { size: sizeFactor, damage: damageFactor }]), - TYPE: [auraType, {ALPHA: opacity}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, - }, - ], - TURRETS: [ - { - POSITION: [20, 0, 0, 0, 360, 1], - TYPE: "frostAuraSymbol" - }, - ] - }; -} -Class.frostAuraBlockTop = { - SHAPE: "M -1.3 -0.15 L -1.3 0.15 L -0.3 0.3 L -0.15 1.3 L 0.15 1.3 L 0.3 0.3 L 1.3 0.15 L 1.3 -0.15 L 0.3 -0.3 L 0.15 -1.3 L -0.15 -1.3 L -0.3 -0.3 Z", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 5 }, - MIRROR_MASTER_ANGLE: true, -} -Class.frostAuraBlockTurret = { - PARENT: "genericTank", - INDEPENDENT: true, - COLOR: 17, - CONTROLLERS: ["nearestDifferentMaster"], - LABEL: "", - BODY: { - FOV: 2, - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [18, 15, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} - }, - }, { - POSITION: [23, 11, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, {density: 0.2}]), - TYPE: "bullet", - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [15, 13, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ], -} -Class.frostAuraBlockAura = addIcosphereAura(0.25, 1.6, 0.15, "Small"); -Class.frostAuraBlock = { - PARENT: 'unsetTrap', - TURRETS: [ - { - POSITION: [20, 0, 0, 45, 0, 1], - TYPE: 'frostAuraBlockTop' - }, { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: 'frostAuraBlockTurret' - }, { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: 'frostAuraBlockAura' - } - ] -} -Class.frostBossBigAura = addIcosphereAura(1.5, 1.45, 0.3, "Large"); - -Class.frostBossAutoTurret = { - PARENT: "autoTankGun", - INDEPENDENT: true, - COLOR: 17, - GUNS: [ - { - POSITION: [17, 14, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} - }, - }, { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.2}]), - TYPE: "bullet", - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [14, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ], - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 0, 1], - TYPE: ["egg", {COLOR: -1, BORDERLESS: true}], - }, - ], -} - -Class.frostBossBaseDeco = { - SHAPE: "M -1.1 0 L -0.956 0.292 L -0.669 0.205 L -0.669 -0.205 L -0.956 -0.292 Z" + - "M -0.55 0.952 L -0.225 0.974 L -0.157 0.682 L -0.512 0.477 L -0.731 0.682 Z" + - "M -0.55 -0.952 L -0.225 -0.974 L -0.157 -0.682 L -0.512 -0.477 L -0.731 -0.682 Z" + - "M 0.55 0.952 L 0.225 0.974 L 0.157 0.682 L 0.512 0.477 L 0.731 0.682 Z" + - "M 0.55 -0.952 L 0.225 -0.974 L 0.157 -0.682 L 0.512 -0.477 L 0.731 -0.682 Z" + - "M 1.1 0 L 0.956 0.292 L 0.669 0.205 L 0.669 -0.205 L 0.956 -0.292 Z", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, - MIRROR_MASTER_ANGLE: true, - GUNS: Array(6).fill().flatMap((_, i) => ([ - { - POSITION: [1.75, 3, -0.75, 7.5, 0, 60 * i, 0], - PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 2.5, SATURATION_SHIFT: 0.9 }, DRAW_ABOVE: true }, - }, { - POSITION: [1, 9, 0, 8.5, 0, 60 * i + 30, 0], - PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 10, SATURATION_SHIFT: 1.15 } }, - }, - ])) -} - -const trebuchetStats = [g.basic, g.sniper, g.predator, g.predator, g.predator, g.predator, {speed: 0.93, maxSpeed: 0.93, reload: 1.7, health: 1.7, damage: 1.4, size: 2}]; -const hielamanStats = [g.trap, g.setTrap, g.hexaTrapper, {reload: 2.4, health: 3.2, range: 1.2}]; -Class.frostBoss = { - PARENT: 'miniboss', - LABEL: 'Extrasolar', - NAME: 'Frostbyte', - FACING_TYPE: 'toTarget', - SHAPE: 6, - COLOR: "aqua", - UPGRADE_COLOR: "aqua", - SIZE: 31, - DANGER: 12, - VALUE: 888888, - UPGRADE_TOOLTIP: "\"When the golden rays of sun shine through this world's\n" + - "darkened skies and looming clouds, the legend of the warrior\n" + - "and his eternal blade will finally come to fruition.\"", - BODY: { - SPEED: base.SPEED * 0.6, - HEALTH: base.HEALTH * 11, - SHIELD: base.SHIELD * 7, - REGEN: base.REGEN * 2.5, - FOV: base.FOV * 1.4, - RESIST: base.RESIST * 1.2, - DENSITY: base.DENSITY * 7.5, - }, - GUNS: [ - ...Array(6).fill().flatMap((_, i) => ({ - // Speed - POSITION: [8, 14.5, 0.001, 9.5, 0, 60*i, 0], - PROPERTIES: {COLOR: 9}, - })), - ...Array(3).fill().flatMap((_, i) => ([ - { // Heavy Snipers - POSITION: [26.5, 9.5, 1, 0, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats(trebuchetStats), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6 }, - }, - }, { - POSITION: [24, 6.65, -1.3, 0, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, - BORDERLESS: true - }, - }, { - POSITION: [19.5, 3.8, -1.4, 0, 0, 120 * i, 0], - PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 10 } }, - }, { - POSITION: [4, 11.5, 1, 19.5, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, - }, - }, { - POSITION: [2, 12, 1, 20.5, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, - }, - }, - { // Aura Blocks - POSITION: [15, 9, 1, 0, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6}} - }, { - POSITION: [4, 7.5, -1.6, 9, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5}} - }, { - POSITION: [15, 5.4, -0.1, 0, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.75}} - }, { - POSITION: [3, 9, 1.6, 15, 0, 120 * i + 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats(hielamanStats), - TYPE: 'frostAuraBlock', - STAT_CALCULATOR: gunCalcNames.trap, - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [2, 7, 1.6, 16, 0, 120 * i + 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...hielamanStats, g.fake]), - TYPE: 'bullet', - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ])), - ], - TURRETS: [ - ...Array(6).fill().flatMap((_, i) => ([ - { - POSITION: [2.95, 8.55, 0, 60 * i + 30, 180, 2], - TYPE: "frostBossAutoTurret", - }, - ])), - { - POSITION: [8.55, 0, 0, 0, 360, 2], - TYPE: "frostBossBigAura", - }, - ], - PROPS: [ - { - POSITION: [12, 0, 0, 180, 1], - TYPE: ["hexagon", {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 7.5}}], - }, { - POSITION: [20, 0, 0, 0, 1], - TYPE: ["frostBossBaseDeco"], - }, - ] -} - -const divide = 1000; -const arraySize = 10; -const colorArray = []; -const damageMultiplayer = 3.5; -const reloadMultiplayer = 2; -for (let i = 0; i < arraySize; i++) { - const rgb = Math.round(255 * i / (arraySize - 1)); - colorArray.push('#' + ((1 << 24) + (rgb << 16) + (rgb << 8) + rgb).toString(16).slice(1)); -} -class io_nearestDifferentMaster2 extends ioTypes.nearestDifferentMaster { - constructor(body, opts = {}) { - super(body); - this.lookAtDanger = opts.lookAtDanger ?? true; - this.firingAtMe = opts.firingAtMe ?? false; - this.timeout = opts.timeout || 90; - } - buildList(range) { - // Establish whom we judge in reference to - let mostDangerous = 0, - keepTarget = false; - // Filter through everybody... - let out = entities.filter(e => - // Only look at those within our view, and our parent's view, not dead, not invisible, not our kind, not a bullet/trap/block etc - this.validate(e, this.body, this.body.master.master, range * range, range * range * 4 / 3) - ).filter((e) => { - // Only look at those within range and arc (more expensive, so we only do it on the few) - if (this.body.firingArc == null || this.body.aiSettings.view360 || Math.abs(util.angleDifference(util.getDirection(this.body, e), this.body.firingArc[0])) < this.body.firingArc[1]) { - mostDangerous = Math.max(e.dangerValue, mostDangerous); - return true; - } - }).filter((e) => { - // Even more expensive - return !this.wouldHitWall(this.body, e); - }).filter((e) => { - // Only return the highest tier of danger - if (!this.lookAtDanger) return true; - if (this.body.aiSettings.farm || e.dangerValue === mostDangerous) { - if (this.targetLock && e.id === this.targetLock.id) keepTarget = true; - return true; - } - }); - // Reset target if it's not in there - if (!keepTarget) this.targetLock = undefined; - return out; - } - think(input) { - // Override target lock upon other commands - if (input.main || input.alt || this.body.master.autoOverride) { - this.targetLock = undefined; - return {}; - } - // Otherwise, consider how fast we can either move to ram it or shoot at a potiential target. - let tracking = this.body.topSpeed, - damageRef = (this.body.bond == null) ? this.body : this.body.bond, - range = this.body.fov; - // Use whether we have functional guns to decide - for (let i = 0; i < this.body.guns.length; i++) { - if (this.body.guns[i].canShoot && !this.body.aiSettings.SKYNET) { - let v = this.body.guns[i].getTracking(); - if (v.speed == 0 || v.range == 0) continue; - tracking = v.speed; - range = Math.min(range, (v.speed || 1.5) * (v.range < (this.body.size * 2) ? this.body.fov : v.range)); - break; - } - } - if (!Number.isFinite(tracking)) { - tracking = this.body.topSpeed + .01; - } - if (!Number.isFinite(range)) { - range = 640 * this.body.FOV; - } - // Check if my target's alive - if (this.targetLock && ( - !this.validate(this.targetLock, this.body, this.body.master.master, range * range, range * range * 4 / 3) || - this.wouldHitWall(this.body, this.targetLock) // Very expensive - )) { - this.targetLock = undefined; - this.tick = 100; - } - // Think damn hard - if (this.tick++ > 15 * c.runSpeed) { - this.tick = 0; - this.validTargets = this.buildList(range); - // Ditch our old target if it's invalid - if (this.targetLock && this.validTargets.indexOf(this.targetLock) === -1) { - this.targetLock = undefined; - } - // Lock new target if we still don't have one. - if (this.targetLock == null && this.validTargets.length) { - this.targetLock = (this.validTargets.length === 1) ? this.validTargets[0] : nearest(this.validTargets, { - x: this.body.x, - y: this.body.y - }); - this.tick = -this.timeout; - } - } - // Lock onto whoever's shooting me. - if (this.firingAtMe && damageRef.collisionArray.length && damageRef.health.display() < this.oldHealth) { - this.oldHealth = damageRef.health.display(); - if (this.validTargets.indexOf(damageRef.collisionArray[0]) === -1) { - let a = (damageRef.collisionArray[0].master.id === -1) - ? damageRef.collisionArray[0].source - : damageRef.collisionArray[0].master; - if ( - this.body.firingArc == null || - this.body.aiSettings.view360 || - Math.abs(util.angleDifference(util.getDirection(this.body, a), this.body.firingArc[0])) < this.body.firingArc[1] - ) { - this.targetLock = a; - this.tick = -(this.timeout * 5); - } - } - } - // Consider how fast it's moving and shoot at it - if (this.targetLock != null) { - let radial = this.targetLock.velocity; - let diff = { - x: this.targetLock.x - this.body.x, - y: this.targetLock.y - this.body.y, - } - /// Refresh lead time - if (this.tick % 4 === 0) { - this.lead = 0 - // Find lead time (or don't) - if (!this.body.aiSettings.chase) { - let toi = timeOfImpact(diff, radial, tracking) - this.lead = toi - } - } - if (!Number.isFinite(this.lead)) { - this.lead = 0; - } - if (!this.accountForMovement) this.lead = 0; - // And return our aim - return { - target: { - x: diff.x + this.lead * radial.x, - y: diff.y + this.lead * radial.y, - }, - fire: true, - main: true - }; - } - return {}; - } -} -ioTypes.nearestDifferentMaster2 = io_nearestDifferentMaster2; -Class.toothlessBase = { - PARENT: "genericTank", - LABEL: "NightFury", - UPGRADE_TOOLTIP: "A power league...", - GLOW: { - RADIUS: 2, - COLOR: 42, - ALPHA: 0.6, - RECURSION: 6, - }, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.5 * base.FOV, - HEALTH: 6 * base.HEALTH, - DAMAGE: 2 * base.DAMAGE, - }, - LEVEL_CAP: 45, - EXTRA_SKILL: 78, // 120 - 42 - SHAPE: 3, - VALUE: 30e+3, - SIZE: 24, - COLOR: "purple", - SKILL_CAP: Array(10).fill(smshskl + 3), - LEVEL_SKILL_POINT_FUNCTION: level => { - if (level < 2) return 0; - if (level <= 40) return 1; - if (level <= 45 && level & 1 == 1) return 1; - return 0; - }, -} -Class.toothlessBossTurret = { - PARENT: "genericTank", - LABEL: "", - BODY: { - FOV: 2, - }, - CONTROLLERS: [ - "onlyAcceptInArc", - [ "nearestDifferentMaster2", { lookAtDanger: false, firingAtMe: true, timeout: 10 } ], - ], - COLOR: "grey", - GUNS: [ - { - POSITION: [32, 8, 1, 0, 0, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, { - pen: 0.8, - health: 0.6, - damage: 0.6, - recoil: 0, - }]), - TYPE: "bullet", - }, - }, - ], - ON: [{ - event: "fire", - handler: ({ body }) => { - const master = body.master; - body._damage ??= []; - body._reload ??= []; - - if (!body._loaded) { - let _temp = 0; - master._maxPower ??= 0; - - body.guns.forEach((gun, i) => { - body._damage[i] = gun.settings.damage; - body._reload[i] = gun.settings.reload; - - _temp += (body._damage[i] * 3) / body._damage[i]; - _temp += body._reload[i] / (body._reload[i] / 3); - _temp /= 2; - }); - - _temp /= body.guns.length; - - master._maxPower += (_temp - 1) * divide * 2; - if (master._maxPower > _temp) master._maxPower /= 2; - - body._loaded = true; - } - - if (master._mode) { - master._power -= 1; - if (master._power < 1) { - master._mode = 0; - master.color.base = 14; - } - } - - if (!master._oldPower) return; - const power = master._oldPower / (divide * 2) + 1; - - body.guns.forEach((gun, i) => { - let _1 = body._damage[i] * (master._mode ? power : 1); - let _2 = body._reload[i] / (master._mode ? power : 1); - let max_damage = body._damage[i] * damageMultiplayer; - let min_reload = body._reload[i] / reloadMultiplayer; - - gun.settings.damage = _1 > max_damage ? max_damage : _1; - gun.settings.reload = _2 < min_reload ? min_reload : _2; - }); - }, - }], -}; -Class.toothlessBossDeco = { - PARENT: "genericTank", - LABEL: "", - SHAPE: 3, - SIZE: 10, - ON: [{ - event: "tick", - handler: ({ body }) => { - const master = body.master; - if (master._maxPower) - body.color.base = colorArray[ - Math.floor(master._power / (master._maxPower / arraySize)) > arraySize - 1 - ? arraySize - 1 - : Math.floor(master._power / (master._maxPower / arraySize) - ) - ]; - }, - }], -}; -Class.toothlessBoss = { - PARENT: "toothlessBase", - UPGRADE_COLOR: "magenta", - TURRETS: [{ - POSITION: { SIZE: 15, LAYER: 1 }, - TYPE: ["toothlessBossDeco", { MIRROR_MASTER_ANGLE: true }], - }, { - POSITION: { SIZE: 23 }, - TYPE: ["triangle", { COLOR: "black", MIRROR_MASTER_ANGLE: true }], - }], - GUNS: [{ - POSITION: { LENGTH: 0, WIDTH: 0 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ g.basic, { - range: 0.1, - speed: 0.1, - maxSpeed: 0.1, - recoil: 0, - }]), - TYPE: "bullet", - ALT_FIRE: true, - }, - }], - ON: [{ - event: "altFire", - handler: ({ body }) => { - if (!body._power || body._mode) return; - const power = Math.floor(body._power); - - if (power >= 1) { - body.sendMessage(`Your power level ${power}`); - body._oldPower = body._power; - body._mode = 1; - body.color.base = 5; - } - }, - }, { - event: "kill", - handler: ({ body, entity }) => { - body._power ??= 0; - body._mode ??= 0; - if (!body._mode) body._power += (entity.skill.score / divide) ** 0.8; - }, - }], -} -for (let b = 0; b < 3; b++) - Class.toothlessBoss.TURRETS.push({ - POSITION: [8, 6, -5.6, 120 * b + 180, 180, 0], - TYPE: "toothlessBossTurret", - }, { - POSITION: [8, 6, 5.6, 120 * b + 180, 180, 0], - TYPE: "toothlessBossTurret", - }); +const { combineStats, skillSet, makeAuto, addAura, LayeredBoss, makeDeco } = require('../facilitators.js'); +const { base, gunCalcNames, smshskl } = require('../constants.js'); +const g = require('../gunvals.js'); +require('./generics.js'); + +Class.miniboss = { + PARENT: "genericBoss", + CONTROLLERS: ["nearestDifferentMaster", "minion", "canRepel"], + AI: { NO_LEAD: true }, +}; +Class.ramMiniboss = { + PARENT: "genericBoss", + CONTROLLERS: ["nearestDifferentMaster", "canRepel", "mapTargetToGoal"], +}; + +// ELITE CRASHERS +Class.elite = { + PARENT: ["miniboss"], + LABEL: "Elite Crasher", + COLOR: "pink", + SHAPE: 3, + SIZE: 27, + VARIES_IN_SIZE: true, + VALUE: 15e4, + BODY: { + FOV: 1.25, + SPEED: 0.1 * base.SPEED, + HEALTH: 7 * base.HEALTH, + DAMAGE: 2.5 * base.DAMAGE, + }, +}; +Class.eliteDestroyer = { + PARENT: ["elite"], + UPGRADE_LABEL: "Elite Destroyer", + UPGRADE_COLOR: "pink", + GUNS: [ + { + POSITION: [5, 16, 1, 6, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, { + POSITION: [5, 16, 1, 6, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, { + POSITION: [5, 16, 1, 6, 0, -60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, + ], + TURRETS: [ + { + POSITION: [11, 0, 0, 180, 360, 0], + TYPE: ["crasherSpawner"], + }, { + POSITION: [11, 0, 0, 60, 360, 0], + TYPE: ["crasherSpawner"], + }, { + POSITION: [11, 0, 0, -60, 360, 0], + TYPE: ["crasherSpawner"], + }, { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: [ "bigauto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +Class.eliteGunner = { + PARENT: ["elite"], + UPGRADE_LABEL: "Elite Gunner", + UPGRADE_COLOR: "pink", + FACING_TYPE: "toTarget", + GUNS: [ + { + POSITION: [14, 16, 1, 0, 0, 180, 0], + }, { + POSITION: [4, 16, 1.5, 14, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: ["unsetPillbox", {MOTION_TYPE: "glide"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, { + POSITION: [6, 14, -2, 2, 0, 60, 0], + }, { + POSITION: [6, 14, -2, 2, 0, 300, 0], + }, + ], + AI: { NO_LEAD: false }, + TURRETS: [ + { + POSITION: [14, 8, 0, 60, 180, 0], + TYPE: ["auto4gun"], + }, { + POSITION: [14, 8, 0, 300, 180, 0], + TYPE: ["auto4gun"], + }, + ], +}; +Class.eliteSprayer = { + PARENT: ["elite"], + UPGRADE_LABEL: "Elite Sprayer", + UPGRADE_COLOR: "pink", + SKILL: [0, 9, 3, 9, 2, 9, 9, 9, 9, 0], + AI: { NO_LEAD: false }, + HAS_NO_RECOIL: true, + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [6, 0, 0, 0, 360, 1], + TYPE: ["machineTripleTurret", { INDEPENDENT: true }], + }, { + POSITION: [9, 6, -5, 180, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, 5, 180, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, 5, 60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, -5, 60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, 5, -60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, -5, -60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, + ], +}; +Class.eliteBattleship = { + PARENT: ["elite"], + UPGRADE_LABEL: "Elite Battleship", + UPGRADE_COLOR: "pink", + GUNS: [ + { + POSITION: [4, 6, 0.6, 7, -8, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 0, 60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 8, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, -8, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 0, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 8, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, -8, -60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 0, -60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 8, -60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], + TURRETS: [ + { + POSITION: [5, 7, 0, 0, 360, 1], + TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [5, 7, 0, 120, 360, 1], + TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [5, 7, 0, 240, 360, 1], + TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +Class.eliteSpawner = { + PARENT: ["elite"], + UPGRADE_LABEL: "Elite Spawner", + UPGRADE_COLOR: "pink", + MAX_CHILDREN: 9, + AI: { STRAFE: false }, + GUNS: [ + { + POSITION: [11, 16, 1, 0, 0, 60, 0], + }, { + POSITION: [11, 16, 1, 0, 0, 180, 0], + }, { + POSITION: [11, 16, 1, 0, 0, 300, 0], + }, { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [2, 18, 1, 11, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), + TYPE: ["sentrySwarm", {GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [2, 18, 1, 11, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), + TYPE: ["sentryTrap", {GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [2, 18, 1, 11, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), + TYPE: ["sentryGun", {GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, + ], + TURRETS: [ + { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: ["auto4gun", { INDEPENDENT: false, COLOR: -1 }], + }, + ], +}; +Class.eliteTrapGuard = { + PARENT: ["elite"], + UPGRADE_LABEL: "Elite Trap Guard", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false }, + GUNS: [], + TURRETS: [ + { + POSITION: [9.5, 0, 0, 0, 360, 1], + TYPE: "triTrapGuardTurret", + }, + ], +}; +for (let i = 0; i < 3; i++) { + Class.eliteTrapGuard.GUNS.push( + { + POSITION: [10.5, 6, 1, 0, 0, 120*i+60, 0], + }, { + POSITION: [3, 6, 1.7, 10.5, 0, 120*i+60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ) + Class.eliteTrapGuard.TURRETS.push( + { + POSITION: [5, 8, -7, 120*i+60, 160, 0], + TYPE: ["autoTurret", { INDEPENDENT: false }], + }, { + POSITION: [5, 8, 7, 120*i+60, 160, 0], + TYPE: ["autoTurret", { INDEPENDENT: false }], + }, + ) +}; +Class.eliteSpinner = { + PARENT: ["elite"], + UPGRADE_LABEL: "Elite Spinner", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false }, + FACING_TYPE: ["spin", {speed: 0.1}], + GUNS: [], + TURRETS: [ + { + POSITION: [9.5, 0, 0, 0, 360, 1], + TYPE: ["eliteSpinnerCyclone", {COLOR: -1}], + }, + ], +}; +for (let i = 0; i < 3; i++) { + Class.eliteSpinner.GUNS.push( + { + POSITION: [9.5, 2, 1, -1.5, 11.5, 120*i+10, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [9.5, 2, 1, 3.5, 6.5, 120*i+10, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [9.5, 2, 1, 8.5, 1.5, 120*i+10, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [2, 20, 0.75, 8, 0, 120*i+60, 0], + }, + ) +}; + +// OLD ELITE +Class.oldEliteSprayer = { + PARENT: ["elite"], + UPGRADE_LABEL: "Elite Sprayer (Old)", + UPGRADE_COLOR: "pink", + AI: { NO_LEAD: false }, + TURRETS: [ + { + POSITION: [14, 6, 0, 180, 190, 0], + TYPE: [ "sprayer", { COLOR: -1 } ], + }, { + POSITION: [14, 6, 0, 60, 190, 0], + TYPE: [ "sprayer", { COLOR: -1 } ], + }, { + POSITION: [14, 6, 0, -60, 190, 0], + TYPE: [ "sprayer", { COLOR: -1 } ], + }, + ], +}; + +// Legionary Crasher +Class.legionaryCrasherTop = { + PARENT: ["elite"], + AI: { STRAFE: false, NO_LEAD: false }, + CONTROLLERS: [ ["spin", { independent: true, speed: -0.005 }] ], + INDEPENDENT: true, + GUNS: [], + TURRETS: [], +} +for (let i = 0; i < 3; i++) { + Class.legionaryCrasherTop.GUNS.push( + { + POSITION: [4, 9.5, 0.7, 7, 5, 120*i+60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), + TYPE: [ "swarm", { INDEPENDENT: true } ], + STAT_CALCULATOR: gunCalcNames.swarm, + AUTOFIRE: true, + + }, + }, { + POSITION: [4, 9.5, 0.7, 7, -5, 120*i+60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), + TYPE: [ "swarm", { INDEPENDENT: true } ], + STAT_CALCULATOR: gunCalcNames.swarm, + AUTOFIRE: true, + }, + }, + ) + Class.legionaryCrasherTop.TURRETS.push( + { + POSITION: [9.5, 10, 0, 120*i, 190, 0], + TYPE: "auto4gun", + }, + ) +} +Class.legionaryCrasher = { + PARENT: ["elite"], + LABEL: "Legionary Crasher", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false, NO_LEAD: false }, + HAS_NO_RECOIL: true, + VALUE: 5e6, + SIZE: 75, + BODY: { + FOV: 1.5, + SPEED: 0.1 * base.SPEED, + HEALTH: 2000, + DAMAGE: 5 * base.DAMAGE, + }, + GUNS: [], + TURRETS: [ + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: "legionaryCrasherTop", + } + ], +} +for (let i = 0; i < 3; i++) { + Class.legionaryCrasher.GUNS.push( + { + POSITION: [14.5, 13, 1, 0, 0, 120*i, 0], + }, { + POSITION: [3, 13, 1.7, 14.5, 0, 120*i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, g.destroyer, { speed: 2.5, size: 0.6, maxSpeed: 3 }]), + TYPE: "legionaryPillbox", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ) +} +for (let i = 0; i < 3; i++) { + Class.legionaryCrasher.GUNS.push( + { + POSITION: [5, 12, 1.6, -11, 0, 120*i, 0], + } + ) + Class.legionaryCrasher.TURRETS.push( + { + POSITION: [14, 8, 0, 120*i+60, 180, 0], + TYPE: [ "sprayer", { COLOR: -1, } ], + }, + ) +} + +Class.sprayerLegion = { + PARENT: ["elite"], + UPGRADE_LABEL: "Sprayer Legion", + UPGRADE_COLOR: "pink", + AI: { NO_LEAD: false }, + TURRETS: [ + { + POSITION: [14, 6, 0, 180, 190, 0], + TYPE: ["machineGun", {COLOR: -1}], + }, { + POSITION: [14, 6, 0, 60, 190, 0], + TYPE: ["machineGun", {COLOR: -1}], + }, { + POSITION: [14, 6, 0, -60, 190, 0], + TYPE: ["machineGun", {COLOR: -1}], + }, + ], +}; + +// STRANGE BOSSES +Class.sorcerer = { + PARENT: ["miniboss"], + LABEL: "Sorcerer", + DANGER: 7, + SHAPE: 0, + COLOR: "veryLightGrey", + UPGRADE_COLOR: "veryLightGrey", + SIZE: 26, + MAX_CHILDREN: 50, + VALUE: 2e5, + BODY: { + FOV: 0.5, + SPEED: 0.12 * base.SPEED, + HEALTH: 6 * base.HEALTH, + DAMAGE: 2 * base.DAMAGE, + }, + GUNS: Array(2).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.machineGun, g.machineGunner, { size: 0.4, spray: 150, speed: 2, shudder: 1.75 }]), + TYPE: "minichip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.summoner = { + PARENT: ["miniboss"], + LABEL: "Summoner", + DANGER: 8, + SHAPE: 4, + COLOR: "gold", + UPGRADE_COLOR: "gold", + SIZE: 26, + MAX_CHILDREN: 28, + VALUE: 3e5, + BODY: { + FOV: 0.5, + SPEED: 0.1 * base.SPEED, + HEALTH: 7 * base.HEALTH, + DAMAGE: 2.6 * base.DAMAGE, + }, + GUNS: Array(4).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.8 }]), + TYPE: ["sunchip"], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.enchantress = { + PARENT: ["miniboss"], + LABEL: "Enchantress", + DANGER: 8, + SHAPE: 3.5, + COLOR: "orange", + UPGRADE_COLOR: "orange", + SIZE: 26, + MAX_CHILDREN: 28, + VALUE: 4e5, + BODY: { + FOV: 0.5, + SPEED: 0.09 * base.SPEED, + HEALTH: 10 * base.HEALTH, + DAMAGE: 3 * base.DAMAGE, + }, + GUNS: Array(3).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.9 }]), + TYPE: "dorito", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.exorcistor = { + PARENT: ["miniboss"], + LABEL: "Exorcistor", + DANGER: 8, + SHAPE: 5.5, + COLOR: "purple", + UPGRADE_COLOR: "purple", + SIZE: 26, + MAX_CHILDREN: 20, + VALUE: 5e5, + BODY: { + FOV: 0.5, + SPEED: 0.08 * base.SPEED, + HEALTH: 15 * base.HEALTH, + DAMAGE: 4 * base.DAMAGE, + }, + GUNS: Array(5).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 72, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), + TYPE: "demonchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.shaman = { + PARENT: "miniboss", + LABEL: "Shaman", + DANGER: 8, + SHAPE: 6, + COLOR: "hexagon", + UPGRADE_COLOR: "hexagon", + SIZE: 26, + MAX_CHILDREN: 20, + VALUE: 6e5, + BODY: { + FOV: 0.5, + SPEED: 0.07 * base.SPEED, + HEALTH: 20 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + }, + GUNS: Array(6).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { size: 1.1 }]), + TYPE: "realchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.eliteSkimmer = { + PARENT: ["elite"], + LABEL: "Elite Skimmer", + COLOR: "orange", + UPGRADE_COLOR: "orange", + TURRETS: [ + { + POSITION: [15, 5, 0, 60, 170, 0], + TYPE: "skimmerTurret", + }, { + POSITION: [15, 5, 0, 180, 170, 0], + TYPE: "skimmerTurret", + }, { + POSITION: [15, 5, 0, 300, 170, 0], + TYPE: "skimmerTurret", + }, + ], +}; + +// Nesters +Class.nestKeeper = { + PARENT: ["miniboss"], + LABEL: "Nest Keeper", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + MAX_CHILDREN: 15, + VALUE: 3e5, + GUNS: [ + { + POSITION: [3.5, 6.65, 1.2, 8, 0, 35, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [3.5, 6.65, 1.2, 8, 0, -35, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [3.5, 6.65, 1.2, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [3.5, 6.65, 1.2, 8, 0, 108, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [3.5, 6.65, 1.2, 8, 0, -108, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, + ], + TURRETS: [ + { + POSITION: [8, 9, 0, 72, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [8, 9, 0, 0, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [8, 9, 0, 144, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [8, 9, 0, 216, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [8, 9, 0, -72, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "boomerTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +Class.nestWarden = { + PARENT: ["miniboss"], + LABEL: "Nest Warden", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + VALUE: 3e5, + GUNS: [], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "barricadeTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +for(let i = 0; i < 5; i++) { + Class.nestWarden.GUNS.push( + { + POSITION: [10.7, 8, 1, 0, 0, 72*i+36, 0], + }, { + POSITION: [1.5, 8, 1.2, 10.7, 0, 72*i+36, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { speed: 1.2 }, g.setTrap, g.constructor]), + TYPE: "unsetTrap", + STAT_CALCULATOR: gunCalcNames.block + }, + }, + ); + Class.nestWarden.TURRETS.push( + { + POSITION: [8, 9, 0, 72*i, 120, 0], + TYPE: [ "cruiserTurret", { INDEPENDENT: true, COLOR: -1 } ], + } + ); +}; +Class.nestGuardian = { + PARENT: ["miniboss"], + LABEL: "Nest Guardian", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + VALUE: 3e5, + GUNS: [], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "twisterTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +for(let i = 0; i < 5; i++) { + Class.nestGuardian.GUNS.push( + { + POSITION: [5.5, 7, 1, 6, 0, 72*i+36, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, + ); + Class.nestGuardian.TURRETS.push( + { + POSITION: [8, 9, 0, 72*i, 120, 0], + TYPE: [ "swarmerTurret", { INDEPENDENT: true, COLOR: -1 } ], + } + ); +}; + +// Rogues +Class.roguePalisade = { + PARENT: ["miniboss"], + LABEL: "Rogue Palisade", + COLOR: "darkGrey", + UPGRADE_COLOR: "darkGrey", + SHAPE: 6, + SIZE: 30, + VALUE: 5e5, + CONTROLLERS: ['nearestDifferentMaster', 'onlyAcceptInArc'], + BODY: { + FOV: 1.4, + SPEED: 0.05 * base.SPEED, + HEALTH: 16 * base.HEALTH, + SHIELD: 3 * base.SHIELD, + DAMAGE: 3 * base.DAMAGE, + }, + GUNS: [ + { POSITION: [4, 6, -1.6, 8, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 60, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 120, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 180, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 240, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 300, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + ], + TURRETS: [ + { POSITION: [5, 10, 0, 30, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 90, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 150, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 210, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 270, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 330, 110, 0], TYPE: "baseTrapTurret" }, + ], +}; +Class.rogueArmada = (() => { + let SHAPE = 7, + GUNS = [], + TURRETS = []; + for (let i = 0; i < SHAPE; i++) { + for (let j = 0; j < 8; j++) { + GUNS.push({ + POSITION: [8, 2 + Math.floor(j / 3), 1, 0, j / 2 - 2, (i + 0.5) * (360 / SHAPE), 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: j % SHAPE < 2 ? "bullet" : "casing" + } + }); + } + GUNS.push({ + POSITION: [8.5, 6, 1, 4, 0, (i + 0.5) * (360 / SHAPE), 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), + TYPE: "casing" + } + }, { + POSITION: [7, 6, -1.6, 4, 0, (i + 0.5) * (360 / SHAPE), 0] + }); + } + for (let i = 0; i < SHAPE; i++) { + TURRETS.push({ + POSITION: [5, 10, 0, i * 360 / SHAPE, 160, 0], + TYPE: "shottrapTurret" + }); + } + return { + PARENT: ["miniboss"], + LABEL: 'Rogue Armada', + COLOR: "darkGrey", + UPGRADE_COLOR: "darkGrey", + SHAPE, + SIZE: 28, + VALUE: 500000, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.1, + HEALTH: base.HEALTH * 16, + SHIELD: base.SHIELD * 3, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 3, + }, + GUNS, TURRETS + }; +})(); + +// Bob. +Class.bob = { + PARENT: ["ramMiniboss"], + LABEL: "Bob", + SHAPE: 0, + COLOR: "aqua", + UPGRADE_COLOR: "aqua", + SIZE: 18, + BODY: { + FOV: 2, + SPEED: 2 * base.SPEED, + HEALTH: 5 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + REGEN: 8 * base.REGEN, + FOV: 0.5 * base.FOV, + DENSITY: 6 * base.DENSITY, + }, + CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody", + }, { + POSITION: [21.5, 0, 0, 30, 360, 0], + TYPE: "landmineBody", + }, { + POSITION: [23.75, 0, 0, 0, 360, 0], + TYPE: "spikeBody", + }, + ], +}; +Class.nemesis = { + PARENT: ["bob"], + LABEL: "Nemesis", + COLOR: "red", + UPGRADE_COLOR: "red", + BODY: { + REGEN: 1e5, + HEALTH: 1e6, + DENSITY: 30, + DAMAGE: 1e5, + FOV: 5, + }, +}; + +// DIEP BOSSES +Class.guardian = { + PARENT: ["elite"], + LABEL: "Guardian of the Pentagons", + UPGRADE_LABEL: "Guardian", + UPGRADE_COLOR: "pink", + FACING_TYPE: "toTarget", + GUNS: [ + { + POSITION: [4, 12, 1.4, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, { size: 0.5 }]), + TYPE: "swarm", + AUTOFIRE: true, + }, + }, + ], + AI: { NO_LEAD: false }, +}; +Class.defenderAutoTankGun = { + PARENT: ["autoTankGun"], + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret]), + TYPE: ["bullet", {COLOR: "yellow"}], + }, + }, + ], +}; +Class.defender = { + PARENT: ["elite"], + LABEL: "Defender", + COLOR: "orange", + UPGRADE_COLOR: "orange", + GUNS: [ + { + POSITION: [15, 7, 1, -3, 0, 60, 0], + }, { + POSITION: [3, 7, 1.7, 12, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: ["trap", {COLOR: "yellow"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, { + POSITION: [15, 7, 1, -3, 0, 180, 0], + }, { + POSITION: [3, 7, 1.7, 12, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: ["trap", {COLOR: "yellow"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, { + POSITION: [15, 7, 1, -3, 0, 300, 0], + }, { + POSITION: [3, 7, 1.7, 12, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: ["trap", {COLOR: "yellow"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], + TURRETS: [ + { + POSITION: [5, 7, 0, 0, 190, 1], + TYPE: "defenderAutoTankGun", + }, { + POSITION: [5, 7, 0, 120, 190, 1], + TYPE: "defenderAutoTankGun", + }, { + POSITION: [5, 7, 0, 240, 190, 1], + TYPE: "defenderAutoTankGun", + }, + ], + AI: { NO_LEAD: false }, +}; + +// CELESTIALS +Class.terrestrial = { + PARENT: ["miniboss"], + LABEL: "Terrestrial", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 5e5, + SHAPE: 7, + SIZE: 35, + BODY: { + FOV: 1, + HEALTH: 1000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 9, + }, +}; +Class.celestial = { + PARENT: ["miniboss"], + LABEL: "Celestial", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 1e6, + SHAPE: 9, + SIZE: 45, + BODY: { + FOV: 1, + HEALTH: 1000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 12, + }, +}; +Class.rogueCelestial = { + PARENT: ["celestial"], + LABEL: "Rogue Celestial", + COLOR: "darkGrey", +}; +Class.eternal = { + PARENT: ["miniboss"], + LABEL: "Eternal", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 4e6, + SHAPE: 11, + SIZE: 90, + BODY: { + FOV: 1, + HEALTH: 3000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 18, + }, +}; + +// Terrestrials +let ares = new LayeredBoss(null, "Ares", "terrestrial", 7, "purple", "terrestrialTrapTurret", 7, 5.5); +ares.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["demonchip", { INDEPENDENT: true, }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, false, null, 18); +ares.addLayer({turret: { + POSITION: [10, 8.5, 0, null, 160, 0], + TYPE: ["protoSwarmerTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let gersemi = new LayeredBoss(null, "Gersemi", "terrestrial", 7, "lightGreen", "terrestrialTrapTurret", 7, 5.5); +gersemi.addLayer({turret: { + POSITION: [9, 8, 0, null, 160, 0], + TYPE: ["swarmTurret", { INDEPENDENT: true }], +}}); +gersemi.addLayer({turret: { + POSITION: [9.5, 7.5, 0, null, 160, 0], + TYPE: ["basicTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let ezekiel = new LayeredBoss(null, "Ezekiel", "terrestrial", 7, "orange", "terrestrialTrapTurret", 7, 5.5); +ezekiel.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["dorito", { COLOR: "orange", INDEPENDENT: true, }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 18); +ezekiel.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["skimmerTurret", { COLOR: "grey", INDEPENDENT: true }], +}}, true, 6.5) + +let eris = new LayeredBoss(null, "Eris", "terrestrial", 7, "pink", "terrestrialTrapTurret", 7, 5.5); +eris.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), + TYPE: ["minion", { INDEPENDENT: true, COLOR: "pink", HAS_NO_RECOIL: true }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, false, null, 14); +eris.addLayer({turret: { + POSITION: [10, 8.5, 0, null, 160, 0], + TYPE: ["rocketeerTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let selene = new LayeredBoss(null, "Selene", "terrestrial", 7, "gold", "terrestrialTrapTurret", 7, 5.5); +selene.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["sunchip", { COLOR: "gold", INDEPENDENT: true }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 18); +selene.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["hyperTwisterTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +// PALADIN +let paladin = new LayeredBoss(null, "Paladin", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); +paladin.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: ["demonchip", {INDEPENDENT: true}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 16); +paladin.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: "swarmerTurret", +}}, true, 6); + +// FREYJA +let freyja = new LayeredBoss(null, "Freyja", "celestial", 9, "lightGreen", "baseTrapTurret", 6.5, 5.5); +freyja.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "cruiserTurret", +}}); +freyja.addLayer({turret: { + POSITION: [10.6, 7.5, 0, null, 160, 0], + TYPE: "auto4gun", +}}, true, 6); + +// ZAPHKIEL +let zaphkiel = new LayeredBoss(null, "Zaphkiel", "celestial", 9, "orange", "baseTrapTurret", 6.5, 5.5); +zaphkiel.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: ["drone", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 16); +zaphkiel.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["skimmerTurret", {COLOR: "grey", INDEPENDENT: true}], +}}, true, 6); + +// NYX +let nyx = new LayeredBoss(null, "Nyx", "celestial", 9, "pink", "baseTrapTurret", 6.5, 5.5); +nyx.addLayer({gun: { + POSITION: [3.8, 7, -1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), + TYPE: ["minion", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 16); +nyx.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: "rocketeerTurret", +}}, true, 6); + +// THEIA +let theia = new LayeredBoss(null, "Theia", "celestial", 9, "gold", "baseTrapTurret", 6.5, 5.5); +theia.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, { size: 0.5 }]), + TYPE: ["summonerDrone", {INDEPENDENT: true}], + AUTOFIRE: true, + WAIT_TO_CYCLE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 35); +theia.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["twisterTurret", {COLOR: "grey"}], +}}, true, 6); + +// ATLAS +let atlas = new LayeredBoss(null, "Atlas", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); +atlas.addLayer({turret: { + POSITION: [7, 9, 0, null, 180, 0], + TYPE: "artilleryTurret", +}}); +atlas.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "nailgunTurret", +}}, true, 6); + +// RHEA +let rhea = new LayeredBoss(null, "Rhea", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +rhea.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "wrenchTurret", +}}); +rhea.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "crowbarTurret", +}}, true, 6); + +// JULIUS +let julius = new LayeredBoss(null, "Julius", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +julius.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "juliusLowerTurret", +}}); +julius.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "launcherTurret", +}}, true, 6); + +// GENGHIS +let genghis = new LayeredBoss(null, "Genghis", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +genghis.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "genghisLowerTurret", +}}); +genghis.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "auto4gun", +}}, true, 6); + +// NAPOLEON +let napoleon = new LayeredBoss(null, "Napoleon", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +napoleon.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "napoleonLowerTurret", +}}); +napoleon.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "napoleonUpperTurret", +}}, true, 6) + +// Eternals +let kronos = new LayeredBoss(null, "Kronos", "eternal", 11, "veryLightGrey", "baseTrapTurret", 6, 5.5); +kronos.addLayer({turret: { + POSITION: [6.5, 9, 0, null, 160, 0], + TYPE: "kronosSkimmerTurret", +}}); +kronos.addLayer({turret: { + POSITION: [6.5, 9, 0, null, 160, 0], + TYPE: "carrierTurret", +}}, true, 4); +kronos.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 160, 0], + TYPE: "tripletTurret", +}}, true, 4); + +let odin = new LayeredBoss(null, "Odin", "eternal", 11, "aqua", "baseTrapTurret", 4.5, 3.5); +odin.addLayer({gun: { + POSITION: [2.25, 3.25, -1.6, 9, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }, g.pounder, {size: 1.7}]), + TYPE: ["gemDrone", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 18); +odin.addLayer({turret: { + POSITION: [7, 8, 0, null, 160, 0], + TYPE: "autosmashTurret", +}}, true, 5.5); +odin.addLayer({turret: { + POSITION: [8, 9, 0, null, 160, 0], + TYPE: "gunnerCruiserTurret", +}}, true, 4.5); + +// Developer Bosses +Class.taureonCoreBase = { + SHAPE: 4, + COLOR: '#00A2E8' +}; +Class.taureonCore = { + PARENT: "genericTank", + LABEL: "Core Turret", + SHAPE: 4.5, + COLOR: '#99D9EA', + CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], + INDEPENDENT: true, + GUNS: [{ + POSITION: [10, 14, -0.5, 14, 0, 0, 0] + },{ + POSITION: [21, 15, -1.1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.destroyer, g.sniper]), + TYPE: "snake", + STAT_CALCULATOR: gunCalcNames.sustained + } + }], + TURRETS: [{ + POSITION: [20 * Math.SQRT2, 0, 0, 0, 0, 0], + TYPE: "taureonCoreBase" + }] +}; +Class.taureonBase = { + SHAPE: 4.5, + COLOR: '#161B54', + MIRROR_MASTER_ANGLE: true +}; +let d = 1/4; +Class.taureonStar = { + SHAPE: [[0,1],[d,d],[1,0],[d,-d],[0,-1],[-d,-d],[-1,0],[-d,d]], + COLOR: '#3F48CC', + MIRROR_MASTER_ANGLE: true +}; +Class.taureonRailgunTurret = { + PARENT: "genericTank", + COLOR: "grey", + LABEL: "Railgun Turret", + CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], + INDEPENDENT: true, + GUNS: [{ + POSITION: [20, 7, 1, 0, 0, 0, 0] + },{ + POSITION: [24, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.destroyer, { speed: 5, penetration: 0.8 }]), + TYPE: "bullet" + } + },{ + POSITION: [5, 7.5, -1.6, 8, 0, 0, 0], + }] +}; +Class.taureonThruster = { + PARENT: "genericTank", + COLOR: "grey", + LABEL: "Thruster", + CONTROLLERS: ["onlyAcceptInArc"], + GUNS: [{ + POSITION: [14, 12, 1, 4, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), + TYPE: ["bullet", { ALPHA: 0.5 }] + } + }, { + POSITION: [12, 12, 1.4, 4, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), + TYPE: ["bullet", { ALPHA: 0.5 }] + }, + }] +}; +Class.taureonMissile = { + PARENT: "bullet", + LABEL: "Missile", + FACING_TYPE: "smoothToTarget", + CONTROLLERS: ["nearestDifferentMaster"], + INDEPENDENT: true, + BODY: { + ACCELERATION: 10, + FOV: base.FOV * 2 + }, + TURRETS: [{/** SIZE X Y ANGLE ARC */ + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + }], + GUNS: [{/* LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [6, 12, 1.4, 8, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] + } + },{ + POSITION: [10, 12, 0.8, 8, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] + } + },...Array(32).fill().map((_, i)=>({ + POSITION: [0, (i % 4) + 1, 0, 0, 0, 0, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, { spray: 1e6, range: 0.5, shudder: 1.5, damage: 1 + (i % 4) }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true + }, + }))] +}; +Class.taureonBoss = { + PARENT: "miniboss", + LABEL: "Diamond Marauder", + NAME: "Taureon", + COLOR: '#2B339B', + UPGRADE_COLOR: "spaceGem", + DANGER: 10, + SHAPE: 4.5, + SIZE: 50, + FACING_TYPE: "smoothToTarget", + UPGRADE_TOOLTIP: "With a powerful Gatling Gun on the front, Rocket Launchers as wings, movable Thrusters on the back, " + + "and equipped with Railgun Turrets, it perfectly excells at terminating those who feel its Wrath.\n" + + "An octahedral carbon robot, exclusively designed to eradicate opponents with sheer brutality alone.\n" + + '"NOW YOU FACE MY ULTIMATE CREATION."', + VALUE: 9e6, + BODY: { + FOV: 1, + SPEED: 0.5 * base.SPEED, + HEALTH: 20 * base.HEALTH, + DAMAGE: 3 * base.DAMAGE, + }, + TURRETS: [{ + POSITION: [23.3, 0, 0, 0, 0, 0], + TYPE: "taureonBase" + },{ + POSITION: [5, 10, 0, -45, 180, 0], + TYPE: "taureonRailgunTurret" + },{ + POSITION: [5, 10, 0, 45, 180, 0], + TYPE: "taureonRailgunTurret" + },{ + POSITION: [5, -10, -2, -45, 90, 0], + TYPE: "taureonThruster" + },{ + POSITION: [5, -10, 2, 45, 90, 0], + TYPE: "taureonThruster" + },{ + POSITION: [25, 0, 0, 0, 0, 1], + TYPE: "taureonStar" + },{ + POSITION: [5, 0, 0, 0, 360, 1], + TYPE: "taureonCore" + }], + GUNS: [...Array(6).fill().map((_, i) => ({ + POSITION: [18, 1.75, 1, 0, Math.cos(Math.PI * i / 3) * 2, 0, i / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, { speed: 2, maxSpeed: 2, damage: 0.75, size: 0.8 }]), + TYPE: "bullet" + } + })),{ + POSITION: [4, 5, -0.5, 12, 0, -90, 0] + },{ + POSITION: [10, 5, -1.2, 5, 0, -90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), + TYPE: "taureonMissile", + STAT_CALCULATOR: gunCalcNames.sustained + } + },{ + POSITION: [4, 5, -0.5, 12, 0, 90, 0] + },{ + POSITION: [10, 5, -1.2, 5, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), + TYPE: "taureonMissile", + STAT_CALCULATOR: gunCalcNames.sustained + } + },{ + POSITION: [5.5, 5, -1.5, 5, 0, -45, 0] + },{ + POSITION: [5.5, 5, -1.5, 5, 0, 45, 0] + },{ + POSITION: [2, 7, 1, 8, 0, 0, 0] + },{ + POSITION: [2, 7, 1, 14.5, 0, 0, 0] + }] +}; + +Class.zephiMiscDeco = makeDeco(4, "white") +Class.zephiMiscDeco2 = makeDeco(4, "black") +Class.zephiSunchip = makeAuto({ + PARENT: "drone", + SHAPE: 4, + HITS_OWN_TYPE: "hard", + BODY: { + FOV: 0.5, + }, + AI: { + BLIND: true, + FARMER: true, + }, + TURRETS: [{ + POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], + TYPE: ["overdriveDeco", { MIRROR_MASTER_ANGLE: true }] + },{ + POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], + TYPE: ["shinySquare", { MIRROR_MASTER_ANGLE: true }] + }] +}, "Robo-Sunchip", {type: 'autoSmasherTurret', size: 6}) +Class.zephiEggchip = { + PARENT: "drone", + LABEL: "Guided Missile", + SHAPE: 0, + HITS_OWN_TYPE: "hard", + BODY: { + FOV: 0.5, + }, + AI: { + BLIND: true, + FARMER: true, + }, + GUNS: [ + { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, g.lowPower, { reload: 0.5, recoil: 1.35, speed: 1.3, maxSpeed: 1.3 }]), + TYPE: ["bullet", { COLOR: "black", PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], + TURRETS: [{ + POSITION: [10, 0, 0, 45, 0, 1], + TYPE: "gem" + }] +} +Class.zephiGearOuter = makeDeco('M 0.5 0.0929 V -0.0908 L 0.3875 -0.1096 C 0.3792 -0.1409 0.3667 -0.1701 0.3521 -0.1952 L 0.4187 -0.2871 L 0.2896 -0.4186 L 0.1958 -0.3539 C 0.1687 -0.3685 0.1396 -0.381 0.1104 -0.3894 L 0.0917 -0.5 H -0.0917 L -0.1104 -0.3873 C -0.1417 -0.3789 -0.1688 -0.3664 -0.1958 -0.3518 L -0.2875 -0.4165 L -0.4188 -0.2871 L -0.3521 -0.1952 C -0.3667 -0.1681 -0.3792 -0.1388 -0.3875 -0.1075 L -0.5 -0.0908 V 0.0929 L -0.3875 0.1117 C -0.3792 0.143 -0.3667 0.1701 -0.3521 0.1973 L -0.4188 0.2912 L -0.2896 0.4207 L -0.1958 0.3539 C -0.1688 0.3685 -0.1396 0.381 -0.1083 0.3894 L -0.0896 0.5 H 0.0938 L 0.1125 0.3873 C 0.1417 0.3789 0.1708 0.3664 0.1979 0.3518 L 0.2917 0.4186 L 0.4208 0.2891 L 0.3542 0.1952 C 0.3688 0.1681 0.3812 0.1409 0.3896 0.1096 L 0.5 0.0929 Z M 0.3333 0 C 0.3333 0.1841 0.1841 0.3333 0 0.3333 C -0.1841 0.3333 -0.3333 0.1841 -0.3333 0 C -0.3333 -0.1841 -0.1841 -0.3333 0 -0.3333 C 0.1841 -0.3333 0.3333 -0.1841 0.3333 0 Z', '#7F7F7F') +Class.zephiGearOuter.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearOuter.BORDERLESS = true +Class.zephiGearCentre = makeDeco(0, '#1F1F1F') +Class.zephiGearCentre.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearCentre.BORDERLESS = true +Class.zephiGearRed = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#FF1F1F') +Class.zephiGearRed.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearRed.BORDERLESS = true +Class.zephiGearGreen = makeDeco('M 0.0771 -0.2552 C 0.0743 -0.2561 0.0691 -0.2576 0.0657 -0.2585 L 0.0607 -0.2597 C 0.0571 -0.2605 0.0514 -0.2617 0.0479 -0.2623 L 0.0428 -0.2632 C 0.0392 -0.2638 0.0334 -0.2646 0.0299 -0.265 L 0.0247 -0.2655 C 0.0211 -0.2659 0.0153 -0.2662 0.0117 -0.2664 L 0.0066 -0.2666 C 0.003 -0.2667 -0.0029 -0.2667 -0.0065 -0.2666 L -0.0116 -0.2664 C -0.0153 -0.2662 -0.0211 -0.2659 -0.0247 -0.2655 L -0.0298 -0.265 C -0.0334 -0.2646 -0.0392 -0.2638 -0.0427 -0.2632 L -0.0478 -0.2623 C -0.0514 -0.2617 -0.0571 -0.2605 -0.0606 -0.2597 L -0.0656 -0.2585 C -0.0691 -0.2576 -0.0747 -0.256 -0.0782 -0.2549 C -0.081 -0.254 -0.0833 -0.2502 -0.0833 -0.2466 V 0.2466 C -0.0833 0.2502 -0.0805 0.2541 -0.0771 0.2552 C -0.0743 0.2561 -0.0691 0.2576 -0.0656 0.2585 L -0.0606 0.2597 C -0.0571 0.2605 -0.0514 0.2617 -0.0478 0.2623 L -0.0427 0.2632 C -0.0392 0.2638 -0.0334 0.2646 -0.0298 0.265 L -0.0247 0.2655 C -0.0211 0.2659 -0.0153 0.2663 -0.0116 0.2664 L -0.0065 0.2666 C -0.0029 0.2667 0.003 0.2667 0.0066 0.2666 L 0.0117 0.2664 C 0.0153 0.2663 0.0211 0.2659 0.0247 0.2655 L 0.0299 0.265 C 0.0334 0.2646 0.0392 0.2638 0.0428 0.2632 L 0.0479 0.2623 C 0.0514 0.2617 0.0571 0.2605 0.0607 0.2597 L 0.0657 0.2585 C 0.0691 0.2576 0.0748 0.256 0.0782 0.2549 C 0.0811 0.254 0.0834 0.2502 0.0834 0.2466 V -0.2466 C 0.0834 -0.2502 0.0806 -0.2541 0.0771 -0.2552 Z', '#1FDF1F') +Class.zephiGearGreen.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearGreen.BORDERLESS = true +Class.zephiGearBlue = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#1F7FDF') +Class.zephiGearBlue.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearBlue.BORDERLESS = true +Class.zephiBoss = { + PARENT: "miniboss", + LABEL: "Shiny Mecha-Thaumaturge", + NAME: "Zephi", + DANGER: 10, + SHAPE: 4, + COLOR: "lightGreen", + UPGRADE_COLOR: "lightGreen", + SIZE: 50, + VALUE: 5e6, + SKILL: skillSet({ + rld: 1, + dam: 1, + pen: 1, + str: 1, + spd: 1, + atk: 1, + hlt: 1, + shi: 1, + rgn: 1, + mob: 1, + }), + BODY: { + FOV: 0.75, + SPEED: 0.05 * base.SPEED, + HEALTH: 15 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + }, + UPGRADE_TOOLTIP: "Good luck.", + GUNS: Array(4).fill().map((_, i) => ([{ + POSITION: [2.5, 3, 1.2, 8, 5, i * 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 50, speed: 1.25, shudder: 1.25 }]), + TYPE: ["zephiEggchip", {COLOR: "black"}], + MAX_CHILDREN: 8, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + COLOR: "black", + } + },{ + POSITION: [2.5, 3, 1.2, 8, -5, i * 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 150, speed: 1.25, shudder: 1.25 }]), + TYPE: ["zephiEggchip", {COLOR: "black"}], + MAX_CHILDREN: 8, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + COLOR: "black", + } + },{ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, g.destroyer, { speed: 2.5 }, { maxSpeed: 3 }]), + TYPE: ["zephiSunchip", {COLOR: "black"}], + MAX_CHILDREN: 4, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true + } + }])).flat(), + TURRETS: [{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearOuter" + },{ + POSITION: [5.375 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearCentre" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearRed" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearGreen" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 180, 360, 2], + TYPE: "zephiGearBlue" + },{ + POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], + TYPE: "overdriveDeco" + },{ + POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], + TYPE: "zephiMiscDeco2" + },{ + POSITION: [20 * Math.SQRT1_2 ** 3, 0, 0, 45, 0, 1], + TYPE: "zephiMiscDeco" + }] +}; + +Class.dogeiscutBody = { + PARENT: "genericTank", + COLOR: "grey", + SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]] +} +Class.dogeiscutTurret = { + PARENT: "genericTank", + COLOR: "grey", + GUNS: [ { + POSITION: [ 50, 5, 2.5, 0, 0, 0, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.minigun, {reload: 0.1}]), + TYPE: "bullet", + }, + }, { + POSITION: [ 18, 8, -2, 0, 0, 0, 0, ], + }, + ], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], + }, + ] +} +function createDogeiscutMissileTurret(color) { + return { + PARENT: "genericTank", + COLOR: "grey", + GUNS: [ { + POSITION: [ 15, 8, 2.5, 0, 0, 180, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ + g.basic, + g.skimmer, + { reload: 0.5 }, + g.lowPower, + { recoil: 1.35 }, + { speed: 1.3, maxSpeed: 1.3 }, + { speed: 1.3, maxSpeed: 1.3 }, + {reload: 0.15, recoil: 1, range: 0.1}]), + TYPE: ["bullet", + { + PERSISTS_AFTER_DEATH: true, + COLOR: color + }, + ], + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], + } +} +function createDogeiscutMissile(color) { + return { + PARENT: "bullet", + LABEL: color + " Missile", + COLOR: color, + GUNS: [...Array(11).fill().map((_, i)=>({ + POSITION: [0, 8, 0, 0, 0, ((360) / 11)*i, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, density: 30 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, COLOR: color }], + SHOOT_ON_DEATH: true, + }, + }))], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutMissileTurret_" + color], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + } + ] + } +} +Class.dogeiscutMissileTurret_red = createDogeiscutMissileTurret('red') +Class.dogeiscutMissile_red = createDogeiscutMissile('red') +Class.dogeiscutMissileTurret_orange = createDogeiscutMissileTurret('orange') +Class.dogeiscutMissile_orange = createDogeiscutMissile('orange') +Class.dogeiscutMissileTurret_yellow = createDogeiscutMissileTurret('yellow') +Class.dogeiscutMissile_yellow = createDogeiscutMissile('yellow') +Class.dogeiscutMissileTurret_green = createDogeiscutMissileTurret('green') +Class.dogeiscutMissile_green = createDogeiscutMissile('green') +Class.dogeiscutMissileTurret_cyan = createDogeiscutMissileTurret('cyan') +Class.dogeiscutMissile_cyan = createDogeiscutMissile('cyan') +Class.dogeiscutMissileTurret_blue = createDogeiscutMissileTurret('blue') +Class.dogeiscutMissile_blue = createDogeiscutMissile('blue') +Class.dogeiscutMissileTurret_purple = createDogeiscutMissileTurret('purple') +Class.dogeiscutMissile_purple = createDogeiscutMissile('purple') +Class.dogeiscutBomb = { + PARENT: "trap", + LABEL: "Bomb", + SHAPE: 0, + GUNS: [...Array(32).fill().map((_, i)=>({ + POSITION: [0, 8, 0, 0, 0, ((360) / 32)*i, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, size: 0.5}]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + }, + })),...Array(10).fill().map((_,i)=>({ + POSITION: [12, 3.5, 1, 0, 0, (360/10)*i, (i%3)/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ + g.basic, + g.twin, + g.gunner, + g.cyclone, + {reload: 3} + ]), + TYPE: "bullet", + AUTOFIRE: true, + }, + })) + ], + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + } + ] + } +Class.dogeiscutBoss = { + PARENT: "miniboss", + LABEL: "DOG", + NAME: "DogeisCut", + DANGER: 10, + FACING_TYPE: "smoothToTarget", + SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]], + COLOR: "yellow", + UPGRADE_COLOR: "yellow", + SIZE: 50, + VALUE: 5e6, + BODY: { + FOV: 0.75, + SPEED: 0.25 * base.SPEED, + HEALTH: 14 * base.HEALTH, + DAMAGE: 4 * base.DAMAGE, + }, + GUNS: [ { + POSITION: [ 6, 8, 1.5, 3, 0, 180, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, {size: 1, reload: 3, recoil: 5}]), + TYPE: ["dogeiscutBomb"], + STAT_CALCULATOR: gunCalcNames.sustained, + } + }, { + POSITION: [ 4, 4, 1.5, 3, 0, 180, 0, ], + PROPERTIES: { + COLOR: "black" + } + }, + + { + POSITION: [ 1, 2, 1, 4, -8, 68, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_red"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'red' + } + }, { + POSITION: [ 1, 2, 1, 4, -5.333, 68, 1/7, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_orange"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'orange' + } + }, { + POSITION: [ 1, 2, 1, 4, -2.666, 68, (1/7)*2, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_yellow"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'yellow' + } + }, { + POSITION: [ 1, 2, 1, 4, 0, 68, (1/7)*3, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_green"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'green' + } + }, { + POSITION: [ 1, 2, 1, 4, 2.666, 68, (1/7)*4, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_cyan"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'cyan' + } + }, { + POSITION: [ 1, 2, 1, 4, 5.333, 68, (1/7)*5, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_blue"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'blue' + } + }, { + POSITION: [ 1, 2, 1, 4, 8, 68, (1/7)*6, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_purple"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'purple' + } + }, + + + { + POSITION: [ 1, 2, 1, 4, 8, -68, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_red"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'red' + } + }, { + POSITION: [ 1, 2, 1, 4, 5.333, -68, 1/7, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_orange"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'orange' + } + }, { + POSITION: [ 1, 2, 1, 4, 2.666, -68, (1/7)*2, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_yellow"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'yellow' + } + }, { + POSITION: [ 1, 2, 1, 4, 0, -68, (1/7)*3, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_green"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'green' + } + }, { + POSITION: [ 1, 2, 1, 4, -2.666, -68, (1/7)*4, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_cyan"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'cyan' + } + }, { + POSITION: [ 1, 2, 1, 4, -5.333, -68, (1/7)*5, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_blue"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'blue' + } + }, { + POSITION: [ 1, 2, 1, 4, -8, -68, (1/7)*6, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_purple"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'purple' + } + }, + ], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], + }, + { + POSITION: [5, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutTurret", { INDEPENDENT: true, CONTROLLERS: ["nearestDifferentMaster"], COLOR: "yellow" }], + }, + { + POSITION: [1, 10.5, 0, 0, 360, 0], + TYPE: ["genericTank", {COLOR: "black"}], + }, + ] +} +Class.trplnrBossAuraBulletAura = addAura(1, 0.8) +Class.trplnrBossAuraBullet = { + PARENT: 'genericTank', + LABEL: 'Nest', + SHAPE: -4, + PERSISTS_AFTER_DEATH: true, + BODY: { + HEALTH: 100, + }, + SIZE: 25, + COLOR: '#F49EFF', + GLOW: { + STRENGTH: 25, + COLOR: 'mirror', + ALPHA: 1 + }, + DRAW_HEALTH: true, + GUNS: (() => { + let output = [] + for (let i = 0; i < 4; i++) { + output.push({ + POSITION: { ANGLE: (360/4)*i, ASPECT: -0.35, X: -5 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { size: 0.8 }, {reload: 1.6, damage: 1.5}]), + TYPE: 'autoswarm', + AUTOFIRE: true, + }, + }) + } + return output + })(), + TURRETS: [ + { + POSITION: {SIZE: 10, LAYER: 1}, + TYPE: "trplnrBossAuraBulletAura" + } + ] +} +const trplnrBossDecor = { + COLOR: '#F49EFF', + UPGRADE_COLOR: "lavender", + LABEL: 'Lavender', + NAME: 'Trioplane', + SHAPE: 3, + SIZE: 25, + VALUE: 5e7, + DANGER: 10, + GLOW: { + RADIUS: 15, + COLOR: 'mirror', + ALPHA: 1, + RECURSION: 5 + }, + PROPS: [{ + POSITION: { SIZE: 25 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, + TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] + }, { + POSITION: { SIZE: 25 ** Math.SQRT1_2, LAYER: 1 }, + TYPE: ['triangle', { COLOR: -1, MIRROR_MASTER_ANGLE: true }] + }, { + POSITION: { SIZE: 25 }, + TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] + }], +} +Class.trplnrBoss = { + PARENT: "miniboss", + ...trplnrBossDecor, + UPGRADE_TOOLTIP: "\"Heck, even The Guardians are afraid of him, \n" + + "They usually call him the The Light, Victory, Death and Ruler of the Pentagon Race a.k.a Lvndr. \n" + + "We don't know where his teleportation powers came from, \n" + + "He was secretive of it. \n" + + "Though some say there was an old script found at the Neutrality Point \n" + + "at the middle of the nest when it still existed, It had some \n" + + "sort of drawing of a tank going through walls, and this thing that said '6@D M0|)3 \n" + + "Nest Reseachers still haven't been able to decipher it though. \n" + + "One day, The Neutrality Point left and on that same day, \n" + + "A sentry's child went missing, \n" + + "Coincidence? I think not.\"", + BODY: { + HEALTH: 500, + }, + ON: [ + { + event: 'fire', + handler: ({ body, gun }) => { + if (gun.identifier != 'onHandler') return + const messages = [ + 'Attack my little swarms!', + 'Deploying, Attack swarms', + 'You really think you can defeat me? Heres a little challenge for you.', + 'This thing is really gonna annoy you HAHA!', + 'I don\'t know what to say uhhh, die i guess.' + ] + sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) + sockets.broadcast('Lavender will turn into `BULL3T HELL F0rM`, Run!') + for (let i = 0; i < 24; i++) { + i < 12 ? + setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) + : + setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) + } + setTimeout(() => { + let range = 500 + let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + body.x += whereToGoX + body.y += whereToGoY + }, 12 * 50); + setTimeout(() => body.define('trplnrBossBulletHellForm'), 24 * 50) + } + } + ], + GUNS: [], + GUNS: (() => { + let output = [] + for (let i = 0; i<2; i++) { + output.push({ + POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), + TYPE: "trplnrBossAuraBullet", + INDEPENDENT_CHILDREN: true, + } + }) + } + output.push({ + POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * 2) - 180 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), + TYPE: "trplnrBossAuraBullet", + INDEPENDENT_CHILDREN: true, + IDENTIFIER: 'onHandler', + ALPHA: 0, + } + }) + for (let i = 0; i < 3; i++) { + output.push({ + POSITION: { WIDTH: 5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'black' + } + }) + output.push({ + POSITION: { WIDTH: 5, HEIGHT: 5, X: -30, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'black' + } + }, { + POSITION: { WIDTH: 5, HEIGHT: 5, X: -25, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'white' + } + }) + } + return output + })() +} + +Class.trplnrBossBulletHellFormPentagonsAuraBullet = { + PARENT: 'bullet', + PERSISTS_AFTER_DEATH: true, + TURRETS: [{ + POSITION: {SIZE: 13, LAYER: 1}, + TYPE: "trplnrBossAuraBulletAura" + }] +} + +Class.trplnrBossBulletHellFormPentagons = { + PARENT: 'bullet', + LABEL: 'Pentagon', + SHAPE: -5, + PROPS: [{ + POSITION: { SIZE: 40 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, + TYPE: ['pentagon', {COLOR: 'black', MIRROR_MASTER_ANGLE: true}] + }], + GUNS: (() => { + let output = [] + for (let i = 0; i < 5; i++) { + output.push({ + POSITION: { WIDTH: 10, HEIGHT: 10, ANGLE: ((360/5)*i) - 180, DELAY: 11.5 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 0.4}]), + TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', + AUTOFIRE: true, + COLOR: 'white', + } + }) + } + return output + })() +} +Class.trplnrBossBulletHellForm = { + PARENT: "miniboss", + ...trplnrBossDecor, + LABEL: 'Lavender - Bullet Hell Form', + BODY: { + HEALTH: 500, + }, + ON: [ + { + event: "fire", + handler: ({ body, masterStore, gun }) => { + if (gun.identifier != 'onHandler') return + masterStore.shotsFired ??= 0 + masterStore.shotsFired++ + + for (let i = 0; i < 24; i++) { + i < 12 ? + setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) + : + setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) + } + setTimeout(() => { + let range = 500 + let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + body.x += whereToGoX + body.y += whereToGoY + }, 12 * 50) + + if (masterStore.shotsFired > 5) { + body.define('trplnrBossVulnerableForm') + const messages = [ + 'I\'m a little tired right now', + 'Ouch my leg!', + 'i sleep', + 'Bruh my keyboard isn\'t working', + 'Omg bruh I chose the wrong form' + ] + sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) + sockets.broadcast('Lavender is in its `VULN3RABLE F0RM`, Attack!') + } + } + } + ], + GUNS: [], + GUNS: (() => { + let output = [] + for (let i = 0; i<3; i++) { + output.push({ + POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -25 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 1 }]), + TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', + COLOR: 'black' + } + }, { + POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -20 }, + PROPERTIES: { + COLOR: 'white' + } + }, { + POSITION: { WIDTH: 10, HEIGHT: 5, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 3 }]), + TYPE: 'trplnrBossBulletHellFormPentagons', + COLOR: 'white' + } + }, { + POSITION: { WIDTH: 8, HEIGHT: 3, X: -1, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'pureWhite', + } + }, { + POSITION: { WIDTH: 5, HEIGHT: 10, X: 5, ASPECT: 0.2, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: -1, + } + }) + } + output.push({ + POSITION: { WIDTH: 0, HEIGHT: 0 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 2 }, g.fake]), + TYPE: 'bullet', + IDENTIFIER: 'onHandler', + ALPHA: 0 + } + }) + return output + })() +} +Class.trplnrBossVulnerableForm = { + PARENT: "miniboss", + ...trplnrBossDecor, + LABEL: 'Lavender - Vulnerable Form', + BODY: { + HEALTH: 500, + SPEED: 0.1 + }, + ON: [ + { + event: "tick", + handler: ({ body }) => { + body.store.ticks ??= 0 + body.store.ticks++ + const spawnCrashers = body.store.ticks % 3 == 0 + const spawnSentries = body.store.ticks % 60 == 0 + const sentries = ["sentrySwarm", "sentryGun", "sentryTrap"] + if (spawnCrashers) new Entity(body, body).define("crasher") + if (spawnSentries) new Entity(body, body).define(sentries[Math.floor(Math.random() * sentries.length)]) + } + }, + { + event: "fire", + handler: ({ body, gun }) => { + if (gun.identifier != 'onHandler') return + setTimeout(() => { + body.define('trplnrBoss') + sockets.broadcast('im awake') + }, 15000) + setTimeout(() => sockets.broadcast('Lavender will activate in 10 seconds and turn into S4nctuary F0rM'), 5000) + } + } + ], + GUNS: [{ + POSITION: {LENGTH: 0, WIDTH: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, {reload: 500}]), + TYPE: 'bullet', + AUTOFIRE: true, + IDENTIFIER: 'onHandler', + ALPHA: 0 + } + }] +} + +Class.frostAuraSmall = { + PARENT: "aura", + LAYER: 30, + FACING_TYPE: ["spin", {speed: -0.04}], + BORDERLESS: true, + SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraSmallOutline' + }] +} +Class.frostAuraSmallOutline = { + PARENT: "aura", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0" + + "L 0.309 0.951 L -0.809 0.588 L -0.809 -0.588 L 0.309 -0.951 L 1 0" + + "L 0 0 L 0.309 0.951 M 0 0 L -0.809 0.588 M 0 0 L -0.809 -0.588 M 0 0 L 0.309 -0.951", +} +Class.frostAuraLarge = { + PARENT: "aura", + LAYER: 30, + FACING_TYPE: ["spin", {speed: -0.04}], + BORDERLESS: true, + SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraLargeOutline' + }] +} +Class.frostAuraLargeOutline = { + PARENT: "aura", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0" + + "M 0.988 -0.156 L 0.988 0.156 L 0.891 0.454 L 0.707 0.707 L 0.454 0.891 L 0.156 0.988 L -0.156 0.988 L -0.454 0.891 L -0.707 0.707 L -0.891 0.454 L -0.988 0.156 L -0.988 -0.156 L -0.891 -0.454 L -0.707 -0.707 L -0.454 -0.891 L -0.156 -0.988 L 0.156 -0.988 L 0.454 -0.891 L 0.707 -0.707 L 0.891 -0.454 L 0.988 -0.156 L 0.949 0" + + "L 0.988 0.156 L 0.891 0.256 L 0.891 0.454 L 0.739 0.537 L 0.707 0.707 L 0.519 0.769 L 0.454 0.891 L 0.293 0.902 L 0.156 0.988 L 0.032 0.927 L -0.156 0.988 L -0.282 0.869 L -0.454 0.891 L -0.571 0.731 L -0.707 0.707 L -0.768 0.558 L -0.891 0.454 L -0.871 0.317 L -0.988 0.156 L -0.914 0 L -0.988 -0.156 L -0.871 -0.317 L -0.891 -0.454 L -0.768 -0.558 L -0.707 -0.707 L -0.571 -0.731 L -0.454 -0.891 L -0.282 -0.869 L -0.156 -0.988 L 0.032 -0.927 L 0.156 -0.988 L 0.293 -0.902 L 0.454 -0.891 L 0.519 -0.769 L 0.707 -0.707 L 0.739 -0.537 L 0.891 -0.454 L 0.891 -0.256 L 0.988 -0.156 L 0.949 0" + + "L 0.891 0.256 L 0.739 0.537 L 0.519 0.769 L 0.293 0.902 L 0.032 0.927 L -0.282 0.869 L -0.571 0.731 L -0.768 0.558 L -0.871 0.317 L -0.914 0 L -0.871 -0.317 L -0.768 -0.558 L -0.571 -0.731 L -0.282 -0.869 L 0.032 -0.927 L 0.293 -0.902 L 0.519 -0.769 L 0.739 -0.537 L 0.891 -0.256 L 0.949 0" + + "M 0.834 0 L 0.891 0.256 L 0.704 0.291 L 0.739 0.537 L 0.495 0.579 L 0.519 0.769 L 0.258 0.793 L 0.032 0.927 L -0.06 0.759 L -0.282 0.869 L -0.398 0.649 L -0.571 0.731 L -0.674 0.49 L -0.871 0.317 L -0.741 0.178 L -0.914 0 L -0.741 -0.178 L -0.871 -0.317 L -0.674 -0.49 L -0.571 -0.731 L -0.398 -0.649 L -0.282 -0.869 L -0.06 -0.759 L 0.032 -0.927 L 0.258 -0.793 L 0.519 -0.769 L 0.495 -0.579 L 0.739 -0.537 L 0.704 -0.291 L 0.891 -0.256 L 0.834 0" + + "L 0.704 0.291 L 0.495 0.579 L 0.258 0.793 L -0.06 0.759 L -0.398 0.649 L -0.674 0.49 L -0.741 0.178 L -0.741 -0.178 L -0.674 -0.49 L -0.398 -0.649 L -0.06 -0.759 L 0.258 -0.793 L 0.495 -0.579 L 0.704 -0.291 L 0.834 0" + + "M 0.592 0 L 0.704 0.291 L 0.413 0.3 L 0.495 0.579 L 0.183 0.563 L -0.06 0.759 L -0.158 0.485 L -0.398 0.649 L -0.479 0.348 L -0.741 0.178 L -0.51 0 L -0.741 -0.178 L -0.479 -0.348 L -0.398 -0.649 L -0.158 -0.485 L -0.06 -0.759 L 0.183 -0.563 L 0.495 -0.579 L 0.413 -0.3 L 0.704 -0.291 L 0.592 0" + + "L 0.413 0.3 L 0.183 0.563 L -0.158 0.485 L -0.479 0.348 L -0.51 0 L -0.479 -0.348 L -0.158 -0.485 L 0.183 -0.563 L 0.413 -0.3 L 0.592 0" + + "M 0.292 0 L 0.413 0.3 L 0.09 0.277 L -0.158 0.485 L -0.236 0.171 L -0.51 0 L -0.236 -0.171 L -0.158 -0.485 L 0.09 -0.277 L 0.413 -0.3 L 0.292 0 L 0.09 0.277" + + "L -0.236 0.171 L -0.236 -0.171 L 0.09 -0.277 L 0.292 0 M 0 0 L 0.949 0" + + "M 0 0 L 0.293 0.902 M 0 0 L -0.768 0.558 M 0 0 L -0.768 -0.558 M 0 0 L 0.293 -0.902", +} +Class.frostAuraSymbol = { + PARENT: ["genericTank"], + CONTROLLERS: [["spin", { speed: -0.04 }]], + INDEPENDENT: true, + BORDERLESS: true, + COLOR: 'teal', + SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraSymbolOutline' + }] +} +Class.frostAuraSymbolOutline = { + PARENT: "genericTank", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z" + + "M 0.52 0.3 L 0.52 -0.3 L 0.797 -0.46 M 0.52 -0.3 L 0 -0.6 L 0 -0.92 M 0 -0.6 L -0.52 -0.3 L -0.797 -0.46 M -0.52 -0.3 L -0.52 0.3 L -0.797 0.46 M -0.52 0.3 L 0 0.6 L 0 0.92 M 0 0.6 L 0.52 0.3 L 0.797 0.46" +} + +function addIcosphereAura(damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraSize = "Medium") { + let auraType = "frostAura" + auraSize; + return { + PARENT: "genericTank", + INDEPENDENT: true, + LABEL: "", + COLOR: 17, + GUNS: [ + { + POSITION: [0, 20, 1, 0, 0, 0, 0,], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.aura, { size: sizeFactor, damage: damageFactor }]), + TYPE: [auraType, {ALPHA: opacity}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, + }, + ], + TURRETS: [ + { + POSITION: [20, 0, 0, 0, 360, 1], + TYPE: "frostAuraSymbol" + }, + ] + }; +} +Class.frostAuraBlockTop = { + SHAPE: "M -1.3 -0.15 L -1.3 0.15 L -0.3 0.3 L -0.15 1.3 L 0.15 1.3 L 0.3 0.3 L 1.3 0.15 L 1.3 -0.15 L 0.3 -0.3 L 0.15 -1.3 L -0.15 -1.3 L -0.3 -0.3 Z", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 5 }, + MIRROR_MASTER_ANGLE: true, +} +Class.frostAuraBlockTurret = { + PARENT: "genericTank", + INDEPENDENT: true, + COLOR: 17, + CONTROLLERS: ["nearestDifferentMaster"], + LABEL: "", + BODY: { + FOV: 2, + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [18, 15, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} + }, + }, { + POSITION: [23, 11, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, {density: 0.2}]), + TYPE: "bullet", + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [15, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ], +} +Class.frostAuraBlockAura = addIcosphereAura(0.25, 1.6, 0.15, "Small"); +Class.frostAuraBlock = { + PARENT: 'unsetTrap', + TURRETS: [ + { + POSITION: [20, 0, 0, 45, 0, 1], + TYPE: 'frostAuraBlockTop' + }, { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: 'frostAuraBlockTurret' + }, { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: 'frostAuraBlockAura' + } + ] +} +Class.frostBossBigAura = addIcosphereAura(1.5, 1.45, 0.3, "Large"); + +Class.frostBossAutoTurret = { + PARENT: "autoTankGun", + INDEPENDENT: true, + COLOR: 17, + GUNS: [ + { + POSITION: [17, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} + }, + }, { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.2}]), + TYPE: "bullet", + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [14, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ], + TURRETS: [ + { + POSITION: [13, 0, 0, 0, 0, 1], + TYPE: ["egg", {COLOR: -1, BORDERLESS: true}], + }, + ], +} + +Class.frostBossBaseDeco = { + SHAPE: "M -1.1 0 L -0.956 0.292 L -0.669 0.205 L -0.669 -0.205 L -0.956 -0.292 Z" + + "M -0.55 0.952 L -0.225 0.974 L -0.157 0.682 L -0.512 0.477 L -0.731 0.682 Z" + + "M -0.55 -0.952 L -0.225 -0.974 L -0.157 -0.682 L -0.512 -0.477 L -0.731 -0.682 Z" + + "M 0.55 0.952 L 0.225 0.974 L 0.157 0.682 L 0.512 0.477 L 0.731 0.682 Z" + + "M 0.55 -0.952 L 0.225 -0.974 L 0.157 -0.682 L 0.512 -0.477 L 0.731 -0.682 Z" + + "M 1.1 0 L 0.956 0.292 L 0.669 0.205 L 0.669 -0.205 L 0.956 -0.292 Z", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, + MIRROR_MASTER_ANGLE: true, + GUNS: Array(6).fill().flatMap((_, i) => ([ + { + POSITION: [1.75, 3, -0.75, 7.5, 0, 60 * i, 0], + PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 2.5, SATURATION_SHIFT: 0.9 }, DRAW_ABOVE: true }, + }, { + POSITION: [1, 9, 0, 8.5, 0, 60 * i + 30, 0], + PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 10, SATURATION_SHIFT: 1.15 } }, + }, + ])) +} + +const trebuchetStats = [g.basic, g.sniper, g.predator, g.predator, g.predator, g.predator, {speed: 0.93, maxSpeed: 0.93, reload: 1.7, health: 1.7, damage: 1.4, size: 2}]; +const hielamanStats = [g.trap, g.setTrap, g.hexaTrapper, {reload: 2.4, health: 3.2, range: 1.2}]; +Class.frostBoss = { + PARENT: 'miniboss', + LABEL: 'Extrasolar', + NAME: 'Frostbyte', + FACING_TYPE: 'toTarget', + SHAPE: 6, + COLOR: "aqua", + UPGRADE_COLOR: "aqua", + SIZE: 31, + DANGER: 12, + VALUE: 888888, + UPGRADE_TOOLTIP: "\"When the golden rays of sun shine through this world's\n" + + "darkened skies and looming clouds, the legend of the warrior\n" + + "and his eternal blade will finally come to fruition.\"", + BODY: { + SPEED: base.SPEED * 0.6, + HEALTH: base.HEALTH * 11, + SHIELD: base.SHIELD * 7, + REGEN: base.REGEN * 2.5, + FOV: base.FOV * 1.4, + RESIST: base.RESIST * 1.2, + DENSITY: base.DENSITY * 7.5, + }, + GUNS: [ + ...Array(6).fill().flatMap((_, i) => ({ + // Speed + POSITION: [8, 14.5, 0.001, 9.5, 0, 60*i, 0], + PROPERTIES: {COLOR: 9}, + })), + ...Array(3).fill().flatMap((_, i) => ([ + { // Heavy Snipers + POSITION: [26.5, 9.5, 1, 0, 0, 120 * i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats(trebuchetStats), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6 }, + }, + }, { + POSITION: [24, 6.65, -1.3, 0, 0, 120 * i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, + BORDERLESS: true + }, + }, { + POSITION: [19.5, 3.8, -1.4, 0, 0, 120 * i, 0], + PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 10 } }, + }, { + POSITION: [4, 11.5, 1, 19.5, 0, 120 * i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, + }, + }, { + POSITION: [2, 12, 1, 20.5, 0, 120 * i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, + }, + }, + { // Aura Blocks + POSITION: [15, 9, 1, 0, 0, 120 * i + 60, 0], + PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6}} + }, { + POSITION: [4, 7.5, -1.6, 9, 0, 120 * i + 60, 0], + PROPERTIES: {COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5}} + }, { + POSITION: [15, 5.4, -0.1, 0, 0, 120 * i + 60, 0], + PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.75}} + }, { + POSITION: [3, 9, 1.6, 15, 0, 120 * i + 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats(hielamanStats), + TYPE: 'frostAuraBlock', + STAT_CALCULATOR: gunCalcNames.trap, + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [2, 7, 1.6, 16, 0, 120 * i + 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...hielamanStats, g.fake]), + TYPE: 'bullet', + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ])), + ], + TURRETS: [ + ...Array(6).fill().flatMap((_, i) => ([ + { + POSITION: [2.95, 8.55, 0, 60 * i + 30, 180, 2], + TYPE: "frostBossAutoTurret", + }, + ])), + { + POSITION: [8.55, 0, 0, 0, 360, 2], + TYPE: "frostBossBigAura", + }, + ], + PROPS: [ + { + POSITION: [12, 0, 0, 180, 1], + TYPE: ["hexagon", {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 7.5}}], + }, { + POSITION: [20, 0, 0, 0, 1], + TYPE: ["frostBossBaseDeco"], + }, + ] +} + +const divide = 1000; +const arraySize = 10; +const colorArray = []; +const damageMultiplayer = 3.5; +const reloadMultiplayer = 2; +for (let i = 0; i < arraySize; i++) { + const rgb = Math.round(255 * i / (arraySize - 1)); + colorArray.push('#' + ((1 << 24) + (rgb << 16) + (rgb << 8) + rgb).toString(16).slice(1)); +} +class io_nearestDifferentMaster2 extends ioTypes.nearestDifferentMaster { + constructor(body, opts = {}) { + super(body); + this.lookAtDanger = opts.lookAtDanger ?? true; + this.firingAtMe = opts.firingAtMe ?? false; + this.timeout = opts.timeout || 90; + } + buildList(range) { + // Establish whom we judge in reference to + let mostDangerous = 0, + keepTarget = false; + // Filter through everybody... + let out = entities.filter(e => + // Only look at those within our view, and our parent's view, not dead, not invisible, not our kind, not a bullet/trap/block etc + this.validate(e, this.body, this.body.master.master, range * range, range * range * 4 / 3) + ).filter((e) => { + // Only look at those within range and arc (more expensive, so we only do it on the few) + if (this.body.firingArc == null || this.body.aiSettings.view360 || Math.abs(util.angleDifference(util.getDirection(this.body, e), this.body.firingArc[0])) < this.body.firingArc[1]) { + mostDangerous = Math.max(e.dangerValue, mostDangerous); + return true; + } + }).filter((e) => { + // Even more expensive + return !this.wouldHitWall(this.body, e); + }).filter((e) => { + // Only return the highest tier of danger + if (!this.lookAtDanger) return true; + if (this.body.aiSettings.farm || e.dangerValue === mostDangerous) { + if (this.targetLock && e.id === this.targetLock.id) keepTarget = true; + return true; + } + }); + // Reset target if it's not in there + if (!keepTarget) this.targetLock = undefined; + return out; + } + think(input) { + // Override target lock upon other commands + if (input.main || input.alt || this.body.master.autoOverride) { + this.targetLock = undefined; + return {}; + } + // Otherwise, consider how fast we can either move to ram it or shoot at a potiential target. + let tracking = this.body.topSpeed, + damageRef = (this.body.bond == null) ? this.body : this.body.bond, + range = this.body.fov; + // Use whether we have functional guns to decide + for (let i = 0; i < this.body.guns.length; i++) { + if (this.body.guns[i].canShoot && !this.body.aiSettings.SKYNET) { + let v = this.body.guns[i].getTracking(); + if (v.speed == 0 || v.range == 0) continue; + tracking = v.speed; + range = Math.min(range, (v.speed || 1.5) * (v.range < (this.body.size * 2) ? this.body.fov : v.range)); + break; + } + } + if (!Number.isFinite(tracking)) { + tracking = this.body.topSpeed + .01; + } + if (!Number.isFinite(range)) { + range = 640 * this.body.FOV; + } + // Check if my target's alive + if (this.targetLock && ( + !this.validate(this.targetLock, this.body, this.body.master.master, range * range, range * range * 4 / 3) || + this.wouldHitWall(this.body, this.targetLock) // Very expensive + )) { + this.targetLock = undefined; + this.tick = 100; + } + // Think damn hard + if (this.tick++ > 15 * c.runSpeed) { + this.tick = 0; + this.validTargets = this.buildList(range); + // Ditch our old target if it's invalid + if (this.targetLock && this.validTargets.indexOf(this.targetLock) === -1) { + this.targetLock = undefined; + } + // Lock new target if we still don't have one. + if (this.targetLock == null && this.validTargets.length) { + this.targetLock = (this.validTargets.length === 1) ? this.validTargets[0] : nearest(this.validTargets, { + x: this.body.x, + y: this.body.y + }); + this.tick = -this.timeout; + } + } + // Lock onto whoever's shooting me. + if (this.firingAtMe && damageRef.collisionArray.length && damageRef.health.display() < this.oldHealth) { + this.oldHealth = damageRef.health.display(); + if (this.validTargets.indexOf(damageRef.collisionArray[0]) === -1) { + let a = (damageRef.collisionArray[0].master.id === -1) + ? damageRef.collisionArray[0].source + : damageRef.collisionArray[0].master; + if ( + this.body.firingArc == null || + this.body.aiSettings.view360 || + Math.abs(util.angleDifference(util.getDirection(this.body, a), this.body.firingArc[0])) < this.body.firingArc[1] + ) { + this.targetLock = a; + this.tick = -(this.timeout * 5); + } + } + } + // Consider how fast it's moving and shoot at it + if (this.targetLock != null) { + let radial = this.targetLock.velocity; + let diff = { + x: this.targetLock.x - this.body.x, + y: this.targetLock.y - this.body.y, + } + /// Refresh lead time + if (this.tick % 4 === 0) { + this.lead = 0 + // Find lead time (or don't) + if (!this.body.aiSettings.chase) { + let toi = timeOfImpact(diff, radial, tracking) + this.lead = toi + } + } + if (!Number.isFinite(this.lead)) { + this.lead = 0; + } + if (!this.accountForMovement) this.lead = 0; + // And return our aim + return { + target: { + x: diff.x + this.lead * radial.x, + y: diff.y + this.lead * radial.y, + }, + fire: true, + main: true + }; + } + return {}; + } +} +ioTypes.nearestDifferentMaster2 = io_nearestDifferentMaster2; +Class.toothlessBase = { + PARENT: "genericTank", + LABEL: "NightFury", + UPGRADE_TOOLTIP: "A power league...", + GLOW: { + RADIUS: 2, + COLOR: 42, + ALPHA: 0.6, + RECURSION: 6, + }, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.5 * base.FOV, + HEALTH: 6 * base.HEALTH, + DAMAGE: 2 * base.DAMAGE, + }, + LEVEL_CAP: 45, + EXTRA_SKILL: 78, // 120 - 42 + SHAPE: 3, + VALUE: 30e+3, + SIZE: 24, + COLOR: "purple", + SKILL_CAP: Array(10).fill(smshskl + 3), + LEVEL_SKILL_POINT_FUNCTION: level => { + if (level < 2) return 0; + if (level <= 40) return 1; + if (level <= 45 && level & 1 == 1) return 1; + return 0; + }, +} +Class.toothlessBossTurret = { + PARENT: "genericTank", + LABEL: "", + BODY: { + FOV: 2, + }, + CONTROLLERS: [ + "onlyAcceptInArc", + [ "nearestDifferentMaster2", { lookAtDanger: false, firingAtMe: true, timeout: 10 } ], + ], + COLOR: "grey", + GUNS: [ + { + POSITION: [32, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, { + pen: 0.8, + health: 0.6, + damage: 0.6, + recoil: 0, + }]), + TYPE: "bullet", + }, + }, + ], + ON: [{ + event: "fire", + handler: ({ body }) => { + const master = body.master; + body._damage ??= []; + body._reload ??= []; + + if (!body._loaded) { + let _temp = 0; + master._maxPower ??= 0; + + body.guns.forEach((gun, i) => { + body._damage[i] = gun.settings.damage; + body._reload[i] = gun.settings.reload; + + _temp += (body._damage[i] * 3) / body._damage[i]; + _temp += body._reload[i] / (body._reload[i] / 3); + _temp /= 2; + }); + + _temp /= body.guns.length; + + master._maxPower += (_temp - 1) * divide * 2; + if (master._maxPower > _temp) master._maxPower /= 2; + + body._loaded = true; + } + + if (master._mode) { + master._power -= 1; + if (master._power < 1) { + master._mode = 0; + master.color.base = 14; + } + } + + if (!master._oldPower) return; + const power = master._oldPower / (divide * 2) + 1; + + body.guns.forEach((gun, i) => { + let _1 = body._damage[i] * (master._mode ? power : 1); + let _2 = body._reload[i] / (master._mode ? power : 1); + let max_damage = body._damage[i] * damageMultiplayer; + let min_reload = body._reload[i] / reloadMultiplayer; + + gun.settings.damage = _1 > max_damage ? max_damage : _1; + gun.settings.reload = _2 < min_reload ? min_reload : _2; + }); + }, + }], +}; +Class.toothlessBossDeco = { + PARENT: "genericTank", + LABEL: "", + SHAPE: 3, + SIZE: 10, + ON: [{ + event: "tick", + handler: ({ body }) => { + const master = body.master; + if (master._maxPower) + body.color.base = colorArray[ + Math.floor(master._power / (master._maxPower / arraySize)) > arraySize - 1 + ? arraySize - 1 + : Math.floor(master._power / (master._maxPower / arraySize) + ) + ]; + }, + }], +}; +Class.toothlessBoss = { + PARENT: "toothlessBase", + UPGRADE_COLOR: "magenta", + TURRETS: [{ + POSITION: { SIZE: 15, LAYER: 1 }, + TYPE: ["toothlessBossDeco", { MIRROR_MASTER_ANGLE: true }], + }, { + POSITION: { SIZE: 23 }, + TYPE: ["triangle", { COLOR: "black", MIRROR_MASTER_ANGLE: true }], + }], + GUNS: [{ + POSITION: { LENGTH: 0, WIDTH: 0 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ g.basic, { + range: 0.1, + speed: 0.1, + maxSpeed: 0.1, + recoil: 0, + }]), + TYPE: "bullet", + ALT_FIRE: true, + }, + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + if (!body._power || body._mode) return; + const power = Math.floor(body._power); + + if (power >= 1) { + body.sendMessage(`Your power level ${power}`); + body._oldPower = body._power; + body._mode = 1; + body.color.base = 5; + } + }, + }, { + event: "kill", + handler: ({ body, entity }) => { + body._power ??= 0; + body._mode ??= 0; + if (!body._mode) body._power += (entity.skill.score / divide) ** 0.8; + }, + }], +} +for (let b = 0; b < 3; b++) + Class.toothlessBoss.TURRETS.push({ + POSITION: [8, 6, -5.6, 120 * b + 180, 180, 0], + TYPE: "toothlessBossTurret", + }, { + POSITION: [8, 6, 5.6, 120 * b + 180, 180, 0], + TYPE: "toothlessBossTurret", + }); \ No newline at end of file diff --git a/server/modules/definitions/groups/dev.js b/server/modules/definitions/groups/dev.js index 2672e650d..4a8071a2f 100644 --- a/server/modules/definitions/groups/dev.js +++ b/server/modules/definitions/groups/dev.js @@ -1,4 +1,4 @@ -const { combineStats, menu, addAura, makeDeco, LayeredBoss, newWeapon, weaponArray } = require('../facilitators.js'); +const { combineStats, menu, addAura, makeDeco, makeHybrid, makeAuto, LayeredBoss, newWeapon, weaponArray } = require('../facilitators.js'); const { base, gunCalcNames, basePolygonDamage, basePolygonHealth, dfltskl, statnames } = require('../constants.js'); const g = require('../gunvals.js'); @@ -291,6 +291,12 @@ Class.diamondShape = { SHAPE: 4.5 }; +Class.rotatedTrap = { + PARENT: "basic", + LABEL: "Rotated Inverted Body", + SHAPE: -3.5 +}; + Class.mummyHat = { SHAPE: 4.5, COLOR: -1 @@ -338,6 +344,39 @@ Class.mummifier = { TYPE: ["mummyHat"] }] }; + +Class.colorMan = { + PARENT: "genericTank", + LABEL: "Testing Animated Colors", + SHAPE: 4, + COLOR: "rainbow", + TURRETS: [{ + POSITION: [20, -20, -20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedBlueRed" } + },{ + POSITION: [20, 0 , -20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedBlueGrey" } + },{ + POSITION: [20, 20, -20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedGreyBlue" } + },{ + POSITION: [20, -20, 0 , 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedRedGrey" } + },{ + POSITION: [20, 20, 0 , 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedGreyRed" } + },{ + POSITION: [20, 20, 20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedLesbian" } + },{ + POSITION: [20, 0 , 20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedTrans" } + },{ + POSITION: [20, 20, 20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedBi" } + }] +}; + Class.miscTestHelper2 = { PARENT: "genericTank", LABEL: "Turret Reload 3", @@ -591,7 +630,7 @@ Class.onTest = { }] } -Class.auraBasicGen = addAura(); +Class.auraBasicGen = addAura(3, 1.3); Class.auraBasic = { PARENT: "genericTank", LABEL: "Aura Basic", @@ -636,9 +675,9 @@ Class.auraHealer = { }; Class.ghoster_ghosted = { - PARENT: "genericTank", + PARENT: 'genericTank', TOOLTIP: 'You are now hidden, roam around and find your next target. You will be visible again in 5 seconds', - LABEL: 'Ghoster', + LABEL: "Ghoster", BODY: { SPEED: 20, ACCELERATION: 10, @@ -651,8 +690,8 @@ Class.ghoster_ghosted = { } Class.ghoster = { - PARENT: "genericTank", - LABEL: 'Ghoster', + PARENT: 'genericTank', + LABEL: "Ghoster", TOOLTIP: 'Shooting will hide you for 5 seconds', BODY: { SPEED: base.SPEED, @@ -662,7 +701,7 @@ Class.ghoster = { { event: 'fire', handler: ({ body }) => { - body.define("ghoster_ghosted") + body.define(Class.ghoster_ghosted) setTimeout(() => { body.SPEED = 1e-99 body.ACCEL = 1e-99 @@ -671,7 +710,7 @@ Class.ghoster = { }, 2000) setTimeout(() => { body.SPEED = base.SPEED - body.define("ghoster") + body.define(Class.ghoster) }, 2500) } } @@ -822,6 +861,49 @@ Class.armyOfOne = { } ], }; +Class.godbasic = { + PARENT: "genericTank", + LABEL: "God Basic", + SKILL_CAP: [31, 31, 31, 31, 31, 31, 31, 31, 31, 31], + SKILL: [ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 ], + BODY: { + ACCELERATION: base.ACCEL * 1, + SPEED: base.SPEED * 1, + HEALTH: base.HEALTH * 1, + DAMAGE: base.DAMAGE * 1, + PENETRATION: base.PENETRATION * 1, + SHIELD: base.SHIELD * 1, + REGEN: base.REGEN * 1, + FOV: base.FOV * 1, + DENSITY: base.DENSITY * 1, + PUSHABILITY: 1, + HETERO: 3, + }, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + COLOR: "grey", + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 0, + ALT_FIRE: false, + NEGATIVE_RECOIL: false, + }, + }, + ], +}; +Class.maximumOverdrive = { + PARENT: "overdrive", + LABEL: "Maximum Overdrive", + SKILL_CAP: Array(10).fill(255), + SKILL: Array(10).fill(255), +}; Class.weirdAutoBasic = { PARENT: "genericTank", LABEL: "Weirdly defined Auto-Basic", @@ -874,7 +956,6 @@ Class.bulletSpawnTest = { } ] } - Class.propTestProp = { PARENT: 'genericTank', SHAPE: 6, @@ -889,6 +970,7 @@ Class.propTestProp = { } ] } + Class.propTest = { PARENT: 'genericTank', LABEL: 'Deco Prop Test', @@ -908,31 +990,6 @@ Class.propTest = { } ] } -Class.weaponArrayTest = { - PARENT: 'genericTank', - LABEL: 'Weapon Array Test', - GUNS: weaponArray([ - { - POSITION: [20, 8, 1, 0, 0, 25, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: 'bullet' - } - }, { - POSITION: [17, 8, 1, 0, 0, 25, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: 'bullet' - } - } - ], 5), - TURRETS: weaponArray( - { - POSITION: [7, 10, 0, -11, 180, 0], - TYPE: 'autoTankGun' - } - , 5), -} Class.levels = menu("Levels") Class.levels.UPGRADES_TIER_0 = [] @@ -972,79 +1029,18 @@ Class['Team' + TEAM_ENEMIES] = { }; Class.teams.UPGRADES_TIER_0.push('Team' + TEAM_ROOM, 'Team' + TEAM_ENEMIES); -Class.testing = menu("Testing") - +Class.testing = menu("Beta Tanks") +Class.features = menu("Features") +Class.overpowered = menu("Dev Funny", "rainbow") +Class.overpowered.UPGRADE_COLOR = "rainbow" +Class.goofytanks = menu("Goofy Shit", "rainbow") +Class.goofytanks.UPGRADE_COLOR = "rainbow" +Class.overpowered.UPGRADE_TOOLTIP = "The Funny v2" +Class.goofytanks.UPGRADE_TOOLTIP = "The Funny v3" + Class.addons = menu("Addon Entities") Class.addons.UPGRADES_TIER_0 = [] -Class.volute = { - PARENT: "genericTank", - LABEL: "Volute", - DANGER: 6, - STAT_NAMES: statnames.desmos, - GUNS: [ - { - POSITION: [20, 13, 0.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.pounder]), - TYPE: ["bullet", {MOTION_TYPE: "desmos"}] - }, - }, - { - POSITION: [5, 10, 2.125, 1, -6.375, 90, 0], - }, - { - POSITION: [5, 10, 2.125, 1, 6.375, -90, 0], - }, - ], -} -Class.snakeOld = { - PARENT: "missile", - LABEL: "Snake", - GUNS: [ - { - POSITION: [6, 12, 1.4, 8, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.snake, g.snakeskin]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - }, - }, - { - POSITION: [10, 12, 0.8, 8, 0, 180, 0.5], - PROPERTIES: { - AUTOFIRE: true, - NEGATIVE_RECOIL: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.snake]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - }, - }, - ], -} -Class.sidewinderOld = { - PARENT: "genericTank", - LABEL: "Sidewinder (old)", - DANGER: 7, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.3 * base.FOV, - }, - GUNS: [ - { - POSITION: [10, 11, -0.5, 14, 0, 0, 0], - }, - { - POSITION: [21, 12, -1.1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder]), - TYPE: "snakeOld", - STAT_CALCULATOR: gunCalcNames.sustained, - }, - }, - ], -} Class.whirlwindDeco = makeDeco(6) Class.whirlwindDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]] Class.whirlwind = { @@ -1081,6 +1077,7 @@ Class.whirlwind = { return output })() } + let testLayeredBoss = new LayeredBoss("testLayeredBoss", "Test Layered Boss", "terrestrial", 7, 3, "terrestrialTrapTurret", 5, 7, {SPEED: 10}); testLayeredBoss.addLayer({gun: { POSITION: [3.6, 7, -1.4, 8, 0, null, 0], @@ -1106,6 +1103,14 @@ Class.flailBallSpike = { Class.flailBall = { PARENT: "genericTank", COLOR: "grey", + TYPE: "flail", + BODY: { + DENSITY: 2 * base.DENSITY, + HEALTH: 10000, + SHIELD: 10000, + DAMAGE: 4.5, + REGEN: 10000 + }, HITS_OWN_TYPE: 'hard', INDEPENDENT: true, TURRETS: [{ @@ -1122,7 +1127,8 @@ Class.flailBolt1 = { }], TURRETS: [{ POSITION: [48, 56, 0, 0, 360, 1], - TYPE: "flailBall" + TYPE: "flailBall", + VULNERABLE: true }], }; Class.flailBolt2 = { @@ -1202,25 +1208,1205 @@ Class.tripleFlail = { }] } -Class.developer.UPGRADES_TIER_0 = ["tanks", "bosses", "spectator", "levels", "teams", "eggGenerator", "testing", "addons"] - Class.tanks.UPGRADES_TIER_0 = ["basic", "unavailable", "arenaCloser", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun"] - Class.unavailable.UPGRADES_TIER_0 = ["flail", "healer", "volute", "whirlwind"] - Class.flail.UPGRADES_TIER_2 = ["doubleFlail"] - Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] - Class.volute.UPGRADES_TIER_3 = ["sidewinderOld"] - Class.dominators.UPGRADES_TIER_0 = ["destroyerDominator", "gunnerDominator", "trapperDominator"] - Class.sanctuaries.UPGRADES_TIER_0 = ["sanctuaryTier1", "sanctuaryTier2", "sanctuaryTier3", "sanctuaryTier4", "sanctuaryTier5", "sanctuaryTier6"] +Class.Trapper_guy = { + PARENT: "trapper", + LABEL: "Trapper_guy", + UPGRADE_COLOR: "blue", + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png?v=1705291478159", + GUNS: [ + { + POSITION: [15, 7, 1, 0, 0, 0, 0] + }, + { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + }, { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.nomove, g.halfrange, g.shockwave]), + TYPE: "shockwave", + STAT_CALCULATOR: gunCalcNames.trap, + ALT_FIRE: true + } + } + ] +}; +Class.shockwave = { + PARENT: "bullet", + LABEL: "funy", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + MOTION_TYPE: "trappershockwave" +}; +Class.watergun = { + LABEL: 'Auto Turret', + SYNCS_SKILLS: true, + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png?v=1705294702951", + BODY: { + FOV: 1, + }, + COLOR: "blue", + CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], + GUNS: [{ + POSITION: [10, 8, 1, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.op, g.shockwave, g.shockwave]), + TYPE: "bullet", + HAS_NO_RECOIL: true + } + } + ] +} +Class.watergundormant = { + LABEL: 'Auto Turret', + SYNCS_SKILLS: true, + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png?v=1705294702951", + BODY: { + FOV: 1 + }, + COLOR: 16, + GUNS: [{ + POSITION: [13.5, 10, 1, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.fake]), + TYPE: "bullet" + } + } + ] +} +Class.waterpet = { + PARENT: "boomerang", + LABEL: "Base", + SHAPE: 0, + INDEPENDENT: true, + TURRETS: [{ + POSITION: [25, 0, 0, 180, 360, 1], + TYPE: "watergun", + }], +ON: [{ + event: "death", + handler: ({ body }) => { + if (!body.master.isDead) return + body.master.define(Class.watertank) + } + } + ] +}; +Class.watertank = { + PARENT: "triAngle", + LABEL: "Waduh", + DANGER: 6, + SYNC_TURRET_SKILLS: true, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, { + POSITION: [1, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.bitlessspeed, g.shockwave, g.xtrahealth]), + TYPE: "waterpet", + ALT_FIRE: true, + } + }], + TURRETS: [{ + POSITION: [17, 9.85, 0, 180, 360, 1], + TYPE: "watergundormant", + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + body.define(Class.watertankFire) + } + } + ] +}; +Class.watertankFire = { + PARENT: "genericTank", + LABEL: "Waduh", + DANGER: 6, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + ] +}; +Class.piszerbeam = { + PARENT: "genericTank", + LABEL: "Pissliner", + COLOR: "yellow", + TEAM: TEAM_ROOM, + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 0.6, + SPEED: base.SPEED * 0.85, + FOV: base.FOV * 3, + }, + GUNS: [ + { + POSITION: [25, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [23, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [21, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, { + POSITION: [25, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + }, + }, + { + POSITION: [23, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true - Class.bosses.UPGRADES_TIER_0 = ["sentries", "elites", "mysticals", "nesters", "rogues", "rammers", "terrestrials", "celestials", "eternals", "devBosses"] - Class.sentries.UPGRADES_TIER_0 = ["sentrySwarm", "sentryGun", "sentryTrap", "shinySentrySwarm", "shinySentryGun", "shinySentryTrap", "sentinelMinigun", "sentinelLauncher", "sentinelCrossbow"] - Class.elites.UPGRADES_TIER_0 = ["eliteDestroyer", "eliteGunner", "eliteSprayer", "eliteBattleship", "eliteSpawner", "eliteTrapGuard", "eliteSpinner", "eliteSkimmer", "legionaryCrasher", "guardian", "defender", "sprayerLegion"] - Class.mysticals.UPGRADES_TIER_0 = ["sorcerer", "summoner", "enchantress", "exorcistor", "shaman"] - Class.nesters.UPGRADES_TIER_0 = ["nestKeeper", "nestWarden", "nestGuardian"] - Class.rogues.UPGRADES_TIER_0 = ["roguePalisade", "rogueArmada", "julius", "genghis", "napoleon"] - Class.rammers.UPGRADES_TIER_0 = ["bob", "nemesis"] - Class.terrestrials.UPGRADES_TIER_0 = ["ares", "gersemi", "ezekiel", "eris", "selene"] - Class.celestials.UPGRADES_TIER_0 = ["paladin", "freyja", "zaphkiel", "nyx", "theia", "atlas", "rhea", "julius", "genghis", "napoleon"] - Class.eternals.UPGRADES_TIER_0 = ["odin", "kronos"] - Class.devBosses.UPGRADES_TIER_0 = ["taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss"] + }, + }, + { + POSITION: [21, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + + }, + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + + }, + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + + }, + }, + ], +}; +Class.oplaser = { + PARENT: "bullet", + SHAPE: -1, + MOTION_TYPE: "fuckingnuclearbomb", + BODY: { + PENETRATION: 10, + SPEED: 30, + RANGE: 155, + DENSITY: 1.25, + HEALTH: 999, + DAMAGE: 999, + PUSHABILITY: 0.3, + }, + BUFF_VS_FOOD: true, +} +Class.deltabaseBullet = { + PARENT: "boomerang", + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + CONTROLLERS: [["spin", { independent: true, speed: 0.1 }]], + INDEPENDENT: true, + COLOR: "rainbow", + BODY: { + COLOR: "rainbow" + }, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["deltagun", { COLOR: "rainbow" }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["deltagun", { COLOR: "rainbow" }] + }], +ON: [{ + event: "death", + handler: ({ body }) => { + if (!body.master.isDead) return + body.master.define(Class.baseThrowerDelta) + } + } + ] +}; +Class.deltagun = { + LABEL: 'Auto Turret', + SYNCS_SKILLS: true, + BODY: { + FOV: 1 + }, + COLOR: 16, + CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], + GUNS: [{ + POSITION: [13.5, 10, 1, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.halfreload, g.halfspeed, g.op, g.op, g.op]), + TYPE: "grenade", + HAS_NO_RECOIL: true + } + } + ] +} +Class.turretBaseDelta = { + LABEL: "Basethingygygyyasgsdgajskhg", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: "rainbow",//iT WonT FUckING SpIN + SYNC_TURRET_SKILLS: true, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["deltagun", { COLOR: "rainbow" }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["deltagun", { COLOR: "rainbow" }] + }] +}; +Class.deltaDeco = { + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png", +}; +Class.baseThrowerDelta = { + PARENT: "genericTank", + LABEL: "Delta", + DANGER: 6, + SYNC_TURRET_SKILLS: true, + GUNS: [ + { + POSITION: [26, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [23, 10, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "bullet", + }, + }, { + POSITION: [1, 38, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.bitlessspeed, g.op, g.xxtrahealth]), + TYPE: ["deltabaseBullet", { COLOR: "rainbow" }], + ALT_FIRE: true, + ALPHA: 0, + HAS_NO_RECOIL: true, + } + }], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBaseDelta" + }, { + POSITION: [34, 0, 0, 0, 360, 3], + TYPE: "deltaDeco" + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + body.define(Class.baseThrowerFireDelta) + } + } + ] +}; +Class.baseThrowerFireDelta = { + PARENT: "genericTank", + LABEL: "Delta Congregation", + DANGER: 6, + GUNS: [ + { + POSITION: [26, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.halfrecoil, g.machineGun, g.op, g.op, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [23, 10, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.halfrecoil, g.machineGun, g.op, g.op, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.halfrecoil, g.op, g.op]), + TYPE: "bullet", + }, + }, { + POSITION: [24, 1, 1, 0, 0, 0, 2 / 3], + PROPERTIES: { + COLOR: 'red', + SHOOT_SETTINGS: combineStats([g.basic, g.op, g.op, g.halfrecoil, g.op]), + TYPE: "laser", + HAS_NO_RECOIL: true, + }, + }], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 3], + TYPE: "deltaDeco" + } + ] +}; +Class.pounerbullet = { + PARENT: "bullet", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png?v=1705772359444' +}; +Class.pouner = { + PARENT: "genericTank", + LABEL: "PouNer", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled979_20240120123618.png?v=1705772311845', + GUNS: [ + { + POSITION: [20.5, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.op]), + TYPE: "pounerbullet" + } + } + ] +} + +Class.grappletest = { + PARENT: "genericTank", + LABEL: "GrappleTest", + DANGER: 4, + ON: [ + { + event: "define", + handler: ({ body }) => { + if (body.hasDefined) { + body.children = [] + body.hasDefined = false + } else { + body.hasDefined = true + } + } + }, + { + event: "tick", + handler: ({ body }) => { + if (body.children != null) { + for (let instance of body.children) { + let deltaX = instance.x - body.x, + deltaY = instance.y - body.y, + distance = util.getDistance(instance, body) + angle = Math.atan2(deltaY, deltaX), + combinedRadii = instance.realSize + body.realSize; + body.velocity.x += 5 * Math.cos(angle) + body.velocity.y += 5 * Math.sin(angle) + if (combinedRadii * 1.3 > distance) { + body.children = [] + break + } + + } + } + if (body.control.fire) { + for (instance of entities) { + if (instance != body && instance.type == "wall" && util.getDistance(instance, { + x: body.control.target.x + body.x, + y: body.control.target.y + body.y + }) < instance.size * 1.3) { + if (body.children == 0) { + body.children.push(instance) + } + } + } + } + } + } + ] +} +Class.hook = { + PARENT: "bullet", + LABEL: "boolet", + ON: [ + { + event: "define", + handler: ({ body }) => { + if (body.master.hasDefined) { + body.master.children = [] + body.master.hasDefined = false + } else { + body.master.hasDefined = true + } + } + }, + { + event: "tick", + handler: ({ body }) => { + if (body.master.children != null) { + for (let instance of body.master.children) { + let deltaX = instance.x - body.master.x, + deltaY = instance.y - body.master.y, + distance = util.getDistance(instance, body) + angle = Math.atan2(deltaY, deltaX), + combinedRadii = instance.realSize + body.realSize; + body.master.velocity.x += 5 * Math.cos(angle) + body.master.velocity.y += 5 * Math.sin(angle) + if (combinedRadii * 1.3 > distance) { + body.master.children = [] + break + } + + } + } + if (body.master.control.fire) { + for (instance of entities) { + if (instance != body.master && instance.type == "wall" && util.getDistance(instance, { + x: body.master.control.target.x + body.master.x, + y: body.master.control.target.y + body.master.y + }) < instance.size * 1.3) { + if (body.master.children == 0) { + body.master.children.push(instance) + } + } + } + } + } + } + ] +}, + +Class.devtesttemplate = { + PARENT: "genericTank", + LABEL: "Single", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ] +}; +Class.speedoflight = { + PARENT: "genericTank", + LABEL: "SpeedOfLight", + DANGER: 7, + GUNS: [ + { + POSITION: [24, 4, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.acceltospeedoflight, { range: 999 }]), + TYPE: ["bullet", { MOTION_TYPE: "acceleratetothespeedoflight" }] + } + } + ] +}; +Class.maxStatTank = { + PARENT: ['genericTank'], + DANGER: 11, + BODY: { + ACCELERATION: base.ACCEL*2, + SPEED: base.SPEED*2, + HEALTH: base.HEALTH*2, + DAMAGE: base.DAMAGE*2, + PENETRATION: base.PENETRATION*2, + SHIELD: base.SHIELD*2, + REGEN: base.REGEN*2, + FOV: base.FOV*2, + DENSITY: base.DENSITY*2, + PUSHABILITY: 2, + HETERO: 6, + }, + SKILL_CAP: Array(10).fill(255), + SKILL: Array(10).fill(255), +} +Class.qlamgSpinnerTurret = { + PARENT: "genericTank", + LABEL: "Spinner Turret", + GUNS: [ + { + POSITION: [15, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.9], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, + ] +} +Class.quiteliterallyAMachineGun = { + PARENT: "genericTank", + LABEL: "Quite Literally a Motherfucking Machine Gun", + UPGRADE_COLOR: "red", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2 + }, + TURRETS: [ + { + POSITION: [10, 14, 0, 0, 0, 1], + TYPE: "qlamgSpinnerTurret" + }, { + POSITION: [5, 14, 0, 0, 0, 3], + TYPE: "lamgSpinnerTurret" + }, { + POSITION: [10, 14, 0, 0, 0, 2], + TYPE: "lamgSpinnerTurret" + } + ], + GUNS: [ + { + POSITION: [22, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [2, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun, g.op]), + TYPE: "bullet" + } + } + ] +} +Class.goofysatellite = { + LABEL: "Satellite", + TYPE: "bullet", + ACCEPTS_SCORE: false, + CONTROLLERS: ["orbit"], + DANGER: 2, + SHAPE: 0, + LAYER: 13, + BODY: { + PENETRATION: 1.2, + PUSHABILITY: 0.6, + ACCELERATION: 0.75, + HEALTH: 0.3, + DAMAGE: 3.375, + SPEED: 10, + RANGE: 10, + DENSITY: 0.03, + RESIST: 1.5, + FOV: 0.5, + }, + COLOR: 'nero', + DRAW_HEALTH: true, + CLEAR_ON_MASTER_UPGRADE: true, + BUFF_VS_FOOD: true, + DIE_AT_RANGE: true, +} + +Class.goofywhirlwind = { + PARENT: "genericTank", + LABEL: "Goofy Whirlwind", + ANGLE: 60, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "whirlwindDeco" + } + ], + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 5; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["goofysatellite", {ANGLE: i * 72}], + MAX_CHILDREN: 4, + AUTOFIRE: true, + SYNCS_SKILLS: false, + } + }) + } + return output + })() +} + +Class.pisseroo = { + PARENT: ['basic'], + LABEL: 'Winsor', + UPGRADES_TIER_0: [], + RESET_UPGRADE_MENU: true, + ON: [ + { + event: "fire", + handler: ({ body, globalMasterStore: store, gun }) => { + if (gun.identifier != 'pisserooGun') return + store.pisseroo_i ??= 0; + store.pisseroo_i++; + store.pisseroo_i %= 4; + body.define(Class.winsor0.UPGRADES_TIER_0[store.pisseroo_i]); + setTimeout(() => body.define("pisseroo"), 3000); + } + } + ], + GUNS: [{ + POSITION: {}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: 'bullet', + IDENTIFIER: 'pisserooGun' + } + }] +} +Class.adsfoipuasdfiopu = { + PARENT: "genericTank", + LABEL: "Random tank i made in music class because i can", + UPGRADE_TOOLTIP: "send this * to the penis explosion chamber and have his penis exploded immediately", + GUNS: [{ + POSITION: [21, 10, 0, 0, 1, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.op]), + TYPE: "bullet" + } + } + ] +} +Class.adsfoipuasdfiopu.UPGRADE_COLOR = "animatednero", +Class.adsfoipuasdfiopu2 = { + PARENT: "genericTank", + LABEL: "Random tank i made on the bus because i can", + UPGRADE_TOOLTIP: "send this non-* to the asshole explosion chamber and have his ashole exploded immediately", + GUNS: [{ + POSITION: [21, 0, 0, 0, 1, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.op]), + TYPE: "bullet" + } + }, { + POSITION: [17, 0, 0, 0, 2, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.op]), + TYPE: "bee", + MAX_CHILDREN: 30, + } + } + ] +} +Class.adsfoipuasdfiopu2.UPGRADE_COLOR = "animatednero", +//wait whats stuff +Class.placeableWall = { + PARENT: "rock", + LABEL: "Wall", + SIZE: 30, + SHAPE: 4, + CLEAR_ON_MASTER_UPGRADE: false, + TEAM: TEAM_ENEMIES, + VARIES_IN_SIZE: false, +}; +Class.placeableWallSmall = { + PARENT: "rock", + LABEL: "Wall", + SIZE: 15, + SHAPE: 4, + CLEAR_ON_MASTER_UPGRADE: false, + TEAM: TEAM_ENEMIES, + VARIES_IN_SIZE: false, +}; +Class.wallPlacerThing = { + PARENT: "genericTank", + SHAPE:0, + MIRROR_MASTER_ANGLE: true, + INTANGIBLE: true, + DRAW_SELF: false, + COLOR: 16, + CLEAR_ON_MASTER_UPGRADE: false, + BODY: { + ACCELERATION: 0.1, + SPEED: true, + HEALTH: 340282366920938463463374607431768211455, + RESIST: 1, + SHIELD: 340282366920938463463374607431768211455, + REGEN: 340282366920938463463374607431768211455, + DAMAGE: false, + PENETRATION: true, + RANGE: true, + FOV: true, + SHOCK_ABSORB: 340282366920938463463374607431768211455, + RECOIL_MULTIPLIER: false, + DENSITY: 340282366920938463463374607431768211455, + STEALTH: true, + PUSHABILITY: false, + HETERO: false, + }, + MOTION_TYPE: "aimassist", + GUNS: [ + { + POSITION: [0, 20, 1, 10, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([{reload:10, speed:0, maxSpeed:0, shudder:0.0001, spray:0.0001}]), + TYPE: "placeableWall", + COLOR: 16, + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 0, + ALT_FIRE: false, + NEGATIVE_RECOIL: false, + DRAW_FILL:false, + BORDERLESS:true, + }, + }, + ], + +}; +Class.wallPlacer = { + PARENT: "genericTank", + LABEL: "Messin' Around", + BODY: { + ACCELERATION: base.ACCEL * 1, + SPEED: base.SPEED * 1, + HEALTH: base.HEALTH * 1, + DAMAGE: base.DAMAGE * 1, + PENETRATION: base.PENETRATION * 1, + SHIELD: base.SHIELD * 1, + REGEN: base.REGEN * 1, + FOV: base.FOV * 1, + DENSITY: base.DENSITY * 1, + PUSHABILITY: 1, + HETERO: 3, + }, + GUNS: [ + { + POSITION: [16, 20, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic,{reload:1/8}]), + TYPE: "wallPlacerThing", + COLOR: 16, + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 1, + ALT_FIRE: false, + NEGATIVE_RECOIL: false, + }, + }, + ], +}; +Class.legacysidewinder = { + PARENT: "genericTank", + LABEL: "Sidewinder", + DANGER: 7, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.3 * base.FOV, + }, + GUNS: [ + { + POSITION: [10, 11, -0.5, 14, 0, 0, 0], + }, + { + POSITION: [21, 12, -1.1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder]), + TYPE: "oldsnake", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + ], +} +Class.imagetest = { + PARENT: "genericTank", + UPGRADE_COLOR: "black", + LABEL: "PapyrusButBlackHoleOfDeath.exe", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "spaghetti" + } + } + ], + ON: [ + { + event: "damage", + handler: ({ body, damageInflictor, damageTool }) => { + damageTool[0].kill() + } + }, + { + event: "tick", + handler: ({ body }) => { + for (let instance of entities) { + let diffX = instance.x - body.x, + diffY = instance.y - body.y, + dist2 = diffX ** 2 + diffY ** 2, + number1 = 1, + number2 = 1, + number3 = 1/7, + number4 = 1, + number5 = 1, + distance = 250, + forceMulti = (((((body.size / 12)*250) ** 2)** number1) * number2) / dist2; + if (dist2 <= ((body.size / 12)*250) ** 2) { + if (instance.id != body.id /*&& !instance.ac && instance.alpha*/) { + instance.velocity.x += util.clamp(body.x - instance.x, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 + instance.velocity.y += util.clamp(body.y - instance.y, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 + } + } + if (dist2 < body.size ** 2 + instance.size ** 2) { + if (instance.id != body.id) { + instance.isProtected = false; + instance.invuln = false; + instance.damageReceived = Infinity, + instance.kill(), + instance.destroy(), + instance.removeFromGrid(), + instance.isGhost = true; + } + } + } + } + }, + ], +} +Class.papyrus = { + PARENT: "genericTank", + LABEL: "Papyrus", + UPGRADE_COLOR: 23, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "spaghetti" + } + } + ] +} +Class.oppenheimer = { + PARENT: "genericTank", + LABEL: "Oppen Heimer", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "nuke" + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ] +} +Class.homingdevbullet = { + PARENT: "bullet", + TYPE: "swarm", + SHAPE: [[-1, -1], [1, -1], [2, 0], [1, 1], [-1, 1]], + ACCEPTS_SCORE: false, + MOTION_TYPE: "swarm", + CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], + BUFF_VS_FOOD: true, + AI: { + FARMER: true + }, + INDEPENDENT: true +} +Class.homingdev = { + PARENT: "developer", + LABEL: "Homing Developer", + GUNS: [ + { + POSITION: [18, 10, -1.4, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.op]), + TYPE: "homingdevbullet" + } + } + ] +} +Class.brella = { + PARENT: "genericTank", + LABEL: "Nero-Brella", + DANGER: 7, + SYNC_TURRET_SKILLS: true, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [1, 10, 0, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.brella]), + TYPE: "brellaShield", + ALT_FIRE: true, + MAX_CHILDREN: 1, + //ALPHA: 1 + } + }] +}; +Class.winsor0 = { + PARENT: "genericTank", + LABEL: "Wi3nsor", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} + +Class.winsor1 = { + PARENT: "genericTank", + LABEL: "Winsor has no Friends 🧐", + SIZE: 30, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144411762_LAYER.jpg?v=1701714034323', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +Class.winsor2 = { + PARENT: "genericTank", + LABEL: "Winsor has no Brain 🧐🧐", + SIZE: 30, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144409218_LAYER.jpg?v=1701714037274', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +Class.winsor3 = { + PARENT: "genericTank", + LABEL: "Winsor has no Muscle 🧐🧐🧐", + SIZE: 30, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144406913_LAYER.jpg?v=1701714040278', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +Class.winsor4 = { + PARENT: "genericTank", + LABEL: "And Winsor certainly, has no Bitches 🧐🧐🧐🧐", + SIZE: 30, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144358408_LAYER.jpg?v=1701714043765', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} + +Class.utilities = { + PARENT: "genericTank", + LABEL: "Utilities", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381' +}; +Class.AIT = menu("AIT") + +Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons"] + Class.tanks.UPGRADES_TIER_0 = ["developer", "overpowered", "testing", "unavailable", "features"] + Class.AIT.UPGRADES_TIER_0 = ["developer", "bosses", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun", "arenaCloser"] + Class.utilities.UPGRADES_TIER_0 = ["developer", "levels", "teams", "eggGenerator", "spectator", "wallPlacer"] + Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "flail", "doubleFlail", "winsor0", "legacysidewinder"] + //Class.flail.UPGRADES_TIER_2 = ["doubleFlail"] + Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] + Class.testing.UPGRADES_TIER_0 = ["tanks", "vanquisher", "mummifier", "tracker3", ["grappletest", "basic"], "brella"] + Class.dominators.UPGRADES_TIER_0 = ["AIT", "destroyerDominator", "gunnerDominator", "trapperDominator"] + Class.sanctuaries.UPGRADES_TIER_0 = ["AIT", "sanctuaryTier1", "sanctuaryTier2", "sanctuaryTier3", "sanctuaryTier4", "sanctuaryTier5", "sanctuaryTier6"] + + Class.bosses.UPGRADES_TIER_0 = ["AIT", "sentries", "elites", "mysticals", "nesters", "rogues", "rammers", "terrestrials", "celestials", "eternals", "devBosses"] + Class.sentries.UPGRADES_TIER_0 = ["bosses", "sentrySwarm", "sentryGun", "sentryTrap", "shinySentrySwarm", "shinySentryGun", "shinySentryTrap", "sentinelMinigun", "sentinelLauncher", "sentinelCrossbow"] + Class.elites.UPGRADES_TIER_0 = ["bosses", "eliteDestroyer", "eliteGunner", "eliteSprayer", "eliteBattleship", "eliteSpawner", "eliteTrapGuard", "eliteSpinner", "eliteSkimmer", "legionaryCrasher", "guardian", "defender", "sprayerLegion"] + Class.mysticals.UPGRADES_TIER_0 = ["bosses", "sorcerer", "summoner", "enchantress", "exorcistor", "shaman"] + Class.nesters.UPGRADES_TIER_0 = ["bosses", "nestKeeper", "nestWarden", "nestGuardian"] + Class.rogues.UPGRADES_TIER_0 = ["bosses", "roguePalisade", "rogueArmada", "julius", "genghis", "napoleon"] + Class.rammers.UPGRADES_TIER_0 = ["bosses", "bob", "nemesis"] + Class.terrestrials.UPGRADES_TIER_0 = ["bosses", "ares", "gersemi", "ezekiel", "eris", "selene"] + Class.celestials.UPGRADES_TIER_0 = ["bosses", "paladin", "freyja", "zaphkiel", "nyx", "theia", "atlas", "rhea", "julius", "genghis", "napoleon"] + Class.eternals.UPGRADES_TIER_0 = ["bosses", "odin", "kronos"] + Class.devBosses.UPGRADES_TIER_0 = ["taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss"] + + Class.features.UPGRADES_TIER_0 = ["tanks", "diamondShape", "rotatedTrap", "colorMan", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "switcheroo", ["developer", "developer"]] + Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight"] + Class.goofytanks.UPGRADES_TIER_0 = ["overpowered", "pisseroo", "papyrus", "Trapper_guy", "watertank", "piszerbeam", "baseThrowerDelta", "pouner", "adsfoipuasdfiopu", "goofywhirlwind"] - Class.testing.UPGRADES_TIER_0 = ["diamondShape", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] + //the "winsor" tank needs this to function, it worked before the "ON" thing was added + Class.winsor0.UPGRADES_TIER_0 = ["winsor1", "winsor2", "winsor3", "winsor4"] + Class.papyrus.UPGRADES_TIER_0 = ["imagetest"] + Class.adsfoipuasdfiopu.UPGRADES_TIER_0 = ["adsfoipuasdfiopu2"] \ No newline at end of file diff --git a/server/modules/definitions/groups/food.js b/server/modules/definitions/groups/food.js index ffaa8cb09..edafbcfe2 100644 --- a/server/modules/definitions/groups/food.js +++ b/server/modules/definitions/groups/food.js @@ -3,7 +3,6 @@ const { basePolygonDamage, basePolygonHealth } = require('../constants.js'), // Code by Damocles (https://discord.com/channels/366661839620407297/508125275675164673/1090010998053818488) // Albeit heavily modified because the math in the original didn't work LOL makeRelic = (type, scale = 1, gem, SIZE) => { - type = ensureIsClass(type); let relicCasing = { PARENT: 'genericEntity', LABEL: 'Relic Casing', @@ -103,33 +102,29 @@ makeCrasher = type => ({ } }), -makeRare = (type, level) => { - type = ensureIsClass(type); - return { - PARENT: "food", - LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Transgender"][level] + " " + type.LABEL, - VALUE: [100, 500, 2000, 4000, 5000][level] * type.VALUE, - SHAPE: type.SHAPE, - SIZE: type.SIZE + level, - COLOR: ["lightGreen", "teal", "pureBlack", "rainbow", "trans"][level], - ALPHA: level == 2 ? 0.25 : 1, - BODY: { - DAMAGE: type.BODY.DAMAGE + level, - DENSITY: type.BODY.DENSITY + level, - HEALTH: [10, 20, 40, 80, 100][level] * type.BODY.HEALTH, - PENETRATION: type.BODY.PENETRATION + level, - ACCELERATION: type.BODY.ACCELERATION - }, - DRAW_HEALTH: true, - INTANGIBLE: false, - GIVE_KILL_MESSAGE: true, - } -}, +makeRare = (type, level) => ({ + PARENT: "food", + LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Transgender"][level] + " " + type.LABEL, + VALUE: [100, 500, 2000, 4000, 5000][level] * type.VALUE, + SHAPE: type.SHAPE, + SIZE: type.SIZE + level, + COLOR: ["lightGreen", "teal", "pureBlack", "rainbow", "animatedTrans"][level], + ALPHA: level == 2 ? 0.25 : 1, + BODY: { + DAMAGE: type.BODY.DAMAGE + level, + DENSITY: type.BODY.DENSITY + level, + HEALTH: [10, 20, 40, 80, 100][level] * type.BODY.HEALTH, + PENETRATION: type.BODY.PENETRATION + level, + ACCELERATION: type.BODY.ACCELERATION + }, + DRAW_HEALTH: true, + INTANGIBLE: false, + GIVE_KILL_MESSAGE: true, +}), lerp = (a, b, t) => a + (b - a) * t, makeLaby = (type, level) => { - type = ensureIsClass(type); let usableSHAPE = Math.max(type.SHAPE, 3), downscale = Math.cos(Math.PI / usableSHAPE), strenghtMultiplier = 6 ** level; @@ -162,7 +157,7 @@ makeLaby = (type, level) => { // EGGS Class.egg = { - PARENT: "food", + PARENT: ["food"], LABEL: "Egg", VALUE: 10, SHAPE: 0, @@ -179,7 +174,7 @@ Class.egg = { DRAW_HEALTH: false, }; Class.gem = { - PARENT: "food", + PARENT: ["food"], LABEL: "Gem", VALUE: 2e3, SHAPE: 6, @@ -199,7 +194,7 @@ Class.gem = { GIVE_KILL_MESSAGE: true, }; Class.jewel = { - PARENT: "food", + PARENT: ["food"], LABEL: "Jewel", VALUE: 1e5, SHAPE: 6, @@ -218,15 +213,15 @@ Class.jewel = { INTANGIBLE: false, GIVE_KILL_MESSAGE: true, }; -Class.shinyEgg = makeRare("egg", 0); -Class.legendaryEgg = makeRare("egg", 1); -Class.shadowEgg = makeRare("egg", 2); -Class.rainbowEgg = makeRare("egg", 3); -Class.transEgg = makeRare("egg", 4); //ironic +Class.shinyEgg = makeRare(Class.egg, 0); +Class.legendaryEgg = makeRare(Class.egg, 1); +Class.shadowEgg = makeRare(Class.egg, 2); +Class.rainbowEgg = makeRare(Class.egg, 3); +Class.transEgg = makeRare(Class.egg, 4); //ironic // SQUARES Class.square = { - PARENT: "food", + PARENT: ["food"], LABEL: "Square", VALUE: 30, SHAPE: 4, @@ -242,15 +237,15 @@ Class.square = { DRAW_HEALTH: true, INTANGIBLE: false, }; -Class.shinySquare = makeRare("square", 0); -Class.legendarySquare = makeRare("square", 1); -Class.shadowSquare = makeRare("square", 2); -Class.rainbowSquare = makeRare("square", 3); -Class.transSquare = makeRare("square", 4); +Class.shinySquare = makeRare(Class.square, 0); +Class.legendarySquare = makeRare(Class.square, 1); +Class.shadowSquare = makeRare(Class.square, 2); +Class.rainbowSquare = makeRare(Class.square, 3); +Class.transSquare = makeRare(Class.square, 4); // TRIANGLES Class.triangle = { - PARENT: "food", + PARENT: ["food"], LABEL: "Triangle", VALUE: 120, SHAPE: 3, @@ -266,15 +261,15 @@ Class.triangle = { }, DRAW_HEALTH: true, }; -Class.shinyTriangle = makeRare("triangle", 0); -Class.legendaryTriangle = makeRare("triangle", 1); -Class.shadowTriangle = makeRare("triangle", 2); -Class.rainbowTriangle = makeRare("triangle", 3); -Class.transTriangle = makeRare("triangle", 4); +Class.shinyTriangle = makeRare(Class.triangle, 0); +Class.legendaryTriangle = makeRare(Class.triangle, 1); +Class.shadowTriangle = makeRare(Class.triangle, 2); +Class.rainbowTriangle = makeRare(Class.triangle, 3); +Class.transTriangle = makeRare(Class.triangle, 4); // PENTAGONS Class.pentagon = { - PARENT: "food", + PARENT: ["food"], LABEL: "Pentagon", VALUE: 400, SHAPE: 5, @@ -290,15 +285,15 @@ Class.pentagon = { }, DRAW_HEALTH: true, }; -Class.shinyPentagon = makeRare("pentagon", 0); -Class.legendaryPentagon = makeRare("pentagon", 1); -Class.shadowPentagon = makeRare("pentagon", 2); -Class.rainbowPentagon = makeRare("pentagon", 3); -Class.transPentagon = makeRare("pentagon", 4); +Class.shinyPentagon = makeRare(Class.pentagon, 0); +Class.legendaryPentagon = makeRare(Class.pentagon, 1); +Class.shadowPentagon = makeRare(Class.pentagon, 2); +Class.rainbowPentagon = makeRare(Class.pentagon, 3); +Class.transPentagon = makeRare(Class.pentagon, 4); // BETA PENTAGONS Class.betaPentagon = { - PARENT: "food", + PARENT: ["food"], LABEL: "Beta Pentagon", VALUE: 2500, SHAPE: 5, @@ -317,15 +312,15 @@ Class.betaPentagon = { DRAW_HEALTH: true, GIVE_KILL_MESSAGE: true, }; -Class.shinyBetaPentagon = makeRare("betaPentagon", 0); -Class.legendaryBetaPentagon = makeRare("betaPentagon", 1); -Class.shadowBetaPentagon = makeRare("betaPentagon", 2); -Class.rainbowBetaPentagon = makeRare("betaPentagon", 3); -Class.transBetaPentagon = makeRare("betaPentagon", 4); +Class.shinyBetaPentagon = makeRare(Class.betaPentagon, 0); +Class.legendaryBetaPentagon = makeRare(Class.betaPentagon, 1); +Class.shadowBetaPentagon = makeRare(Class.betaPentagon, 2); +Class.rainbowBetaPentagon = makeRare(Class.betaPentagon, 3); +Class.transBetaPentagon = makeRare(Class.betaPentagon, 4); // ALPHA PENTAGONS Class.alphaPentagon = { - PARENT: "food", + PARENT: ["food"], LABEL: "Alpha Pentagon", VALUE: 15e3, SHAPE: 5, @@ -344,15 +339,15 @@ Class.alphaPentagon = { DRAW_HEALTH: true, GIVE_KILL_MESSAGE: true, }; -Class.shinyAlphaPentagon = makeRare("alphaPentagon", 0); -Class.legendaryAlphaPentagon = makeRare("alphaPentagon", 1); -Class.shadowAlphaPentagon = makeRare("alphaPentagon", 2); -Class.rainbowAlphaPentagon = makeRare("alphaPentagon", 3); -Class.transAlphaPentagon = makeRare("alphaPentagon", 4); +Class.shinyAlphaPentagon = makeRare(Class.alphaPentagon, 0); +Class.legendaryAlphaPentagon = makeRare(Class.alphaPentagon, 1); +Class.shadowAlphaPentagon = makeRare(Class.alphaPentagon, 2); +Class.rainbowAlphaPentagon = makeRare(Class.alphaPentagon, 3); +Class.transAlphaPentagon = makeRare(Class.alphaPentagon, 4); // HEXAGONS Class.hexagon = { - PARENT: "food", + PARENT: ["food"], LABEL: "Hexagon", VALUE: 500, SHAPE: 6, @@ -369,15 +364,15 @@ Class.hexagon = { }, DRAW_HEALTH: true, }; -Class.shinyHexagon = makeRare("hexagon", 0); -Class.legendaryHexagon = makeRare("hexagon", 1); -Class.shadowHexagon = makeRare("hexagon", 2); -Class.rainbowHexagon = makeRare("hexagon", 3); -Class.transHexagon = makeRare("hexagon", 4); +Class.shinyHexagon = makeRare(Class.hexagon, 0); +Class.legendaryHexagon = makeRare(Class.hexagon, 1); +Class.shadowHexagon = makeRare(Class.hexagon, 2); +Class.rainbowHexagon = makeRare(Class.hexagon, 3); +Class.transHexagon = makeRare(Class.hexagon, 4); // 3D POLYGONS Class.sphere = { - PARENT: "food", + PARENT: ["food"], LABEL: "The Sphere", FACING_TYPE: "noFacing", VALUE: 1e7, @@ -418,7 +413,7 @@ Class.sphere = { }] }; Class.cube = { - PARENT: "food", + PARENT: ["food"], LABEL: "The Cube", VALUE: 2e7, SIZE: 10, @@ -437,7 +432,7 @@ Class.cube = { GIVE_KILL_MESSAGE: true, }; Class.tetrahedron = { - PARENT: "food", + PARENT: ["food"], LABEL: "The Tetrahedron", VALUE: 3e7, SIZE: 12, @@ -455,7 +450,7 @@ Class.tetrahedron = { GIVE_KILL_MESSAGE: true }; Class.octahedron = { - PARENT: "food", + PARENT: ["food"], LABEL: "The Octahedron", VALUE: 4e7, SIZE: 13, @@ -473,7 +468,7 @@ Class.octahedron = { GIVE_KILL_MESSAGE: true }; Class.dodecahedron = { - PARENT: "food", + PARENT: ["food"], LABEL: "The Dodecahedron", VALUE: 5e7, SIZE: 18, @@ -491,7 +486,7 @@ Class.dodecahedron = { GIVE_KILL_MESSAGE: true, }; Class.icosahedron = { - PARENT: "food", + PARENT: ["food"], LABEL: "The Icosahedron", VALUE: 1e8, SIZE: 20, @@ -529,17 +524,17 @@ for (let [gemColor, name] of [ } } - Class[name + "EggRelic"] = makeRelic("egg", 0.5, gem, 7); - Class[name + "SquareRelic"] = makeRelic("square", 1, gem); - Class[name + "TriangleRelic"] = makeRelic("triangle", 1.45, gem); - Class[name + "PentagonRelic"] = makeRelic("pentagon", -0.6, gem); - Class[name + "BetaPentagonRelic"] = makeRelic("betaPentagon", -0.6, gem); - Class[name + "AlphaPentagonRelic"] = makeRelic("alphaPentagon", -0.6, gem); + Class[name + "EggRelic"] = makeRelic(Class.egg, 0.5, gem, 7); + Class[name + "SquareRelic"] = makeRelic(Class.square, 1, gem); + Class[name + "TriangleRelic"] = makeRelic(Class.triangle, 1.45, gem); + Class[name + "PentagonRelic"] = makeRelic(Class.pentagon, -0.6, gem); + Class[name + "BetaPentagonRelic"] = makeRelic(Class.betaPentagon, -0.6, gem); + Class[name + "AlphaPentagonRelic"] = makeRelic(Class.alphaPentagon, -0.6, gem); } // 4D Class.tesseract = { - PARENT: "food", + PARENT: ["food"], LABEL: "The Tesseract", VALUE: 42e7, SIZE: 25, diff --git a/server/modules/definitions/groups/generics.js b/server/modules/definitions/groups/generics.js index 2a84838cc..2fd4e9f0a 100644 --- a/server/modules/definitions/groups/generics.js +++ b/server/modules/definitions/groups/generics.js @@ -138,6 +138,12 @@ Class.genericSmasher = { DENSITY: 2 * base.DENSITY } } +Class.genericLancer = { + PARENT: "genericTank", + DANGER: 6, + SKILL_CAP: [dfltskl, dfltskl, dfltskl, dfltskl, 0, dfltskl, dfltskl, dfltskl, dfltskl, dfltskl], + STAT_NAMES: statnames.lancer, +} Class.genericBoss = { PARENT: "genericTank", TYPE: "miniboss", @@ -236,7 +242,6 @@ Class.drone = { CLEAR_ON_MASTER_UPGRADE: true, BUFF_VS_FOOD: true, }; - Class.swarm = { LABEL: "Swarm Drone", TYPE: "swarm", @@ -262,7 +267,6 @@ Class.swarm = { DIE_AT_RANGE: true, BUFF_VS_FOOD: true, }; - Class.trap = { LABEL: "Thrown Trap", TYPE: "trap", @@ -357,3 +361,10 @@ Class.auraSymbol = { COLOR: "teal", SHAPE: [[-0.598,-0.7796],[-0.3817,-0.9053],[0.9688,-0.1275],[0.97,0.125],[-0.3732,0.9116],[-0.593,0.785]] }; +Class.rangeAuraSymbol = { + PARENT: "genericTank", + CONTROLLERS: [["spin", {speed: -0.04}]], + INDEPENDENT: true, + COLOR: "teal", + SHAPE: "M -0.7671 0.6521 L -0.7671 -0.6521 L -0.6521 -0.7671 L -0.6521 -0.7671 L 0.6521 -0.7671 L 0.7671 -0.6521 L 0.7671 0.6521 L 0.6521 0.7671 L -0.6521 0.7671 L -0.7671 0.6521" +}; \ No newline at end of file diff --git a/server/modules/definitions/groups/misc.js b/server/modules/definitions/groups/misc.js index d868c7879..41ef0c754 100644 --- a/server/modules/definitions/groups/misc.js +++ b/server/modules/definitions/groups/misc.js @@ -46,6 +46,17 @@ Class.wall = { SHAPE: "M 1 1 L -1 1 L -1 -1 L 1 -1 Z", VARIES_IN_SIZE: false } +Class.dfxwall = { + PARENT: "rock", + LABEL: "Wall", + SIZE: 25, + SHAPE: "M 1 1 L -1 1 L -1 -1 L 1 -1 Z", + VARIES_IN_SIZE: false, + TURRETS: [{ + POSITION: [7, -5, -5, 0, 0, 3], + TYPE: "dfxskin" + },] +} Class.moon = { PARENT: "rock", LABEL: "Moon", @@ -221,7 +232,7 @@ for (let tier of sancTiers) { }, { POSITION: {LENGTH: 1.5, WIDTH: 4, ASPECT: 1.7, X: 12, ANGLE: (360/tier)*i}, PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, {shudder: 0.15, speed: 0.8, health: 3, reload: 1.5}]), + SHOOT_SETTINGS: combineStats([g.trap, {shudder: 0.15, spray: 1.2, speed: 0.8, reload: 1.5}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, AUTOFIRE: true, @@ -269,7 +280,7 @@ Class.crasher = { DRAW_HEALTH: true, }; Class.crasherSpawner = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Spawned", STAT_NAMES: statnames.drone, CONTROLLERS: ["nearestDifferentMaster"], @@ -343,7 +354,7 @@ Class.sentry = { GIVE_KILL_MESSAGE: true, }; Class.sentrySwarm = { - PARENT: "sentry", + PARENT: ["sentry"], UPGRADE_LABEL: "Swarm Sentry", UPGRADE_COLOR: "pink", GUNS: [ @@ -357,18 +368,18 @@ Class.sentrySwarm = { }, ], }; -Class.sentryGun = makeAuto("sentry", "Sentry", { +Class.sentryGun = makeAuto(Class.sentry, "Sentry", { type: "megaAutoTankGun", size: 12, }); Class.sentryGun.UPGRADE_LABEL = "Gun Sentry"; -Class.sentryTrap = makeAuto("sentry", "Sentry", { +Class.sentryTrap = makeAuto(Class.sentry, "Sentry", { type: "trapTurret", size: 12, }); Class.sentryTrap.UPGRADE_LABEL = "Trap Sentry"; Class.shinySentry = { - PARENT: "sentry", + PARENT: ["sentry"], COLOR: "lightGreen", UPGRADE_COLOR: "lightGreen", DANGER: 4, @@ -380,7 +391,7 @@ Class.shinySentry = { }, }; Class.shinySentrySwarm = { - PARENT: "shinySentry", + PARENT: ["shinySentry"], UPGRADE_LABEL: "Shiny Swarm Sentry", UPGRADE_COLOR: "lightGreen", GUNS: [ @@ -394,12 +405,12 @@ Class.shinySentrySwarm = { }, ], }; -Class.shinySentryGun = makeAuto("shinySentry", "Sentry", { +Class.shinySentryGun = makeAuto(Class.shinySentry, "Sentry", { type: Class.artilleryAutoTankgun, size: 12, }); Class.shinySentryGun.UPGRADE_LABEL = "Shiny Gun Sentry"; -Class.shinySentryTrap = makeAuto("shinySentry", "Sentry", { +Class.shinySentryTrap = makeAuto(Class.shinySentry, "Sentry", { type: "barricadeTurret", size: 12, }); @@ -407,7 +418,7 @@ Class.shinySentryTrap.UPGRADE_LABEL = "Shiny Trap Sentry"; // SENTINELS (by ranar) Class.sentinel = { - PARENT: "genericTank", + PARENT: ["genericTank"], TYPE: "crasher", LABEL: "Sentinel", DANGER: 7, @@ -555,7 +566,7 @@ Class.sentinelMinigun = { // MISCELLANEOUS TANKS Class.baseProtector = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Base", UPGRADE_LABEL: "Base Protector", ON_MINIMAP: false, @@ -824,5 +835,4 @@ Class.bot = { Class.tagMode = { PARENT: "bullet", LABEL: "Players", - SHAPE: "" -}; +}; \ No newline at end of file diff --git a/server/modules/definitions/groups/projectiles.js b/server/modules/definitions/groups/projectiles.js index f4eddd911..6ffbbdfb4 100644 --- a/server/modules/definitions/groups/projectiles.js +++ b/server/modules/definitions/groups/projectiles.js @@ -1,4 +1,4 @@ -const { combineStats, makeAuto } = require('../facilitators.js'); +const { combineStats, makeAuto, makeHybrid } = require('../facilitators.js'); const { gunCalcNames, base } = require('../constants.js'); const g = require('../gunvals.js'); @@ -49,15 +49,15 @@ Class.superSplitterBullet = { } Class.turretedBullet = makeAuto('bullet', "Auto-Bullet", {size: 14, color: "veryLightGrey", angle: 0}); Class.speedBullet = { - PARENT: "bullet", + PARENT: ["bullet"], MOTION_TYPE: "accel", } Class.growBullet = { - PARENT: "bullet", + PARENT: ["bullet"], MOTION_TYPE: "grow", } Class.flare = { - PARENT: "growBullet", + PARENT: ["growBullet"], LABEL: "Flare", SHAPE: 4, } @@ -278,7 +278,7 @@ Class.hive = { ], } Class.protoHive = { - PARENT: "bullet", + PARENT: ["bullet"], LABEL: "Proto-Hive", BODY: { RANGE: 90, @@ -456,7 +456,7 @@ Class.surgeonPillbox = { // Drones Class.turretedDrone = makeAuto('drone', "Auto-Drone", {type: 'droneAutoTurret'}) Class.gemDrone = { - PARENT: "drone", + PARENT: ["drone"], COLOR: "aqua", DRAW_HEALTH: true, SHAPE: 6, @@ -743,3 +743,414 @@ Class.homingBullet = { }, CAN_GO_OUTSIDE_ROOM: true } + +//delta projectiles +Class.autobullet = makeAuto('bullet', "AutoBullet", {type: 'projectileAutoTurret'}) +Class.heavyautobullet = makeAuto('bullet', "HeavyAutoBullet", {type: 'pillboxTurret'}) +Class.shrapnel = { + PARENT: "bullet", + SHAPE: 5, + LABEL: "expold heheahah", + BODY: { + RANGE: 1, + FOV: 0.5, + }, + INDEPENDENT: true, + CONTROLLERS: ["alwaysFire"], + AI: { + NO_LEAD: true, + }, + GUNS: [ + { + POSITION: [7, 9.5, 1, 7, 0, 72, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfspeed, g.halfrange, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 9.5, 1, 7, 0, 72*2, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 9.5, 1, 7, 0, 72*3, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 9.5, 1, 7, 0, 72*4, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 9.5, 1, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], +} +Class.grenade = { + PARENT: "bullet", + INDEPENDENT: true, + BODY: { RANGE: 80 }, + GUNS: [{ + POSITION: [1, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.grenade_explosion]), + TYPE: ["shrapnel", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + } + }, { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, { reload: 0.5 }, g.lowPower, { recoil: 1.35 }, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + } + } + ], + TURRETS: [{ + POSITION: [9, -8, 0, 0, 0, 1], + TYPE: ["grenadeDeco"] + } + ] +} +Class.firecrackerbomb = { + PARENT: "bullet", + INDEPENDENT: true, + BODY: { RANGE: 70 }, + GUNS: [{ + POSITION: [1, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.explosion]), + TYPE: ["growBullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + } + }, { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0.5 }, g.lowPower]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: "firecrackerDeco" + }] +} +Class.baseBullet = { + PARENT: "boomerang", + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + CONTROLLERS: [["spin", { independent: true, speed: 0.1 }]], + INDEPENDENT: true, + COLOR: "orange", + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["revogun", { COLOR: "orange", BODY: { FOV: 2 } }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["revogun", { COLOR: "orange", BODY: { FOV: 2 } }] + }], +ON: [{ + event: "death", + handler: ({ body }) => { + if (!body.master.isDead) return + body.master.define(Class.baseThrower) + } + } + ] +}; +Class.brellaShield = { + PARENT: "bullet", + TYPE: "brella", + LABEL: "Base", + SIZE: 7, + //SHAPE: 'M 1 3.5 L 2 2 L 2 0 L 1 -1.5 L 0 -1.8 L 0 -1 L 2 0.5 L 0 -1 L 0 0 L 2 0.85 L 0 0 L 0 1 L 2 1 L 0 1 L 0 1 L 0 2 L 2 1.15 L 0 2 L 0 3 L 2 1.5 L 0 3 L 0 3.8 L 1 3.5', + SHAPE: 'M -0 2.2587 L 0.9 0.905 L 0.9 -0.9 L -0 -2.2537 L -0.9 -2.5245 L -0.9 2.5295 L -0 2.2587', + INDEPENDENT: true, + COLOR: "grey", + GUNS: [ + { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0.35 }, g.lowPower]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], +}; +Class.laser = { + PARENT: ["bullet"], + SHAPE: -1, + BODY: { + PENETRATION: 1.15, + SPEED: 5.8, + RANGE: 100, + DENSITY: 0.9, + HEALTH: 0.155, + DAMAGE: 5.6, + }, + BUFF_VS_FOOD: true, +} +Class.fastdrone = { + PARENT: "drone", + LABEL: 'Drone', + BODY: { + PENETRATION: 1.2, + PUSHABILITY: 0.6, + ACCELERATION: 0.05, + HEALTH: 0.5, + DAMAGE: 3.125, + SPEED: 6, + RANGE: 200, + DENSITY: 0.03, + RESIST: 1.5, + FOV: 0.8, + }, + GUNS: [ { /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [ 15, 5, 1, 0, 0, 180, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.muchmorerecoil, g.muchmorerecoil, g.weak]), + TYPE: "bullet", + AUTOFIRE: true + }, }, + ], + HITS_OWN_TYPE: 'hard', + DRAW_HEALTH: false, + CLEAR_ON_MASTER_UPGRADE: true, + BUFF_VS_FOOD: true, +}; + +Class.revoorbitdrone = { + PARENT: "drone", + LABEL: 'Drone', + SYNC_TURRET_SKILLS: true, + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "droneturretBase", + }, + ], +}; +Class.hiveprobe = { + PARENT: "genericTank", + LABEL: "Probe", + TYPE: "drone", + HITS_OWN_TYPE: "hardWithBuffer", + DRAW_HEALTH: true, + BODY: { + FOV: 0.5, + SPEED: 3, + ACCELERATION: 0.4, + HEALTH: 2.5, + SHIELD: 0, + DAMAGE: 1.2, + RESIST: 1, + PENETRATION: 1, + DENSITY: 0.4 + }, + AI: { + BLIND: true + }, + CLEAR_ON_MASTER_UPGRADE: true, + GIVE_KILL_MESSAGE: false, + ACCEPTS_SCORE: false, + CONTROLLERS: [ + "nearestDifferentMaster", + "mapAltToFire", + "minion", + "canRepel", + "hangOutNearMaster" + ], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower]), + TYPE: "bullet" + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [27, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; +Class.clonerprobe = { + PARENT: "hiveprobe", + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower]), + TYPE: "bullet" + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [24, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +} +Class.autoclonerprobe = makeAuto(Class.clonerprobe) +Class.spaghetti = { + PARENT: "bullet", + SHOOT_ON_DEATH: true, + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg?v=1701450288242", + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +const timer = (run, duration) => { + let timer = setInterval(() => run(), 31.25); + setTimeout(() => { + clearInterval(timer); + }, duration * 1000); +}; + const damageOnTick = (body, instance, multiplier, duration, stopAtSetHealth, hitsOwnTeam) => { + if (!instance) return + if (!instance.damageOnTicking && !instance.godmode && !instance.invuln && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) { + instance.damageOnTicking = true; + setTimeout(() => { + instance.damageOnTicking = false; + }, 2 * duration * 1000); + timer(() => { + if (instance.damageOnTicking && instance.health.amount > stopAtSetHealth && instance.health.amount - (multiplier * 0.5) > stopAtSetHealth) { + instance.health.amount -= multiplier * 0.5; + } //else {if (instance.health.amount - (multiplier * 0.5) < stopAtSetHealth) {instance.health.amount === stopAtSetHealth}} + }, 2 * duration); + } +}; +const iceOnTick = (body, instance, multiplier, duration, hitsOwnTeam) => { + if (!instance) return + if (!instance.invuln && !instance.godmode && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) timer(() => { + instance.velocity.x /= 1.05 * multiplier; + instance.velocity.y /= 1.05 * multiplier; + }, 1.5 * duration); +}; +Class.poisonbullet = { + PARENT: "bullet", + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + TURRETS: [{ + POSITION: [5.5, 0, 0, 0, 0, 1], + TYPE: ["effectBulletDeco", { color: "green" }] + }], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + damageOnTick(body, damageTool[0], 1, 1, 1, true); + } + }] +} +Class.icebullet = { + PARENT: "bullet", + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + TURRETS: [{ + POSITION: [5.5, 0, 0, 0, 0, 1], + TYPE: ["effectBulletDeco", { color: "#28B1DE" }] + }], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + iceOnTick(body, damageTool[0], 1, 1, true); + } + }] +} +Class.ceptionistbullet = { + PARENT: "bullet", + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.slightlyweaker, g.slightlyweaker, g.halfreload, g.halfreload, g.turret]), + TYPE: "bullet", + COLOR: "black", + AUTOFIRE: true + } + } + ] +} +Class.autoturretswarm = makeAuto('swarm', "AutoturretSwarm", {type: 'droneAutoTurret'}) +Class.hybridclonerprobe = makeHybrid('clonerprobe', "hybrid-cloner-probe") +Class.nuke = { + PARENT: "growBullet", + LABEL: "Nuke", + MOTION_TYPE: "fuckingnuclearbomb", + BODY: { + PENETRATION: 100, + SPEED: 7, + RANGE: 600, + DENSITY: 99999999999, + HEALTH: 99999, + DAMAGE: 999999, + PUSHABILITY: -99999999, + }, +}; +Class.oldsnake = { + PARENT: "missile", + LABEL: "Snake", + GUNS: [ + { + POSITION: [6, 12, 1.4, 8, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.snake, g.snakeskin]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + }, + }, + { + POSITION: [10, 12, 0.8, 8, 0, 180, 0.5], + PROPERTIES: { + AUTOFIRE: true, + NEGATIVE_RECOIL: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.snake]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + }, + }, + ], +} \ No newline at end of file diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 36743cc72..3c4090376 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -1,3864 +1,5844 @@ -const { combineStats, makeAuto, makeHybrid, makeOver, makeDeco, makeGuard, makeBird, makeMulti } = require('../facilitators.js'); -const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); -require('./generics.js'); -const g = require('../gunvals.js'); - -// Basic & starting upgrades -Class.basic = { - PARENT: "genericTank", - LABEL: "Basic", - DANGER: 4, - /*BODY: { - ACCELERATION: base.ACCEL * 1, - SPEED: base.SPEED * 1, - HEALTH: base.HEALTH * 1, - DAMAGE: base.DAMAGE * 1, - PENETRATION: base.PENETRATION * 1, - SHIELD: base.SHIELD * 1, - REGEN: base.REGEN * 1, - FOV: base.FOV * 1, - DENSITY: base.DENSITY * 1, - PUSHABILITY: 1, - HETERO: 3 - },*/ - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet", - /*COLOR: "grey", - LABEL: "", - STAT_CALCULATOR: 0, - WAIT_TO_CYCLE: false, - AUTOFIRE: false, - SYNCS_SKILLS: false, - MAX_CHILDREN: 0, - ALT_FIRE: false, - NEGATIVE_RECOIL: false*/ - } - } - ] -} -Class.twin = { - PARENT: "genericTank", - LABEL: "Twin", - GUNS: [ - { - POSITION: [20, 8, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin]), - TYPE: "bullet" - } - } - ] -} -Class.sniper = { - PARENT: "genericTank", - LABEL: "Sniper", - BODY: { - FOV: 1.2 * base.FOV - }, - GUNS: [ - { - POSITION: [24, 8.5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), - TYPE: "bullet" - } - } - ] -} -Class.machineGun = { - PARENT: "genericTank", - LABEL: "Machine Gun", - GUNS: [ - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), - TYPE: "bullet" - } - } - ] -} -Class.flankGuard = makeMulti({ - PARENT: "genericTank", - BODY: { - SPEED: 1.1 * base.SPEED - }, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet" - } - } - ] -}, 3, "Flank Guard") -Class.director = { - PARENT: "genericTank", - LABEL: "Director", - STAT_NAMES: statnames.drone, - BODY: { - FOV: base.FOV * 1.1 - }, - GUNS: [ - { - POSITION: [6, 11, 1.3, 7, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - MAX_CHILDREN: 6, - WAIT_TO_CYCLE: true - } - } - ] -} -Class.pounder = { - PARENT: "genericTank", - LABEL: "Pounder", - GUNS: [ - { - POSITION: [20.5, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), - TYPE: "bullet" - } - } - ] -} -Class.trapper = { - PARENT: "genericTank", - LABEL: "Trapper", - STAT_NAMES: statnames.trap, - GUNS: [ - { - POSITION: [15, 7, 1, 0, 0, 0, 0] - }, - { - POSITION: [3, 7, 1.7, 15, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap - } - } - ] -} -Class.desmos = { - PARENT: "genericTank", - LABEL: "Desmos", - STAT_NAMES: statnames.desmos, - GUNS: [ - { - POSITION: [20, 10, 0.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: "desmos"}] - } - }, - { - POSITION: [3.75, 10, 2.125, 1.25, -6.25, 90, 0] - }, - { - POSITION: [3.75, 10, 2.125, 1.25, 6.25, -90, 0] - } - ] -} -Class.smasher = { - PARENT: "genericSmasher", - LABEL: "Smasher", - DANGER: 6, - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody" - } - ] -} -Class.healer = { - PARENT: "genericTank", - LABEL: "Healer", - STAT_NAMES: statnames.heal, - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 360, 1], - TYPE: "healerSymbol" - } - ], - GUNS: [ - { - POSITION: [8, 9, -0.5, 12.5, 0, 0, 0] - }, - { - POSITION: [18, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.healer]), - TYPE: "healerBullet" - } - } - ] -} - -// Twin upgrades -Class.doubleTwin = makeMulti({ - PARENT: "genericTank", - LABEL: "Twin", - DANGER: 6, - GUNS: [ - { - POSITION: [20, 8, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin]), - TYPE: "bullet" - } - } - ] -}, 2) -Class.tripleShot = { - PARENT: "genericTank", - LABEL: "Triple Shot", - DANGER: 6, - BODY: { - SPEED: base.SPEED * 0.9 - }, - GUNS: [ - { - POSITION: [19, 8, 1, 0, -2, -17.5, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, - { - POSITION: [19, 8, 1, 0, 2, 17.5, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, - { - POSITION: [22, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), - TYPE: "bullet" - } - } - ] -} - -// Double Twin upgrades -Class.tripleTwin = makeMulti({ - PARENT: "genericTank", - LABEL: "Twin", - DANGER: 7, - GUNS: [ - { - POSITION: [20, 8, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.spam, g.doubleTwin]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.spam, g.doubleTwin]), - TYPE: "bullet" - } - } - ] -}, 3) -Class.hewnDouble = { - PARENT: "genericTank", - LABEL: "Hewn Double", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, 5.5, 205, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.doubleTwin, g.hewnDouble, { recoil: 1.15 }]), - TYPE: "bullet" - } - }, - { - POSITION: [19, 8, 1, 0, -5.5, -205, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.doubleTwin, g.hewnDouble, { recoil: 1.15 }]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 8, 1, 0, 5.5, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin, g.hewnDouble, { recoil: 1.15 }]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 8, 1, 0, -5.5, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin, g.hewnDouble, { recoil: 1.15 }]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 8, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin, g.hewnDouble]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin, g.hewnDouble]), - TYPE: "bullet" - } - } - ] -} - -// Triple Shot upgrades -Class.pentaShot = { - PARENT: "genericTank", - LABEL: "Penta Shot", - DANGER: 7, - BODY: { - SPEED: 0.85 * base.SPEED - }, - GUNS: [ - { - POSITION: [16, 8, 1, 0, -3, -30, 0.667], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, - { - POSITION: [16, 8, 1, 0, 3, 30, 0.667], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, - { - POSITION: [19, 8, 1, 0, -2, -15, 0.333], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, - { - POSITION: [19, 8, 1, 0, 2, 15, 0.333], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, - { - POSITION: [22, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), - TYPE: "bullet" - } - } - ] -} -Class.spreadshot = { - PARENT: "genericTank", - LABEL: "Spreadshot", - DANGER: 7, - GUNS: [ - { - POSITION: [13, 4, 1, 0, -0.5, -75, 5 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [13, 4, 1, 0, 0.5, 75, 5 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [14.5, 4, 1, 0, -0.5, -60, 4 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [14.5, 4, 1, 0, 0.5, 60, 4 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [16, 4, 1, 0, -0.5, -45, 3 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [16, 4, 1, 0, 0.5, 45, 3 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [17.5, 4, 1, 0, -0.5, -30, 2 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [17.5, 4, 1, 0, 0.5, 30, 2 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [19, 4, 1, 0, -1, -15, 1 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [19, 4, 1, 0, 1, 15, 1 / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), - TYPE: "bullet", - LABEL: "Spread" - } - }, - { - POSITION: [12, 8, 1, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.spreadshotMain, g.spreadshot]), - TYPE: "bullet" - } - } - ] -} -Class.bentDouble = makeMulti({ - PARENT: "genericTank", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, -2, -17.5, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.doubleTwin]), - TYPE: "bullet" - } - }, - { - POSITION: [19, 8, 1, 0, 2, 17.5, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.doubleTwin]), - TYPE: "bullet" - } - }, - { - POSITION: [22, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.doubleTwin]), - TYPE: "bullet" - } - } - ] -}, 2, "Bent Double") -Class.triplet = { - PARENT: "genericTank", - DANGER: 7, - LABEL: "Triplet", - BODY: { - FOV: 1.05 * base.FOV - }, - GUNS: [ - { - POSITION: [18, 10, 1, 0, 5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet]), - TYPE: "bullet" - } - }, - { - POSITION: [18, 10, 1, 0, -5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet]), - TYPE: "bullet" - } - }, - { - POSITION: [21, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet]), - TYPE: "bullet" - } - } - ] -} - -// Sniper upgrades -Class.assassin = { - PARENT: "genericTank", - DANGER: 6, - LABEL: "Assassin", - BODY: { - SPEED: 0.85 * base.SPEED, - FOV: 1.4 * base.FOV - }, - GUNS: [ - { - POSITION: [27, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), - TYPE: "bullet" - } - }, - { - POSITION: [5, 8, -1.4, 8, 0, 0, 0] - } - ] -} -Class.hunter = { - PARENT: "genericTank", - LABEL: "Hunter", - DANGER: 6, - BODY: { - SPEED: base.SPEED * 0.9, - FOV: base.FOV * 1.25 - }, - CONTROLLERS: ["zoom"], - TOOLTIP: "Hold right click to zoom.", - GUNS: [ - { - POSITION: [24, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, - { - POSITION: [21, 12, 1, 0, 0, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter]), - TYPE: "bullet" - } - } - ] -} -Class.rifle = { - PARENT: "genericTank", - LABEL: "Rifle", - DANGER: 6, - BODY: { - FOV: base.FOV * 1.225 - }, - GUNS: [ - { - POSITION: [20, 12, 1, 0, 0, 0, 0] - }, - { - POSITION: [24, 7, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle]), - TYPE: "bullet" - } - } - ] -} - -// Assassin upgrades -Class.ranger = { - PARENT: "genericTank", - LABEL: "Ranger", - DANGER: 7, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.5 * base.FOV, - }, - GUNS: [ - { - POSITION: [32, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), - TYPE: "bullet", - }, - }, - { - POSITION: [5, 8, -1.4, 8, 0, 0, 0], - }, - ], -} -Class.stalker = { - PARENT: "genericTank", - DANGER: 7, - LABEL: "Stalker", - BODY: { - SPEED: 0.85 * base.SPEED, - FOV: 1.35 * base.FOV - }, - INVISIBLE: [0.08, 0.03], - TOOLTIP: "Stay still to turn invisible.", - GUNS: [ - { - POSITION: [27, 8, -1.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), - TYPE: "bullet" - } - } - ] -} -Class.single = { - PARENT: "genericTank", - LABEL: "Single", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet" - } - }, - { - POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] - } - ] -} - -// Hunter upgrades -Class.predator = { - PARENT: "genericTank", - LABEL: "Predator", - DANGER: 7, - BODY: { - SPEED: base.SPEED * 0.9, - FOV: base.FOV * 1.25 - }, - CONTROLLERS: ["zoom"], - TOOLTIP: "Hold right click to zoom.", - GUNS: [ - { - POSITION: [24, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator]), - TYPE: "bullet" - } - }, - { - POSITION: [21, 12, 1, 0, 0, 0, 0.15], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.predator]), - TYPE: "bullet" - } - }, - { - POSITION: [18, 16, 1, 0, 0, 0, 0.3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.predator]), - TYPE: "bullet" - } - } - ] -} -Class.xHunter = { - PARENT: "genericTank", - LABEL: "X-Hunter", - DANGER: 7, - BODY: { - SPEED: base.SPEED * 0.9, - FOV: base.FOV * 1.25 - }, - CONTROLLERS: [["zoom", { distance: 550 }]], - TOOLTIP: "Hold right click to zoom.", - GUNS: [ - { - POSITION: [24, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, - { - POSITION: [21, 12, 1, 0, 0, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter]), - TYPE: "bullet" - } - }, - { - POSITION: [5, 12, -1.2, 7, 0, 0, 0] - } - ] -} -Class.dual = { - PARENT: "genericTank", - LABEL: "Dual", - DANGER: 7, - BODY: { - FOV: 1.1 * base.FOV - }, - CONTROLLERS: ["zoom"], - TOOLTIP: "Hold right click to zoom.", - GUNS: [ - { - POSITION: [18, 7, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.dual, g.lowPower]), - TYPE: "bullet", - LABEL: "Small" - } - }, - { - POSITION: [18, 7, 1, 0, -5.5, 0, .5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.dual, g.lowPower]), - TYPE: "bullet", - LABEL: "Small" - } - }, - { - POSITION: [16, 8.5, 1, 0, 5.5, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.dual]), - TYPE: "bullet" - } - }, - { - POSITION: [16, 8.5, 1, 0, -5.5, 0, .75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.dual]), - TYPE: "bullet" - } - } - ] -} - -// Rifle upgrades -Class.musket = { - PARENT: "genericTank", - LABEL: "Musket", - DANGER: 7, - BODY: { - FOV: base.FOV * 1.225 - }, - GUNS: [ - { - POSITION: [16, 19, 1, 0, 0, 0, 0], - }, - { - POSITION: [18, 7, 1, 0, 4, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin]), - TYPE: "bullet" - } - }, - { - POSITION: [18, 7, 1, 0, -4, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin]), - TYPE: "bullet" - } - } - ] -} -Class.crossbow = { - PARENT: "genericTank", - LABEL: "Crossbow", - DANGER: 7, - BODY: { - FOV: base.FOV * 1.225 - }, - GUNS: [ - { - POSITION: [12.5, 2.5, 1, 0, 3.5, 35, 1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { recoil: 0.5 }]), - TYPE: "bullet" - } - }, - { - POSITION: [12.5, 2.5, 1, 0, -3.5, -35, 1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { recoil: 0.5 }]), - TYPE: "bullet" - } - }, - { - POSITION: [15, 2.5, 1, 0, 3.5, 35/2, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { recoil: 0.5 }]), - TYPE: "bullet" - } - }, - { - POSITION: [15, 2.5, 1, 0, -3.5, -35/2, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { speed: 0.7, maxSpeed: 0.7 }, { recoil: 0.5 }]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 3.5, 1, 0, 4, 0, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { speed: 0.7, maxSpeed: 0.7 }, { recoil: 0.5 }]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 3.5, 1, 0, -4, 0, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { speed: 0.7, maxSpeed: 0.7 }, { recoil: 0.5 }]), - TYPE: "bullet" - } - }, - { - POSITION: [24, 7, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { speed: 0.7, maxSpeed: 0.7 }, { recoil: 0.5 }]), - TYPE: "bullet" - } - } - ] -} - -// Machine Gun upgrades -Class.minigun = { - PARENT: "genericTank", - LABEL: "Minigun", - DANGER: 6, - BODY: { - FOV: base.FOV * 1.2 - }, - GUNS: [ - { - POSITION: [21, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), - TYPE: "bullet" - } - }, - { - POSITION: [19, 8, 1, 0, 0, 0, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), - TYPE: "bullet" - } - }, - { - POSITION: [17, 8, 1, 0, 0, 0, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), - TYPE: "bullet" - } - } - ] -} -Class.gunner = { - PARENT: "genericTank", - LABEL: "Gunner", - DANGER: 6, - GUNS: [ - { - POSITION: [12, 3.5, 1, 0, 7.25, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), - TYPE: "bullet" - } - }, - { - POSITION: [12, 3.5, 1, 0, -7.25, 0, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), - TYPE: "bullet" - } - }, - { - POSITION: [16, 3.5, 1, 0, 3.75, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), - TYPE: "bullet" - } - }, - { - POSITION: [16, 3.5, 1, 0, -3.75, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), - TYPE: "bullet" - } - } - ] -} -Class.sprayer = { - PARENT: "genericTank", - LABEL: "Sprayer", - DANGER: 6, - GUNS: [ - { - POSITION: [23, 7, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.lowPower, g.pelleter, { recoil: 1.15 }]), - TYPE: "bullet" - } - }, - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), - TYPE: "bullet" - } - } - ] -} - -// Minigun upgrades -Class.streamliner = { - PARENT: "genericTank", - LABEL: "Streamliner", - DANGER: 7, - BODY: { - FOV: 1.3, - }, - GUNS: [ - { - POSITION: [25, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - { - POSITION: [23, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - { - POSITION: [21, 8, 1, 0, 0, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - { - POSITION: [19, 8, 1, 0, 0, 0, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - { - POSITION: [17, 8, 1, 0, 0, 0, 0.8], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - ], -} -Class.barricade = { - PARENT: "genericTank", - DANGER: 7, - LABEL: "Barricade", - STAT_NAMES: statnames.trap, - BODY: { - FOV: 1.15, - }, - GUNS: [ - { - POSITION: [24, 8, 1, 0, 0, 0, 0], - }, - { - POSITION: [4, 8, 1.3, 22, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.minigun, { range: 0.5 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [4, 8, 1.3, 18, 0, 0, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.minigun, { range: 0.5 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [4, 8, 1.3, 14, 0, 0, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.minigun, { range: 0.5 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], -} - -// Gunner upgrades -Class.nailgun = { - PARENT: "genericTank", - LABEL: "Nailgun", - DANGER: 7, - BODY: { - FOV: base.FOV * 1.1, - SPEED: base.SPEED * 0.9, - }, - GUNS: [ - { - POSITION: [19, 2, 1, 0, -2.5, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, g.nailgun]), - TYPE: "bullet", - }, - }, - { - POSITION: [19, 2, 1, 0, 2.5, 0, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, g.nailgun]), - TYPE: "bullet", - }, - }, - { - POSITION: [20, 2, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, g.nailgun]), - TYPE: "bullet", - }, - }, - { - POSITION: [5.5, 7, -1.8, 6.5, 0, 0, 0], - }, - ], -} -Class.machineGunner = { - PARENT: "genericTank", - LABEL: "Machine Gunner", - DANGER: 7, - BODY: { - SPEED: 0.9 * base.SPEED, - }, - GUNS: [ - { - POSITION: [14, 3, 4, -3, 5, 0, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), - TYPE: "bullet", - }, - }, - { - POSITION: [14, 3, 4, -3, -5, 0, 0.8], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), - TYPE: "bullet", - }, - }, - { - POSITION: [14, 3, 4, 0, 2.5, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), - TYPE: "bullet", - }, - }, - { - POSITION: [14, 3, 4, 0, -2.5, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), - TYPE: "bullet", - }, - }, - { - POSITION: [14, 3, 4, 3, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), - TYPE: "bullet", - }, - }, - ], -} - -// Sprayer upgrades -Class.redistributor = { - PARENT: "genericTank", - LABEL: "Redistributor", - DANGER: 7, - GUNS: [ - { - POSITION: [26, 7, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [23, 10, 1, 0, 0, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), - TYPE: "bullet", - }, - }, - ], -} -Class.atomizer = { - PARENT: "genericTank", - LABEL: "Atomizer", - DANGER: 7, - GUNS: [ - { - POSITION: [5, 7.5, 1.3, 18.5, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }, g.atomizer]), - TYPE: "bullet", - }, - }, - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), - TYPE: "bullet", - }, - }, - ], -} -Class.focal = { - PARENT: "genericTank", - LABEL: "Focal", - DANGER: 7, - GUNS: [ - { - POSITION: [25, 7, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [14, 10, 1.3, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal]), - TYPE: "bullet", - }, - }, - ], -} - -// Flank Guard upgrades -Class.hexaTank = makeMulti({ - PARENT: "genericTank", - DANGER: 6, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet" - } - }, - { - POSITION: [18, 8, 1, 0, 0, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet" - } - } - ] -}, 3, "Hexa Tank") -Class.triAngle = { - PARENT: "genericTank", - LABEL: "Tri-Angle", - BODY: { - HEALTH: 0.8 * base.HEALTH, - SHIELD: 0.8 * base.SHIELD, - DENSITY: 0.6 * base.DENSITY, - }, - DANGER: 6, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), - TYPE: "bullet", - LABEL: "Front", - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - ], -} -Class.auto3 = { - PARENT: "genericTank", - LABEL: "Auto-3", - DANGER: 6, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [11, 8, 0, 0, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 120, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 240, 190, 0], - TYPE: "autoTankGun", - }, - ], -} - -// Hexa Tank upgrades -Class.octoTank = makeMulti({ - PARENT: "genericTank", - DANGER: 6, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 45, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.spam]), - TYPE: "bullet" - } - }, - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.spam]), - TYPE: "bullet" - } - } - ] -}, 4, "Octo Tank") -Class.cyclone = makeMulti({ - PARENT: "genericTank", - DANGER: 7, - GUNS: [ - { - POSITION: [15, 3.5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), - TYPE: "bullet" - } - }, - { - POSITION: [15, 3.5, 1, 0, 0, 30, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), - TYPE: "bullet" - } - }, - { - POSITION: [15, 3.5, 1, 0, 0, 60, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), - TYPE: "bullet" - } - }, - { - POSITION: [15, 3.5, 1, 0, 0, 90, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), - TYPE: "bullet" - } - } - ] -}, 3, "Cyclone") - -// Tri-Angle upgrades -Class.fighter = { - PARENT: "genericTank", - LABEL: "Fighter", - BODY: { - DENSITY: 0.6 * base.DENSITY, - }, - DANGER: 7, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), - TYPE: "bullet", - LABEL: "Front", - }, - }, - { - POSITION: [16, 8, 1, 0, -1, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), - TYPE: "bullet", - LABEL: "Side", - }, - }, - { - POSITION: [16, 8, 1, 0, 1, -90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), - TYPE: "bullet", - LABEL: "Side", - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - ], -} -Class.booster = { - PARENT: "genericTank", - LABEL: "Booster", - BODY: { - HEALTH: base.HEALTH * 0.4, - SHIELD: base.SHIELD * 0.4, - DENSITY: base.DENSITY * 0.3 - }, - DANGER: 7, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), - TYPE: "bullet", - LABEL: "Front" - } - }, - { - POSITION: [14, 8, 1, 0, -1, 140, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster - } - }, - { - POSITION: [14, 8, 1, 0, 1, -140, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster - } - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster - } - }, - { - POSITION: [16, 8, 1, 0, 0, -150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster - } - } - ] -} -Class.surfer = { - PARENT: "genericTank", - LABEL: "Surfer", - BODY: { - DENSITY: 0.6 * base.DENSITY, - }, - DANGER: 7, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), - TYPE: "bullet", - LABEL: "Front", - }, - }, - { - POSITION: [7, 7.5, 0.6, 7, -1, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 7.5, 0.6, 7, 1, -90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - ], -} - -// Auto-3 upgrades -Class.auto5 = { - PARENT: "genericTank", - LABEL: "Auto-5", - DANGER: 7, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [11, 8, 0, 0, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 72, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 144, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 216, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 288, 190, 0], - TYPE: "autoTankGun", - }, - ], -} -Class.mega3 = { - PARENT: "genericTank", - LABEL: "Mega-3", - BODY: { - SPEED: 0.95 * base.SPEED, - }, - DANGER: 7, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [14, 8, 0, 0, 190, 0], - TYPE: "megaAutoTankGun", - }, - { - POSITION: [14, 8, 0, 120, 190, 0], - TYPE: "megaAutoTankGun", - }, - { - POSITION: [14, 8, 0, 240, 190, 0], - TYPE: "megaAutoTankGun", - }, - ], -} -Class.auto4 = { - PARENT: "genericTank", - LABEL: "Auto-4", - FACING_TYPE: ["spin", {speed: 0.02}], - DANGER: 7, - TURRETS: [ - { - POSITION: [13, 6, 0, 45, 160, 0], - TYPE: "auto4gun", - }, - { - POSITION: [13, 6, 0, 135, 160, 0], - TYPE: "auto4gun", - }, - { - POSITION: [13, 6, 0, 225, 160, 0], - TYPE: "auto4gun", - }, - { - POSITION: [13, 6, 0, 315, 160, 0], - TYPE: "auto4gun", - }, - ], -} -Class.banshee = { - PARENT: "genericTank", - LABEL: "Banshee", - DANGER: 7, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.1 * base.FOV, - }, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [10, 8, 0, 0, 80, 0], - TYPE: "bansheegun", - }, - { - POSITION: [10, 8, 0, 120, 80, 0], - TYPE: "bansheegun", - }, - { - POSITION: [10, 8, 0, 240, 80, 0], - TYPE: "bansheegun", - }, - ], - GUNS: [ - { - POSITION: [6, 11, 1.2, 8, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }, - { - POSITION: [6, 11, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }, - { - POSITION: [6, 11, 1.2, 8, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }, - ], -} - -// Director upgrades -Class.overseer = makeMulti({ - PARENT: "genericTank", - DANGER: 6, - STAT_NAMES: statnames.drone, - BODY: { - SPEED: 0.9 * base.SPEED, - FOV: 1.1 * base.FOV, - }, - MAX_CHILDREN: 8, - GUNS: [ - { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true - } - } - ] -}, 2, "Overseer", 90) -Class.cruiser = { - PARENT: "genericTank", - LABEL: "Cruiser", - DANGER: 6, - FACING_TYPE: "locksFacing", - STAT_NAMES: statnames.swarm, - BODY: { - FOV: 1.2 * base.FOV, - }, - GUNS: [ - { - POSITION: [7, 7.5, 0.6, 7, 4, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 7.5, 0.6, 7, -4, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - ], -} -Class.underseer = makeMulti({ - PARENT: "genericTank", - DANGER: 6, - STAT_NAMES: statnames.drone, - BODY: { - SPEED: 0.9 * base.SPEED, - }, - SHAPE: 4, - MAX_CHILDREN: 14, - GUNS: [ - { - POSITION: [5.25, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - } - } - ] -}, 2, "Underseer", 90) -Class.spawner = { - PARENT: "genericTank", - LABEL: "Spawner", - DANGER: 6, - STAT_NAMES: statnames.drone, - BODY: { - SPEED: base.SPEED * 0.8, - FOV: 1.1, - }, - GUNS: [ - { - POSITION: [4.5, 10, 1, 10.5, 0, 0, 0], - }, - { - POSITION: [1, 12, 1, 15, 0, 0, 0], - PROPERTIES: { - MAX_CHILDREN: 4, - SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory]), - TYPE: "minion", - STAT_CALCULATOR: gunCalcNames.drone, - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, - }, - { - POSITION: [11.5, 12, 1, 0, 0, 0, 0], - }, - ], -} -Class.manager = { - PARENT: "genericTank", - LABEL: "Manager", - DANGER: 7, - STAT_NAMES: statnames.drone, - BODY: { - SPEED: 0.85 * base.SPEED, - FOV: 1.1 * base.FOV, - }, - INVISIBLE: [0.08, 0.03], - TOOLTIP: "Stay still to turn invisible.", - MAX_CHILDREN: 8, - GUNS: [ - { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, { reload: 0.5 }]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, - ], -} -Class.bigCheese = { - PARENT: "genericTank", - LABEL: "Big Cheese", - STAT_NAMES: statnames.drone, - DANGER: 7, - BODY: { - FOV: base.FOV * 1.1, - }, - GUNS: [ - { - POSITION: [16, 16, 1.4, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.bigCheese]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - MAX_CHILDREN: 1, - }, - }, - ], -} - -// Overseer upgrades -Class.overlord = makeMulti({ - PARENT: "genericTank", - DANGER: 7, - STAT_NAMES: statnames.drone, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.1 * base.FOV, - }, - MAX_CHILDREN: 8, - GUNS: [ - { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true - } - } - ] -}, 4, "Overlord", 90) -Class.overdrive = makeMulti({ - PARENT: "genericTank", - DANGER: 7, - STAT_NAMES: statnames.drone, - BODY: { - SPEED: 0.9 * base.SPEED, - FOV: 1.1 * base.FOV, - }, - TURRETS: [ - { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: "overdriveDeco", - }, - ], - GUNS: [ - { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "turretedDrone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 4 - } - } - ] -}, 2, "Overdrive", 90) -Class.commander = makeMulti({ - PARENT: "genericTank", - STAT_NAMES: statnames.drone, - DANGER: 7, - BODY: { - FOV: base.FOV * 1.15, - }, - GUNS: [ - { - POSITION: [8, 11, 1.3, 6, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - MAX_CHILDREN: 2, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, - { - POSITION: [7, 7.5, 0.6, 7, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.commander]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - } - ] -}, 3, "Commander") - -// Cruiser upgrades -Class.carrier = { - PARENT: "genericTank", - LABEL: "Carrier", - DANGER: 7, - STAT_NAMES: statnames.swarm, - FACING_TYPE: "locksFacing", - BODY: { - FOV: base.FOV * 1.2, - }, - GUNS: [ - { - POSITION: [7, 8, 0.6, 7, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, g.carrier]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 8, 0.6, 7, 2, 30, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, g.carrier]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 8, 0.6, 7, -2, -30, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, g.carrier]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - ], -} -Class.battleship = { - PARENT: "genericTank", - LABEL: "Battleship", - DANGER: 7, - STAT_NAMES: statnames.swarm, - FACING_TYPE: "locksFacing", - BODY: { - FOV: 1.2 * base.FOV - }, - GUNS: [ - { - POSITION: [7, 7.5, 0.6, 7, 4, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - LABEL: "Guided" - } - }, - { - POSITION: [7, 7.5, 0.6, 7, -4, 90, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: ["autoswarm"], - STAT_CALCULATOR: gunCalcNames.swarm, - LABEL: "Autonomous" - } - }, - { - POSITION: [7, 7.5, 0.6, 7, 4, 270, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: ["autoswarm"], - STAT_CALCULATOR: gunCalcNames.swarm, - LABEL: "Autonomous" - } - }, - { - POSITION: [7, 7.5, 0.6, 7, -4, 270, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - LABEL: "Guided" - } - } - ] -} -Class.fortress = { - PARENT: "genericTank", - LABEL: "Fortress", - DANGER: 7, - STAT_NAMES: statnames.mixed, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.2 * base.FOV, - }, - GUNS: [ - { - POSITION: [7, 7.5, 0.6, 7, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: [ - "swarm", - { - CONTROLLERS: ["canRepel"], - }, - ], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 7.5, 0.6, 7, 0, 180, 1 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: [ - "swarm", - { - CONTROLLERS: ["canRepel"], - }, - ], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 7.5, 0.6, 7, 0, 300, 2 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: [ - "swarm", - { - CONTROLLERS: ["canRepel"], - }, - ], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [14, 9, 1, 0, 0, 0, 0], - }, - { - POSITION: [4, 9, 1.5, 14, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [14, 9, 1, 0, 0, 120, 0], - }, - { - POSITION: [4, 9, 1.5, 14, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [14, 9, 1, 0, 0, 240, 0], - }, - { - POSITION: [4, 9, 1.5, 14, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], -} - -// Underseer upgrades -Class.necromancer = { - PARENT: "genericTank", - LABEL: "Necromancer", - DANGER: 7, - STAT_NAMES: statnames.necro, - BODY: { - SPEED: 0.8 * base.SPEED, - }, - SHAPE: 4, - MAX_CHILDREN: 14, - GUNS: [ - { - POSITION: [5.25, 12, 1.2, 8, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - }, - }, - { - POSITION: [5.25, 12, 1.2, 8, 0, 270, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - }, - }, - { - POSITION: [5.25, 12, 1.2, 8, 0, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - MAX_CHILDREN: 4, - STAT_CALCULATOR: gunCalcNames.necro, - }, - }, - { - POSITION: [5.25, 12, 1.2, 8, 0, 180, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - MAX_CHILDREN: 4, - STAT_CALCULATOR: gunCalcNames.necro, - }, - }, - ], -} -Class.maleficitor = { - PARENT: "genericTank", - LABEL: "Maleficitor", - DANGER: 7, - TOOLTIP: "Press R and wait to turn your drones invisible.", - STAT_NAMES: statnames.necro, - BODY: { - SPEED: base.SPEED * 0.85, - }, - SHAPE: 4, - MAX_CHILDREN: 20, - GUNS: [ - { - POSITION: [5.25, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, g.maleficitor]), - TYPE: [ - "sunchip", - { - INVISIBLE: [0.06, 0.03], - }, - ], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - }, - }, - ], -} -Class.infestor = makeMulti({ - PARENT: "genericTank", - DANGER: 7, - STAT_NAMES: statnames.drone, - BODY: { - SPEED: base.SPEED * 0.9, - }, - MAX_CHILDREN: 20, - GUNS: [ - { - POSITION: [7.25, 6, 1.2, 6, -5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "eggchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro - } - }, - { - POSITION: [7.25, 6, 1.2, 6, 5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "eggchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro - } - } - ] -}, 2, "Infestor", 90) - -// Spawner upgrades -Class.factory = { - PARENT: "genericTank", - LABEL: "Factory", - DANGER: 7, - STAT_NAMES: statnames.drone, - BODY: { - SPEED: base.SPEED * 0.8, - FOV: 1.1, - }, - MAX_CHILDREN: 6, - GUNS: [ - { - POSITION: [5, 11, 1, 10.5, 0, 0, 0], - }, - { - POSITION: [2, 14, 1, 15.5, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory]), - TYPE: "minion", - STAT_CALCULATOR: gunCalcNames.drone, - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, - }, - { - POSITION: [12, 14, 1, 0, 0, 0, 0], - }, - ], -} - -// Pounder upgrades -Class.destroyer = { - PARENT: "genericTank", - LABEL: "Destroyer", - DANGER: 6, - GUNS: [ - { - POSITION: [21, 14, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), - TYPE: "bullet", - }, - }, - ], -} -Class.artillery = { - PARENT: "genericTank", - LABEL: "Artillery", - DANGER: 6, - GUNS: [ - { - POSITION: [17, 3, 1, 0, -6, -7, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [17, 3, 1, 0, 6, 7, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [19, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), - TYPE: "bullet", - LABEL: "Heavy", - }, - }, - ], -} -Class.launcher = { - PARENT: "genericTank", - LABEL: "Launcher", - DANGER: 6, - BODY: { - FOV: base.FOV * 1.1, - }, - GUNS: [ - { - POSITION: [10, 9, 1, 9, 0, 0, 0], - }, - { - POSITION: [17, 13, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.launcher]), - TYPE: "minimissile", - STAT_CALCULATOR: gunCalcNames.sustained, - }, - }, - ], -} -Class.shotgun = { - PARENT: "genericTank", - LABEL: "Shotgun", - DANGER: 7, - GUNS: [ - { - POSITION: [4, 3, 1, 11, -3, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "bullet", - }, - }, - { - POSITION: [4, 3, 1, 11, 3, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "bullet", - }, - }, - { - POSITION: [4, 4, 1, 13, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "casing", - }, - }, - { - POSITION: [1, 4, 1, 12, -1, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "casing", - }, - }, - { - POSITION: [1, 4, 1, 11, 1, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "casing", - }, - }, - { - POSITION: [1, 3, 1, 13, -1, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "bullet", - }, - }, - { - POSITION: [1, 3, 1, 13, 1, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "bullet", - }, - }, - { - POSITION: [1, 2, 1, 13, 2, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "casing", - }, - }, - { - POSITION: [1, 2, 1, 13, -2, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), - TYPE: "casing", - }, - }, - { - POSITION: [15, 14, 1, 6, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), - TYPE: "casing", - }, - }, - { - POSITION: [8, 14, -1.3, 4, 0, 0, 0], - }, - ], -} - -// Destroyer upgrades -Class.annihilator = { - PARENT: "genericTank", - LABEL: "Annihilator", - DANGER: 7, - GUNS: [ - { - POSITION: [20.5, 19.5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator]), - TYPE: "bullet", - }, - }, - ], -} - -// Artillery upgrades -Class.mortar = { - PARENT: "genericTank", - LABEL: "Mortar", - DANGER: 7, - GUNS: [ - { - POSITION: [13, 3, 1, 0, -8, -7, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [13, 3, 1, 0, 8, 7, 0.8], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [17, 3, 1, 0, -6, -7, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [17, 3, 1, 0, 6, 7, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [19, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), - TYPE: "bullet", - LABEL: "Heavy", - }, - }, - ], -} -Class.ordnance = { - PARENT: "genericTank", - LABEL: "Ordnance", - DANGER: 7, - BODY: { - SPEED: base.SPEED * 0.9, - FOV: base.FOV * 1.25, - }, - CONTROLLERS: ["zoom"], - TOOLTIP: "Hold right click to zoom.", - GUNS: [ - { - POSITION: [17, 3, 1, 0, -5.75, -6, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [17, 3, 1, 0, 5.75, 6, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [24, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary]), - TYPE: "bullet", - }, - }, - { - POSITION: [21, 11, 1, 0, 0, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter]), - TYPE: "bullet", - }, - }, - ], -} -Class.beekeeper = { - PARENT: "genericTank", - LABEL: "Beekeeper", - DANGER: 7, - GUNS: [ - { - POSITION: [14, 3, 1, 0, -6, -7, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.bee]), - TYPE: ["bee", { INDEPENDENT: true }], - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - LABEL: "Secondary", - }, - }, - { - POSITION: [14, 3, 1, 0, 6, 7, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.bee]), - TYPE: ["bee", { INDEPENDENT: true }], - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - LABEL: "Secondary", - }, - }, - { - POSITION: [19, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), - TYPE: "bullet", - LABEL: "Heavy", - }, - }, - ], -} -Class.fieldGun = { - PARENT: "genericTank", - LABEL: "Field Gun", - BODY: { - FOV: base.FOV * 1.1, - }, - DANGER: 7, - GUNS: [ - { - POSITION: [15, 3, 1, 0, -6, -7, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [15, 3, 1, 0, 6, 7, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [10, 9, 1, 9, 0, 0, 0], - }, - { - POSITION: [17, 13, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery]), - TYPE: "minimissile", - STAT_CALCULATOR: gunCalcNames.sustained, - }, - }, - ], -} - -// Launcher upgrades -Class.skimmer = { - PARENT: "genericTank", - LABEL: "Skimmer", - DANGER: 7, - BODY: { - FOV: 1.15 * base.FOV, - }, - GUNS: [ - { - POSITION: [10, 14, -0.5, 9, 0, 0, 0], - }, - { - POSITION: [17, 15, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer]), - TYPE: "missile", - STAT_CALCULATOR: gunCalcNames.sustained, - }, - }, - ], -} -Class.twister = { - PARENT: "genericTank", - LABEL: "Twister", - TOOLTIP: "Hold right click to reverse missile rotation.", - DANGER: 7, - BODY: { - FOV: 1.1 * base.FOV, - }, - GUNS: [ - { - POSITION: [10, 13, -0.5, 9, 0, 0, 0], - }, - { - POSITION: [17, 14, -1.4, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, { reload: 4/3 }]), - TYPE: "spinmissile", - STAT_CALCULATOR: gunCalcNames.sustained, - }, - }, - ], -} -Class.swarmer = { - PARENT: "genericTank", - DANGER: 7, - LABEL: "Swarmer", - GUNS: [ - { - POSITION: [15, 14, -1.2, 5, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.hive]), - TYPE: "hive", - }, - }, - { - POSITION: [15, 12, 1, 5, 0, 0, 0], - }, - ], -} -Class.rocketeer = { - PARENT: "genericTank", - LABEL: "Rocketeer", - BODY: { - FOV: 1.15 * base.FOV, - }, - DANGER: 7, - GUNS: [ - { - POSITION: [10, 12.5, -0.7, 10, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.launcher, g.rocketeer]), - TYPE: "rocketeerMissile", - STAT_CALCULATOR: gunCalcNames.sustained, - }, - }, - { - POSITION: [17, 18, 0.65, 0, 0, 0, 0], - }, - ], -} - -// Trapper upgrades -Class.builder = { - PARENT: "genericTank", - LABEL: "Builder", - DANGER: 6, - STAT_NAMES: statnames.trap, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.15 * base.FOV - }, - GUNS: [ - { - POSITION: [18, 12, 1, 0, 0, 0, 0], - }, - { - POSITION: [2, 12, 1.1, 18, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), - TYPE: "setTrap", - STAT_CALCULATOR: gunCalcNames.block - } - } - ] -} -Class.triTrapper = makeMulti({ - PARENT: "genericTank", - DANGER: 6, - STAT_NAMES: statnames.trap, - GUNS: [ - { - POSITION: [15, 7, 1, 0, 0, 0, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap - } - } - ] -}, 3, "Tri-Trapper") -Class.trapGuard = makeGuard({ - PARENT: "genericTank", - LABEL: "Trap", - STAT_NAMES: statnames.mixed, - GUNS: [ - { - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet" - } - } - ] -}) - -// Builder upgrades -Class.construct = { // it's "construct" and not "constructor" because "constructor" breaks things - PARENT: "genericTank", - LABEL: "Constructor", - STAT_NAMES: statnames.trap, - DANGER: 7, - BODY: { - SPEED: 0.7 * base.SPEED, - FOV: 1.15 * base.FOV - }, - GUNS: [ - { - POSITION: [18, 18, 1, 0, 0, 0, 0], - }, - { - POSITION: [2, 18, 1.2, 18, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.construct]), - TYPE: "setTrap", - STAT_CALCULATOR: gunCalcNames.block - } - } - ] -} -Class.engineer = { - PARENT: "genericTank", - DANGER: 7, - LABEL: "Engineer", - STAT_NAMES: statnames.trap, - BODY: { - SPEED: 0.75 * base.SPEED, - FOV: 1.15 * base.FOV, - }, - GUNS: [ - { - POSITION: [5, 11, 1, 10.5, 0, 0, 0], - }, - { - POSITION: [3, 14, 1, 15.5, 0, 0, 0], - }, - { - POSITION: [2, 14, 1.3, 18, 0, 0, 0], - PROPERTIES: { - MAX_CHILDREN: 6, - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), - TYPE: "pillbox", - SYNCS_SKILLS: true, - DESTROY_OLDEST_CHILD: true, - STAT_CALCULATOR: gunCalcNames.block - }, - }, - { - POSITION: [4, 14, 1, 8, 0, 0, 0], - }, - ], -} -Class.boomer = { - PARENT: "genericTank", - DANGER: 7, - LABEL: "Boomer", - STAT_NAMES: statnames.trap, - FACING_TYPE: "locksFacing", - BODY: { - SPEED: base.SPEED * 0.8, - FOV: base.FOV * 1.15, - }, - GUNS: [ - { - POSITION: [5, 10, 1, 14, 0, 0, 0], - }, - { - POSITION: [6, 10, -1.5, 7, 0, 0, 0], - }, - { - POSITION: [2, 10, 1.3, 18, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang]), - TYPE: "boomerang", - STAT_CALCULATOR: gunCalcNames.block - }, - }, - ], -} -Class.assembler = { - PARENT: "genericTank", - DANGER: 7, - LABEL: 'Assembler', - STAT_NAMES: statnames.trap, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.15 * base.FOV, - }, - GUNS: [ - { - POSITION: [18, 12, 1, 0, 0, 0, 0], - }, - { - POSITION: [2, 12, 1.1, 18, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), - TYPE: 'assemblerTrap', - MAX_CHILDREN: 8, - STAT_CALCULATOR: gunCalcNames.block, - } - } - ], - TURRETS: [ - { - /** SIZE X Y ANGLE ARC */ - POSITION: [2.5, 14, 0, 0, 360, 1], - TYPE: 'assemblerDot' - } - ] -} - -// Tri-Trapper upgrades -Class.hexaTrapper = makeAuto(makeMulti({ - PARENT: "genericTank", - DANGER: 7, - BODY: { - SPEED: 0.8 * base.SPEED, - }, - STAT_NAMES: statnames.trap, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [15, 7, 1, 0, 0, 0, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 180, 0.5], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], -}, 3), "Hexa-Trapper") -Class.septaTrapper = (() => { - let a = 360 / 7, - d = 1 / 7; - return { - PARENT: "genericTank", - LABEL: "Septa-Trapper", - DANGER: 7, - BODY: { - SPEED: base.SPEED * 0.8, - }, - STAT_NAMES: statnames.trap, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [15, 7, 1, 0, 0, 0, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, a, 4 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, a, 4 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 2 * a, 1 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 2 * a, 1 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 3 * a, 5 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 3 * a, 5 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 4 * a, 2 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 4 * a, 2 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 5 * a, 6 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 5 * a, 6 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 6 * a, 3 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 6 * a, 3 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], - }; -})() -Class.architect = { - PARENT: "genericTank", - LABEL: "Architect", - DANGER: 7, - BODY: { - SPEED: 1.1 * base.SPEED, - }, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [12, 8, 0, 0, 190, 0], - TYPE: "architectGun", - }, - { - POSITION: [12, 8, 0, 120, 190, 0], - TYPE: "architectGun", - }, - { - POSITION: [12, 8, 0, 240, 190, 0], - TYPE: "architectGun", - }, - ], -} - -// Trap Guard upgrades -Class.bushwhacker = makeGuard("sniper", "Bushwhacker") -Class.gunnerTrapper = { - PARENT: "genericTank", - LABEL: "Gunner Trapper", - DANGER: 7, - STAT_NAMES: statnames.mixed, - BODY: { - FOV: 1.25 * base.FOV, - }, - GUNS: [ - { - POSITION: [19, 2, 1, 0, -2.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { recoil: 4 }, { recoil: 1.8 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [19, 2, 1, 0, 2.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { recoil: 4 }, { recoil: 1.8 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [12, 11, 1, 0, 0, 0, 0], - }, - { - POSITION: [13, 11, 1, 0, 0, 180, 0], - }, - { - POSITION: [4, 11, 1.7, 13, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { speed: 1.2 }, { recoil: 0.5 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], -} -Class.bomber = { - PARENT: "genericTank", - LABEL: "Bomber", - BODY: { - DENSITY: base.DENSITY * 0.6, - }, - DANGER: 7, - GUNS: [ - { - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), - TYPE: "bullet", - LABEL: "Front", - }, - }, - { - POSITION: [18, 8, 1, 0, 0, 130, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle]), - TYPE: "bullet", - LABEL: "Wing", - }, - }, - { - POSITION: [18, 8, 1, 0, 0, 230, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle]), - TYPE: "bullet", - LABEL: "Wing", - }, - }, - { - POSITION: [13, 8, 1, 0, 0, 180, 0], - }, - { - POSITION: [4, 8, 1.7, 13, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], -} -Class.conqueror = { - PARENT: "genericTank", - DANGER: 7, - LABEL: "Conqueror", - STAT_NAMES: statnames.mixed, - BODY: { - SPEED: 0.8 * base.SPEED, - }, - REVERSE_TARGET_WITH_TANK: true, - GUNS: [ - { - POSITION: [21, 14, 1, 0, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), - TYPE: "bullet", - }, - }, - { - POSITION: [18, 12, 1, 0, 0, 0, 0], - }, - { - POSITION: [2, 12, 1.1, 18, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), - TYPE: "setTrap", - STAT_CALCULATOR: gunCalcNames.block - }, - }, - ], -} -Class.bulwark = { - PARENT: "genericTank", - LABEL: "Bulwark", - STAT_NAMES: statnames.mixed, - DANGER: 7, - GUNS: [ - { - POSITION: [20, 8, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.twin]), - TYPE: "bullet", - }, - }, - { - POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.twin]), - TYPE: "bullet", - }, - }, - { - POSITION: [14, 8, 1, 0, 5.5, 185, 0], - }, - { - POSITION: [3, 9, 1.5, 14, 5.5, 185, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.twin]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [14, 8, 1, 0, -5.5, 175, 0], - }, - { - POSITION: [3, 9, 1.5, 14, -5.5, 175, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.twin]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], -} - -// Desmos upgrades -Class.helix = { - PARENT: "genericTank", - LABEL: "Helix", - DANGER: 6, - STAT_NAMES: statnames.desmos, - GUNS: [ - { - POSITION: [20, 8, 0.75, 0, -5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: false}]}] - }, - }, - { - POSITION: [20, 8, 0.75, 0, 5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: true}]}] - }, - }, - { - POSITION: [3.625, 7.5, 2.75, 5.75, -6.75, 90, 0], - }, - { - POSITION: [3.625, 7.5, 2.75, 5.75, 6.75, -90, 0], - }, - { - POSITION: [6, 8, 0.25, 10.5, 0, 0, 0], - }, - ], -} -Class.sidewinder = { - PARENT: "genericTank", - LABEL: "Sidewinder", - DANGER: 6, - STAT_NAMES: statnames.desmos, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", - GUNS: [ - { - POSITION: [10, 8.5, 1.4, 7, 0, 0, 0] - }, - { - POSITION: [20, 10, 0.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: "desmos"}] - } - }, - { - POSITION: [4.25, 11, 2, 2.25, -4.25, 92.5, 0] - }, - { - POSITION: [4.25, 11, 2, 2.25, 4.25, -92.5, 0] - } - ] -} -Class.undertow = { - PARENT: "genericTank", - LABEL: "Undertow", - DANGER: 6, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", - GUNS: [ - { - POSITION: [14, 12, 0.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { reload: 1.2 }]), - TYPE: "bullet" - } - }, - { - POSITION: [11.25, 8, 0.15, 4.25, 4, 13.5, 0] - }, - { - POSITION: [11.25, 8, 0.15, 4.25, -4, -13.5, 0] - } - ] -} -Class.repeater = { - PARENT: "genericTank", - LABEL: "Repeater", - GUNS: [ - { - POSITION: [20, 10, 0.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["splitterBullet", {MOTION_TYPE: "desmos"}] - } - }, - { - POSITION: [4.625, 9.5, 2, 0.375, -8, 91.5, 0] - }, - { - POSITION: [4.625, 9.5, 2, 0.375, 8, -91.5, 0] - }, - { - POSITION: [3.75, 10, 2.125, 0, -4.75, 50, 0] - }, - { - POSITION: [3.75, 10, 2.125, 0, 4.75, -50, 0] - } - ] -} - -// Helix upgrades -Class.triplex = { - PARENT: "genericTank", - LABEL: "Triplex", - DANGER: 7, - STAT_NAMES: statnames.desmos, - GUNS: [ - { - POSITION: [18, 10, 0.7, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.desmos]), - TYPE: "bullet", - }, - }, - { - POSITION: [18, 10, 0.7, 0, 0, 45, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: "desmos"}] - }, - }, - { - POSITION: [18, 10, 0.7, 0, 0, -45, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: true}]}] - }, - }, - { - POSITION: [3.75, 10, 2.125, 1, -4.25, 10, 0], - }, - { - POSITION: [3.75, 10, 2.125, 1, 4.25, -10, 0], - }, - { - POSITION: [5, 6, 0.5, 10.5, 0, 22.5, 0], - }, - { - POSITION: [5, 6, 0.5, 10.5, 0, -22.5, 0], - }, - ], -} -Class.quadruplex = { - PARENT: "genericTank", - LABEL: "Quadruplex", - DANGER: 7, - STAT_NAMES: statnames.desmos, - GUNS: [ - { - POSITION: [20, 10, 0.8, 0, 0, 45, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25}]}] - } - }, - { - POSITION: [3.75, 10, 2.125, 1.25, -6.25, 135, 0] - }, - { - POSITION: [3.75, 10, 2.125, 1.25, 6.25, -45, 0] - }, - { - POSITION: [20, 10, 0.8, 0, 0, -45, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25, invert: true}]}] - } - }, - { - POSITION: [3.75, 10, 2.125, 1.25, -6.25, 45, 0] - }, - { - POSITION: [3.75, 10, 2.125, 1.25, 6.25, -135, 0] - }, - { - POSITION: [20, 10, 0.8, 0, 0, 135, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10}]}] - } - }, - { - POSITION: [3.75, 10, 2.125, 1.25, -6.25, -135, 0] - }, - { - POSITION: [3.75, 10, 2.125, 1.25, 6.25, 45, 0] - }, - { - POSITION: [20, 10, 0.8, 0, 0, -135, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10, invert: true}]}] - } - }, - { - POSITION: [3.75, 10, 2.125, 1.25, -6.25, -45, 0] - }, - { - POSITION: [3.75, 10, 2.125, 1.25, 6.25, 135, 0] - }, - ], -} - -// Sidewinder upgrades -Class.coil = { - PARENT: "genericTank", - LABEL: "Coil", - DANGER: 7, - STAT_NAMES: statnames.desmos, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", - GUNS: [ - { - POSITION: [20, 8, 0.75, 0, -5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: false}]}] - }, - }, - { - POSITION: [20, 8, 0.75, 0, 5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: true}]}] - }, - }, - { - POSITION: [21, 4, 0.75, 0, -5, 0, 0] - }, - { - POSITION: [21, 4, 0.75, 0, 5, 0, 0] - }, - { - POSITION: [3.625, 7.5, 2.75, 5.75, -6.75, 90, 0], - }, - { - POSITION: [3.625, 7.5, 2.75, 5.75, 6.75, -90, 0], - }, - { - POSITION: [6, 8, 0.25, 10.5, 0, 0, 0], - } - ] -} -Class.python = { - PARENT: "genericTank", - LABEL: "Python", - DANGER: 7, - STAT_NAMES: statnames.desmos, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank is a placeholder!" -} -Class.ranch = { - PARENT: "genericTank", - LABEL: "Ranch", - DANGER: 7, - STAT_NAMES: statnames.drone, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", - BODY: { - SPEED: base.SPEED * 0.8, - FOV: 1.1, - }, - GUNS: [ - { - POSITION: [4.5, 10, 1, 10.5, 0, 0, 0], - }, - { - POSITION: [1, 12, 1, 15, 0, 0, 0], - PROPERTIES: { - MAX_CHILDREN: 3, - SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory]), - TYPE: "minion", - STAT_CALCULATOR: gunCalcNames.drone, - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, - }, - { - POSITION: [11.5, 12, 1, 0, 0, 0, 0], - }, - { - POSITION: [5, 7.5, 2.5, 1, -4.5, 95, 0], - }, - { - POSITION: [5, 7.5, 2.5, 1, 4.5, -95, 0], - }, - ], -} -Class.oroboros = { - PARENT: "genericTank", - LABEL: "Oroboros", - DANGER: 7, - STAT_NAMES: statnames.desmos, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank is a placeholder!" -} -Class.cocci = { - PARENT: "genericSmasher", - LABEL: "Cocci", - UPGRADE_TOOLTIP: "[DEV NOTE] This tank is a placeholder!", - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody" - } - ] -} - -// Undertow upgrades -Class.riptide = { - PARENT: "genericTank", - LABEL: "Riptide", - DANGER: 7, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", - GUNS: [ - { - POSITION: [6.5, 23.5, 0.25, 3, 0, 180, 0], - }, - { - POSITION: [18, 16, 0.75, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { size: 0.9, reload: 1.2 }]), - TYPE: "bullet" - } - }, - { - POSITION: [17, 16, 0.1, 0.25, 4, 13.5, 0] - }, - { - POSITION: [17, 16, 0.1, 0.25, -4, -13.5, 0] - } - ] -} - -// Repeater upgrades -Class.iterator = { - PARENT: "genericTank", - LABEL: "Iterator", - DANGER: 7, - STAT_NAMES: statnames.desmos, - GUNS: [ - { - POSITION: [22, 10, 0.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["superSplitterBullet", {MOTION_TYPE: "desmos"}] - } - }, - { - POSITION: [4.625, 10.5, 2.75, 0.375, -7, 91.5, 0] - }, - { - POSITION: [4.625, 10.5, 2.75, 0.375, 7, -91.5, 0] - }, - { - POSITION: [4, 9, 3, 1.5, -5, 95, 0] - }, - { - POSITION: [4, 9, 3, 1.5, 5, -95, 0] - }, - { - POSITION: [3.75, 10, 2.125, -1.5, -5.25, 50, 0] - }, - { - POSITION: [3.75, 10, 2.125, -1.5, 5.25, -50, 0] - } - ] -} -Class.duplicator = { - PARENT: "genericTank", - LABEL: "Duplicator", - DANGER: 7, - STAT_NAMES: statnames.desmos, - GUNS: [ - { - POSITION: [20, 10, 0.8, 0, 0, 20, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), - TYPE: ["splitterBullet", {MOTION_TYPE: ["desmos", {invert: false}]}] - } - }, - { - POSITION: [20, 10, 0.8, 0, 0, -20, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), - TYPE: ["splitterBullet", {MOTION_TYPE: ["desmos", {invert: true}]}] - } - }, - { - POSITION: [5.625, 9.5, 2, 0.375-1, -8, 111.5, 0] - }, - { - POSITION: [3.75, 10, 2.125, 0, 4.75, -30, 0] - }, - { - POSITION: [5.625, 9.5, 2, 0.375-1, 8, -111.5, 0] - }, - { - POSITION: [3.75, 10, 2.125, 0, -4.75, 30, 0] - }, - { - POSITION: [17, 8, 0.65, 0, 0, 0, 0] - }, - { - POSITION: [18, 8, 0.25, 0, 0, 0, 0] - }, - ] -} - -// Smasher upgrades -Class.megaSmasher = { - PARENT: "genericSmasher", - LABEL: "Mega-Smasher", - BODY: { - SPEED: 1.05 * base.SPEED, - FOV: 1.1 * base.FOV, - DENSITY: 4 * base.DENSITY, - }, - TURRETS: [ - { - POSITION: [25, 0, 0, 0, 360, 0], - TYPE: "smasherBody", - }, - ], -} -Class.spike = { - PARENT: "genericSmasher", - LABEL: "Spike", - BODY: { - SPEED: base.SPEED * 0.9, - DAMAGE: base.DAMAGE * 1.1, - }, - TURRETS: [ - { - POSITION: [18.5, 0, 0, 0, 360, 0], - TYPE: "spikeBody", - }, - { - POSITION: [18.5, 0, 0, 90, 360, 0], - TYPE: "spikeBody", - }, - { - POSITION: [18.5, 0, 0, 180, 360, 0], - TYPE: "spikeBody", - }, - { - POSITION: [18.5, 0, 0, 270, 360, 0], - TYPE: "spikeBody", - }, - ], -} -Class.landmine = { - PARENT: "genericSmasher", - LABEL: "Landmine", - INVISIBLE: [0.06, 0.01], - TOOLTIP: "Stay still to turn invisible.", - BODY: { - SPEED: 1.1 * base.SPEED - }, - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody" - }, - { - POSITION: [21.5, 0, 0, 30, 360, 0], - TYPE: "landmineBody" - } - ] -} - -// Healer upgrades -Class.medic = { - PARENT: "genericTank", - LABEL: "Medic", - BODY: { - FOV: base.FOV * 1.2, - }, - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 360, 1], - TYPE: "healerSymbol", - }, - ], - GUNS: [ - { - POSITION: [8, 9, -0.5, 16.5, 0, 0, 0], - }, - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.healer, g.sniper]), - TYPE: "healerBullet", - }, - }, - ], - STAT_NAMES: statnames.heal, -} -Class.ambulance = { - PARENT: "genericTank", - LABEL: "Ambulance", - BODY: { - HEALTH: base.HEALTH * 0.8, - SHIELD: base.SHIELD * 0.8, - DENSITY: base.DENSITY * 0.6, - }, - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 360, 1], - TYPE: "healerSymbol", - }, - ], - GUNS: [ - { - POSITION: [8, 9, -0.5, 12.5, 0, 0, 0], - }, - { - POSITION: [18, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }, g.healer]), - TYPE: "healerBullet", - LABEL: "Front", - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - ], - STAT_NAMES: statnames.heal, -} -Class.surgeon = { - PARENT: "genericTank", - LABEL: "Surgeon", - STAT_NAMES: statnames.trap, - BODY: { - SPEED: base.SPEED * 0.75, - FOV: base.FOV * 1.15, - }, - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 360, 1], - TYPE: "healerSymbol", - }, - ], - GUNS: [ - { - POSITION: [5, 11, 1, 10.5, 0, 0, 0], - }, - { - POSITION: [3, 14, 1, 15.5, 0, 0, 0], - }, - { - POSITION: [2, 14, 1.3, 18, 0, 0, 0], - PROPERTIES: { - MAX_CHILDREN: 2, - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, { speed: 0.7, maxSpeed: 0.7 }]), - TYPE: "surgeonPillbox", - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.block - }, - }, - { - POSITION: [4, 14, 1, 8, 0, 0, 0], - }, - ], - STAT_NAMES: statnames.heal, -} -Class.paramedic = { - PARENT: "genericTank", - LABEL: "Paramedic", - BODY: { - SPEED: base.SPEED * 0.9, - }, - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 360, 1], - TYPE: "healerSymbol", - }, - ], - GUNS: [ - { - POSITION: [8, 9, -0.5, 10, 0, -17.5, 0.5], - }, - { - POSITION: [15.5, 10, 1, 0, 0, -17.5, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.healer]), - TYPE: "healerBullet", - }, - }, - { - POSITION: [8, 9, -0.5, 10, 0, 17.5, 0.5], - }, - { - POSITION: [15.5, 10, 1, 0, 0, 17.5, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.healer]), - TYPE: "healerBullet", - }, - }, - { - POSITION: [8, 9, -0.5, 12.5, 0, 0, 0], - }, - { - POSITION: [18, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.healer]), - TYPE: "healerBullet", - }, - }, - ], - STAT_NAMES: statnames.heal, -} - -// Bird tanks -Class.falcon = makeBird("assassin", "Falcon") -Class.vulture = makeBird({ - PARENT: "genericTank", - DANGER: 7, - BODY: { - FOV: base.FOV * 1.2, - }, - GUNS: [ - { - POSITION: [22, 7, -1.5, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 7.5, -1.5, 0, 0, 0, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, {size: 7/7.5}]), - TYPE: "bullet" - } - }, - { - POSITION: [18, 8, -1.5, 0, 0, 0, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, {size: 7/8}]), - TYPE: "bullet" - } - } - ] -}, "Vulture") -Class.phoenix = makeBird("sprayer", "Phoenix") -Class.eagle = makeBird("pounder", "Eagle") - -// Hybrid tanks -Class.bentHybrid = makeHybrid('tripleShot', "Bent Hybrid") -Class.poacher = makeHybrid('hunter', "Poacher") -Class.armsman = makeHybrid('rifle', "Armsman") -Class.cropDuster = makeHybrid('minigun', "Crop Duster") -Class.hybrid = makeHybrid('destroyer', "Hybrid") - -// Over tanks -Class.overgunner = makeOver({ - PARENT: "genericTank", - LABEL: "Gunner", - DANGER: 6, - GUNS: [ - { - POSITION: [19, 2, 1, 0, -2.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [19, 2, 1, 0, 2.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [12, 11, 1, 0, 0, 0, 0], - }, - ], -}) -Class.overtrapper = makeOver({ - PARENT: "genericTank", - LABEL: "Trapper", - DANGER: 6, - STAT_NAMES: statnames.mixed, - BODY: { - SPEED: base.SPEED * 0.8, - FOV: base.FOV * 1.2 - }, - GUNS: [ - { - POSITION: [14, 8, 1, 0, 0, 0, 0], - }, - { - POSITION: [4, 8, 1.5, 14, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap - } - } - ] -}) - -// Auto tanks -Class.autoDouble = makeAuto("doubleTwin", "Auto-Double") -Class.autoAssassin = makeAuto("assassin") -Class.autoGunner = makeAuto("gunner") -Class.autoTriAngle = makeAuto("triAngle") -Class.autoOverseer = makeAuto("overseer") -Class.autoCruiser = makeAuto("cruiser") -Class.autoSpawner = makeAuto("spawner") -Class.autoBuilder = makeAuto("builder") -Class.autoSmasher = makeAuto({ - PARENT: "genericSmasher", - DANGER: 6, - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody" - } - ], - SKILL_CAP: [smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl] -}, "Auto-Smasher", { - type: "autoSmasherTurret", - size: 11, -}) - -// Upgrade paths -Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "desmos"] - Class.basic.UPGRADES_TIER_2 = ["smasher"] - Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "autoSmasher", "landmine", "cocci"] - Class.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] - - Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "helix"] - Class.twin.UPGRADES_TIER_3 = ["dual", "bulwark", "musket"] - Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble"] - Class.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentHybrid", "bentDouble", "triplet", "triplex"] - - Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle"] - Class.sniper.UPGRADES_TIER_3 = ["bushwhacker"] - Class.assassin.UPGRADES_TIER_3 = ["ranger", "falcon", "stalker", "autoAssassin", "single"] - Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "dual"] - Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman"] - - Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer"] - Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture"] - Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner"] - Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal"] - - Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper"] - Class.flankGuard.UPGRADES_TIER_3 = ["tripleTwin", "quadruplex"] - Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper"] - Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "surfer", "eagle", "phoenix", "vulture"] - Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee"] - - Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "spawner"] - Class.director.UPGRADES_TIER_3 = ["manager", "bigCheese"] - Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "overdrive", "commander"] - Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "autoCruiser", "commander"] - Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor"] - Class.spawner.UPGRADES_TIER_3 = ["factory", "autoSpawner", "ranch"] - - Class.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher"] - Class.pounder.UPGRADES_TIER_3 = ["shotgun", "eagle"] - Class.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct"] - Class.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun"] - Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun"] - - Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard"] - Class.trapper.UPGRADES_TIER_3 = ["barricade", "overtrapper"] - Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror"] - Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect"] - Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark"] - - Class.desmos.UPGRADES_TIER_2 = ["helix", "sidewinder", "undertow", "repeater"] - Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "coil", "duplicator"] - Class.sidewinder.UPGRADES_TIER_3 = ["coil", "python", "ranch", "oroboros", "cocci"] - Class.undertow.UPGRADES_TIER_3 = ["riptide"] - Class.repeater.UPGRADES_TIER_3 = ["iterator", "duplicator"] +const { combineStats, makeAuto, makeHybrid, makeHybridDrive, makeOver, makeDeco, makeGuard, makeBird, makeMulti, makeCeption, makeCeptionNerf, makeTracker, addBackTurret, makeAura } = require('../facilitators.js'); +const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); +require('./generics.js'); +const g = require('../gunvals.js'); + +// Basic & starting upgrades +Class.basic = { + PARENT: "genericTank", + LABEL: "Basic", + DANGER: 4, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + /*BODY: { + ACCELERATION: base.ACCEL * 1, + SPEED: base.SPEED * 1, + HEALTH: base.HEALTH * 1, + DAMAGE: base.DAMAGE * 1, + PENETRATION: base.PENETRATION * 1, + SHIELD: base.SHIELD * 1, + REGEN: base.REGEN * 1, + FOV: base.FOV * 1, + DENSITY: base.DENSITY * 1, + PUSHABILITY: 1, + HETERO: 3 + },*/ + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + /*COLOR: "grey", + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 0, + ALT_FIRE: false, + NEGATIVE_RECOIL: false*/ + } + } + ] +} +Class.twin = { + PARENT: "genericTank", + LABEL: "Twin", + GUNS: [ + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet" + } + } + ] +} +Class.sniper = { + PARENT: "genericTank", + LABEL: "Sniper", + BODY: { + FOV: 1.2 * base.FOV + }, + GUNS: [ + { + POSITION: [24, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "bullet" + } + } + ] +} +Class.machineGun = { + PARENT: "genericTank", + LABEL: "Machine Gun", + GUNS: [ + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "bullet" + } + } + ] +} +Class.flankGuard = makeMulti({ + PARENT: "genericTank", + BODY: { + SPEED: 1.1 * base.SPEED + }, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + } + ] +}, 3, "Flank Guard") +Class.director = { + PARENT: "genericTank", + LABEL: "Director", + STAT_NAMES: statnames.drone, + BODY: { + FOV: base.FOV * 1.1 + }, + GUNS: [ + { + POSITION: [6, 11, 1.3, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 6, + WAIT_TO_CYCLE: true + } + } + ] +} +Class.pounder = { + PARENT: "genericTank", + LABEL: "Pounder", + GUNS: [ + { + POSITION: [20.5, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), + TYPE: "bullet" + } + } + ] +} +Class.trapper = { + PARENT: "genericTank", + LABEL: "Trapper", + STAT_NAMES: statnames.trap, + GUNS: [ + { + POSITION: [15, 7, 1, 0, 0, 0, 0] + }, + { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + } + ] +} +Class.desmos = { + PARENT: "genericTank", + LABEL: "Desmos", + STAT_NAMES: statnames.desmos, + GUNS: [ + { + POSITION: [20, 10, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: "desmos"}] + } + }, + { + POSITION: [3.75, 10, 2.125, 1.25, -6.25, 90, 0] + }, + { + POSITION: [3.75, 10, 2.125, 1.25, 6.25, -90, 0] + } + ] +} +Class.smasher = { + PARENT: "genericSmasher", + LABEL: "Smasher", + DANGER: 6, + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + } + ] +} +Class.healer = { + PARENT: "genericTank", + LABEL: "Healer", + STAT_NAMES: statnames.heal, + TURRETS: [ + { + POSITION: [13, 0, 0, 0, 360, 1], + TYPE: "healerSymbol" + } + ], + GUNS: [ + { + POSITION: [8, 9, -0.5, 12.5, 0, 0, 0] + }, + { + POSITION: [18, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.healer]), + TYPE: "healerBullet" + } + } + ] +} + +// Twin upgrades +Class.doubleTwin = makeMulti({ + PARENT: "genericTank", + LABEL: "Twin", + DANGER: 6, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin]), + TYPE: "bullet" + } + } + ] +}, 2) +Class.tripleShot = { + PARENT: "genericTank", + LABEL: "Triple Shot", + DANGER: 6, + BODY: { + SPEED: base.SPEED * 0.9 + }, + GUNS: [ + { + POSITION: [19, 8, 1, 0, -2, -17.5, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: [19, 8, 1, 0, 2, 17.5, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: [22, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + } + ] +} + +// Double Twin upgrades +Class.tripleTwin = makeMulti({ + PARENT: "genericTank", + LABEL: "Twin", + DANGER: 7, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.spam, g.doubleTwin]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.spam, g.doubleTwin]), + TYPE: "bullet" + } + } + ] +}, 3) +Class.hewnDouble = { + PARENT: "genericTank", + LABEL: "Hewn Double", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 5.5, 205, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.doubleTwin, g.hewnDouble, { recoil: 1.15 }]), + TYPE: "bullet" + } + }, + { + POSITION: [19, 8, 1, 0, -5.5, -205, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.doubleTwin, g.hewnDouble, { recoil: 1.15 }]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, 5.5, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin, g.hewnDouble, { recoil: 1.15 }]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin, g.hewnDouble, { recoil: 1.15 }]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin, g.hewnDouble]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.doubleTwin, g.hewnDouble]), + TYPE: "bullet" + } + } + ] +} + +// Triple Shot upgrades +Class.pentaShot = { + PARENT: "genericTank", + LABEL: "Penta Shot", + DANGER: 7, + BODY: { + SPEED: 0.85 * base.SPEED + }, + GUNS: [ + { + POSITION: [16, 8, 1, 0, -3, -30, 0.667], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: [16, 8, 1, 0, 3, 30, 0.667], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: [19, 8, 1, 0, -2, -15, 0.333], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: [19, 8, 1, 0, 2, 15, 0.333], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, + { + POSITION: [22, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot]), + TYPE: "bullet" + } + } + ] +} +Class.spreadshot = { + PARENT: "genericTank", + LABEL: "Spreadshot", + DANGER: 7, + GUNS: [ + { + POSITION: [13, 4, 1, 0, -0.5, -75, 5 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [13, 4, 1, 0, 0.5, 75, 5 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [14.5, 4, 1, 0, -0.5, -60, 4 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [14.5, 4, 1, 0, 0.5, 60, 4 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [16, 4, 1, 0, -0.5, -45, 3 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [16, 4, 1, 0, 0.5, 45, 3 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [17.5, 4, 1, 0, -0.5, -30, 2 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [17.5, 4, 1, 0, 0.5, 30, 2 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [19, 4, 1, 0, -1, -15, 1 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [19, 4, 1, 0, 1, 15, 1 / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin, g.spreadshot]), + TYPE: "bullet", + LABEL: "Spread" + } + }, + { + POSITION: [12, 8, 1, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.spreadshotMain, g.spreadshot]), + TYPE: "bullet" + } + } + ] +} +Class.bentDouble = makeMulti({ + PARENT: "genericTank", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, -2, -17.5, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.doubleTwin]), + TYPE: "bullet" + } + }, + { + POSITION: [19, 8, 1, 0, 2, 17.5, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.doubleTwin]), + TYPE: "bullet" + } + }, + { + POSITION: [22, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.doubleTwin]), + TYPE: "bullet" + } + } + ] +}, 2, "Bent Double") +Class.triplet = { + PARENT: "genericTank", + DANGER: 7, + LABEL: "Triplet", + BODY: { + FOV: 1.05 * base.FOV + }, + GUNS: [ + { + POSITION: [18, 10, 1, 0, 5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet]), + TYPE: "bullet" + } + }, + { + POSITION: [18, 10, 1, 0, -5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet]), + TYPE: "bullet" + } + }, + { + POSITION: [21, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet]), + TYPE: "bullet" + } + } + ] +} + +// Sniper upgrades +Class.assassin = { + PARENT: "genericTank", + DANGER: 6, + LABEL: "Assassin", + BODY: { + SPEED: 0.85 * base.SPEED, + FOV: 1.4 * base.FOV + }, + GUNS: [ + { + POSITION: [27, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), + TYPE: "bullet" + } + }, + { + POSITION: [5, 8, -1.4, 8, 0, 0, 0] + } + ] +} +Class.hunter = { + PARENT: "genericTank", + LABEL: "Hunter", + DANGER: 6, + BODY: { + SPEED: base.SPEED * 0.9, + FOV: base.FOV * 1.25 + }, + CONTROLLERS: ["zoom"], + TOOLTIP: "Hold right click to zoom.", + GUNS: [ + { + POSITION: [24, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, + { + POSITION: [21, 12, 1, 0, 0, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter]), + TYPE: "bullet" + } + } + ] +} +Class.rifle = { + PARENT: "genericTank", + LABEL: "Rifle", + DANGER: 6, + BODY: { + FOV: base.FOV * 1.225 + }, + GUNS: [ + { + POSITION: [20, 12, 1, 0, 0, 0, 0] + }, + { + POSITION: [24, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle]), + TYPE: "bullet" + } + } + ] +} + +// Assassin upgrades +Class.ranger = { + PARENT: "genericTank", + LABEL: "Ranger", + DANGER: 7, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.5 * base.FOV, + }, + GUNS: [ + { + POSITION: [32, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), + TYPE: "bullet", + }, + }, + { + POSITION: [5, 8, -1.4, 8, 0, 0, 0], + }, + ], +} +Class.stalker = { + PARENT: "genericTank", + DANGER: 7, + LABEL: "Stalker", + BODY: { + SPEED: 0.85 * base.SPEED, + FOV: 1.35 * base.FOV + }, + INVISIBLE: [0.08, 0.03], + TOOLTIP: "Stay still to turn invisible.", + GUNS: [ + { + POSITION: [27, 8, -1.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), + TYPE: "bullet" + } + } + ] +} +Class.single = { + PARENT: "genericTank", + LABEL: "Single", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ] +} + +// Hunter upgrades +Class.predator = { + PARENT: "genericTank", + LABEL: "Predator", + DANGER: 7, + BODY: { + SPEED: base.SPEED * 0.9, + FOV: base.FOV * 1.25 + }, + CONTROLLERS: ["zoom"], + TOOLTIP: "Hold right click to zoom.", + GUNS: [ + { + POSITION: [24, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, + { + POSITION: [21, 12, 1, 0, 0, 0, 0.15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, + { + POSITION: [18, 16, 1, 0, 0, 0, 0.3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.predator]), + TYPE: "bullet" + } + } + ] +} +Class.xHunter = { + PARENT: "genericTank", + LABEL: "X-Hunter", + DANGER: 7, + BODY: { + SPEED: base.SPEED * 0.9, + FOV: base.FOV * 1.25 + }, + CONTROLLERS: [["zoom", { distance: 550 }]], + TOOLTIP: "Hold right click to zoom.", + GUNS: [ + { + POSITION: [24, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, + { + POSITION: [21, 12, 1, 0, 0, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter]), + TYPE: "bullet" + } + }, + { + POSITION: [5, 12, -1.2, 7, 0, 0, 0] + } + ] +} +Class.dual = { + PARENT: "genericTank", + LABEL: "Dual", + DANGER: 7, + BODY: { + FOV: 1.1 * base.FOV + }, + CONTROLLERS: ["zoom"], + TOOLTIP: "Hold right click to zoom.", + GUNS: [ + { + POSITION: [18, 7, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.dual, g.lowPower]), + TYPE: "bullet", + LABEL: "Small" + } + }, + { + POSITION: [18, 7, 1, 0, -5.5, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.dual, g.lowPower]), + TYPE: "bullet", + LABEL: "Small" + } + }, + { + POSITION: [16, 8.5, 1, 0, 5.5, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.dual]), + TYPE: "bullet" + } + }, + { + POSITION: [16, 8.5, 1, 0, -5.5, 0, .75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.dual]), + TYPE: "bullet" + } + } + ] +} + +// Rifle upgrades +Class.musket = { + PARENT: "genericTank", + LABEL: "Musket", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.225 + }, + GUNS: [ + { + POSITION: [16, 19, 1, 0, 0, 0, 0], + }, + { + POSITION: [18, 7, 1, 0, 4, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin]), + TYPE: "bullet" + } + }, + { + POSITION: [18, 7, 1, 0, -4, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin]), + TYPE: "bullet" + } + } + ] +} +Class.crossbow = { + PARENT: "genericTank", + LABEL: "Crossbow", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.225 + }, + GUNS: [ + { + POSITION: [12.5, 2.5, 1, 0, 3.5, 35, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { recoil: 0.5 }]), + TYPE: "bullet" + } + }, + { + POSITION: [12.5, 2.5, 1, 0, -3.5, -35, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { recoil: 0.5 }]), + TYPE: "bullet" + } + }, + { + POSITION: [15, 2.5, 1, 0, 3.5, 35/2, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { recoil: 0.5 }]), + TYPE: "bullet" + } + }, + { + POSITION: [15, 2.5, 1, 0, -3.5, -35/2, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { speed: 0.7, maxSpeed: 0.7 }, { recoil: 0.5 }]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 3.5, 1, 0, 4, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { speed: 0.7, maxSpeed: 0.7 }, { recoil: 0.5 }]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 3.5, 1, 0, -4, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { speed: 0.7, maxSpeed: 0.7 }, { recoil: 0.5 }]), + TYPE: "bullet" + } + }, + { + POSITION: [24, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.crossbow, { speed: 0.7, maxSpeed: 0.7 }, { recoil: 0.5 }]), + TYPE: "bullet" + } + } + ] +} + +// Machine Gun upgrades +Class.minigun = { + PARENT: "genericTank", + LABEL: "Minigun", + DANGER: 6, + BODY: { + FOV: base.FOV * 1.2 + }, + GUNS: [ + { + POSITION: [21, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "bullet" + } + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "bullet" + } + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "bullet" + } + } + ] +} +Class.gunner = { + PARENT: "genericTank", + LABEL: "Gunner", + DANGER: 6, + GUNS: [ + { + POSITION: [12, 3.5, 1, 0, 7.25, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), + TYPE: "bullet" + } + }, + { + POSITION: [12, 3.5, 1, 0, -7.25, 0, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), + TYPE: "bullet" + } + }, + { + POSITION: [16, 3.5, 1, 0, 3.75, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), + TYPE: "bullet" + } + }, + { + POSITION: [16, 3.5, 1, 0, -3.75, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.2 }]), + TYPE: "bullet" + } + } + ] +} +Class.sprayer = { + PARENT: "genericTank", + LABEL: "Sprayer", + DANGER: 6, + GUNS: [ + { + POSITION: [23, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.lowPower, g.pelleter, { recoil: 1.15 }]), + TYPE: "bullet" + } + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "bullet" + } + } + ] +} + +// Minigun upgrades +Class.streamliner = { + PARENT: "genericTank", + LABEL: "Streamliner", + DANGER: 7, + BODY: { + FOV: 1.3, + }, + GUNS: [ + { + POSITION: [25, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [23, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [21, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + ], +} +Class.barricade = { + PARENT: "genericTank", + DANGER: 7, + LABEL: "Barricade", + STAT_NAMES: statnames.trap, + BODY: { + FOV: 1.15, + }, + GUNS: [ + { + POSITION: [24, 8, 1, 0, 0, 0, 0], + }, + { + POSITION: [4, 8, 1.3, 22, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.minigun, { range: 0.5 }]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [4, 8, 1.3, 18, 0, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.minigun, { range: 0.5 }]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [4, 8, 1.3, 14, 0, 0, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.minigun, { range: 0.5 }]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], +} + +// Gunner upgrades +Class.nailgun = { + PARENT: "genericTank", + LABEL: "Nailgun", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.1, + SPEED: base.SPEED * 0.9, + }, + GUNS: [ + { + POSITION: [19, 2, 1, 0, -2.5, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, g.nailgun]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 2, 1, 0, 2.5, 0, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, g.nailgun]), + TYPE: "bullet", + }, + }, + { + POSITION: [20, 2, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, g.nailgun]), + TYPE: "bullet", + }, + }, + { + POSITION: [5.5, 7, -1.8, 6.5, 0, 0, 0], + }, + ], +} +Class.machineGunner = { + PARENT: "genericTank", + LABEL: "Machine Gunner", + DANGER: 7, + BODY: { + SPEED: 0.9 * base.SPEED, + }, + GUNS: [ + { + POSITION: [14, 3, 4, -3, 5, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 3, 4, -3, -5, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 3, 4, 0, 2.5, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 3, 4, 0, -2.5, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 3, 4, 3, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.machineGunner]), + TYPE: "bullet", + }, + }, + ], +} + +// Sprayer upgrades +Class.redistributor = { + PARENT: "genericTank", + LABEL: "Redistributor", + DANGER: 7, + GUNS: [ + { + POSITION: [26, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [23, 10, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "bullet", + }, + }, + ], +} +Class.atomizer = { + PARENT: "genericTank", + LABEL: "Atomizer", + DANGER: 7, + GUNS: [ + { + POSITION: [5, 7.5, 1.3, 18.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }, g.atomizer]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "bullet", + }, + }, + ], +} +Class.focal = { + PARENT: "genericTank", + LABEL: "Focal", + DANGER: 7, + GUNS: [ + { + POSITION: [25, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 10, 1.3, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.focal]), + TYPE: "bullet", + }, + }, + ], +} + +// Flank Guard upgrades +Class.hexaTank = makeMulti({ + PARENT: "genericTank", + DANGER: 6, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet" + } + }, + { + POSITION: [18, 8, 1, 0, 0, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet" + } + } + ] +}, 3, "Hexa Tank") +Class.triAngle = { + PARENT: "genericTank", + LABEL: "Tri-Angle", + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.6 * base.DENSITY, + }, + DANGER: 6, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + ], +} +Class.auto3 = { + PARENT: "genericTank", + LABEL: "Auto-3", + DANGER: 6, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [ + { + POSITION: [11, 8, 0, 0, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 120, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 240, 190, 0], + TYPE: "autoTankGun", + }, + ], +} + +// Hexa Tank upgrades +Class.octoTank = makeMulti({ + PARENT: "genericTank", + DANGER: 6, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 45, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.spam]), + TYPE: "bullet" + } + }, + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.spam]), + TYPE: "bullet" + } + } + ] +}, 4, "Octo Tank") +Class.cyclone = makeMulti({ + PARENT: "genericTank", + DANGER: 7, + GUNS: [ + { + POSITION: [15, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), + TYPE: "bullet" + } + }, + { + POSITION: [15, 3.5, 1, 0, 0, 30, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), + TYPE: "bullet" + } + }, + { + POSITION: [15, 3.5, 1, 0, 0, 60, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), + TYPE: "bullet" + } + }, + { + POSITION: [15, 3.5, 1, 0, 0, 90, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), + TYPE: "bullet" + } + } + ] +}, 3, "Cyclone") + +// Tri-Angle upgrades +Class.fighter = { + PARENT: "genericTank", + LABEL: "Fighter", + BODY: { + DENSITY: 0.6 * base.DENSITY, + }, + DANGER: 7, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, -1, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), + TYPE: "bullet", + LABEL: "Side", + }, + }, + { + POSITION: [16, 8, 1, 0, 1, -90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), + TYPE: "bullet", + LABEL: "Side", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + ], +} +Class.booster = { + PARENT: "genericTank", + LABEL: "Booster", + BODY: { + HEALTH: base.HEALTH * 0.4, + SHIELD: base.SHIELD * 0.4, + DENSITY: base.DENSITY * 0.3 + }, + DANGER: 7, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front" + } + }, + { + POSITION: [14, 8, 1, 0, -1, 140, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster + } + }, + { + POSITION: [14, 8, 1, 0, 1, -140, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster + } + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster + } + }, + { + POSITION: [16, 8, 1, 0, 0, -150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster + } + } + ] +} +Class.surfer = { + PARENT: "genericTank", + LABEL: "Surfer", + BODY: { + DENSITY: 0.6 * base.DENSITY, + }, + DANGER: 7, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, -1, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, 1, -90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + ], +} + +// Auto-3 upgrades +Class.auto5 = { + PARENT: "genericTank", + LABEL: "Auto-5", + DANGER: 7, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [ + { + POSITION: [11, 8, 0, 0, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 72, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 144, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 216, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 288, 190, 0], + TYPE: "autoTankGun", + }, + ], +} +Class.mega3 = { + PARENT: "genericTank", + LABEL: "Mega-3", + BODY: { + SPEED: 0.95 * base.SPEED, + }, + DANGER: 7, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [ + { + POSITION: [14, 8, 0, 0, 190, 0], + TYPE: "megaAutoTankGun", + }, + { + POSITION: [14, 8, 0, 120, 190, 0], + TYPE: "megaAutoTankGun", + }, + { + POSITION: [14, 8, 0, 240, 190, 0], + TYPE: "megaAutoTankGun", + }, + ], +} +Class.auto4 = { + PARENT: "genericTank", + LABEL: "Auto-4", + FACING_TYPE: ["spin", {speed: 0.02}], + DANGER: 7, + TURRETS: [ + { + POSITION: [13, 6, 0, 45, 160, 0], + TYPE: "auto4gun", + }, + { + POSITION: [13, 6, 0, 135, 160, 0], + TYPE: "auto4gun", + }, + { + POSITION: [13, 6, 0, 225, 160, 0], + TYPE: "auto4gun", + }, + { + POSITION: [13, 6, 0, 315, 160, 0], + TYPE: "auto4gun", + }, + ], +} +Class.banshee = { + PARENT: "genericTank", + LABEL: "Banshee", + DANGER: 7, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.1 * base.FOV, + }, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [ + { + POSITION: [10, 8, 0, 0, 80, 0], + TYPE: "bansheegun", + }, + { + POSITION: [10, 8, 0, 120, 80, 0], + TYPE: "bansheegun", + }, + { + POSITION: [10, 8, 0, 240, 80, 0], + TYPE: "bansheegun", + }, + ], + GUNS: [ + { + POSITION: [6, 11, 1.2, 8, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 2, + }, + }, + { + POSITION: [6, 11, 1.2, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 2, + }, + }, + { + POSITION: [6, 11, 1.2, 8, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 2, + }, + }, + ], +} + +// Director upgrades +Class.overseer = makeMulti({ + PARENT: "genericTank", + DANGER: 6, + STAT_NAMES: statnames.drone, + BODY: { + SPEED: 0.9 * base.SPEED, + FOV: 1.1 * base.FOV, + }, + MAX_CHILDREN: 8, + GUNS: [ + { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true + } + } + ] +}, 2, "Overseer", 90) +Class.cruiser = { + PARENT: "genericTank", + LABEL: "Cruiser", + DANGER: 6, + FACING_TYPE: "locksFacing", + STAT_NAMES: statnames.swarm, + BODY: { + FOV: 1.2 * base.FOV, + }, + GUNS: [ + { + POSITION: [7, 7.5, 0.6, 7, 4, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, -4, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], +} +Class.underseer = makeMulti({ + PARENT: "genericTank", + DANGER: 6, + STAT_NAMES: statnames.drone, + BODY: { + SPEED: 0.9 * base.SPEED, + }, + SHAPE: 4, + MAX_CHILDREN: 14, + GUNS: [ + { + POSITION: [5.25, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + } + } + ] +}, 2, "Underseer", 90) +Class.spawner = { + PARENT: "genericTank", + LABEL: "Spawner", + DANGER: 6, + STAT_NAMES: statnames.drone, + BODY: { + SPEED: base.SPEED * 0.8, + FOV: 1.1, + }, + GUNS: [ + { + POSITION: [4.5, 10, 1, 10.5, 0, 0, 0], + }, + { + POSITION: [1, 12, 1, 15, 0, 0, 0], + PROPERTIES: { + MAX_CHILDREN: 4, + SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory]), + TYPE: "minion", + STAT_CALCULATOR: gunCalcNames.drone, + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, + }, + { + POSITION: [11.5, 12, 1, 0, 0, 0, 0], + }, + ], +} +Class.manager = { + PARENT: "genericTank", + LABEL: "Manager", + DANGER: 7, + STAT_NAMES: statnames.drone, + BODY: { + SPEED: 0.85 * base.SPEED, + FOV: 1.1 * base.FOV, + }, + INVISIBLE: [0.08, 0.03], + TOOLTIP: "Stay still to turn invisible.", + MAX_CHILDREN: 8, + GUNS: [ + { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, { reload: 0.5 }]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, + ], +} +Class.bigCheese = { + PARENT: "genericTank", + LABEL: "Big Cheese", + STAT_NAMES: statnames.drone, + DANGER: 7, + BODY: { + FOV: base.FOV * 1.1, + }, + GUNS: [ + { + POSITION: [16, 16, 1.4, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.bigCheese]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 1, + }, + }, + ], +} + +// Overseer upgrades +Class.overlord = makeMulti({ + PARENT: "genericTank", + DANGER: 7, + STAT_NAMES: statnames.drone, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.1 * base.FOV, + }, + MAX_CHILDREN: 8, + GUNS: [ + { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true + } + } + ] +}, 4, "Overlord", 90) +Class.overdrive = makeMulti({ + PARENT: "genericTank", + DANGER: 7, + STAT_NAMES: statnames.drone, + BODY: { + SPEED: 0.9 * base.SPEED, + FOV: 1.1 * base.FOV, + }, + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "overdriveDeco", + }, + ], + GUNS: [ + { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "turretedDrone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 4 + } + } + ] +}, 2, "Overdrive", 90) +Class.commander = makeMulti({ + PARENT: "genericTank", + STAT_NAMES: statnames.drone, + DANGER: 7, + BODY: { + FOV: base.FOV * 1.15, + }, + GUNS: [ + { + POSITION: [8, 11, 1.3, 6, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + MAX_CHILDREN: 2, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.commander]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + } + ] +}, 3, "Commander") + +// Cruiser upgrades +Class.carrier = { + PARENT: "genericTank", + LABEL: "Carrier", + DANGER: 7, + STAT_NAMES: statnames.swarm, + FACING_TYPE: "locksFacing", + BODY: { + FOV: base.FOV * 1.2, + }, + GUNS: [ + { + POSITION: [7, 8, 0.6, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, g.carrier]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 8, 0.6, 7, 2, 30, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, g.carrier]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 8, 0.6, 7, -2, -30, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, g.carrier]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], +} +Class.battleship = { + PARENT: "genericTank", + LABEL: "Battleship", + DANGER: 7, + STAT_NAMES: statnames.swarm, + FACING_TYPE: "locksFacing", + BODY: { + FOV: 1.2 * base.FOV + }, + GUNS: [ + { + POSITION: [7, 7.5, 0.6, 7, 4, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, + LABEL: "Guided" + } + }, + { + POSITION: [7, 7.5, 0.6, 7, -4, 90, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: ["autoswarm"], + STAT_CALCULATOR: gunCalcNames.swarm, + LABEL: "Autonomous" + } + }, + { + POSITION: [7, 7.5, 0.6, 7, 4, 270, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: ["autoswarm"], + STAT_CALCULATOR: gunCalcNames.swarm, + LABEL: "Autonomous" + } + }, + { + POSITION: [7, 7.5, 0.6, 7, -4, 270, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, + LABEL: "Guided" + } + } + ] +} +Class.fortress = { + PARENT: "genericTank", + LABEL: "Fortress", + DANGER: 7, + STAT_NAMES: statnames.mixed, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.2 * base.FOV, + }, + GUNS: [ + { + POSITION: [7, 7.5, 0.6, 7, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: [ + "swarm", + { + CONTROLLERS: ["canRepel"], + }, + ], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, 0, 180, 1 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: [ + "swarm", + { + CONTROLLERS: ["canRepel"], + }, + ], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, 0, 300, 2 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: [ + "swarm", + { + CONTROLLERS: ["canRepel"], + }, + ], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [14, 9, 1, 0, 0, 0, 0], + }, + { + POSITION: [4, 9, 1.5, 14, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [14, 9, 1, 0, 0, 120, 0], + }, + { + POSITION: [4, 9, 1.5, 14, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [14, 9, 1, 0, 0, 240, 0], + }, + { + POSITION: [4, 9, 1.5, 14, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], +} + +// Underseer upgrades +Class.necromancer = { + PARENT: "genericTank", + LABEL: "Necromancer", + DANGER: 7, + STAT_NAMES: statnames.necro, + BODY: { + SPEED: 0.8 * base.SPEED, + }, + SHAPE: 4, + MAX_CHILDREN: 14, + GUNS: [ + { + POSITION: [5.25, 12, 1.2, 8, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + }, + }, + { + POSITION: [5.25, 12, 1.2, 8, 0, 270, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + }, + }, + { + POSITION: [5.25, 12, 1.2, 8, 0, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + MAX_CHILDREN: 4, + STAT_CALCULATOR: gunCalcNames.necro, + }, + }, + { + POSITION: [5.25, 12, 1.2, 8, 0, 180, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + MAX_CHILDREN: 4, + STAT_CALCULATOR: gunCalcNames.necro, + }, + }, + ], +} +Class.maleficitor = { + PARENT: "genericTank", + LABEL: "Maleficitor", + DANGER: 7, + TOOLTIP: "Press R and wait to turn your drones invisible.", + STAT_NAMES: statnames.necro, + BODY: { + SPEED: base.SPEED * 0.85, + }, + SHAPE: 4, + MAX_CHILDREN: 20, + GUNS: [ + { + POSITION: [5.25, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, g.maleficitor]), + TYPE: [ + "sunchip", + { + INVISIBLE: [0.06, 0.03], + }, + ], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + }, + }, + ], +} +Class.infestor = makeMulti({ + PARENT: "genericTank", + DANGER: 7, + STAT_NAMES: statnames.drone, + BODY: { + SPEED: base.SPEED * 0.9, + }, + MAX_CHILDREN: 20, + GUNS: [ + { + POSITION: [7.25, 6, 1.2, 6, -5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "eggchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro + } + }, + { + POSITION: [7.25, 6, 1.2, 6, 5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "eggchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro + } + } + ] +}, 2, "Infestor", 90) + +// Spawner upgrades +Class.factory = { + PARENT: "genericTank", + LABEL: "Factory", + DANGER: 7, + STAT_NAMES: statnames.drone, + BODY: { + SPEED: base.SPEED * 0.8, + FOV: 1.1, + }, + MAX_CHILDREN: 6, + GUNS: [ + { + POSITION: [5, 11, 1, 10.5, 0, 0, 0], + }, + { + POSITION: [2, 14, 1, 15.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory]), + TYPE: "minion", + STAT_CALCULATOR: gunCalcNames.drone, + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, + }, + { + POSITION: [12, 14, 1, 0, 0, 0, 0], + }, + ], +} + +// Pounder upgrades +Class.destroyer = { + PARENT: "genericTank", + LABEL: "Destroyer", + DANGER: 6, + GUNS: [ + { + POSITION: [21, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), + TYPE: "bullet", + }, + }, + ], +} +Class.artillery = { + PARENT: "genericTank", + LABEL: "Artillery", + DANGER: 6, + GUNS: [ + { + POSITION: [17, 3, 1, 0, -6, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [17, 3, 1, 0, 6, 7, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [19, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), + TYPE: "bullet", + LABEL: "Heavy", + }, + }, + ], +} +Class.launcher = { + PARENT: "genericTank", + LABEL: "Launcher", + DANGER: 6, + BODY: { + FOV: base.FOV * 1.1, + }, + GUNS: [ + { + POSITION: [10, 9, 1, 9, 0, 0, 0], + }, + { + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.launcher]), + TYPE: "minimissile", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + ], +} +Class.shotgun = { + PARENT: "genericTank", + LABEL: "Shotgun", + DANGER: 7, + GUNS: [ + { + POSITION: [4, 3, 1, 11, -3, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "bullet", + }, + }, + { + POSITION: [4, 3, 1, 11, 3, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "bullet", + }, + }, + { + POSITION: [4, 4, 1, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "casing", + }, + }, + { + POSITION: [1, 4, 1, 12, -1, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "casing", + }, + }, + { + POSITION: [1, 4, 1, 11, 1, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "casing", + }, + }, + { + POSITION: [1, 3, 1, 13, -1, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "bullet", + }, + }, + { + POSITION: [1, 3, 1, 13, 1, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "bullet", + }, + }, + { + POSITION: [1, 2, 1, 13, 2, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "casing", + }, + }, + { + POSITION: [1, 2, 1, 13, -2, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun]), + TYPE: "casing", + }, + }, + { + POSITION: [15, 14, 1, 6, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), + TYPE: "casing", + }, + }, + { + POSITION: [8, 14, -1.3, 4, 0, 0, 0], + }, + ], +} + +// Destroyer upgrades +Class.annihilator = { + PARENT: "genericTank", + LABEL: "Annihilator", + DANGER: 7, + GUNS: [ + { + POSITION: [20.5, 19.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator]), + TYPE: "bullet", + }, + }, + ], +} + +// Artillery upgrades +Class.mortar = { + PARENT: "genericTank", + LABEL: "Mortar", + DANGER: 7, + GUNS: [ + { + POSITION: [13, 3, 1, 0, -8, -7, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [13, 3, 1, 0, 8, 7, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [17, 3, 1, 0, -6, -7, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [17, 3, 1, 0, 6, 7, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, g.twin]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [19, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), + TYPE: "bullet", + LABEL: "Heavy", + }, + }, + ], +} +Class.ordnance = { + PARENT: "genericTank", + LABEL: "Ordnance", + DANGER: 7, + BODY: { + SPEED: base.SPEED * 0.9, + FOV: base.FOV * 1.25, + }, + CONTROLLERS: ["zoom"], + TOOLTIP: "Hold right click to zoom.", + GUNS: [ + { + POSITION: [17, 3, 1, 0, -5.75, -6, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [17, 3, 1, 0, 5.75, 6, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [24, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary]), + TYPE: "bullet", + }, + }, + { + POSITION: [21, 11, 1, 0, 0, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter]), + TYPE: "bullet", + }, + }, + ], +} +Class.beekeeper = { + PARENT: "genericTank", + LABEL: "Beekeeper", + DANGER: 7, + GUNS: [ + { + POSITION: [14, 3, 1, 0, -6, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.bee]), + TYPE: ["bee", { INDEPENDENT: true }], + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + LABEL: "Secondary", + }, + }, + { + POSITION: [14, 3, 1, 0, 6, 7, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.bee]), + TYPE: ["bee", { INDEPENDENT: true }], + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + LABEL: "Secondary", + }, + }, + { + POSITION: [19, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), + TYPE: "bullet", + LABEL: "Heavy", + }, + }, + ], +} +Class.fieldGun = { + PARENT: "genericTank", + LABEL: "Field Gun", + BODY: { + FOV: base.FOV * 1.1, + }, + DANGER: 7, + GUNS: [ + { + POSITION: [15, 3, 1, 0, -6, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [15, 3, 1, 0, 6, 7, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [10, 9, 1, 9, 0, 0, 0], + }, + { + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery]), + TYPE: "minimissile", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + ], +} + +// Launcher upgrades +Class.skimmer = { + PARENT: "genericTank", + LABEL: "Skimmer", + DANGER: 7, + BODY: { + FOV: 1.15 * base.FOV, + }, + GUNS: [ + { + POSITION: [10, 14, -0.5, 9, 0, 0, 0], + }, + { + POSITION: [17, 15, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer]), + TYPE: "missile", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + ], +} +Class.twister = { + PARENT: "genericTank", + LABEL: "Twister", + TOOLTIP: "Hold right click to reverse missile rotation.", + DANGER: 7, + BODY: { + FOV: 1.1 * base.FOV, + }, + GUNS: [ + { + POSITION: [10, 13, -0.5, 9, 0, 0, 0], + }, + { + POSITION: [17, 14, -1.4, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, { reload: 4/3 }]), + TYPE: "spinmissile", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + ], +} +Class.swarmer = { + PARENT: "genericTank", + DANGER: 7, + LABEL: "Swarmer", + GUNS: [ + { + POSITION: [15, 14, -1.2, 5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.hive]), + TYPE: "hive", + }, + }, + { + POSITION: [15, 12, 1, 5, 0, 0, 0], + }, + ], +} +Class.rocketeer = { + PARENT: "genericTank", + LABEL: "Rocketeer", + BODY: { + FOV: 1.15 * base.FOV, + }, + DANGER: 7, + GUNS: [ + { + POSITION: [10, 12.5, -0.7, 10, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.launcher, g.rocketeer]), + TYPE: "rocketeerMissile", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + { + POSITION: [17, 18, 0.65, 0, 0, 0, 0], + }, + ], +} + +// Trapper upgrades +Class.builder = { + PARENT: "genericTank", + LABEL: "Builder", + DANGER: 6, + STAT_NAMES: statnames.trap, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.15 * base.FOV + }, + GUNS: [ + { + POSITION: [18, 12, 1, 0, 0, 0, 0], + }, + { + POSITION: [2, 12, 1.1, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), + TYPE: "setTrap", + STAT_CALCULATOR: gunCalcNames.block + } + } + ] +} +Class.triTrapper = makeMulti({ + PARENT: "genericTank", + DANGER: 6, + STAT_NAMES: statnames.trap, + GUNS: [ + { + POSITION: [15, 7, 1, 0, 0, 0, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + } + ] +}, 3, "Tri-Trapper") +Class.trapGuard = makeGuard({ + PARENT: "genericTank", + LABEL: "Trap", + STAT_NAMES: statnames.mixed, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet" + } + } + ] +}) + +// Builder upgrades +Class.construct = { // it's "construct" and not "constructor" because "constructor" breaks things + PARENT: "genericTank", + LABEL: "Constructor", + STAT_NAMES: statnames.trap, + DANGER: 7, + BODY: { + SPEED: 0.7 * base.SPEED, + FOV: 1.15 * base.FOV + }, + GUNS: [ + { + POSITION: [18, 18, 1, 0, 0, 0, 0], + }, + { + POSITION: [2, 18, 1.2, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.construct]), + TYPE: "setTrap", + STAT_CALCULATOR: gunCalcNames.block + } + } + ] +} +Class.engineer = { + PARENT: "genericTank", + DANGER: 7, + LABEL: "Engineer", + STAT_NAMES: statnames.trap, + BODY: { + SPEED: 0.75 * base.SPEED, + FOV: 1.15 * base.FOV, + }, + GUNS: [ + { + POSITION: [5, 11, 1, 10.5, 0, 0, 0], + }, + { + POSITION: [3, 14, 1, 15.5, 0, 0, 0], + }, + { + POSITION: [2, 14, 1.3, 18, 0, 0, 0], + PROPERTIES: { + MAX_CHILDREN: 6, + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), + TYPE: "pillbox", + SYNCS_SKILLS: true, + DESTROY_OLDEST_CHILD: true, + STAT_CALCULATOR: gunCalcNames.block + }, + }, + { + POSITION: [4, 14, 1, 8, 0, 0, 0], + }, + ], +} +Class.boomer = { + PARENT: "genericTank", + DANGER: 7, + LABEL: "Boomer", + STAT_NAMES: statnames.trap, + FACING_TYPE: "locksFacing", + BODY: { + SPEED: base.SPEED * 0.8, + FOV: base.FOV * 1.15, + }, + GUNS: [ + { + POSITION: [5, 10, 1, 14, 0, 0, 0], + }, + { + POSITION: [6, 10, -1.5, 7, 0, 0, 0], + }, + { + POSITION: [2, 10, 1.3, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang]), + TYPE: "boomerang", + STAT_CALCULATOR: gunCalcNames.block + }, + }, + ], +} +Class.assembler = { + PARENT: "genericTank", + DANGER: 7, + LABEL: 'Assembler', + STAT_NAMES: statnames.trap, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.15 * base.FOV, + }, + GUNS: [ + { + POSITION: [18, 12, 1, 0, 0, 0, 0], + }, + { + POSITION: [2, 12, 1.1, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), + TYPE: 'assemblerTrap', + MAX_CHILDREN: 8, + STAT_CALCULATOR: gunCalcNames.block, + } + } + ], + TURRETS: [ + { + /** SIZE X Y ANGLE ARC */ + POSITION: [2.5, 14, 0, 0, 360, 1], + TYPE: 'assemblerDot' + } + ] +} + +// Tri-Trapper upgrades +Class.hexaTrapper = makeAuto(makeMulti({ + PARENT: "genericTank", + DANGER: 7, + BODY: { + SPEED: 0.8 * base.SPEED, + }, + STAT_NAMES: statnames.trap, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [15, 7, 1, 0, 0, 0, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [15, 7, 1, 0, 0, 180, 0.5], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], +}, 3), "Hexa-Trapper") +Class.septaTrapper = (() => { + let a = 360 / 7, + d = 1 / 7; + return { + PARENT: "genericTank", + LABEL: "Septa-Trapper", + DANGER: 7, + BODY: { + SPEED: base.SPEED * 0.8, + }, + STAT_NAMES: statnames.trap, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [15, 7, 1, 0, 0, 0, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [15, 7, 1, 0, 0, a, 4 * d], + }, + { + POSITION: [3, 7, 1.7, 15, 0, a, 4 * d], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [15, 7, 1, 0, 0, 2 * a, 1 * d], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 2 * a, 1 * d], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [15, 7, 1, 0, 0, 3 * a, 5 * d], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 3 * a, 5 * d], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [15, 7, 1, 0, 0, 4 * a, 2 * d], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 4 * a, 2 * d], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [15, 7, 1, 0, 0, 5 * a, 6 * d], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 5 * a, 6 * d], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [15, 7, 1, 0, 0, 6 * a, 3 * d], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 6 * a, 3 * d], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], + }; +})() +Class.architect = { + PARENT: "genericTank", + LABEL: "Architect", + DANGER: 7, + BODY: { + SPEED: 1.1 * base.SPEED, + }, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [ + { + POSITION: [12, 8, 0, 0, 190, 0], + TYPE: "architectGun", + }, + { + POSITION: [12, 8, 0, 120, 190, 0], + TYPE: "architectGun", + }, + { + POSITION: [12, 8, 0, 240, 190, 0], + TYPE: "architectGun", + }, + ], +} + +// Trap Guard upgrades +Class.bushwhacker = makeGuard(Class.sniper, "Bushwhacker") +Class.gunnerTrapper = { + PARENT: "genericTank", + LABEL: "Gunner Trapper", + DANGER: 7, + STAT_NAMES: statnames.mixed, + BODY: { + FOV: 1.25 * base.FOV, + }, + GUNS: [ + { + POSITION: [19, 2, 1, 0, -2.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { recoil: 4 }, { recoil: 1.8 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 2, 1, 0, 2.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { recoil: 4 }, { recoil: 1.8 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 11, 1, 0, 0, 0, 0], + }, + { + POSITION: [13, 11, 1, 0, 0, 180, 0], + }, + { + POSITION: [4, 11, 1.7, 13, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { speed: 1.2 }, { recoil: 0.5 }]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], +} +Class.bomber = { + PARENT: "genericTank", + LABEL: "Bomber", + BODY: { + DENSITY: base.DENSITY * 0.6, + }, + DANGER: 7, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 130, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle]), + TYPE: "bullet", + LABEL: "Wing", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 230, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle]), + TYPE: "bullet", + LABEL: "Wing", + }, + }, + { + POSITION: [13, 8, 1, 0, 0, 180, 0], + }, + { + POSITION: [4, 8, 1.7, 13, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], +} +Class.conqueror = { + PARENT: "genericTank", + DANGER: 7, + LABEL: "Conqueror", + STAT_NAMES: statnames.mixed, + BODY: { + SPEED: 0.8 * base.SPEED, + }, + REVERSE_TARGET_WITH_TANK: true, + GUNS: [ + { + POSITION: [21, 14, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 12, 1, 0, 0, 0, 0], + }, + { + POSITION: [2, 12, 1.1, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), + TYPE: "setTrap", + STAT_CALCULATOR: gunCalcNames.block + }, + }, + ], +} +Class.bulwark = { + PARENT: "genericTank", + LABEL: "Bulwark", + STAT_NAMES: statnames.mixed, + DANGER: 7, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.twin]), + TYPE: "bullet", + }, + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.twin]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 8, 1, 0, 5.5, 185, 0], + }, + { + POSITION: [3, 9, 1.5, 14, 5.5, 185, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: [14, 8, 1, 0, -5.5, 175, 0], + }, + { + POSITION: [3, 9, 1.5, 14, -5.5, 175, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.twin]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], +} + +// Desmos upgrades +Class.helix = { + PARENT: "genericTank", + LABEL: "Helix", + DANGER: 6, + STAT_NAMES: statnames.desmos, + GUNS: [ + { + POSITION: [20, 8, 0.75, 0, -5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: false}]}] + }, + }, + { + POSITION: [20, 8, 0.75, 0, 5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: true}]}] + }, + }, + { + POSITION: [3.625, 7.5, 2.75, 5.75, -6.75, 90, 0], + }, + { + POSITION: [3.625, 7.5, 2.75, 5.75, 6.75, -90, 0], + }, + { + POSITION: [6, 8, 0.25, 10.5, 0, 0, 0], + }, + ], +} +Class.sidewinder = { + PARENT: "genericTank", + LABEL: "Sidewinder", + DANGER: 6, + STAT_NAMES: statnames.desmos, + UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + GUNS: [ + { + POSITION: [10, 8.5, 1.4, 7, 0, 0, 0] + }, + { + POSITION: [20, 10, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: "desmos"}] + } + }, + { + POSITION: [4.25, 11, 2, 2.25, -4.25, 92.5, 0] + }, + { + POSITION: [4.25, 11, 2, 2.25, 4.25, -92.5, 0] + } + ] +} +Class.undertow = { + PARENT: "genericTank", + LABEL: "Undertow", + DANGER: 6, + UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + GUNS: [ + { + POSITION: [14, 12, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { reload: 1.2 }]), + TYPE: "bullet" + } + }, + { + POSITION: [11.25, 8, 0.15, 4.25, 4, 13.5, 0] + }, + { + POSITION: [11.25, 8, 0.15, 4.25, -4, -13.5, 0] + } + ] +} +Class.repeater = { + PARENT: "genericTank", + LABEL: "Repeater", + GUNS: [ + { + POSITION: [20, 10, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + TYPE: ["splitterBullet", {MOTION_TYPE: "desmos"}] + } + }, + { + POSITION: [4.625, 9.5, 2, 0.375, -8, 91.5, 0] + }, + { + POSITION: [4.625, 9.5, 2, 0.375, 8, -91.5, 0] + }, + { + POSITION: [3.75, 10, 2.125, 0, -4.75, 50, 0] + }, + { + POSITION: [3.75, 10, 2.125, 0, 4.75, -50, 0] + } + ] +} + +// Helix upgrades +Class.triplex = { + PARENT: "genericTank", + LABEL: "Triplex", + DANGER: 7, + STAT_NAMES: statnames.desmos, + GUNS: [ + { + POSITION: [18, 10, 0.7, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.desmos]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 10, 0.7, 0, 0, 45, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: "desmos"}] + }, + }, + { + POSITION: [18, 10, 0.7, 0, 0, -45, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: true}]}] + }, + }, + { + POSITION: [3.75, 10, 2.125, 1, -4.25, 10, 0], + }, + { + POSITION: [3.75, 10, 2.125, 1, 4.25, -10, 0], + }, + { + POSITION: [5, 6, 0.5, 10.5, 0, 22.5, 0], + }, + { + POSITION: [5, 6, 0.5, 10.5, 0, -22.5, 0], + }, + ], +} +Class.quadruplex = { + PARENT: "genericTank", + LABEL: "Quadruplex", + DANGER: 7, + STAT_NAMES: statnames.desmos, + GUNS: [ + { + POSITION: [20, 10, 0.8, 0, 0, 45, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25}]}] + } + }, + { + POSITION: [3.75, 10, 2.125, 1.25, -6.25, 135, 0] + }, + { + POSITION: [3.75, 10, 2.125, 1.25, 6.25, -45, 0] + }, + { + POSITION: [20, 10, 0.8, 0, 0, -45, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25, invert: true}]}] + } + }, + { + POSITION: [3.75, 10, 2.125, 1.25, -6.25, 45, 0] + }, + { + POSITION: [3.75, 10, 2.125, 1.25, 6.25, -135, 0] + }, + { + POSITION: [20, 10, 0.8, 0, 0, 135, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10}]}] + } + }, + { + POSITION: [3.75, 10, 2.125, 1.25, -6.25, -135, 0] + }, + { + POSITION: [3.75, 10, 2.125, 1.25, 6.25, 45, 0] + }, + { + POSITION: [20, 10, 0.8, 0, 0, -135, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10, invert: true}]}] + } + }, + { + POSITION: [3.75, 10, 2.125, 1.25, -6.25, -45, 0] + }, + { + POSITION: [3.75, 10, 2.125, 1.25, 6.25, 135, 0] + }, + ], +} + +// Sidewinder upgrades +Class.coil = { + PARENT: "genericTank", + LABEL: "Coil", + DANGER: 7, + STAT_NAMES: statnames.desmos, + UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + GUNS: [ + { + POSITION: [20, 8, 0.75, 0, -5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: false}]}] + }, + }, + { + POSITION: [20, 8, 0.75, 0, 5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: true}]}] + }, + }, + { + POSITION: [21, 4, 0.75, 0, -5, 0, 0] + }, + { + POSITION: [21, 4, 0.75, 0, 5, 0, 0] + }, + { + POSITION: [3.625, 7.5, 2.75, 5.75, -6.75, 90, 0], + }, + { + POSITION: [3.625, 7.5, 2.75, 5.75, 6.75, -90, 0], + }, + { + POSITION: [6, 8, 0.25, 10.5, 0, 0, 0], + } + ] +} +Class.python = { + PARENT: "genericTank", + LABEL: "Python", + DANGER: 7, + STAT_NAMES: statnames.desmos, + UPGRADE_TOOLTIP: "[DEV NOTE] This tank is a placeholder!" +} +Class.ranch = { + PARENT: "genericTank", + LABEL: "Ranch", + DANGER: 7, + STAT_NAMES: statnames.drone, + UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + BODY: { + SPEED: base.SPEED * 0.8, + FOV: 1.1, + }, + GUNS: [ + { + POSITION: [4.5, 10, 1, 10.5, 0, 0, 0], + }, + { + POSITION: [1, 12, 1, 15, 0, 0, 0], + PROPERTIES: { + MAX_CHILDREN: 3, + SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory]), + TYPE: "minion", + STAT_CALCULATOR: gunCalcNames.drone, + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, + }, + { + POSITION: [11.5, 12, 1, 0, 0, 0, 0], + }, + { + POSITION: [5, 7.5, 2.5, 1, -4.5, 95, 0], + }, + { + POSITION: [5, 7.5, 2.5, 1, 4.5, -95, 0], + }, + ], +} +Class.oroboros = { + PARENT: "genericTank", + LABEL: "Oroboros", + DANGER: 7, + STAT_NAMES: statnames.desmos, + UPGRADE_TOOLTIP: "[DEV NOTE] This tank is a placeholder!" +} +Class.cocci = { + PARENT: "genericSmasher", + LABEL: "Cocci", + UPGRADE_TOOLTIP: "[DEV NOTE] This tank is a placeholder!", + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + } + ] +} + +// Undertow upgrades +Class.riptide = { + PARENT: "genericTank", + LABEL: "Riptide", + DANGER: 7, + UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + GUNS: [ + { + POSITION: [6.5, 23.5, 0.25, 3, 0, 180, 0], + }, + { + POSITION: [18, 16, 0.75, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { size: 0.9, reload: 1.2 }]), + TYPE: "bullet" + } + }, + { + POSITION: [17, 16, 0.1, 0.25, 4, 13.5, 0] + }, + { + POSITION: [17, 16, 0.1, 0.25, -4, -13.5, 0] + } + ] +} +// Repeater upgrades +Class.iterator = { + PARENT: "genericTank", + LABEL: "Iterator", + DANGER: 7, + STAT_NAMES: statnames.desmos, + GUNS: [ + { + POSITION: [22, 10, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + TYPE: ["superSplitterBullet", {MOTION_TYPE: "desmos"}] + } + }, + { + POSITION: [4.625, 10.5, 2.75, 0.375, -7, 91.5, 0] + }, + { + POSITION: [4.625, 10.5, 2.75, 0.375, 7, -91.5, 0] + }, + { + POSITION: [4, 9, 3, 1.5, -5, 95, 0] + }, + { + POSITION: [4, 9, 3, 1.5, 5, -95, 0] + }, + { + POSITION: [3.75, 10, 2.125, -1.5, -5.25, 50, 0] + }, + { + POSITION: [3.75, 10, 2.125, -1.5, 5.25, -50, 0] + } + ] +} +Class.duplicator = { + PARENT: "genericTank", + LABEL: "Duplicator", + DANGER: 7, + STAT_NAMES: statnames.desmos, + GUNS: [ + { + POSITION: [20, 10, 0.8, 0, 0, 20, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), + TYPE: ["splitterBullet", {MOTION_TYPE: ["desmos", {invert: false}]}] + } + }, + { + POSITION: [20, 10, 0.8, 0, 0, -20, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), + TYPE: ["splitterBullet", {MOTION_TYPE: ["desmos", {invert: true}]}] + } + }, + { + POSITION: [5.625, 9.5, 2, 0.375-1, -8, 111.5, 0] + }, + { + POSITION: [3.75, 10, 2.125, 0, 4.75, -30, 0] + }, + { + POSITION: [5.625, 9.5, 2, 0.375-1, 8, -111.5, 0] + }, + { + POSITION: [3.75, 10, 2.125, 0, -4.75, 30, 0] + }, + { + POSITION: [17, 8, 0.65, 0, 0, 0, 0] + }, + { + POSITION: [18, 8, 0.25, 0, 0, 0, 0] + }, + ] +} + + + +// Smasher upgrades +Class.megaSmasher = { + PARENT: "genericSmasher", + LABEL: "Mega-Smasher", + BODY: { + SPEED: 1.05 * base.SPEED, + FOV: 1.1 * base.FOV, + DENSITY: 4 * base.DENSITY, + }, + TURRETS: [ + { + POSITION: [25, 0, 0, 0, 360, 0], + TYPE: "smasherBody", + }, + ], +} +Class.spike = { + PARENT: "genericSmasher", + LABEL: "Spike", + BODY: { + SPEED: base.SPEED * 0.9, + DAMAGE: base.DAMAGE * 1.1, + }, + TURRETS: [ + { + POSITION: [18.5, 0, 0, 0, 360, 0], + TYPE: "spikeBody", + }, + { + POSITION: [18.5, 0, 0, 90, 360, 0], + TYPE: "spikeBody", + }, + { + POSITION: [18.5, 0, 0, 180, 360, 0], + TYPE: "spikeBody", + }, + { + POSITION: [18.5, 0, 0, 270, 360, 0], + TYPE: "spikeBody", + }, + ], +} +Class.landmine = { + PARENT: "genericSmasher", + LABEL: "Landmine", + INVISIBLE: [0.06, 0.01], + TOOLTIP: "Stay still to turn invisible.", + BODY: { + SPEED: 1.1 * base.SPEED + }, + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, + { + POSITION: [21.5, 0, 0, 30, 360, 0], + TYPE: "landmineBody" + } + ] +} + +// Healer upgrades +Class.medic = { + PARENT: "genericTank", + LABEL: "Medic", + BODY: { + FOV: base.FOV * 1.2, + }, + TURRETS: [ + { + POSITION: [13, 0, 0, 0, 360, 1], + TYPE: "healerSymbol", + }, + ], + GUNS: [ + { + POSITION: [8, 9, -0.5, 16.5, 0, 0, 0], + }, + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.healer, g.sniper]), + TYPE: "healerBullet", + }, + }, + ], + STAT_NAMES: statnames.heal, +} +Class.ambulance = { + PARENT: "genericTank", + LABEL: "Ambulance", + BODY: { + HEALTH: base.HEALTH * 0.8, + SHIELD: base.SHIELD * 0.8, + DENSITY: base.DENSITY * 0.6, + }, + TURRETS: [ + { + POSITION: [13, 0, 0, 0, 360, 1], + TYPE: "healerSymbol", + }, + ], + GUNS: [ + { + POSITION: [8, 9, -0.5, 12.5, 0, 0, 0], + }, + { + POSITION: [18, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }, g.healer]), + TYPE: "healerBullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + ], + STAT_NAMES: statnames.heal, +} +Class.surgeon = { + PARENT: "genericTank", + LABEL: "Surgeon", + STAT_NAMES: statnames.trap, + BODY: { + SPEED: base.SPEED * 0.75, + FOV: base.FOV * 1.15, + }, + TURRETS: [ + { + POSITION: [13, 0, 0, 0, 360, 1], + TYPE: "healerSymbol", + }, + ], + GUNS: [ + { + POSITION: [5, 11, 1, 10.5, 0, 0, 0], + }, + { + POSITION: [3, 14, 1, 15.5, 0, 0, 0], + }, + { + POSITION: [2, 14, 1.3, 18, 0, 0, 0], + PROPERTIES: { + MAX_CHILDREN: 2, + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, { speed: 0.7, maxSpeed: 0.7 }]), + TYPE: "surgeonPillbox", + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.block + }, + }, + { + POSITION: [4, 14, 1, 8, 0, 0, 0], + }, + ], + STAT_NAMES: statnames.heal, +} +Class.paramedic = { + PARENT: "genericTank", + LABEL: "Paramedic", + BODY: { + SPEED: base.SPEED * 0.9, + }, + TURRETS: [ + { + POSITION: [13, 0, 0, 0, 360, 1], + TYPE: "healerSymbol", + }, + ], + GUNS: [ + { + POSITION: [8, 9, -0.5, 10, 0, -17.5, 0.5], + }, + { + POSITION: [15.5, 10, 1, 0, 0, -17.5, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.healer]), + TYPE: "healerBullet", + }, + }, + { + POSITION: [8, 9, -0.5, 10, 0, 17.5, 0.5], + }, + { + POSITION: [15.5, 10, 1, 0, 0, 17.5, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.healer]), + TYPE: "healerBullet", + }, + }, + { + POSITION: [8, 9, -0.5, 12.5, 0, 0, 0], + }, + { + POSITION: [18, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.tripleShot, g.healer]), + TYPE: "healerBullet", + }, + }, + ], + STAT_NAMES: statnames.heal, +} + +// Bird tanks +Class.falcon = makeBird("assassin", "Falcon") + +Class.vulture = makeBird({ + PARENT: "genericTank", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2, + }, + GUNS: [ + { + POSITION: [22, 7, -1.5, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 7.5, -1.5, 0, 0, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, {size: 7/7.5}]), + TYPE: "bullet" + } + }, + { + POSITION: [18, 8, -1.5, 0, 0, 0, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, {size: 7/8}]), + TYPE: "bullet" + } + } + ] +}, "Vulture") +Class.phoenix = makeBird("sprayer", "Phoenix") +Class.eagle = makeBird("pounder", "Eagle") + +// Over tanks +Class.overgunner = makeOver({ + PARENT: "genericTank", + LABEL: "Gunner", + DANGER: 6, + GUNS: [ + { + POSITION: [19, 2, 1, 0, -2.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 2, 1, 0, 2.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 11, 1, 0, 0, 0, 0], + }, + ], +}) +Class.overtrapper = makeOver({ + PARENT: "genericTank", + LABEL: "Trapper", + DANGER: 6, + STAT_NAMES: statnames.mixed, + BODY: { + SPEED: base.SPEED * 0.8, + FOV: base.FOV * 1.2 + }, + GUNS: [ + { + POSITION: [14, 8, 1, 0, 0, 0, 0], + }, + { + POSITION: [4, 8, 1.5, 14, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + } + ] +}) + +//delta upgrades +Class.minilaser = { + PARENT: "genericTank", + LABEL: "Plasma SMG", + DANGER: 6, + BODY: { + FOV: 1.2, + }, + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [21, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 1 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 2 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + { + POSITION: [24, 1, 1, 0, 0, 0, 2 / 3], + PROPERTIES: { + COLOR: 'red', + SHOOT_SETTINGS: combineStats([g.fake]), + TYPE: "laser", + }, + } + ], +} +Class.volute = { + PARENT: "genericTank", + LABEL: "Volute", + DANGER: 6, + STAT_NAMES: statnames.desmos, + GUNS: [ + { + POSITION: [20, 13, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.pounder]), + TYPE: ["bullet", {MOTION_TYPE: "desmos"}] + }, + }, + { + POSITION: [5, 10, 2.125, 1, -6.375, 90, 0], + }, + { + POSITION: [5, 10, 2.125, 1, 6.375, -90, 0], + }, + ], +} +Class.cruiserdrive = { + PARENT: "genericTank", + LABEL: "Swarmdrive", + DANGER: 6, + FACING_TYPE: "locksFacing", + STAT_NAMES: statnames.swarm, + BODY: { + FOV: 1.2 * base.FOV, + }, + GUNS: [ + { + POSITION: [7, 7.5, 0.6, 7, 4, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "autoturretswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, -4, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "autoturretswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], +} +Class.shrapnelgun = { + PARENT: "genericTank", + LABEL: "Albuquerque", + DANGER: 7, + GUNS: [{ + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, { reload: 1.8 }]), + TYPE: "grenade" + } + } + ], + TURRETS: [{ + POSITION: [8.2, 16.7, 0, 0, 0, 0], + TYPE: ["grenadeDeco", { MIRROR_MASTER_ANGLE: true }], + } + ] +} +Class.firecracker = { + PARENT: "genericTank", + LABEL: "Firecracker", + DANGER: 7, + GUNS: [{ + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, g.halfspeed, { reload: 2.5 }]), + TYPE: "firecrackerbomb" + } + } + ], + TURRETS: [{ + POSITION: [8.2, 13, 0, 0, 0, 2], + TYPE: ["firecrackerDeco", { MIRROR_MASTER_ANGLE: true }], + } + ] +} +Class.inception = { + PARENT: "genericTank", + LABEL: "Inception", + DANGER: 4, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "autobullet", + } + } + ], + TURRETS: [{ + POSITION: [5.5, 18, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.inceptionist = { + PARENT: "genericTank", + LABEL: "Ceptionist", + DANGER: 4, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "ceptionistbullet", + } + } + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.twinceptionist = { + PARENT: "genericTank", + LABEL: "Twinceptionist", + DANGER: 4, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "ceptionistbullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "ceptionistbullet" + } + } + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.machinception = { + PARENT: "genericTank", + LABEL: "Machceptioner", + DANGER: 4, + GUNS: [ + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "autobullet" + } + } + ], + TURRETS: [{ + POSITION: [6.5, 20, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.machceptionist = { + PARENT: "genericTank", + LABEL: "Machceptionist", + DANGER: 4, + GUNS: [ + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "ceptionistbullet" + } + } + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.flankinception = makeMulti({ + PARENT: "genericTank", + BODY: { + SPEED: 1.1 * base.SPEED + }, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "autobullet" + } + } + ], + TURRETS: [{ + POSITION: [5.5, 18, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + },{ + POSITION: [5.5, 18, 0, 120, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + },{ + POSITION: [5.5, 18, 0, 240, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +}, 3, "Flankceptioner") +Class.flankceptionist = makeMulti({ + PARENT: "genericTank", + BODY: { + SPEED: 1.1 * base.SPEED + }, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "ceptionistbullet" + } + } + ], + TURRETS: [{ + POSITION: [5.5, 18, 0, 0, 0, 0], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + },{ + POSITION: [5.5, 18, 0, 120, 0, 0], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + },{ + POSITION: [5.5, 18, 0, 240, 0, 0], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +}, 3, "Flankceptionist") +Class.flankdue = makeMulti({ + PARENT: "genericTank", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.1, + SPEED: base.SPEED * 1.1, + }, + GUNS: [{ + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter]), + TYPE: "bullet" + } + }] +}, 3, "Flankduer") +Class.tailgator = { + PARENT: "genericTank", + LABEL: "Tailgator", + DANGER: 4, + GUNS: [ + { + POSITION: [20.5, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), + TYPE: "heavyautobullet" + } + } + ], + TURRETS: [{ + POSITION: [7.5, 20, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.poundceptionist = { + PARENT: "genericTank", + LABEL: "PoundCeptionist", + DANGER: 4, + GUNS: [ + { + POSITION: [20.5, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), + TYPE: "ceptionistbullet" + } + } + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.interceptor = { + PARENT: "genericTank", + LABEL: "Interceptor", + DANGER: 4, + GUNS: [ + { + POSITION: [21, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), + TYPE: "heavyautobullet" + } + } + ], + TURRETS: [{ + POSITION: [7.5, 20, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.revolutionist = { + PARENT: "genericTank", + LABEL: "Revolutionist", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBase", + }, + ], +}; +Class.proton = { + PARENT: "genericTank", + LABEL: "Proton", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "protonturretBase", + }, + ], +}; +Class.baseThrower = { + PARENT: "genericTank", + LABEL: "Kivaaritehdas", + DANGER: 6, + SYNC_TURRET_SKILLS: true, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [1, 38, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.bitlessspeed, g.halfdamage, g.halfpen, g.kiva]), + TYPE: ["baseBullet", { COLOR: "orange", KEEP_OWN_COLOR: false }], + ALT_FIRE: true, + ALPHA: 0 + } + }], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBaseKiva" + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + body.define(Class.baseThrowerFire) + } + } + ] +}; +Class.baseThrowerFire = { + PARENT: "genericTank", + LABEL: "Kivaaritehdas", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }] +}; +Class.subverter = { + PARENT: "genericTank", + LABEL: "Subverter", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "subverterturretBase", + }, + ], +}; +Class.pion = { + PARENT: "genericSmasher", + LABEL: "Pion", + DANGER: 6, + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, { + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "pionturretBase", + }] +} +Class.equilibrium = { + PARENT: "genericTank", + LABEL: "Equilibrium", + DANGER: 6, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.twin]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.twin]), + TYPE: "bullet" + } + } + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBase", + }, + ], +}; +Class.hadron = { + PARENT: "genericTank", + LABEL: "Hadron", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "hadronturretBase", + } + ], +}; +Class.hivemind = { + PARENT: "genericTank", + LABEL: "Hivemind", + //CONTROLLERS: ['nearestDifferentMaster'], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 90, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "hiveprobe", + MAX_CHILDREN: 1 + } + }, + { + POSITION: [0, 20, 1, 0, 0, 270, 3.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "hiveprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [27, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; +Class.cloner = { + PARENT: ["genericTank"], + LABEL: "Cloner", + //CONTROLLERS: ['nearestDifferentMaster'], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 180, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "clonerprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [24, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; + Class.dictator = { + PARENT: ["genericTank"], + LABEL: "Dictator", + STAT_NAMES: statnames.drone, + DANGER: 5, + SHAPE: 8, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + FOV: base.FOV * 1.1, + }, + MAX_CHILDREN: 4, + GUNS: [ { /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [ 6, 12, 1.2, 8, 0, 0, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "fastdrone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, }, + ], + }; +Class.littleHunter = { + PARENT: "genericTank", + LABEL: "Subduer", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter]), + TYPE: "bullet" + } + }] +}; +Class.subway = makeBird({ + PARENT: "genericTank", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.05 + }, + GUNS: [{ + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.triAngle, g.triAngleFront, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.triAngle, g.triAngleFront, g.hunter]), + TYPE: "bullet" + } + }] +}, "Subway") +Class.binary = { + PARENT: "genericTank", + LABEL: "Binary", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [20, 5, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [17, 8, 1, 0, 5.5, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter]), + TYPE: "bullet" + } + }, { + POSITION: [20, 5, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [17, 8, 1, 0, -5.5, 0, 0.7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter]), + TYPE: "bullet" + } + }] +} +Class.trinary = { + PARENT: "genericTank", + LABEL: 'Trinary', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .7, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [22, 5, 1, 0, 2, 20, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [19, 8, 1, 0, 2, 20, .7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [22, 5, 1, 0, -2, -20, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [19, 8, 1, 0, -2, -20, .7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [25, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [22, 8, 1, 0, 0, 0, .2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }] +}; +Class.bigSubduer = { + PARENT: "genericTank", + LABEL: 'Mitochondrion', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .9, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [26, 2, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [23, 5, 1, 0, 0, 0, .15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, .3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.predator]), + TYPE: "bullet" + } + }] +} +Class.clubbin = makeMulti({ + PARENT: "genericTank", + LABEL: 'Mitochondrion', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .9, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [26, 2, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [23, 5, 1, 0, 0, 0, .15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, .3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.predator]), + TYPE: "bullet" + } + }] +}, 3, "Clubbin") +Class.biggerSubduer = { + PARENT: "genericTank", + LABEL: 'Cytochrome', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 0.8, + SPEED: base.SPEED * 0.95, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [29, 2, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.hunterSecondary, g.predator, g.lessrecoil]), + TYPE: "bullet" + } + }, { + POSITION: [26, 4, 1, 0, 0, 0, 2/15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator, g.lessrecoil]), + TYPE: "bullet" + } + }, { + POSITION: [23, 6, 1, 0, 0, 0, 4/15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.predator]), + TYPE: "bullet" + } + }] +} +Class.accelminigun = { + PARENT: "genericTank", + LABEL: "Rainmaker", + DANGER: 6, + BODY: { + FOV: base.FOV * 1.4 + }, + GUNS: [ + { + POSITION: [8, .1, -54, 21, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.fake, g.triplereload]), + TYPE: "bullet", + COLOR: 12 + } + }, + { + POSITION: [21, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + } + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + } + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + } + } + ] +} +Class.railgun = { + PARENT: "genericTank", + DANGER: 6, + LABEL: "Railgun", + BODY: { + SPEED: 0.9 * base.SPEED, + FOV: 1.25 * base.FOV + }, + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [1, 6.5, 1, 25, 0, 0, 0.15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.fast, g.fast, g.railgun]), + TYPE: "bullet" + } + }, { + POSITION: [1, 6.5, 1, 10, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.railgun]), + TYPE: "bullet" + } + }, { + POSITION: [1, 6.5, 1, 15, 0, 0, 0.05], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.railgun]), + TYPE: "bullet" + } + }, + { + POSITION: [1, 6.5, 1, 20, 0, 0, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.fast, g.railgun]), + TYPE: "bullet" + } + }, + { + POSITION: [22, 1.9, 1, 5, 4, 0, 0] + }, + { + POSITION: [22, 1.9, 1, 5, -4, 0, 0] + } + ] +} +Class.skater = { + PARENT: "genericSmasher", + LABEL: "Skater", + DANGER: 6, + BODY: { + SPEED: base.SPEED * 2.4, + ACCELERATION: base.ACCEL * 0.56, + }, + + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, { + POSITION: [15, 0, 0, 0, 360, 1], + TYPE: ["skaterDeco", { COLOR: "#49bdde" }] + } + ] +} +Class.revodirector = { + PARENT: "genericTank", + LABEL: "Solar System", + STAT_NAMES: statnames.drone, + BODY: { + FOV: base.FOV * 1.1 + }, + GUNS: [ + { + POSITION: [6, 11, 1.3, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone]), + TYPE: "revoorbitdrone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 5 + } + } + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBasenoguns", + }, { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "overdriveDeco", + }, + ], +} +Class.directdrive = { + PARENT: "genericTank", + LABEL: "Motor", + STAT_NAMES: statnames.drone, + BODY: { + FOV: base.FOV * 1.1 + }, + GUNS: [ + { + POSITION: [6, 11, 1.3, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone]), + TYPE: "turretedDrone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 6 + } + } + ], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "overdriveDeco", + }, + ] +} +Class.contagion = { + PARENT: "genericTank", + LABEL: 'Contagion', + DANGER: 6, + BODY: { + FOV: 1.1, + ACCELERATION: base.ACCEL * 0.9 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [13, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [4, 8, 1.7, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.morerange, g.lessspread]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + }] +}; +Class.triContagion = makeMulti({ + PARENT: "genericTank", + DANGER: 6, + BODY: { + FOV: 1.1, + ACCELERATION: base.ACCEL * 0.9 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [13, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [4, 8, 1.7, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.morerange, g.lessspread, g.flankGuard]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + }] +}, 3, "Tri-Contagion"); +Class.autoContagion = makeAuto(Class.contagion); +Class.fort = { + PARENT: "genericTank", + LABEL: "Fort", + DANGER: 7, + BODY: { + SPEED: base.SPEED * 0.8, + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.15 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [22, 5.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [18, 12, 1, 0, 0, 0, 0] + }, { + POSITION: [2, 12, 1.1, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), + TYPE: "setTrap" + } + }] +}; +Class.droneTrapper = { + PARENT: "genericTank", + LABEL: "Magician", + DANGER: 7, + BODY: { + FOV: 1.1, + ACCELERATION: base.ACCEL * .9 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.lesspower]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 6 + } + }, { + POSITION: [13, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [4, 8, 1.7, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + }] +} +Class.trojan = { + PARENT: "genericTank", + LABEL: "Trojan", + STAT_NAMES: statnames.mixed, + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 0.675, + SPEED: base.SPEED * 0.875, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, 0, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.bitlessreload]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 4 + } + }, { + POSITION: [19, 5.5, 1, 0, 0, 180, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [6, 12, 1.2, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.bitlessreload]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 4 + } + }] +} +Class.gundirector = { + PARENT: "genericTank", + LABEL: "Pathogen", + STAT_NAMES: statnames.mixed, + DANGER: 6, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: base.SPEED * 0.95, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, 0, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.bitlessreload]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 6 + } + }] +} +Class.protist = { + PARENT: "genericTank", + LABEL: "Protist", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .9, + SPEED: base.SPEED * .8, + FOV: 1.1 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [18, 5.5, 1, 0, 0, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [4.5, 10, 1, 10.5, 0, 0, 0] + }, { + POSITION: [1, 12, 1.01, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory]), + TYPE: "minion", + STAT_CALCULATOR: gunCalcNames.drone, + AUTOFIRE: true, + SYNCS_SKILLS: true, + MAX_CHILDREN: 4 + } + }, { + POSITION: [3.5, 12, 1, 8, 0, 0, 0] + }] +}; +Class.acid = { + PARENT: "genericTank", + LABEL: 'Acid', + DANGER: 6, + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: base.SPEED * 0.85, + FOV: base.FOV * 1.2, + }, + GUNS: [{ + POSITION: [24, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "poisonbullet", + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "green" + } + }] +}; +Class.disintegrator = { + PARENT: "genericTank", + DANGER: 6, + LABEL: "Disintegrator", + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: 0.7 * base.SPEED, + FOV: 1.4 * base.FOV + }, + GUNS: [ + { + POSITION: [27, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), + TYPE: "poisonbullet" + } + }, { + POSITION: [16, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "green" + } + }, { + POSITION: [5, 8, -1.4, 8, 0, 0, 0] + } + ] +} +Class.chiller = { + PARENT: "genericTank", + LABEL: 'Chiller', + DANGER: 6, + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.7, + FOV: 1.2 + }, + GUNS: [{ + POSITION: [24, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "icebullet" + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + }] +}; +Class.freezer = { + PARENT: "genericTank", + DANGER: 6, + LABEL: "Freezer", + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: 0.7 * base.SPEED, + FOV: 1.4 * base.FOV + }, + GUNS: [ + { + POSITION: [27, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), + TYPE: "icebullet" + } + }, { + POSITION: [16, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + }, { + POSITION: [5, 8, -1.4, 8, 0, 0, 0] + } + ] +} +Class.helecopter = { + PARENT: "genericTank", + LABEL: "Attack Helicopter", + BODY: { + SPEED: 6, + PUSHABILITY: 0, + ACCELERATION: 0.8, + }, + DANGER: 6, + GUNS: [{ + POSITION: [19, 2, 1, 0, -2.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + HAS_NO_RECOIL: true, + }, + }, + { + POSITION: [19, 2, 1, 0, 2.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + HAS_NO_RECOIL: true, + }, + }, { + POSITION: [2, 2, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.triAngle, g.thruster, g.thruster, g.fakewithrecoil]), + TYPE: "bullet", + AUTOFIRE: true, + }, + }, { + POSITION: [12, 11, 1, 0, 0, 0, 0], + }, + { + POSITION: [26.5, 8, 0.7, 0, 0, 180, 0], + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 180, 0], + }, + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [20, -27.5, 0, 0, 360, 1], + TYPE: "helecoptersblade", + }, + { + /* SIZE X Y ANGLE ARC */ + POSITION: [25, 0, 0, 0, 360, 1], + TYPE: "helecopterblade", + }, + ], +}; +Class.twinsniper = { + PARENT: "genericTank", + LABEL: "Twiper", + DANGER: 7, + BODY: { + FOV: 1.1 * base.FOV + }, + CONTROLLERS: ["zoom"], + TOOLTIP: "Hold right click to zoom.", + GUNS: [ + { + POSITION: [24, 8.5, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sniper]), + TYPE: "bullet" + } + }, + { + POSITION: [24, 8.5, 1, 0, -5.5, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sniper]), + TYPE: "bullet" + } + } + ] +} +Class.backShield = { + PARENT: "genericTank", + LABEL: 'BackShield', + DANGER: 7, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }], + TURRETS: [{ + POSITION: [18, 18, 0, 180, 360, 1], + TYPE: ["backshieldturret", { SHAPE: 12 }], + VULNERABLE: true + }] +}; +Class.mirrorBackShield = { + PARENT: "genericTank", + LABEL: 'BackMirror', + DANGER: 7, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }], + TURRETS: [{ + POSITION: [16.7, -18.5, 0, 0, 360, 1], + TYPE: ["mirrorbackshieldturret", { SHAPE: 14 }], + VULNERABLE: true + }] +}; +Class.waterfall = { + PARENT: "genericTank", + LABEL: "Waterfall", + DANGER: 6, + GUNS: [ + { + POSITION: [21, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 2, 1, 0, -2.5, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 2, 1, 0, 2.5, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 11, 1, 0, 0, 180, 0], + }, + ], +} +Class.auto2 = { + PARENT: "genericTank", + LABEL: "Auto-2", + DANGER: 5, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [{ + POSITION: [11, 8, 0, 0, 190, 0], + TYPE: "autoTankGun" + }, { + POSITION: [11, 8, 0, 180, 190, 0], + TYPE: "autoTankGun" + }] +} +Class.swivel2 = { + PARENT: "genericTank", + LABEL: "Swivel-2", + DANGER: 5, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [{ + POSITION: [9, 7, 0, 0, 360, 1], + TYPE: "autoTankGun" + }, { + POSITION: [9, 7, 0, 180, 360, 1], + TYPE: "autoTankGun" + }] +} +Class.swivel3 = { + PARENT: "genericTank", + LABEL: "Swivel-3", + DANGER: 5, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [{ + POSITION: [11, 8, 0, 0, 360, 1], + TYPE: "autoTankGun" + }, { + POSITION: [11, 8, 0, 120, 360, 1], + TYPE: "autoTankGun" + }, { + POSITION: [11, 8, 0, 240, 360, 1], + TYPE: "autoTankGun" + }] +} +const timer = (run, duration) => { + let timer = setInterval(() => run(), 31.25); + setTimeout(() => { + clearInterval(timer); + }, duration * 1000); +}; + const damageOnTick = (body, instance, multiplier, duration, stopAtSetHealth, hitsOwnTeam) => { + if (!instance) return + if (!instance.damageOnTicking && !instance.godmode && !instance.invuln && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) { + instance.damageOnTicking = true; + setTimeout(() => { + instance.damageOnTicking = false; + }, 2 * duration * 1000); + timer(() => { + if (instance.damageOnTicking && instance.health.amount > stopAtSetHealth && instance.health.amount - (multiplier * 0.5) > stopAtSetHealth) { + instance.health.amount -= multiplier * 0.5; + } //else {if (instance.health.amount - (multiplier * 0.5) < stopAtSetHealth) {instance.health.amount === stopAtSetHealth}} + }, 2 * duration); + } +}; +const iceOnTick = (body, instance, multiplier, duration, hitsOwnTeam) => { + if (!instance) return + if (!instance.invuln && !instance.godmode && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) timer(() => { + instance.velocity.x /= 1.05 * multiplier; + instance.velocity.y /= 1.05 * multiplier; + }, 1.5 * duration); +}; +Class.acidsmasher = { + PARENT: "genericSmasher", + LABEL: "Injector", + DANGER: 6, + BODY: { + DAMAGE: base.DAMAGE * 0.87, + }, + TURRETS: [ + { + POSITION: [21.8, 0, 0, 0, 360, 0], + TYPE: "greenSmasherBody", + }, { + POSITION: [22.3, 0, 0, 0, 360, -1], + TYPE: "smasherBody" + } + ], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + damageOnTick(body, damageTool[0], 1, 1, 1, true); + } + }] +} +Class.autoinceptionistbody = { + PARENT: "genericTank", + LABEL: "Auto-Inceptionist base", + DANGER: 4, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "ceptionistbullet", + } + } + ] +} + +// Auto tanks +Class.autoBasic = makeAuto(Class.basic, "Auto-Basic"); +Class.autoTwin = makeAuto(Class.twin, "Auto-Twin"); +Class.autoMach = makeAuto(Class.machineGun, "Auto-Mach"); +Class.autoSniper = makeAuto(Class.sniper, "Auto-Sniper"); +Class.autoFlank = makeAuto(Class.flankGuard, "Auto-Flank"); +Class.autoDirector = makeAuto(Class.director, "Chairman"); +Class.autoPound = makeAuto(Class.pounder, "Scratcher"); +Class.autoTrap = makeAuto(Class.trapper, "Auto-Trapper"); +Class.autoDesmos = makeAuto(Class.desmos, "Auto-Desmos"); +Class.autolittleHunter = makeAuto(Class.littleHunter, "Auto-Subduer") +Class.autoinception = makeAuto(Class.inception, "Auto-inception"); +Class.autoauto2 = makeAuto(Class.auto2, "Auto-Auto-2"); +Class.autoCloner = makeAuto({ + PARENT: "genericTank", + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 180, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "autoclonerprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [24, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}, "Auto-Cloner"); +Class.autoDouble = makeAuto(Class.doubleTwin, "Auto-Double") +Class.autoAssassin = makeAuto(Class.assassin) +Class.autoGunner = makeAuto(Class.gunner) +Class.autoTriAngle = makeAuto(Class.triAngle) +Class.autoOverseer = makeAuto(Class.overseer) +Class.autoRevolutionist = makeAuto(Class.revolutionist, "Audioboard"); +Class.autoCruiser = makeAuto(Class.cruiser) +Class.autoSpawner = makeAuto(Class.spawner) +Class.autoBuilder = makeAuto(Class.builder) +Class.autoBinary = makeAuto(Class.binary, "Auto-Binary") +Class.autoinceptionist = makeAuto(Class.autoinceptionistbody, "Auto-Inceptionist", {type: 'ceptionistturret'}); +Class.autoGundirector = makeAuto(Class.gundirector, "Auto-Pathogen") +Class.autoBigSubduer = makeAuto(Class.bigSubduer, "Auto-Mitochondrion") +Class.autoFlankdue = makeAuto(Class.flankdue, "Auto-Flankduer") +Class.autoTripleShot = makeAuto(Class.tripleShot, "Auto-Triple Shot"); +Class.autoHunter = makeAuto(Class.hunter, "Auto-Hunter"); +Class.autoRifle = makeAuto(Class.rifle, "Auto-Rifle"); +Class.autoTwinsniper = makeAuto(Class.twinsniper, "Auto-Twiper"); +Class.autoAcid = makeAuto(Class.acid, "Cyanide"); +Class.autoChill = makeAuto(Class.chiller, "Auto-Chiller"); +Class.autoMini = makeAuto(Class.minigun, "Auto-Minigun"); +Class.autoSprayer = makeAuto(Class.sprayer, "Auto-Sprayer"); +Class.autoHexaTank = makeAuto(Class.hexaTank, "Auto-HexaTank"); +Class.autoAuto3 = makeAuto(Class.auto3, "Auto-Auto3"); +Class.autoUnderseer = makeAuto(Class.underseer, "Auto-Underseer"); +Class.autoDestroy = makeAuto(Class.destroyer, "Auto-Destroyer"); +Class.autoArtillery = makeAuto(Class.artillery, "Auto-Artillery"); +Class.autoLaunch = makeAuto(Class.launcher, "Auto-Launcher"); +Class.autoTriTrapper = makeAuto(Class.triTrapper, "Auto-Tri Trapper"); +Class.autoTrapGuard = makeAuto(Class.trapGuard, "Auto-TrapGuard"); +Class.autoSidewinder = makeAuto(Class.sidewinder, "Auto-Sidewinder"); +Class.autoHelix = makeAuto(Class.helix, "Auto-Helix"); +Class.autoUndertow = makeAuto(Class.undertow, "Auto-Undertow"); +Class.autoRepeater = makeAuto(Class.repeater, "Auto-Repeater"); +Class.automachinception = makeAuto(Class.machinception, "Auto-Machceptioner"); +Class.autotailgator = makeAuto(Class.tailgator, "Auto-Tailgator"); +Class.autoflankinception = makeAuto(Class.flankinception, "Auto-Flankceptioner"); +Class.autoBackShield = makeAuto(Class.backShield, "Auto-BackShield"); +Class.autoSmasher = makeAuto({ + PARENT: "genericSmasher", + DANGER: 6, + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + } + ], + SKILL_CAP: [smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl] +}, "Auto-Smasher", { + type: "autoSmasherTurret", + size: 11, +}) + +//Hybrid Tanks +Class.bascrid = makeHybrid('basic', "Basic-Hybrid") +Class.twinbrid = makeHybrid('twin', "Twin-Hybrid") +Class.machbrid = makeHybrid('machineGun', "Machine-Hybrid") +Class.snipebrid = makeHybrid('sniper', "Snipe-Hybrid") +Class.flankbrid = makeHybrid('flankGuard', "Flank-Hybrid") +Class.poundbrid = makeHybrid('pounder', "Pound-Hybrid") +Class.trapbrid = makeHybrid('trapper', "Trapper-Hybrid") +Class.desmosbrid = makeHybrid('desmos', "Desmos-Hybrid") +Class.littleHunterbrid = makeHybrid('littleHunter', "Subduer-Hybrid") +Class.inceptionbrid = makeHybrid('inception', "Inception-Hybrid") +Class.auto2brid = makeHybrid('auto2', "Auto-2-Hybrid") +Class.doubletwinbrid = makeHybrid('doubleTwin', "Double Twin-Hybrid") +Class.hexatankbrid = makeHybrid('hexaTank', "Hexatank-Hybrid") +Class.auto3brid = makeHybrid('auto3', "Auto3-Hybrid") +Class.binarybrid = makeHybrid('binary', "Binary-Hybrid") +Class.flankduebrid = makeHybrid('flankdue', "Flankduer-Hybrid") +Class.bigsubduerbrid = makeHybrid('bigSubduer', "Mitochondrion-Hybrid") +Class.clonebrid = makeHybrid({ + PARENT: "genericTank", + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 180, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "hybridclonerprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + POSITION: [24, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}, "Cloner-Hybrid") +Class.bentHybrid = makeHybrid('tripleShot', "Bent Hybrid") +Class.revobrid = makeHybrid(Class.revolutionist, "Revobrid"); +Class.contagionbrid = makeHybrid('contagion', "Contagion-Hybrid") +Class.poacher = makeHybrid('hunter', "Poacher") +Class.armsman = makeHybrid('rifle', "Armsman") +Class.cropDuster = makeHybrid('minigun', "Crop Duster") +Class.hybrid = makeHybrid('destroyer', "Hybrid") +Class.assbrid = makeHybrid('assassin', "Assassin-Hybrid") +Class.twipebrid = makeHybrid('twinsniper', "Twiper-Hybrid") +Class.acidbrid = makeHybrid('acid', "Acid-Hybrid") +Class.chillbrid = makeHybrid('chiller', "Chiller-Hybrid") +Class.artilbrid = makeHybrid('artillery', "Artillery-Hybrid") +Class.spraybrid = makeHybrid('sprayer', "Sprayer-Hybrid") +Class.trapguardbrid = makeHybrid('trapGuard', "TG-Hybrid") +Class.builderbrid = makeHybrid('builder', "Builder-Hybrid") +Class.launchbrid = makeHybrid('launcher', "Launcher-Hybrid") +Class.tritrapperbrid = makeHybrid('triTrapper', "Tri-Trapper-Hybrid") +Class.helixbrid = makeHybrid('helix', "Helix-Hybrid") +Class.sidewinderbrid = makeHybrid('sidewinder', "Sidewinder-Hybrid") +Class.undertowbrid = makeHybrid('undertow', "Undertow-Hybrid") +Class.repeaterbrid = makeHybrid('repeater', "Repeater-Hybrid") +Class.inceptionistbrid = makeHybrid('inceptionist', "Inceptionist-Hybrid") +Class.machinceptionbrid = makeHybrid('machinception', "Flankceptioner-Hybrid") +Class.tailgatorbrid = makeHybrid('tailgator', "Tailgator-Hybrid") +Class.flankinceptionbrid = makeHybrid('flankinception', "Flankceptioner-Hybrid") + +//auto hybrid tanks +Class.autotwinbrid = makeHybrid('autoTwin', "Auto-Twin-Hybrid") +Class.autosnipebrid = makeHybrid('autoSniper', "Auto-Sniper-Hybrid") +Class.automachbrid = makeHybrid('autoMach', "Auto-Machine-Hybrid") +Class.autoflankbrid = makeHybrid('autoFlank', "Auto-Flank-Hybrid") +Class.autopoundbrid = makeHybrid('autoPound', "Auto-Pound-Hybrid") +Class.autotrapbrid = makeHybrid('autoTrap', "Auto-Trapper-Hybrid") +Class.autodesmosbrid = makeHybrid('autoDesmos', "Auto-Desmos-Hybrid") +Class.autobascrid = makeHybrid('autoBasic', "Auto-Basic-Hybrid") +Class.autoinceptionbrid = makeHybrid('autoinception', "Auto-Inception-Hybrid") +Class.autolittleHunterbrid = makeHybrid('autolittleHunter', "Auto-Subduer-Hybrid") +Class.autoauto2brid = makeHybrid('auto2', "Auto-Auto-2-Hybrid") + + +//hybrid drive tanks +Class.car = makeHybridDrive('basic', "Car") +Class.mercedes = makeHybridDrive('twin', "Mercedes") +Class.tesla = makeHybridDrive('sniper', "Tesla") +Class.toyota = makeHybridDrive('machineGun', "Toyota") +Class.ford = makeHybridDrive('flankGuard', "Ford") +Class.honda = makeHybridDrive('pounder', "Honda") +Class.gmc = makeHybridDrive('trapper', "GMC") +Class.porsche = makeHybridDrive('autoBasic', "Porsche") +Class.mazda = makeHybridDrive('desmos', "Mazda") +Class.volkswagen = makeHybridDrive('littleHunter', "Volkswagen") +Class.audi = makeHybridDrive('inception', "Audi") +Class.ferrari = makeHybridDrive('auto2', "Ferrari") + +//Ceptions +Class.basicCeption = makeCeptionNerf(Class.basic, "Basic-Ception"); +Class.twinCeption = makeCeptionNerf(Class.twin, "Twin-Ception"); +Class.snipeCeption = makeCeptionNerf(Class.sniper, "Snipe-Ception"); +Class.machCeption = makeCeptionNerf(Class.machineGun, "Mach-Ception"); +Class.flankCeption = makeCeptionNerf(Class.flankGuard, "Flank-Ception"); +Class.directCeption = makeCeptionNerf(Class.director, "Drone-Ception"); +Class.poundCeption = makeCeptionNerf(Class.pounder, "Pound-Ception"); +Class.trapCeption = makeCeptionNerf(Class.trapper, "Trap-Ception"); +Class.desmosCeption = makeCeptionNerf(Class.desmos, "Desmos-Ception"); +Class.bascridCeption = makeCeptionNerf(Class.bascrid, "Basic-Hybrid-Ception"); +Class.littleHunterCeption = makeCeptionNerf(Class.littleHunter, "Subduer-Ception"); +Class.inceptCeption = makeCeptionNerf(Class.inception, "Incept-Ception"); +Class.auto2Ception = makeCeptionNerf(Class.auto2, "Auto-2-Ception"); +Class.revoception = makeCeption(Class.revolutionist, "revoception"); + +//Trackers +Class.trackerSmasher = makeTracker(Class.smasher, "Scanner"); +Class.trackerSniper = makeTracker(Class.sniper, "Marksman"); +Class.trackerAssassin = makeTracker(Class.assassin, "Hitman"); +Class.trackerHunter = makeTracker(Class.hunter, "Pinner"); +Class.trackerMini = makeTracker(Class.minigun, "Scout"); +Class.trackerRifle = makeTracker(Class.rifle, "DMR"); +Class.trackerTwinsniper = makeTracker(Class.twinsniper, "Bolt Action"); +Class.trackerSniperHybrid = makeTracker(Class.snipebrid, "Camper"); +Class.trackerAcid = makeTracker(Class.acid, "Acidilizer"); +Class.trackerChill = makeTracker(Class.chiller, "Icilizer"); + +//Homing Auto Tanks +Class.homingautoBasic = makeAuto(Class.basic, "Homing Auto-Basic", {type: 'homingAutoTurret'}); +Class.homingautoTwin = makeAuto(Class.twin, "Homing Auto-Twin", {type: 'homingAutoTurret'}); +Class.homingautoMach = makeAuto(Class.machineGun, "Homing Auto-Mach", {type: 'homingAutoTurret'}); +Class.homingautoSniper = makeAuto(Class.sniper, "Homing-Auto Sniper", {type: 'homingAutoTurret'}); +Class.homingautoFlank = makeAuto(Class.flankGuard, "Homing Auto-Flank", {type: 'homingAutoTurret'}); +Class.homingautoDirector = makeAuto(Class.director, "Homing Auto-Director", {type: 'homingAutoTurret'}); +Class.homingautoPound = makeAuto(Class.pounder, "Homing Auto-Pounder", {type: 'homingAutoTurret'}); +Class.homingautoTrap = makeAuto(Class.trapper, "Homing Auto-Trapper", {type: 'homingAutoTurret'}); +Class.homingautoDesmos = makeAuto(Class.desmos, "Homing Auto-Desmos", {type: 'homingAutoTurret'}); +Class.homingautobascrid = makeAuto(Class.bascrid, "Homing Auto-Bascrid", {type: 'homingAutoTurret'}) +Class.homingautolittleHunter = makeAuto(Class.littleHunter, "Homing Auto-Subduer", {type: 'homingAutoTurret'}) +Class.homingautoinception = makeAuto(Class.inception, "Auto Inception", {type: 'homingAutoTurret'}); +Class.homingautoauto2 = makeAuto(Class.auto2, "Auto-2", {type: 'homingAutoTurret'}); + +//Reveries +Class.reverie = addBackTurret(Class.basic, "Reverie", {type: 'autoTankGun'}); +Class.twinreverie = addBackTurret(Class.basic, "Tyverie", {type: 'fastbigauto4gun'}); +Class.poundreverie = addBackTurret(Class.basic, "Pyverie", {type: 'megaAutoTankGun'}); +Class.dualreverie = addBackTurret(Class.basic, "Douverie", {type: 'dualAutoTankGun'}); +Class.autoReverie = makeAuto(Class.inception, "Auto-Reverie"); +Class.reveriebrid = makeHybrid('reverie', "Reverie-Hybrid"); + +//Auras +Class.auraTwin = makeAura(Class.twin); +Class.auraSniper = makeAura(Class.sniper); +Class.auraMachineGun = makeAura(Class.machineGun); +Class.auraFlankGuard = makeAura(Class.flankGuard); +Class.auraDirector = makeAura(Class.director); +Class.auraPounder = makeAura(Class.pounder); +Class.auraTrapper = makeAura(Class.trapper); +Class.auraAutoBasic = makeAura(Class.autoBasic); +Class.auraBascrid = makeAura(Class.bascrid); +Class.auraLittleHunter = makeAura(Class.littleHunter); +Class.auraInception = makeAura(Class.inception); +Class.auraDesmos = makeAura(Class.desmos); +Class.auraAuto2 = makeAura(Class.auto2); +Class.auraSmasher = makeAura(Class.smasher); + +Class.damageAuraBasic = makeAura(Class.basic, "Omen Basic", {type: 'auraDamageGen'}); +Class.damageAuraTwin = makeAura(Class.twin, "Omen Twin", {type: 'auraDamageGen'}); +Class.damageAuraSniper = makeAura(Class.sniper, "Omen Sniper", {type: 'auraDamageGen'}); +Class.damageAuraMachineGun = makeAura(Class.machineGun, "Omen Machine Gun", {type: 'auraDamageGen'}); +Class.damageAuraFlankGuard = makeAura(Class.flankGuard, "Omen Flank Guard", {type: 'auraDamageGen'}); +Class.damageAuraDirector = makeAura(Class.director, "Omen Director", {type: 'auraDamageGen'}); +Class.damageAuraPounder = makeAura(Class.pounder, "Omen Pounder", {type: 'auraDamageGen'}); +Class.damageAuraTrapper = makeAura(Class.trapper, "Omen Trapper", {type: 'auraDamageGen'}); +Class.damageAuraAutoBasic = makeAura(Class.autoBasic, "Omen Auto-Basic", {type: 'auraDamageGen'}); +Class.damageAuraBascrid = makeAura(Class.bascrid, "Omen Bascrid", {type: 'auraDamageGen'}); +Class.damageAuraLittleHunter = makeAura(Class.littleHunter, "Omen Subduer", {type: 'auraDamageGen'}); +Class.damageAuraInception = makeAura(Class.inception, "Omen Inception", {type: 'auraDamageGen'}); +Class.damageAuraDesmos = makeAura(Class.desmos, "Omen Desmos", {type: 'auraDamageGen'}); +Class.damageAuraAuto2 = makeAura(Class.auto2, "Omen Auto-2", {type: 'auraDamageGen'}); + +Class.rangeAuraBasic = makeAura(Class.basic, "Mega-Aura Basic", {type: 'auraRangeGen'}); +Class.rangeAuraTwin = makeAura(Class.twin, "Mega-Aura Twin", {type: 'auraRangeGen'}); +Class.rangeAuraSniper = makeAura(Class.sniper, "Mega-Aura Sniper", {type: 'auraRangeGen'}); +Class.rangeAuraMachineGun = makeAura(Class.machineGun, "Mega-Aura Machine Gun", {type: 'auraRangeGen'}); +Class.rangeAuraFlankGuard = makeAura(Class.flankGuard, "Mega-Aura Flank Guard", {type: 'auraRangeGen'}); +Class.rangeAuraDirector = makeAura(Class.director, "Mega-Aura Director", {type: 'auraRangeGen'}); +Class.rangeAuraPounder = makeAura(Class.pounder, "Mega-Aura Pounder", {type: 'auraRangeGen'}); +Class.rangeAuraTrapper = makeAura(Class.trapper, "Mega-Aura Trapper", {type: 'auraRangeGen'}); +Class.rangeAuraAutoBasic = makeAura(Class.autoBasic, "Mega-Aura Auto-Basic", {type: 'auraRangeGen'}); +Class.rangeAuraBascrid = makeAura(Class.bascrid, "Mega-Aura Bascrid", {type: 'auraRangeGen'}); +Class.rangeAuraLittleHunter = makeAura(Class.littleHunter, "Mega-Aura Subduer", {type: 'auraRangeGen'}); +Class.rangeAuraInception = makeAura(Class.inception, "Mega-Aura Inception", {type: 'auraRangeGen'}); +Class.rangeAuraDesmos = makeAura(Class.desmos, "Mega-Aura Desmos", {type: 'auraRangeGen'}); +Class.rangeAuraAuto2 = makeAura(Class.auto2, "Mega-Aura Auto-2", {type: 'auraRangeGen'}); + +Class.damagerangeAuraBasic = makeAura(Class.basic, "Mega-Omen Basic", {type: 'auraDamageRangeGen'}); +Class.moredamageAuraBasic = makeAura(Class.basic, "X-Omen Basic", {type: 'auraMoreDamageGen'}); +Class.morerangeAuraBasic = makeAura(Class.basic, "X-Mega-Aura Basic", {type: 'auraMoreRangeGen'}); + + +Class.auraDoubleTwin = makeAura(Class.doubleTwin); +Class.auraTripleShot = makeAura(Class.tripleShot); + +Class.auraAssassin = makeAura(Class.assassin); +Class.auraHunter = makeAura(Class.hunter); +Class.auraRifle = makeAura(Class.rifle); +Class.auraTrackerSniper = makeAura(Class.trackerSniper); +Class.auraTwinSniper = makeAura(Class.twinsniper); +Class.auraAcid = makeAura(Class.acid); +Class.auraChiller = makeAura(Class.chiller); + +Class.auraMinigun = makeAura(Class.minigun); +Class.auraGunner = makeAura(Class.gunner); +Class.auraSprayer = makeAura(Class.sprayer); + +Class.auraHexaTank = makeAura(Class.hexaTank); +Class.auraTriAngle = makeAura(Class.triAngle); +Class.auraAuto3 = makeAura(Class.auto3); +Class.auraReverie = makeAura(Class.reverie); +Class.auraBackShield = makeAura(Class.backShield); + +Class.auraOverseer = makeAura(Class.overseer); +Class.auraCruiser = makeAura(Class.cruiser); +Class.auraUnderseer = makeAura(Class.underseer); +Class.auraSpawner = makeAura(Class.spawner); +Class.auraDirectdrive = makeAura(Class.directdrive); + +Class.auraDestroyer = makeAura(Class.destroyer); +Class.auraArtillery = makeAura(Class.artillery); +Class.auraLauncher = makeAura(Class.launcher); + +Class.auraBuilder = makeAura(Class.builder); +Class.auraTriTrapper = makeAura(Class.triTrapper); +Class.auraTrapGuard = makeAura(Class.trapGuard); + +Class.auraAutoTwin = makeAura(Class.autoTwin); +Class.auraAutoSniper = makeAura(Class.autoSniper); +Class.auraAutoMach = makeAura(Class.autoMach); +Class.auraAutoFlank = makeAura(Class.autoFlank); +Class.auraAutoDirector = makeAura(Class.autoDirector); +Class.auraAutoPound = makeAura(Class.autoPound); +Class.auraAutoTrap = makeAura(Class.autoTrap); +Class.auraAutoDesmos = makeAura(Class.autoDesmos); +Class.auraRevolutionist = makeAura(Class.revolutionist); +Class.auraAutoLittleHunter = makeAura(Class.autolittleHunter); +Class.auraAutoInception = makeAura(Class.autoinception); +Class.auraAutoAuto2 = makeAura(Class.autoauto2); +Class.auraBasicCeption = makeAura(Class.basicCeption); +Class.auraHomingautoBasic = makeAura(Class.homingautoBasic); + +Class.auratwinbrid = makeAura(Class.launcher); +Class.aurasnipebrid = makeAura(Class.launcher); +Class.auramachbrid = makeAura(Class.machbrid); +Class.auraflankbrid = makeAura(Class.flankbrid); +Class.aurapoundbrid = makeAura(Class.poundbrid); +Class.auratrapbrid = makeAura(Class.trapbrid); +Class.auraautobascrid = makeAura(Class.autobascrid); +Class.auradesmosbrid = makeAura(Class.desmosbrid); +Class.auralittlehunterbrid = makeAura(Class.littleHunterbrid); +Class.aurainceptionbrid = makeAura(Class.inceptionbrid); +Class.auraauto2brid = makeAura(Class.auto2brid); +Class.jeep = makeAura(Class.car, "jeep"); + +Class.auraBinary = makeAura(Class.binary); +Class.auraContagion = makeAura(Class.contagion); +Class.auraGundirector = makeAura(Class.gundirector); +Class.auraBigSubduer = makeAura(Class.bigSubduer); +Class.auraFlankdue = makeAura(Class.flankdue); + +Class.auraMachinception = makeAura(Class.machinception); +Class.auraTailgator = makeAura(Class.tailgator); +Class.auraFlankinception = makeAura(Class.flankinception); + +Class.auraSidewinder = makeAura(Class.sidewinder); +Class.auraHelix = makeAura(Class.helix); +Class.auraUndertow = makeAura(Class.undertow); +Class.auraRepeater = makeAura(Class.repeater); + +// TANK UPGRADE PATHS +Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "autoBasic", "desmos", "bascrid", "littleHunter", "inception", "auraBasic", "auto2"] + Class.basic.UPGRADES_TIER_2 = ["smasher", "cloner"] + Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "landmine", "cocci", "pion", "trackerSmasher", "skater", "acidsmasher", "flail", "autoSmasher", "auraSmasher"] + Class.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] + Class.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner"] + + Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "autoTwin", "helix", "twinbrid", "binary", "twinsniper", "auraTwin"] + Class.twin.UPGRADES_TIER_3 = ["bulwark"] + Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble", "doubletwinbrid", "auraDoubleTwin"] + Class.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentDouble", "triplet", "autoTripleShot", "triplex", "bentHybrid", "trinary", "auraTripleShot"] + + Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "twinsniper", "autoSniper", "snipebrid", "trackerSniper", "acid", "chiller", "auraSniper"] + Class.sniper.UPGRADES_TIER_3 = ["bushwhacker"] + Class.assassin.UPGRADES_TIER_3 = ["ranger", "xHunter", "falcon", "stalker", "autoAssassin", "assbrid", "trackerAssassin", "disintegrator", "freezer", "auraAssassin", "single"] + Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "railgun", "dual","autoHunter", "trackerHunter", 'auraHunter'] + Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman", "autoRifle", "trackerRifle", "auraRifle"] + Class.trackerSniper.UPGRADES_TIER_3 = ["trackerAssassin", "trackerHunter", "trackerMini", "trackerRifle", "trackerTwinsniper", "trackerSniperHybrid", "trackerAcid", "trackerChill", "auraTrackerSniper"] + Class.twinsniper.UPGRADES_TIER_3 = ["dual", "musket", "autoTwinsniper", "twipebrid", "trackerTwinsniper", "auraTwinSniper"] + Class.acid.UPGRADES_TIER_3 = ["disintegrator", "acidsmasher", "autoAcid", "acidbrid", "trackerAcid", "auraAcid"] + Class.chiller.UPGRADES_TIER_3 = ["freezer", "autoChill", "chillbrid", "trackerChill", "auraChiller"] + + Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "autoMach", "machbrid", "machinception", "auraMachineGun"] + Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture", "minilaser", "autoMini", "trackerMini", "accelminigun", "auraMinigun"] + Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner", "waterfall", "helecopter", "auraGunner"] + Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "autoSprayer", "spraybrid", "auraSprayer"] + + Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank", "flankbrid", "flankdue", "flankinception", "backShield", "auraBackShield"] + Class.flankGuard.UPGRADES_TIER_3 = ["tripleTwin", "quadruplex"] + Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper", "autoHexaTank", "hexatankbrid", "auraHexaTank", "auraTriAngle"] + Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "surfer", "eagle", "phoenix", "vulture", "subway", "helecopter"] + Class.backShield.UPGRADES_TIER_3 = ["mirrorBackShield", "brella", "autoBackShield", "auraBackShield"] + + Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "gundirector", "spawner", "directdrive", "autoDirector", "auraDirector"] + Class.director.UPGRADES_TIER_3 = ["manager", "bigCheese"] + Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "trojan", "overdrive", "commander", "auraOverseer"] + Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "autoCruiser", "commander", "auraCruiser"] + Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor", "autoUnderseer", "auraUnderseer"] + Class.spawner.UPGRADES_TIER_3 = ["factory", "protist", "ranch", "autoSpawner", "auraSpawner"] + Class.directdrive.UPGRADES_TIER_3 = ["overdrive", "cruiserdrive", "revodirector", "honda", "dictator", "auraDirectdrive"] + + Class.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher", "autoPound", "sidewinder", "poundbrid", "tailgator", "auraPounder"] + Class.pounder.UPGRADES_TIER_3 = ["shotgun", "eagle"] + Class.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct", "autoDestroy", "waterfall", "interceptor", "auraDestroyer"] + Class.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun", "autoArtillery", "artilbrid", "auraArtillery"] + Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun", "shrapnelgun", "firecracker", "autoLaunch", "launchbrid", "auraLauncher"] + + Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "contagion", "autoTrap", "trapbrid", "auraTrapper"] + Class.trapper.UPGRADES_TIER_3 = ["barricade"] + Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "builderbrid"] + Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "triContagion", "autoTriTrapper", "tritrapperbrid"] + Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "autoTrapGuard", "trapguardbrid"] + + Class.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "autoDesmos", "basicCeption", "autobascrid", "autolittleHunter", "autoinception", "autoauto2", "revolutionist", "reverie", "auraAutoBasic", "homingautoBasic"] + Class.autoBasic.UPGRADES_TIER_3 = ["autoSmasher", "autoCloner"] + Class.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "equilibrium", "autoBinary", "autoTwinsniper", "twinCeption", "autotwinbrid", "auraAutoTwin", "homingautoTwin"] + Class.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "autoTwinsniper", "autoAcid", "autoChill", "snipeCeption", "autosnipebrid", "auraAutoSniper", "homingautoSniper"] + Class.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "machCeption", "automachbrid", "automachinception", "auraAutoMach", "homingautoMach"] + Class.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "autoTriTrapper", "flankCeption", "autoflankbrid", "autoFlankdue", "autoflankinception", "auraAutoFlank", "homingautoFlank"] + Class.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoGundirector", "autoSpawner", "directCeption", "auraAutoDirector", "homingautoDirector"] + Class.autoPound.UPGRADES_TIER_3 = ["autoDestroy", "autoBuilder", "autoArtillery", "autoLaunch", "poundCeption", "autoSidewinder", "autopoundbrid", "autotailgator", "auraAutoPound", "homingautoPound"] + Class.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "autoTriTrapper", "autoTrapGuard", "autoContagion", "trapCeption", "autotrapbrid", "auraAutoTrap", "homingautoTrap"] + Class.autoDesmos.UPGRADES_TIER_3 = ["autoSidewinder", "autoHelix", "autoUndertow", "autoRepeater", "desmosCeption", "autodesmosbrid", "auraAutoDesmos", "homingautoDesmos"] + Class.autolittleHunter.UPGRADES_TIER_3 = ["autoMini", "autoBinary", "autoHunter", "autoSprayer", "autoContagion", "autoGundirector", "autoBigSubduer", "autoFlankdue", "autolittleHunterbrid", "littleHunterCeption", "auraAutoLittleHunter", "homingautolittleHunter"] + Class.autoinception.UPGRADES_TIER_3 = ["autoinceptionist", "automachinception", "autotailgator", "autoflankinception", "autoinceptionbrid", "inceptCeption", "auraAutoInception", "homingautoinception"] + Class.autoauto2.UPGRADES_TIER_3 = ["autoAuto3", "autoRevolutionist", "autoReverie", "autoauto2brid", "auto2Ception", "auraAutoAuto2", "homingautoauto2"] + Class.reverie.UPGRADES_TIER_3 = ["twinreverie", "poundreverie", "dualreverie", "autoReverie", "reveriebrid", "auraReverie"] + Class.basicCeption.UPGRADES_TIER_3 = ["twinCeption", "snipeCeption", "machCeption", "flankCeption", "directCeption", "poundCeption", "trapCeption", "desmosCeption", "bascridCeption", "littleHunterCeption", "inceptCeption", "auraBasicCeption"] + Class.homingautoBasic.UPGRADES_TIER_3 = ["homingautoTwin", "homingautoSniper", "homingautoMach", "homingautoFlank", "homingautoDirector", "homingautoPound", "homingautoTrap", "homingautoDesmos", "homingautobascrid", "homingautolittleHunter", "homingautoinception", "auraHomingautoBasic"] + + Class.bascrid.UPGRADES_TIER_2 = ["twinbrid", "snipebrid", "machbrid", "flankbrid", "overseer", "poundbrid", "trapbrid", "autobascrid", "desmosbrid", "littleHunterbrid", "inceptionbrid", "auto2brid", "car", "auraBascrid"] + Class.bascrid.UPGRADES_TIER_3 = ["clonebrid"] + Class.twinbrid.UPGRADES_TIER_3 = ["doubletwinbrid", "bentHybrid", "overgunner", "hexatankbrid", "autotwinbrid", "helixbrid", "binarybrid", "twipebrid", "mercedes", "auratwinbrid"] + Class.snipebrid.UPGRADES_TIER_3 = ["assbrid", "poacher", "cropDuster", "armsman", "twipebrid", "autosnipebrid", "trackerSniperHybrid", "acidbrid", "chillbrid", "tesla", "aurasnipebrid"] + Class.machbrid.UPGRADES_TIER_3 = ["artilbrid", "cropDuster", "overgunner", "spraybrid", "automachbrid", "machinceptionbrid", "toyota", "auramachbrid"] + Class.flankbrid.UPGRADES_TIER_3 = ["hexatankbrid", "surfer", "auto3brid", "trapguardbrid", "tritrapperbrid", "autoflankbrid", "flankduebrid", "flankinceptionbrid", "ford", "auraflankbrid"] + Class.poundbrid.UPGRADES_TIER_3 = ["hybrid", "builderbrid", "artilbrid", "launchbrid", "autopoundbrid", "sidewinderbrid", "tailgatorbrid", "honda", "aurapoundbrid"] + Class.trapbrid.UPGRADES_TIER_3 = ["builderbrid", "tritrapperbrid", "trapguardbrid", "contagionbrid", "autotrapbrid", "overtrapper", "gmc", "auratrapbrid"] + Class.autobascrid.UPGRADES_TIER_3 = ["autotwinbrid", "autosnipebrid", "automachbrid", "autoflankbrid", "autopoundbrid", "autotrapbrid", "autodesmosbrid", "autolittleHunterbrid", "autoinceptionbrid", "revobrid", "reveriebrid", "bascridCeption", "porsche", "auraautobascrid"] + Class.desmosbrid.UPGRADES_TIER_3 = ["sidewinderbrid", "helixbrid", "undertowbrid", "repeaterbrid", "autodesmosbrid", "mazda", "auradesmosbrid"] + Class.littleHunterbrid.UPGRADES_TIER_3 = ["cropDuster", "binarybrid", "poacher", "spraybrid", "contagionbrid", "bigsubduerbrid", "flankduebrid", "autolittleHunterbrid", "volkswagen", "auralittlehunterbrid"] + Class.inceptionbrid.UPGRADES_TIER_3 = ["inceptionistbrid", "machinceptionbrid", "tailgatorbrid", "flankinceptionbrid", "overdrive", "autoinceptionbrid", "audi", "aurainceptionbrid"] + Class.auto2brid.UPGRADES_TIER_3 = ["auto3brid", "revobrid", "reveriebrid", "autoauto2brid", "ferrari", "auraauto2brid"] + Class.car.UPGRADES_TIER_3 = ["mercedes", "tesla", "toyota", "ford", "overdrive", "honda", "gmc", "porsche", "mazda", "volkswagen", "audi", "jeep"] + + Class.littleHunter.UPGRADES_TIER_2 = ["minigun", "binary", "hunter", "sprayer", "contagion", "gundirector", "bigSubduer", "flankdue", "autolittleHunter", "littleHunterbrid", "auraLittleHunter"] + Class.binary.UPGRADES_TIER_3 = ["trinary", "dual", "autoBinary", "binarybrid", "auraBinary"] + Class.contagion.UPGRADES_TIER_3 = ["fort", "triContagion", "autoContagion", "droneTrapper", "contagionbrid", "auraContagion"] + Class.gundirector.UPGRADES_TIER_3 = ["trojan", "protist", "droneTrapper", "autoGundirector"] + Class.bigSubduer.UPGRADES_TIER_3 = ["predator", "redistributor", "biggerSubduer", "clubbin", "autoBigSubduer", "bigsubduerbrid", "auraBigSubduer"] + Class.flankdue.UPGRADES_TIER_3 = ["subway", "triContagion", "clubbin", "autoFlankdue", "flankduebrid", "auraFlankdue"] + + Class.inception.UPGRADES_TIER_2 = ["inceptionist", "machinception", "tailgator", "launcher", "flankinception", "directdrive", "autoinception", "inceptionbrid", "auraInception"] + Class.inceptionist.UPGRADES_TIER_3 = ["twinceptionist", "machceptionist", "poundceptionist", "flankceptionist", "factory", "autoinceptionist", "inceptionistbrid"] + Class.machinception.UPGRADES_TIER_3 = ["machceptionist", "automachinception", "machinceptionbrid", "auraMachinception", "auraTailgator"] + Class.tailgator.UPGRADES_TIER_3 = ["poundceptionist", "interceptor", "engineer", "shrapnelgun", "autotailgator", "tailgatorbrid"] + Class.flankinception.UPGRADES_TIER_3 = ["flankceptionist", "autoflankinception", "flankinceptionbrid", "auraFlankinception"] + + Class.desmos.UPGRADES_TIER_2 = ["helix", "sidewinder", "undertow", "repeater", "autoDesmos", "desmosbrid", "auraDesmos"] + Class.sidewinder.UPGRADES_TIER_3 = ["coil", "python", "ranch", "oroboros", "cocci"] + Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "coil", "duplicator", "autoHelix", "helixbrid", "auraHelix"] + Class.undertow.UPGRADES_TIER_3 = ["riptide", "autoUndertow", "undertowbrid", "auraUndertow"] + Class.repeater.UPGRADES_TIER_3 = ["iterator", "duplicator", "autoRepeater", "repeaterbrid", "auraRepeater"] + + Class.auraBasic.UPGRADES_TIER_2 = ["auraTwin", "auraSniper", "auraMachineGun", "auraFlankGuard", "auraDirector", "auraPounder", "auraTrapper", "auraAutoBasic", "auraDesmos", "auraBascrid", "auraLittleHunter", "auraInception", "auraAuto2", "damageAuraBasic", "rangeAuraBasic"] + Class.auraBasic.UPGRADES_TIER_3 = ["auraSmasher"] + Class.auraTwin.UPGRADES_TIER_3 = ["auraDoubleTwin", "auraTripleShot", "auraGunner", "auraHexaTank", "auraAutoTwin", "auraHelix", "auratwinbrid", "auraBinary", "auraTwinSniper"] + Class.auraSniper.UPGRADES_TIER_3 = ["auraAssassin", "auraHunter", "auraMinigun", "auraRifle", "auraTwinSniper", "auraAutoSniper", "aurasnipebrid", "auraTrackerSniper", "auraAcid", "auraChiller", "damageAuraSniper", "rangeAuraSniper"] + Class.auraMachineGun.UPGRADES_TIER_3 = ["auraArtillery", "auraMinigun", "auraGunner", "auraSprayer", "auraAutoMach", "auramachbrid", "auraMachinception", "damageAuraMachineGun", "rangeAuraMachineGun"] + Class.auraFlankGuard.UPGRADES_TIER_3 = ["auraHexaTank", "auraTriAngle", "auraAuto3", "auraTrapGuard", "auraTriTrapper", "auraAutoFlank", "auraflankbrid", "auraFlankdue", "auraFlankinception", "auraBackShield", "damageAuraFlankGuard", "rangeAuraFlankGuard"] + Class.auraDirector.UPGRADES_TIER_3 = ["auraOverseer", "auraCruiser", "auraUnderseer", "auraSpawner", "auraDirectdrive", "auraAutoDirector", "damageAuraDirector", "rangeAuraDirector"] + Class.auraPounder.UPGRADES_TIER_3 = ["auraBuilder", "auraArtillery", "auraLauncher", "auraAutoPound", "auraSidewinder", "aurapoundbrid", "auraTailgator", "damageAuraPounder", "rangeAuraPounder"] + Class.auraTrapper.UPGRADES_TIER_3 = ["auraBuilder", "auraTriTrapper", "auraTrapGuard", "auraContagion", "auraAutoTrap", "auratrapbrid", "damageAuraTrapper", "rangeAuraTrapper"] + Class.auraAutoBasic.UPGRADES_TIER_3 = ["auraAutoTwin", "auraAutoSniper", "auraAutoMach", "auraAutoFlank", "auraAutoDirector", "auraAutoPound", "auraAutoTrap", "auraAutoDesmos", "auraautobascrid", "auraAutoLittleHunter", "auraAutoInception", "auraRevolutionist", "auraReverie", "auraBasicCeption", "auraHomingautoBasic", "damageAuraAutoBasic", "rangeAuraAutoBasic"] + Class.auraBascrid.UPGRADES_TIER_3 = ["auratwinbrid", "aurasnipebrid", "auramachbrid", "auraflankbrid", "aurapoundbrid", "auratrapbrid", "auradesmosbrid", "auraautobascrid", "auralittlehunterbrid", "aurainceptionbrid", "jeep", "damageAuraBascrid", "rangeAuraBascrid"] + Class.auraDesmos.UPGRADES_TIER_3 = ["auraSidewinder", "auraHelix", "auraUndertow", "auraRepeater", "auraAutoDesmos", "auradesmosbrid", "damageAuraDesmos", "rangeAuraDesmos"] + Class.auraLittleHunter.UPGRADES_TIER_3 = ["auraMinigun", "auraBinary", "auraHunter", "auraSprayer", "auraContagion", "auraGundirector", "auraBigSubduer", "auraFlankdue", "auraAutoLittleHunter", "auralittlehunterbrid", "damageAuraLittleHunter", "rangeAuraLittleHunter"] + Class.auraInception.UPGRADES_TIER_3 = ["auraMachinception", "auraTailgator", "auraFlankinception", "auraAutoInception", "aurainceptionbrid", "damageAuraInception", "rangeAuraInception"] + Class.auraAuto2.UPGRADES_TIER_3 = ["auraAuto3", "auraRevolutionist", "auraReverie", "auraAutoAuto2", "auraauto2brid", "damageAuraAuto2", "rangeAuraAuto2"] + Class.damageAuraBasic.UPGRADES_TIER_3 = ["damageAuraTwin", "damageAuraSniper", "damageAuraMachineGun", "damageAuraFlankGuard", "damageAuraDirector", "damageAuraPounder", "damageAuraTrapper", "damageAuraAutoBasic", "damageAuraBascrid", "damageAuraDesmos", "damageAuraLittleHunter", "damageAuraInception", "damageAuraAuto2", "moredamageAuraBasic", "damagerangeAuraBasic"] + Class.rangeAuraBasic.UPGRADES_TIER_3 = ["rangeAuraTwin", "rangeAuraSniper", "rangeAuraMachineGun", "rangeAuraFlankGuard", "rangeAuraDirector", "rangeAuraPounder", "rangeAuraTrapper", "rangeAuraAutoBasic", "rangeAuraBascrid", "rangeAuraDesmos", "rangeAuraLittleHunter", "rangeAuraInception", "rangeAuraAuto2", "morerangeAuraBasic", "damagerangeAuraBasic"] + + Class.auto2.UPGRADES_TIER_2 = ["auto3", "revolutionist", "swivel2", "reverie", "autoauto2", "auto2brid", "auraAuto2"] + Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee", "autoAuto3", "auto3brid", "auraAuto3"] + Class.revolutionist.UPGRADES_TIER_3 = ["subverter", "autoRevolutionist", "proton", "pion", "hadron", "equilibrium", "revobrid", "baseThrower", "revodirector", "auraRevolutionist"] + Class.swivel2.UPGRADES_TIER_3 = ["swivel3"] \ No newline at end of file diff --git a/server/modules/definitions/groups/turrets.js b/server/modules/definitions/groups/turrets.js index e3d95cfb1..62dc14371 100644 --- a/server/modules/definitions/groups/turrets.js +++ b/server/modules/definitions/groups/turrets.js @@ -1,4 +1,4 @@ -const { combineStats, makeDeco } = require('../facilitators.js'); +const { combineStats, makeDeco, addAura } = require('../facilitators.js'); const { gunCalcNames, base } = require('../constants.js'); const g = require('../gunvals.js'); @@ -147,7 +147,7 @@ Class.trapTurret = { ], }; Class.baseTrapTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", INDEPENDENT: true, COLOR: "grey", @@ -166,7 +166,7 @@ Class.baseTrapTurret = { ], } Class.terrestrialTrapTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", INDEPENDENT: true, COLOR: "grey", @@ -191,7 +191,7 @@ let makeshottrapTurretProps = () => ({ STAT_CALCULATOR: gunCalcNames.block, }); Class.shottrapTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: 'Turret', BODY: { FOV: 0, @@ -240,7 +240,7 @@ Class.shottrapTurret = { } ] } Class.machineTripleTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Machine Gun", BODY: { FOV: 2 }, CONTROLLERS: [ ["spin", {speed: 0.04}] ], @@ -272,7 +272,7 @@ Class.machineTripleTurret = { ], }; Class.launcherTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Launcher", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -292,7 +292,7 @@ Class.launcherTurret = { ], }; Class.skimmerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Skimmer", BODY: { FOV: 2 * base.FOV }, COLOR: -1, @@ -311,7 +311,7 @@ Class.skimmerTurret = { ], }; Class.kronosSkimmerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Skimmer", BODY: { FOV: 10 }, COLOR: "grey", @@ -330,7 +330,7 @@ Class.kronosSkimmerTurret = { ], } Class.autosmashTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Launcher", BODY: { FOV: 10 }, COLOR: "grey", @@ -349,7 +349,7 @@ Class.autosmashTurret = { ], } Class.twisterTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Twister", BODY: { FOV: 2 }, COLOR: -1, @@ -368,7 +368,7 @@ Class.twisterTurret = { ], }; Class.hyperTwisterTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Twister", BODY: { FOV: 2 }, COLOR: -1, @@ -387,7 +387,7 @@ Class.hyperTwisterTurret = { ], }; Class.rocketeerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Rocketeer", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -406,7 +406,7 @@ Class.rocketeerTurret = { ], }; Class.boomerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Boomer", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -430,7 +430,7 @@ Class.boomerTurret = { ], }; Class.triTrapGuardTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], COLOR: -1, CONTROLLERS: [["spin", { independent: true }]], GUNS: [], @@ -456,7 +456,7 @@ for(let i = 0; i < 3; i++) { ) }; Class.eliteSpinnerCyclone = { - PARENT: "genericTank", + PARENT: ["genericTank"], COLOR: -1, CONTROLLERS: [["spin", { speed: 0.1, independent: true }]], GUNS: [], @@ -488,7 +488,7 @@ for (let i = 0; i < 12; i++) { ) }; Class.barricadeTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", BODY: { FOV: 0.5, @@ -531,7 +531,7 @@ Class.barricadeTurret = { ], }; Class.artilleryAutoTankgun = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Artillery", BODY: { FOV: 2, @@ -570,7 +570,7 @@ Class.artilleryAutoTankgun = { ], } Class.artilleryTurret = { // This one has half the dps of the one above - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Artillery", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -601,7 +601,7 @@ Class.artilleryTurret = { // This one has half the dps of the one above ], }; Class.legionaryTwin = { - PARENT: "auto4gun", + PARENT: ["auto4gun"], COLOR: "grey", INDEPENDENT: true, GUNS: [ @@ -621,7 +621,7 @@ Class.legionaryTwin = { ], } Class.nailgunTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Nailgun", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -651,7 +651,7 @@ Class.nailgunTurret = { ], }; Class.crowbarTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], COLOR: "grey", LABEL: "Crowbar", BODY: { FOV: 2 }, @@ -679,7 +679,7 @@ Class.crowbarTurret = { ], }; Class.wrenchTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], COLOR: "grey", LABEL: "Wrench", BODY: { FOV: 2 }, @@ -706,7 +706,7 @@ Class.wrenchTurret = { ], }; Class.protoSwarmerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Swarmer", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -724,7 +724,7 @@ Class.protoSwarmerTurret = { ], } Class.swarmTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Swarm", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -741,7 +741,7 @@ Class.swarmTurret = { ], }; Class.napoleonLowerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -765,7 +765,7 @@ Class.napoleonLowerTurret = { ], }; Class.genghisLowerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "", MAX_CHILDREN: 4, BODY: { FOV: 2 }, @@ -787,7 +787,7 @@ Class.genghisLowerTurret = { }; Class.cruiserTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Cruiser", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -811,7 +811,7 @@ Class.cruiserTurret = { ], }; Class.carrierTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Carrier", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -843,7 +843,7 @@ Class.carrierTurret = { ], } Class.gunnerCruiserTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Launcher", BODY: { FOV: 10 }, COLOR: "grey", @@ -880,7 +880,7 @@ Class.gunnerCruiserTurret = { ], } Class.juliusLowerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "", MAX_CHILDREN: 3, BODY: { FOV: 2 }, @@ -898,7 +898,7 @@ Class.juliusLowerTurret = { ], }; Class.swarmerTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Swarmer", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -916,7 +916,7 @@ Class.swarmerTurret = { ], }; Class.basicTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Turret", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -932,7 +932,7 @@ Class.basicTurret = { ], }; Class.napoleonUpperTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -1026,7 +1026,7 @@ Class.pillboxTurret = { ], } Class.tripletTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Triplet", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -1122,7 +1122,7 @@ Class.surgeonPillboxTurret = { // Miscellaneous Class.baseSwarmTurret = { - PARENT: "genericTank", + PARENT: ["genericTank"], LABEL: "Protector", COLOR: "grey", BODY: { @@ -1238,6 +1238,7 @@ Class.assemblerDot = { INDEPENDENT: true } Class.healerSymbol = { + PARENT: ["genericEntity"], SHAPE: [[0.3, -0.3],[1,-0.3],[1,0.3],[0.3,0.3],[0.3,1],[-0.3,1],[-0.3,0.3],[-1,0.3],[-1,-0.3],[-0.3,-0.3],[-0.3,-1],[0.3,-1]], SIZE: 13, COLOR: "red", @@ -1269,3 +1270,365 @@ Class.dominationBody = { SHAPE: 6, INDEPENDENT: true } + +//delta turrets +Class.projectileAutoTurret = { + PARENT: "autoTurret", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret, g.overdrive]), + TYPE: "bullet", + }, + }, + ], +} +Class.homingAutoTurret = { + PARENT: "genericTank", + LABEL: "Turret", + COLOR: "orange", + INDEPENDENT: true, + CONTROLLERS: ['nearestDifferentMaster'], + BODY: { + FOV: 0.8, + }, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret]), + TYPE: "homingBullet", + COLOR: "orange", + }, + }, + ], +} +Class.ceptionistturret = { + PARENT: "genericTank", + LABEL: "Turret", + COLOR: "darkGray", + BODY: { + FOV: 0.8, + }, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret]), + TYPE: "ceptionistbullet", + COLOR: "darkGray", + }, + }, + ], +} +Class.fastbigauto4gun = { + PARENT: "auto4gun", + GUNS: [ + { + POSITION: [14, 5, 1, 0, -4.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 1.2 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 5, 1, 0, 4.5, 0, 0.33], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 1.2 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [16, 5, 1, 0, 0, 0, 0.67], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 2 }]), + TYPE: "bullet", + }, + }, + ], +} +Class.helecopterblade = { + LABEL: "whatat", + CONTROLLERS: [["spin", { independent: true, speed: 0.16 }]], + COLOR: 16, + // M 0.1 -1.3 C 0.1 -1.4 0.1 -1.5 -0.1 -1.6 L -0.1 -0.3 A 0.5 0.5 -180 0 0 -0.3 -0.1 L -1.3 -0.1 C -1.4 -0.1 -1.5 -0.1 -1.6 0.1 L -0.3 0.1 A 0.5 0.5 -180 0 0 -0.1 0.3 L -0.1 1.3 C -0.1 1.4 -0.1 1.5 0.1 1.6 L 0.1 0.3 A 0.5 0.5 -180 0 0 0.3 0.1 L 1.3 0.1 C 1.4 0.1 1.5 0.1 1.6 -0.1 L 0.3 -0.1 A 0.5 0.5 -180 0 0 0.1 -0.3 Z + SHAPE: "M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.4 0.1 A 0.5 0.5 90 0 0 -0.1 0.4 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.4 A 0.5 0.5 90 0 0 0.4 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.4 -0.1 A 0.5 0.5 90 0 0 0.1 -0.4 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.4 A 0.5 0.5 90 0 0 -0.4 -0.1 Z", + // SHAPE: 'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.5 0.1 A 0.5 0.5 90 0 0 -0.1 0.5 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.5 A 0.5 0.5 90 0 0 0.5 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.5 -0.1 A 0.5 0.5 90 0 0 0.1 -0.5 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.5 A 0.5 0.5 90 0 0 -0.5 -0.1 Z', + INDEPENDENT: true, +}; +Class.helecoptersblade = { + LABEL: "what", + CONTROLLERS: [["spin", { independent: true, speed: 0.16 }]], + COLOR: 16, + SHAPE: "M -0.1 1 C -0.1 1.1 -0.1 1.2 0.1 1.3 L 0.1 0.3 A 0.5 0.5 0 0 0 0.3 0.1 L 1 0.1 C 1.1 0.1 1.2 0.1 1.3 -0.1 L 0.3 -0.1 A 0.5 0.5 0 0 0 0.1 -0.3 L 0.1 -1 C 0.1 -1.1 0.1 -1.2 -0.1 -1.3 L -0.1 -0.3 A 0.5 0.5 0 0 0 -0.3 -0.1 L -1 -0.1 C -1.1 -0.1 -1.2 -0.1 -1.3 0.1 L -0.3 0.1 A 0.5 0.5 0 0 0 -0.1 0.3 Z", + // M 0.1 -1.3 C 0.1 -1.4 0.1 -1.5 -0.1 -1.6 L -0.1 -0.3 A 0.5 0.5 -180 0 0 -0.3 -0.1 L -1.3 -0.1 C -1.4 -0.1 -1.5 -0.1 -1.6 0.1 L -0.3 0.1 A 0.5 0.5 -180 0 0 -0.1 0.3 L -0.1 1.3 C -0.1 1.4 -0.1 1.5 0.1 1.6 L 0.1 0.3 A 0.5 0.5 -180 0 0 0.3 0.1 L 1.3 0.1 C 1.4 0.1 1.5 0.1 1.6 -0.1 L 0.3 -0.1 A 0.5 0.5 -180 0 0 0.1 -0.3 Z + // SHAPE:'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.4 0.1 A 0.5 0.5 90 0 0 -0.1 0.4 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.4 A 0.5 0.5 90 0 0 0.4 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.4 -0.1 A 0.5 0.5 90 0 0 0.1 -0.4 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.4 A 0.5 0.5 90 0 0 -0.4 -0.1 Z', + // SHAPE: 'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.5 0.1 A 0.5 0.5 90 0 0 -0.1 0.5 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.5 A 0.5 0.5 90 0 0 0.5 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.5 -0.1 A 0.5 0.5 90 0 0 0.1 -0.5 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.5 A 0.5 0.5 90 0 0 -0.5 -0.1 Z', + INDEPENDENT: true, +}; +Class.turretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 10.5, 0, 90, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 270, 220, 1], + TYPE: "revogun", + }] +}; +Class.turretBasenoguns = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, +}; +Class.grenadeDeco = makeDeco(0); +Class.turretBaseKiva = { + LABEL: "Basethingygygyyasgsdgajskhg", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: "orange",//iT WonT FUckING SpIN + SYNC_TURRET_SKILLS: true, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["revogun", { COLOR: "orange" }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["revogun", { COLOR: "orange" }] + }] +}; +Class.hadronturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 'red', + CONTROLLERS: ["hadron"], + TURRETS: [{ + POSITION: [4.65, 10.5, 0, 90, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 270, 220, 1], + TYPE: "revogun", + }] +}; +Class.subverterturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 10.5, 0, 90, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 180, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 270, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 0, 220, 1], + TYPE: "revogun", + }] +}; +Class.protonturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [5, 10.5, 0, 0, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + + }, { + POSITION: [5, 10.5, 0, 360/3, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + + }, { + POSITION: [5, 10.5, 0, 360/3*2, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + }] +}; +Class.pionturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [5, 10.5, 0, 90, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + }, { + POSITION: [5, 10.5, 0, 270, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + }] +}; +Class.revogun = { + LABEL: 'Auto Turret', + SYNCS_SKILLS: true, + BODY: { + FOV: 1 + }, + COLOR: 16, + CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], + GUNS: [{ + POSITION: [13.5, 10, 1, 8, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.halfreload]), + TYPE: "bullet" + } + } + ] +} +Class.revosheild = { + PARENT: "genericTank", + DAMAGE_CLASS: 1, + TYPE: "shield", + COLOR: "darkGray", + SHAPE: 0, + INDEPENDENT: true, + BODY: { + PUSHABILITY: 0, + HEALTH: 10000, + SHIELD: 10000, + REGEN: 1000, + DAMAGE: 1, + RESIST: 100, + STEALTH: 1, + DENSITY: 10000, + }, +} +Class.backshieldturret = { + PARENT: "genericTank", + TYPE: "shield", + DAMAGE_CLASS: 1, + SHAPE: "m -0.702 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099", + COLOR: "#FF7F00", + INDEPENDENT: true, + BODY: { + HEALTH: 10000, + SHIELD: 10000, + REGEN: 1000, + }, +} +Class.mirrorDeco = makeDeco("M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -0.9 A 0.001 0.001 0 0 1 0 0.9 A 0.001 0.001 0 0 1 0 -0.9") +Class.mirrorbackshieldturret = { + PARENT: "genericTank", + TYPE: "shield", + INDEPENDENT: true, + BODY: { + HEALTH: 10000, + SHIELD: 10000, + REGEN: 1000, + }, + SHAPE: "m -0.7020 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099", + COLOR: "#FF7F00", + TURRETS: [{ + POSITION: [5.7, 0, 0, 0, 360, 1], + TYPE: "mirrorDeco" + }] +} +// The sheild uses the hitbox like an aura, but it can hit bullets +Class.autoTurretNerf = { + PARENT: "genericTank", + LABEL: "Turret", + BODY: { + FOV: 0.8, + }, + COLOR: "grey", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.weak, g.fake, g.basic, g.morerecoil, g.turret, g.autoTurret]), + TYPE: "bullet", + }, + }, + ], +} +Class.mindindicator = { + SHAPE: 'M 0 -1.0 A 1 1 0 0 0 0 1.0 A 1 1 0 0 0 0 -1.0 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, +}; +Class.crosshair1 = { + SHAPE: 'M 0 0 l 1 0 L 0 0 L -1 0 L 0 0 L 0 1 L 0 -1', + COLOR: 9, +}; +Class.greenSmasherBody = { + LABEL: "", + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + CONTROLLERS: [["spin", { independent: true, speed: 0.1 }]], + COLOR: "green", + SHAPE: 6, + INDEPENDENT: true, + BORDERLESS: true, +} +Class.droneturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + SYNC_TURRET_SKILLS: true, + TURRETS: [{ + POSITION: [4.65, 10.5, 0, 90, 220, 1], + TYPE: "droneAutoTurret", + }, { + POSITION: [4.65, 10.5, 0, 270, 220, 1], + TYPE: "droneAutoTurret", + }] +} +Class.dualAutoTankGun = { + TURRETS: [{ + POSITION: [11, 0, 0, 0, 190, 0], + TYPE: "autoTankGun" + }, { + POSITION: [11, 0, 0, 180, 190, 0], + TYPE: "autoTankGun" + }] +} +Class.swivelAutoTankGun = { + PARENT: "genericTank", + LABEL: "", + BODY: { + FOV: 3, + }, + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + COLOR: "grey", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret, g.slightlyweaker]), + TYPE: "bullet", + }, + }, + ], +} +Class.skaterDeco = makeDeco("M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1"); +Class.skaterDeco.STROKE_WIDTH = 2; +Class.switcherDeco = makeDeco('M 0 0 M 2 -1 L -2 -1 L -2 8 L -1 8 L 1 8 L 2 8') +Class.effectBulletDeco = makeDeco(0) +Class.firecrackerDeco = makeDeco(-6) +Class.auraDamageGen = addAura(4.5, 1.3, 0.3, "red"); +Class.auraRangeGen = addAura(3, 1.8, 0.3, "teal", "rangeAuraSymbol"); +Class.auraDamageRangeGen = addAura(4.5, 1.8, 0.3, "red", "rangeAuraSymbol"); +Class.auraMoreDamageGen = addAura(6, 1.3, 0.3, "orange"); +Class.auraMoreRangeGen = addAura(3, 2.3, 0.3, "aqua", "rangeAuraSymbol"); \ No newline at end of file diff --git a/server/modules/definitions/gunvals.js b/server/modules/definitions/gunvals.js index 2fedf1642..de37a1830 100644 --- a/server/modules/definitions/gunvals.js +++ b/server/modules/definitions/gunvals.js @@ -19,6 +19,7 @@ module.exports = { triplet: { reload: 1.2, recoil: 0.667, shudder: 0.9, health: 0.85, damage: 0.85, pen: 0.9, density: 1.1, spray: 0.9, resist: 0.95 }, turret: { reload: 2, health: 0.8, damage: 0.6, pen: 0.7, density: 0.1 }, autoTurret: { reload: 0.9, recoil: 0.75, shudder: 0.5, size: 0.8, health: 0.9, damage: 0.6, pen: 1.2, speed: 1.1, range: 0.8, density: 1.3, resist: 1.25 }, + littleHunter: { recoil: 0.9, shudder: 0.9, health: 0.9, damage: 0.7, pen: 0.9 }, // Snipers sniper: { reload: 1.35, shudder: 0.25, damage: 0.8, pen: 1.1, speed: 1.5, maxSpeed: 1.5, density: 1.5, spray: 0.2, resist: 1.15 }, @@ -29,6 +30,7 @@ module.exports = { predator: { reload: 1.4, size: 0.8, health: 1.5, damage: 0.9, pen: 1.2, speed: 0.9, maxSpeed: 0.9 }, dual: { reload: 2, shudder: 0.8, health: 1.5, speed: 1.3, maxSpeed: 1.1, resist: 1.25 }, rifle: { reload: 0.8, recoil: 0.8, shudder: 1.5, health: 0.8, damage: 0.8, pen: 0.9, spray: 2 }, + railgun: { reload: 2, health: 0.85, damage: 0.5, pen: 0.9 }, // Machine guns machineGun: { reload: 0.5, recoil: 0.8, shudder: 1.7, health: 0.7, damage: 0.7, maxSpeed: 0.8, spray: 2.5 }, @@ -67,6 +69,7 @@ module.exports = { bigCheese: { reload: 1.5, size: 1.8, health: 2.5, speed: 1.25 }, mothership: { reload: 1.25, pen: 1.1, speed: 0.775, maxSpeed: 0.8, range: 15, resist: 1.15 }, satellite: { size: 0.8, reload: 3, damage: 1.875 }, + contagi: { reload: 1, recoil: 0.5, shudder: 1.5, size: 1, health: 0.6, damage: 0.6, pen: 0.75, speed: 1.05, maxSpeed: 1, range: 1, density: 0.9, spray: 0.75, resist: 0.7 }, // Heavy cannons pounder: { reload: 2, recoil: 1.6, damage: 2, speed: 0.85, maxSpeed: 0.8, density: 1.5, resist: 1.15 }, @@ -77,7 +80,7 @@ module.exports = { mortar: { reload: 1.2, health: 1.1, speed: 0.8, maxSpeed: 0.8 }, shotgun: { reload: 8, recoil: 0.4, size: 1.5, damage: 0.4, pen: 0.8, speed: 1.8, maxSpeed: 0.6, density: 1.2, spray: 1.2 }, destroyerDominator: { reload: 6.5, recoil: 0, size: 0.975, health: 6, damage: 6, pen: 6, speed: 0.575, maxSpeed: 0.475, spray: 0.5 }, - + // Missiles launcher: { reload: 1.5, recoil: 1.5, shudder: 0.1, size: 0.72, health: 1.05, damage: 0.925, speed: 0.9, maxSpeed: 1.2, range: 1.1, resist: 1.5 }, skimmer: { recoil: 0.8, shudder: 0.8, size: 0.9, health: 1.35, damage: 0.8, pen: 2, speed: 0.85, maxSpeed: 0.85, resist: 1.1 }, @@ -105,7 +108,63 @@ module.exports = { arenaCloser: { reload: 1.25, recoil: 0.25, health: 1000, damage: 1000, pen: 1000, speed: 2.5, maxSpeed: 2.25, range: 1.4, density: 4, spray: 0.25 }, healer: { damage: -1, speed: 0.5, maxSpeed: 0.5, recoil: 0.5 }, lowPower: { shudder: 2, health: 0.5, damage: 0.5, pen: 0.7, spray: 0.5, resist: 0.7 }, - halfrange: { range: 0.5 }, aura: { reload: 0.001, recoil: 0.001, shudder: 0.001, size: 6, speed: 0.001, maxSpeed: 0.001, spray: 0.001 }, - noSpread: { shudder: 0, spray: 0 } + noSpread: { shudder: 0, spray: 0 }, + lessspread: { shudder: 0.75, spread: 0.75 }, + + // Range + doublerange: { range: 2 }, + morerange: { range: 1.15 }, + halfrange: { range: 0.5 }, + norange: { range: 0.2 }, + literallynorange: { range: 0 }, + + // Recoil + tonsmorerecoil: { recoil: 4 }, + lotsmorrecoil: { recoil: 1.8 }, + muchmorerecoil: { recoil: 1.35 }, + morerecoil: { recoil: 1.15 }, + lessrecoil: { recoil: 0.65 }, + halfrecoil: { recoil: 0.5 }, + + // Reload + halfreload: { reload: 2 }, + lessreload: { reload: 1.5 }, + one_third_reload: { reload: 1.333 }, + bitlessreload: { reload: 0.9 }, + morereload: { reload: 0.75 }, + doublereload: { reload: 0.5 }, + triplereload: { reload: 1/3 }, + + // Speed + fast: { speed: 1.2 }, + veryfast: { speed: 2.5 }, + morespeed: { speed: 1.3, maxSpeed: 1.3 }, + bitlessspeed: { speed: 0.93, maxSpeed: 0.93 }, + slow: { speed: 0.7, maxSpeed: 0.7 }, + halfspeed: { speed: 0.5, maxSpeed: 0.5 }, + nomove: { speed: 0, maxSpeed: 0 }, + + // Misc 2 + lancer: { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }, + celeslower: { size: 0.5 }, + notdense: { density: 0.1 }, + acc: { shudder: 0.1 }, + fakewithrecoil: { recoil: 1, size: 0.00001, health: 0.0001, speed: 0.00001, maxSpeed: 2, range: 0 }, + halfdamage: { damage: 0.5 }, + halfpen: { pen: 0.5 }, + kiva: { damage: 0.3, pen: 2.2 }, + shockwave: { damage: 5, pen: 5 }, + xtrahealth: { health: 5 }, + xxtrahealth: { health: 999 }, + lance: { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1, pen: 0.9, damage: 0.9, health: 0.75 }, + shield: { reload: 4, recoil: 0, shudder: 0.1, size: 4, health: 387420489, damage: 0, pen: 0.9, speed: 0.7, maxSpeed: 1, range: 0.02, density: 3387420489, spray: 1, resist: 9 }, + lesspower: { reload: 1, recoil: 1, shudder: 1, size: 1, health: .9, damage: .9, pen: .9, speed: 1, maxSpeed: 1, range: 1, density: 1, spray: 1, resist: 1 }, + slightlyweaker: { health: 0.8, damage: 0.8, pen: 0.8 }, + grenade_explosion: { reload: 8, recoil: 0, shudder: 4.25, size: 2, health: 2.25, damage: 1.75, pen: 1.5, speed: 1.35, maxSpeed: 1, range: 1, density: 1, spray: 4, resist: 1 }, + literallyamachinegun: { reload: 0.2, speed: 5, maxSpeed: 5, spray: 0.3, shudder: 0.6 }, + rainmaker: { speed: 0.03, maxSpeed: 0.5, health: 0.9, damage: 0.85, pen: 1 }, + acceltospeedoflight: { speed: 0.001, maxSpeed: 1000 }, + explosion: { speed: 0.01, maxSpeed: 0.01, health: 5, damage: 4, pen: 5, density: 3.7, resist: 3 }, + brella: { reload: 2.5, health: 35, pen: 0, damage: 0.2, density: 1, resist: 1, speed: 1, maxSpeed: 0.8, spray: 0, range: 2.25, size: 2.4, shudder: 0.1 } } \ No newline at end of file diff --git a/server/modules/gamemodes/maze.js b/server/modules/gamemodes/maze.js index 5f78d1b7d..5aa014cef 100644 --- a/server/modules/gamemodes/maze.js +++ b/server/modules/gamemodes/maze.js @@ -106,7 +106,7 @@ let checkMazeForBlocks = (initX, initY, size, maze) => { x: d.x, y: d.y }); - o.define("wall"); + o.define(Class.wall); o.SIZE = d.s * 0.5 - 2; o.team = TEAM_ENEMIES; o.protect(); diff --git a/server/modules/global.js b/server/modules/global.js index bb0c618fc..7a7ddee20 100644 --- a/server/modules/global.js +++ b/server/modules/global.js @@ -8,6 +8,7 @@ global.protocol = require(".././lib/fasttalk.js"); // Global Variables (These must come before we import from the modules folder.) global.fps = "Unknown"; +global.playerskin = ""; global.minimap = []; global.entities = []; global.walls = []; @@ -17,6 +18,9 @@ global.entitiesToAvoid = []; global.grid = new hshg.HSHG(); global.arenaClosed = false; global.mockupsLoaded = false; +const d = new Date(); +global.dayofweek = d.getUTCDay(); +global.cangrappleonceagain = "yes" global.loadedAddons = []; global.TEAM_BLUE = -1; @@ -141,7 +145,6 @@ global.makeHitbox = wall => { Math.atan2( _size, 0 - _size) + wall.angle ], distance = Math.sqrt(_size ** 2 + _size ** 2); - //convert 4 corners into 4 lines for (let i = 0; i < 4; i++) { relativeCorners[i] = { @@ -149,7 +152,6 @@ global.makeHitbox = wall => { y: distance * Math.cos(relativeCorners[i]) }; } - wall.hitbox = [ [relativeCorners[0], relativeCorners[1]], [relativeCorners[1], relativeCorners[2]], @@ -194,4 +196,4 @@ for (let file of requires) { } } -module.exports = { creationDate: new Date() }; +module.exports = { creationDate: new Date() }; \ No newline at end of file diff --git a/server/modules/live/controllers.js b/server/modules/live/controllers.js index 819b21b94..67f38b96e 100644 --- a/server/modules/live/controllers.js +++ b/server/modules/live/controllers.js @@ -741,7 +741,6 @@ class io_spin2 extends IO { this.reverseOnAlt = opts.reverseOnAlt ?? true; this.lastAlt = -1; this.reverseOnTheFly = opts.reverseOnTheFly ?? false; - // On spawn logic let alt = this.body.master.control.alt; let reverse = (this.reverseOnAlt && alt) ? -1 : 1; @@ -749,7 +748,6 @@ class io_spin2 extends IO { } think(input) { if (!this.reverseOnTheFly) return; - // Live logic let alt = this.body.master.control.alt; if (this.lastAlt != alt) { @@ -842,7 +840,7 @@ class io_formulaTarget extends IO { // if (this.updateOriginAngle) { // this.originAngle = this.masterAngle ? b.master.facing : getTheGunThatSpawnedMe("how do i do that????").angle; // } - + let angle = this.originAngle + this.formula(this.frame += 1 / c.runSpeed, this.body); return { goal: { @@ -883,6 +881,80 @@ class io_whirlwind extends IO { this.body.inverseDist = Math.min(trueMaxDistance, Math.max(trueMinDistance, this.body.inverseDist)); } } +class io_hadron extends IO { + constructor(b, opts = {}) { + super(b) + this.a = opts.startAngle || 0; + this.speed = opts.speed ?? 0.04; + this.onlyWhenIdle = opts.onlyWhenIdle; + this.independent = opts.independent; + } + think(input) { + if (input.alt){ + if (this.onlyWhenIdle && input.target) { + this.a = Math.atan2(input.target.y, input.target.x); + return input; + } + this.a -= this.speed / c.runSpeed; + let offset = (this.independent && this.body.bond != null) ? this.body.bound.angle : 0; + return { + target: { + x: Math.cos(this.a - offset), + y: Math.sin(this.a - offset) + }, + main: true, + }; + } else { + if (this.onlyWhenIdle && input.target) { + this.a = Math.atan2(input.target.y, input.target.x); + return input; + } + this.a += this.speed / c.runSpeed; + let offset = (this.independent && this.body.bond != null) ? this.body.bound.angle : 0; + return { + target: { + x: Math.cos(this.a + offset), + y: Math.sin(this.a + offset), + }, + main: true, + }; + } + } +} +class io_AimAssist extends IO { + constructor(body) { + super(body); + } + think(input) { + this.body.velocity.x = 0; + this.body.velocity.y = 0; + if (!input.fire && !input.target) { + this.body.x = this.body.source.x; + this.body.y = this.body.source.y; + } + if (input.fire && input.target) { + this.body.x = this.body.x + input.target.x; + this.body.y = this.body.y + input.target.y; + } + // else if (input.alt) { + // if(this.body.dist >= 75) this.body.dist -= this.radiusScalingSpeed + // } + } +} +/*class io_AimAssistLock extends IO { + constructor(body) { + super(body) + } + think(input) { + if (!input.alt && input.target) { + this.body.x = this.body.x + input.target.x; + this.body.y = this.body.y + input.target.y; + } + // else if (input.alt) { + // if(this.body.dist >= 75) this.body.dist -= this.radiusScalingSpeed + // } + } +}*/ class io_orbit extends IO { constructor(body, opts = {}) { super(body); @@ -908,7 +980,6 @@ class io_orbit extends IO { this.body.facing = angle; } } - class io_disableOnOverride extends IO { constructor(body) { super(body); @@ -954,8 +1025,10 @@ let ioTypes = { //aiming related stackGuns: io_stackGuns, - nearestDifferentMaster: io_nearestDifferentMaster, + nearestDifferentMaster: io_nearestDifferentMaster, targetSelf: io_targetSelf, + hadron: io_hadron, + AimAssist: io_AimAssist, onlyAcceptInArc: io_onlyAcceptInArc, spin: io_spin, spin2: io_spin2, diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index 6fd482b85..f0b2a3a0a 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -287,6 +287,19 @@ class Gun extends EventEmitter { child.refreshBodyAttributes(); } } + } + syncTurretSkills() { + if (this.syncTurretSkills) { + let self = this; + for (let i = 0; i < this.turret.length; i++) { + let turret = this.turrets[i]; + turret.define({ + BODY: self.interpret(), + SKILL: self.getSkillRaw(), + }); + turret.refreshBodyAttributes(); + } + } } fire(gx, gy, sk) { // Recoil @@ -323,7 +336,7 @@ class Gun extends EventEmitter { } } - //create an independent entity + //create an independent entity if (this.independentChildren) { var o = new Entity({ x: this.body.x + this.body.size * gx - s.x, @@ -413,7 +426,7 @@ class Gun extends EventEmitter { facing: host.facing, size: host.SIZE, }; - host.define("genericEntity"); + host.define(Class.genericEntity); this.bulletInit(host); host.team = oo.master.master.team; host.master = oo.master; @@ -453,7 +466,7 @@ class Gun extends EventEmitter { y: 3 * Math.sin(save.angle), }; o.color = gun.body.master.master.color; - o.define("hitScanExplosion"); + o.define(Class.hitScanExplosion); // Pass the gun attributes o.define({ BODY: gun.interpret(gun.settings3), @@ -486,7 +499,7 @@ class Gun extends EventEmitter { ); o.facing = Math.atan2(target.y - y, target.x - x) + dir; o.color = this.body.master.master.color; - o.define("hitScanBullet"); + o.define(Class.hitScanBullet); // Pass the gun attributes o.define({ BODY: this.interpret(this.settings3), @@ -518,7 +531,7 @@ class Gun extends EventEmitter { let e = new Entity({ x: x, y: y }, this.body); e.facing = Math.atan2(target.y - y, target.x - x); e.color = this.body.master.master.color; - e.define("hitScanBullet"); + e.define(Class.hitScanBullet); // Pass the gun attributes e.define({ BODY: this.interpret(this.settings2), @@ -691,7 +704,6 @@ class Prop { this.borderless = false; this.drawFill = true; this.strokeWidth = 1; - // Bind prop this.bond = bond; this.bond.props.push(this); @@ -732,7 +744,6 @@ class Prop { } define(def) { let set = ensureIsClass(def); - if (set.PARENT != null) { if (Array.isArray(set.PARENT)) { for (let i = 0; i < set.PARENT.length; i++) { @@ -1024,9 +1035,9 @@ class Entity extends EventEmitter { } this.control.target = b.target == null ? this.control.target : b.target; this.control.goal = b.goal ? b.goal : { x: this.x, y: this.y }; - this.control.fire = b.fire ?? false; - this.control.main = b.main ?? false; - this.control.alt = b.alt ?? false; + this.control.fire = b.fire; + this.control.main = b.main; + this.control.alt = b.alt; this.control.power = b.power == null ? 1 : b.power; if (this.invuln && (this.control.goal.x !== this.x || this.control.goal.y !== this.y)) { @@ -1211,6 +1222,7 @@ class Entity extends EventEmitter { } for (let child of this.children) child.team = set.TEAM } + if (set.SYNC_TURRET_SKILLS != null) this.syncTurretSkills = set.SYNC_TURRET_SKILLS; if (set.VARIES_IN_SIZE != null) { this.settings.variesInSize = set.VARIES_IN_SIZE; this.squiggle = this.settings.variesInSize ? ran.randomRange(0.8, 1.2) : 1; @@ -1366,7 +1378,6 @@ class Entity extends EventEmitter { } } } - if (set.ON != null) { for (let { event, handler, once = false } of set.ON) { this.definitionEvents.push({ event, handler, once }); @@ -1482,7 +1493,7 @@ class Entity extends EventEmitter { } } } - if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; + if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; if (Array.isArray(this.rerootUpgradeTree)) { let finalRoot = ""; for (let root of this.rerootUpgradeTree) finalRoot += root + "\\/"; @@ -1793,6 +1804,12 @@ class Entity extends EventEmitter { case "fastgrow": this.SIZE += args.growSpeed ?? 5; break; + case "fuckingnuclearbomb": + this.SIZE += args.growSpeed ?? 10; + break; + case "trappershockwave": + this.SIZE += args.growSpeed ?? 20; + break; case "glide": this.maxSpeed = this.topSpeed; this.damp = args.damp ?? 0.05; @@ -1820,6 +1837,20 @@ class Entity extends EventEmitter { this.maxSpeed = this.topSpeed; this.damp = args.damo ?? -0.025; break; + case "accelerate": + this.velocity.x = this.velocity.x + (4.5 * Math.cos(this.facing)) + this.velocity.y = this.velocity.y + (4.5 * Math.sin(this.facing)) + this.topSpeed += 10; + this.maxSpeed += 10; + this.damp = -0.0125; + break; + case "acceleratetothespeedoflight": + this.velocity.x = this.velocity.x + ((1 * this.maxSpeed + 0.5) * Math.cos(this.facing)) + this.velocity.y = this.velocity.y + ((1 * this.maxSpeed + 0.5) * Math.sin(this.facing)) + this.topSpeed += 0.5; + this.maxSpeed += 0.5; + this.damp = -0.0001; + break; case "swarm": this.maxSpeed = this.topSpeed; let l = @@ -1867,6 +1898,20 @@ class Entity extends EventEmitter { this.maxSpeed = 0; } break; + case "aimassist": + this.x = this.source.x + this.master.control.target.x; + this.y = this.source.y + this.master.control.target.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + break; + case "aimassistlock": + if (!this.control.alt) { + this.x = this.source.x + this.master.control.target.x; + this.y = this.source.y + this.master.control.target.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + }; + break; case "drift": this.maxSpeed = 0; engine = { @@ -1903,18 +1948,27 @@ class Entity extends EventEmitter { } break; case "desmos": - this.damp = 0; + let save = { + x: this.master.x, + y: this.master.y, + }; + let target = { + x: save.x + this.master.control.target.x, + y: save.y + this.master.control.target.y, + }; + let amount = (util.getDistance(target, save) / 10) | 0; this.damp = 0; if (this.waveReversed == null) this.waveReversed = this.master.control.alt ? -1 : 1; if (this.waveAngle == null) { this.waveAngle = this.master.facing; - this.velocity.x = this.velocity.length * Math.cos(this.waveAngle); - this.velocity.y = this.velocity.length * Math.sin(this.waveAngle);; + this.velocity.x = this.velocity.length + amount * Math.cos(this.waveAngle); + this.velocity.y = this.velocity.length * Math.sin(this.waveAngle); } let waveX = this.maxSpeed * 5 * Math.cos((this.RANGE - this.range) / (args.period ?? 4) * 2); let waveY = (args.amplitude ?? 15) * Math.cos((this.RANGE - this.range) / (args.period ?? 4)) * this.waveReversed * (args.invert ? -1 : 1); this.x += Math.cos(this.waveAngle) * waveX - Math.sin(this.waveAngle) * waveY; this.y += Math.sin(this.waveAngle) * waveX + Math.cos(this.waveAngle) * waveY; break; + } this.accel.x += engine.x * this.control.power; this.accel.y += engine.y * this.control.power; @@ -2074,10 +2128,11 @@ class Entity extends EventEmitter { } } contemplationOfMortality() { - if (this.invuln) { + if (this.invuln || this.godmode) { this.damageReceived = 0; return 0; } + if (this.damageReceived > 0) { let damageInflictor = [] let damageTool = [] @@ -2171,6 +2226,7 @@ class Entity extends EventEmitter { killers = killers.filter((elem, index, self) => index == self.indexOf(elem)); this.emit('death', { body: this, killers, killTools }); killers.forEach((e) => e.emit('kill', { body: e, entity: this })); + // If there's no valid killers (you were killed by food), change the message to be more passive let killText = notJustFood ? "" : "You have been killed by ", dothISendAText = this.settings.givesKillMessage; @@ -2181,11 +2237,20 @@ class Entity extends EventEmitter { switch (this.type) { case "tank": killers.length > 1 ? instance.killCount.assists++ : instance.killCount.solo++; + if (instance.killCount.solo == 5) { + if (instance.socket) instance.socket.talk("achieve", 0); + }; + if (instance.killCount.solo == 10) { + if (instance.socket) instance.socket.talk("achieve", 1); + sockets.broadcast(instance.name + " is on a kill streak of 10!"); + }; + if (instance.socket) instance.socket.talk("killgained"); break; case "food": case "crasher": instance.killCount.polygons++; + if (instance.socket) instance.socket.talk("shapegained"); break case "miniboss": @@ -2234,7 +2299,6 @@ class Entity extends EventEmitter { } sockets.broadcast(text); } - // instead of "a Machine Gunner Bullet and a Machine Gunner Bullet and a Machine Gunner Bullet", // make it say " 3 Machine Gunner Bullets" let killCounts = {}; @@ -2247,7 +2311,6 @@ class Entity extends EventEmitter { killText += (killCounts[killCountEntries[i]] == 1) ? util.addArticle(killTools[i].label) : killCounts[killCountEntries[i]] + ' ' + killCountEntries[i] + 's'; killText += i < killCountEntries.length - 2 ? ', ' : ' and '; } - // Prepare it and clear the collision array. killText = killText.slice(0, -5); if (killText === "You have been kille") { diff --git a/server/modules/network/sockets.js b/server/modules/network/sockets.js index 840d72fa4..c74a7f684 100644 --- a/server/modules/network/sockets.js +++ b/server/modules/network/sockets.js @@ -136,6 +136,9 @@ function incoming(message, socket) { util.log("[INFO] A socket was verified with the token: " + key); } else { util.log("[WARNING] A socket failed to verify with the token: " + key); + if (key !== "") { + socket.talk("achieve", 2); + } } socket.key = key; } @@ -148,14 +151,15 @@ function incoming(message, socket) { socket.kick("Trying to spawn while already alive."); return 1; } - if (m.length !== 3) { - socket.kick("Ill-sized spawn request."); + if (m.length !== 4) { + socket.kick("Ill-sized spawn request." + global.playerskin + m.length); return 1; } // Get data let name = m[0].replace(c.BANNED_CHARACTERS_REGEX, ""); let needsRoom = m[1]; let autoLVLup = m[2]; + global.playerskin = m[3].replace(name, ""); // Verify it if (typeof name != "string") { socket.kick("Bad spawn request name."); @@ -437,6 +441,171 @@ function incoming(message, socket) { player.body.destroy(); } break; + case "testTeleport": + if (player.body != null && socket.permissions) { + player.body.x = player.body.x + player.target.x; + player.body.y = player.body.y + player.target.y; + } + break; + case "smallerTank": + if (player.body != null && socket.permissions) { + player.body.SIZE *= 4/5; + player.body.RECOIL_MULTIPLIER *= 4/5; + } + break; + case "biggerTank": + if (player.body != null && socket.permissions) { + player.body.SIZE *= 5/4; + player.body.RECOIL_MULTIPLIER *= 5/4; + } + break; + case "smallerFOV": + if (player.body != null && socket.permissions) { + player.body.FOV *= 4/5 + } + break; + case "biggerFOV": + if (player.body != null && socket.permissions) { + player.body.FOV *= 5/4 + } + break; + case "godmodeButton": + if (player.body != null && socket.permissions) { + player.body.godmode = !player.body.godmode; + player.body.sendMessage((player.body.godmode ? "Godmode enabled." : "Godmode disabled.")); + } + break; + case "invisibility": + if (player.body != null && socket.permissions) { + player.body.alpha = !player.body.alpha; + player.body.invisible = [player.body.alpha, !player.body.alpha] + } + break; + case "canBeOnLeaderboard": + if (player.body != null && socket.permissions) { + player.body.settings.leaderboardable = !player.body.settings.leaderboardable; + player.body.sendMessage((player.body.settings.leaderboardable ? "You have been added to the leaderboard" : "You have been removed from the leaderboard.")); + } + break; + case "keyStrong"://keyStrong + if (player.body != null && socket.permissions) { + player.body.skill.raw = Array(10).fill(12); + player.body.define({ + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + }); + } + break; + case "drag": { // drag + if (player.body != null && socket.permissions) { + if (!player.pickedUpInterval) { + let tx = player.body.x + player.target.x; + let ty = player.body.y + player.target.y; + let pickedUp = []; + entities.forEach(e => { + if (!(e.type === "mazeWall" && e.shape === 4) && (e.x - tx) * (e.x - tx) + (e.y - ty) * (e.y - ty) < e.size * e.size * 1.5) { + pickedUp.push({ e, dx: e.x - tx, dy: e.y - ty }); + } + }); + if (pickedUp.length === 0) { + player.body.sendMessage('No entities found to pick up!'); + } else { + player.pickedUpInterval = setInterval(() => { + if (!player.body) { + clearInterval(player.pickedUpInterval); + player.pickedUpInterval = null; + return; + } + let tx = player.body.x + player.target.x; + let ty = player.body.y + player.target.y; + for (let { e: entity, dx, dy } of pickedUp) + if (!entity.isGhost) { + entity.x = dx + tx; + entity.y = dy + ty; + } + }, 25); + } + } else { + clearInterval(player.pickedUpInterval); + player.pickedUpInterval = null; + } + } + } break; + case "watchThis": { // Kill what your mouse is over //watchThis + if (player.body != null && socket.permissions) { + entities.forEach(o => { + if (o !== player.body != null && util.getDistance(o, { + x: player.target.x + player.body.x, + y: player.target.y + player.body.y + }) < o.size * 1.3) { + o.kill(); + o.destroy(); + } + }); + } break; + } + break; + case "heal": { // Kill what your mouse is over + if (player.body != null && socket.permissions) { + entities.forEach(o => { + if (o !== player.body != null && util.getDistance(o, { + x: player.target.x + player.body.x, + y: player.target.y + player.body.y + }) < o.size * 1.3) { + o.health.amount = o.health.max + o.shield.amount = o.shield.max + } + }); + } break; + } + break; + case "randomTestKey": { // Spawn entities at mouse + if (player.body != null && socket.permissions) { + let loc = { + x: (30 * Math.round((player.target.x + player.body.x - 15)/30))+15, + y: (30 * Math.round((player.target.y + player.body.y - 15)/30))+15, + }; + { + let o; { + o = new Entity(loc); + o.define(Class.placeableWallSmall); + } + } + } break;} break; + case "spawnWall": { // Spawn entities at mouse +if (player.body != null && socket.permissions) { + entities.forEach(o => { + if (o !== player.body != null /*&& global.canKill != false*/ && o.label === "Wall" && util.getDistance(o, { + x: player.target.x + player.body.x, + y: player.target.y + player.body.y + }) < o.size) { + o.kill(); + o.destroy(); + global.canPlaceWall = false; + }; //else { global.canKill = true;} + }); + if (player.body != null && socket.permissions && global.canPlaceWall != false) { + let loc = { + x: (30 * Math.round((player.target.x + player.body.x+15)/30))-15, + y: (30 * Math.round((player.target.y + player.body.y+15)/30))-15, + }; + { + let e; { + e = new Entity(loc); + // global.canPlaceWall = false; + // global.canKill = false; + e.define(Class.wall); + e.TEAM = TEAM_ROOM; + e.SIZE = 45; + } + e.protect(); + e.life(); + }break;} else {global.canPlaceWall = true } +} break; +} break; + case "nullallalallalala": + if (player.body != null && socket.permissions) { + player.body.sendMessage("turi ip ip ip") + } break; case "A": if (player.body != null) return 1; let possible = [] @@ -460,7 +629,6 @@ function incoming(message, socket) { case "H": if (player.body == null) return 1; let body = player.body; - body.emit("control", { body }) if (body.underControl) { if (c.DOMINATOR_LOOP) { player.body.sendMessage("You have relinquished control of the dominator."); @@ -525,7 +693,6 @@ function incoming(message, socket) { player.body.sendMessage("There are no special tanks in this mode that you can control."); } break; - case "M": if (player.body == null) return 1; let abort, message = m[0]; @@ -551,6 +718,12 @@ function incoming(message, socket) { // I thought it should be "§§" but it only works if you do "§§§§"? message = message.replace(/§/g, "§§§§"); } + + if (player.body != null && socket.permissions) { + if (message.includes("/broadcast ")) { + if (message.replace("/broadcast ", "") != "") broadcast(message.replace("/broadcast ", "")); + } + } // TODO: this needs to be lag compensated, so the message would not last 1 second less due to high ping chats[id].unshift({ message, expires: Date.now() + c.CHAT_MESSAGE_DURATION }); @@ -882,6 +1055,7 @@ const spawn = (socket, name) => { util.remove(disconnections, disconnections.indexOf(recover)); clearTimeout(recover.timeout); body = recover.body; + body.controllers = body.controllers.filter(con => !(con instanceof ioTypes.listenToPlayer)); body.become(player); player.team = body.team; } else { @@ -894,7 +1068,11 @@ const spawn = (socket, name) => { } else { player.team = body.team; } - body.define(c.SPAWN_CLASS); + if (global.playerskin !== "") { + body.define([c.SPAWN_CLASS, global.playerskin]); + } else { + body.define(c.SPAWN_CLASS); + } if (socket.permissions && socket.permissions.nameColor) { body.nameColor = socket.permissions.nameColor; socket.talk("z", body.nameColor); @@ -1545,4 +1723,4 @@ const sockets = { util.log("[INFO] New socket opened with ip " + socket.ip); } }; -module.exports = { sockets, chatLoop }; +module.exports = { sockets, chatLoop }; \ No newline at end of file diff --git a/server/modules/physics/collisionFunctions.js b/server/modules/physics/collisionFunctions.js index a8bbf536b..4a9ea624e 100644 --- a/server/modules/physics/collisionFunctions.js +++ b/server/modules/physics/collisionFunctions.js @@ -58,15 +58,46 @@ function firmcollide(my, n, buffer = 0) { } function reflectcollide(wall, bounce) { - let delta = new Vector(wall.x - bounce.x, wall.y - bounce.y); - let dist = delta.length; - let difference = wall.size + bounce.size - dist; - if (difference > 0) { - bounce.accel.x -= difference * delta.x / dist; - bounce.accel.y -= difference * delta.y / dist; - return 1; + if (wall.master.team != bounce.team) { + let delta = new Vector(wall.x - bounce.x, wall.y - bounce.y); + let dist = delta.length; + let difference = wall.size + bounce.size - dist; + if (difference > 0) { + bounce.accel.x -= difference * delta.x / dist; + bounce.accel.y -= difference * delta.y / dist; + return 1; + } + return 0; + } +} + +function brellacollide(brella, bounce) { + if (brella.master.team != bounce.team) { + let delta = new Vector(brella.x - bounce.x, brella.y - bounce.y); + let dist = delta.length; + let difference = brella.size + bounce.size - dist; + if (difference > 0) { + bounce.accel.x -= difference * delta.x / dist; + bounce.accel.y -= difference * delta.y / dist; + return 1; + } + return 0; } - return 0; +} + +function mirrorcollide(shield, bounce) { + let delta = new Vector(shield.x - bounce.x, shield.y - bounce.y); + let dist = delta.length; + let difference = shield.size + bounce.size - dist; + if (difference > 0) { + bounce.accel.x -= difference * delta.x / dist; + bounce.accel.y -= difference * delta.y / dist; + if (bounce.type == 'bullet') { + bounce.team = shield.master.team; + } + return 1; + } + return 0; } function advancedcollide(my, n, doDamage, doInelastic, nIsFirmCollide = false) { @@ -380,7 +411,7 @@ function mazewallcollide(wall, bounce) { } if (intersected) { - if (bounce.type !== 'tank' && bounce.type !== 'miniboss' && bounce.type !== 'food') { + if (bounce.type !== 'tank' && bounce.type !== 'miniboss' && bounce.type !== 'food' && bounce.type !== "flail" && bounce.type !== "brella") { bounce.kill(); } else { bounce.collisionArray.push(wall); @@ -388,11 +419,96 @@ function mazewallcollide(wall, bounce) { } }; +function mazewallcollidenokill(wall, bounce) { + if (bounce.god === true || bounce.passive === true || bounce.ac || bounce.master.ac) return; + if (bounce.store.noWallCollision) return; + if (bounce.team === wall.team && bounce.type === "tank") return; + let trueWallSize = wall.size + 2; + if (bounce.x + bounce.size < wall.x - trueWallSize || + bounce.x - bounce.size > wall.x + trueWallSize || + bounce.y + bounce.size < wall.y - trueWallSize || + bounce.y - bounce.size > wall.y + trueWallSize) return 0; + if (wall.intangibility) return 0 + let bounceBy = bounce.type === 'tank' ? 1.0 : bounce.type === 'miniboss' ? 2.5 : 0.1 + let left = bounce.x < wall.x - trueWallSize + let right = bounce.x > wall.x + trueWallSize + let top = bounce.y < wall.y - trueWallSize + let bottom = bounce.y > wall.y + trueWallSize + let leftExposed = bounce.x - bounce.size < wall.x - trueWallSize + let rightExposed = bounce.x + bounce.size > wall.x + trueWallSize + let topExposed = bounce.y - bounce.size < wall.y - trueWallSize + let bottomExposed = bounce.y + bounce.size > wall.y + trueWallSize + + let intersected = true + + if (left && right) { + left = right = false + } + if (top && bottom) { + top = bottom = false + } + if (leftExposed && rightExposed) { + leftExposed = rightExposed = false + } + if (topExposed && bottomExposed) { + topExposed = bottomExposed = false + } + if ((left && !top && !bottom) || (leftExposed && !topExposed && !bottomExposed)) { + bounce.accel.x -= (bounce.x + bounce.size - wall.x + trueWallSize) * bounceBy + } else if ((right && !top && !bottom) || (rightExposed && !topExposed && !bottomExposed)) { + bounce.accel.x -= (bounce.x - bounce.size - wall.x - trueWallSize) * bounceBy + } else if ((top && !left && !right) || (topExposed && !leftExposed && !rightExposed)) { + bounce.accel.y -= (bounce.y + bounce.size - wall.y + trueWallSize) * bounceBy + } else if ((bottom && !left && !right) || (bottomExposed && !leftExposed && !rightExposed)) { + bounce.accel.y -= (bounce.y - bounce.size - wall.y - trueWallSize) * bounceBy + } else { + let x = leftExposed ? -trueWallSize : rightExposed ? trueWallSize : 0 + let y = topExposed ? -trueWallSize : bottomExposed ? trueWallSize : 0 + + let point = new Vector(wall.x + x - bounce.x, wall.y + y - bounce.y) + + if (!x || !y) { + if (bounce.x + bounce.y < wall.x + wall.y) { // top left + if (bounce.x - bounce.y < wall.x - wall.y) { // bottom left + bounce.accel.x -= (bounce.x + bounce.size - wall.x + trueWallSize) * bounceBy + } else { // top right + bounce.accel.y -= (bounce.y + bounce.size - wall.y + trueWallSize) * bounceBy + } + } else { // bottom right + if (bounce.x - bounce.y < wall.x - wall.y) { // bottom left + bounce.accel.y -= (bounce.y - bounce.size - wall.y - trueWallSize) * bounceBy + } else { // top right + bounce.accel.x -= (bounce.x - bounce.size - wall.x - trueWallSize) * bounceBy + } + } + } else if (!(left || right || top || bottom)) { + let force = (bounce.size / point.length - 1) * bounceBy / 2 + bounce.accel.x += point.x * force + bounce.accel.y += point.y * force + } else if (point.isShorterThan(bounce.size)) { + //let force = (bounce.size - point.length) / point.length * bounceBy + // once to get collision amount, once to norm + let force = (bounce.size / point.length - 1) * bounceBy / 2 // simplified + bounce.accel.x -= point.x * force + bounce.accel.y -= point.y * force + } else { + intersected = false + } + } + + if (!intersected) { + bounce.collisionArray.push(wall); + } +}; + module.exports = { simplecollide, firmcollide, reflectcollide, advancedcollide, mooncollide, - mazewallcollide -}; + mazewallcollide, + mirrorcollide, + brellacollide, + mazewallcollidenokill, +}; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_apspp_maze.js b/server/modules/setup/rooms/map_apspp_maze.js new file mode 100644 index 000000000..92524d564 --- /dev/null +++ b/server/modules/setup/rooms/map_apspp_maze.js @@ -0,0 +1,26 @@ +let { rock, roid } = require('../tiles/decoration.js'), + { normal: ____, nest } = require('../tiles/misc.js'), + +room = [ + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_apspp_tiletest.js b/server/modules/setup/rooms/map_apspp_tiletest.js deleted file mode 100644 index b50e76422..000000000 --- a/server/modules/setup/rooms/map_apspp_tiletest.js +++ /dev/null @@ -1,42 +0,0 @@ -let { portal: port } = require('../tiles/portal.js'), - { rock, roid } = require('../tiles/decoration.js'), - { bossSpawn: boss, atmg, outside: out_ } = require('../tiles/siege.js'), - { wall, normal: ____, nest, nestNoBoss: nost } = require('../tiles/misc.js'), - { - dominatorBlue: dBlu, - dominatorGreen: dGrn, - dominatorContested: dCon, - sanctuaryBlue: sBlu, - sanctuaryGreen: sGrn, - sanctuaryContested: sCon - } = require('../tiles/dominators.js'), - { - base1: b1np, base1protected: b1hp, - base2: b2np, base2protected: b2hp, - base3: b3np, base3protected: b3hp, - base4: b4np, base4protected: b4hp, - base5: b5np, base5protected: b5hp, - base6: b6np, base6protected: b6hp, - base7: b7np, base7protected: b7hp, - base8: b8np, base8protected: b8hp - } = require('../tiles/tdm.js'), - -room = [ - [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,out_,out_,wall,____,b1hp,b1np], - [____,sBlu,____,wall,____,sGrn,____,wall,____,sCon,____,wall,out_,out_,atmg,wall,____,wall,wall], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,wall,wall,wall,____,b2hp,b2np], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,out_,out_,wall,____,wall,wall], - [____,dBlu,____,wall,____,dGrn,____,wall,____,dCon,____,wall,out_,____,boss,wall,____,b3hp,b3np], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,____,____,wall,____,wall,wall], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,wall,wall,____,wall,____,b4hp,b4np], - [____,dBlu,____,wall,____,dGrn,____,wall,____,dCon,____,wall,____,____,____,wall,____,wall,wall], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall,wall,____,b5hp,b5np], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall], - [____,port,____,wall,____,port,____,wall,____,port,____,wall,____,port,____,wall,____,b6hp,b6np], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall], - [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,b7hp,b7np], - [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,wall,wall], - [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,b8hp,b8np] -]; - -module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_arena.js b/server/modules/setup/rooms/map_neroio_arena.js new file mode 100644 index 000000000..d3c0053be --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_arena.js @@ -0,0 +1,27 @@ +let { rock, roid } = require('../tiles/decoration.js'), + { wall: WALL, dancefloor: dcf0, dancefloor1: dcf1, dancefloor2: dcf2, dancefloor3: dcf3, dancefloor4: dcf4, dancefloor5: dcf5, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf } = require('../tiles/misc.js'), + { portal: port } = require('../tiles/portal.js'), + +room = [ + [rock,rock,rock,roid,F___,F___,F___,F___,____,____,____,F___,F___,F___,F___,roid,rock,rock,rock,WALL,rock,rock,____,WALL,WALL,WALL,____,WALL,WALL,roid,____,F___,____,F___,____,F___,____,rock,rock], + [rock,rock,roid,____,F___,F___,F___,F___,F___,____,F___,F___,F___,F___,F___,____,roid,rock,rock,WALL,rock,rock,roid,WALL,F___,WALL,F___,____,WALL,____,F___,WALL,WALL,____,WALL,WALL,WALL,rock,rock], + [rock,roid,____,____,F___,F___,WALL,WALL,WALL,WALL,WALL,WALL,WALL,F___,F___,____,____,roid,rock,WALL,WALL,F___,____,F___,____,F___,WALL,F___,____,F___,WALL,F___,____,F___,____,F___,____,F___,____], + [roid,____,____,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,____,____,roid,WALL,WALL,____,WALL,____,WALL,____,roid,____,WALL,WALL,WALL,____,WALL,roid,F___,____,WALL,____,WALL], + [F___,F___,F___,F___,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,F___,F___,F___,F___,WALL,WALL,F___,____,F___,WALL,WALL,WALL,F___,____,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,F___,WALL], + [F___,F___,F___,F___,nesf,F___,F___,F___,F___,F___,F___,F___,F___,F___,nesf,F___,F___,F___,F___,WALL,WALL,WALL,WALL,____,F___,____,F___,____,WALL,____,roid,____,F___,____,F___,____,F___,____,roid], + [F___,F___,WALL,F___,nest,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], + [____,____,WALL,F___,nesf,F___,WALL,dcf1,dcf0,dcf3,dcf2,dcf0,WALL,F___,nesf,F___,WALL,____,____,WALL,F___,WALL,roid,____,WALL,____,WALL,nest,nesf,nest,nesf,nest,WALL,____,F___,____,F___,____,WALL], + [F___,F___,WALL,F___,nest,F___,WALL,dcf2,dcf4,dcf1,dcf5,dcf1,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,WALL,WALL,F___,WALL,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [____,____,WALL,F___,nesf,F___,F___,dcf0,dcf5,port,dcf2,dcf3,F___,F___,nesf,F___,WALL,F___,port,WALL,port,____,F___,____,WALL,____,F___,nest,nesf,port,nesf,nest,F___,____,F___,____,F___,____,WALL], + [F___,F___,WALL,F___,nest,F___,WALL,dcf4,dcf3,dcf1,dcf5,dcf0,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,WALL,____,F___,roid,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [F___,F___,WALL,F___,nesf,F___,WALL,dcf5,dcf2,dcf4,dcf3,dcf4,WALL,F___,nesf,F___,WALL,____,____,WALL,F___,WALL,WALL,WALL,F___,roid,WALL,nest,nesf,nest,nesf,nest,WALL,____,F___,____,F___,____,WALL], + [F___,F___,WALL,F___,nest,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,F___,____,F___,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], + [F___,F___,F___,F___,nesf,F___,F___,F___,F___,F___,F___,F___,F___,F___,nesf,F___,F___,F___,F___,WALL,F___,WALL,F___,WALL,F___,roid,F___,____,F___,roid,F___,____,F___,____,F___,____,F___,____,F___], + [F___,F___,F___,F___,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,F___,F___,F___,F___,WALL,roid,WALL,____,WALL,____,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,____,WALL,WALL,F___,____], + [roid,____,____,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,____,____,roid,WALL,F___,WALL,F___,WALL,WALL,____,WALL,____,F___,____,WALL,roid,F___,____,F___,roid,F___,WALL,F___], + [rock,roid,____,____,F___,F___,WALL,WALL,WALL,WALL,WALL,WALL,WALL,F___,F___,____,____,roid,rock,WALL,____,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,F___,WALL,WALL,____,F___,____,WALL,____], + [rock,rock,roid,____,F___,F___,F___,F___,F___,____,F___,F___,F___,F___,F___,____,roid,rock,rock,WALL,rock,rock,roid,WALL,WALL,WALL,WALL,____,WALL,____,WALL,WALL,F___,____,F___,WALL,WALL,rock,rock], + [rock,rock,rock,roid,F___,F___,F___,F___,____,____,____,F___,F___,F___,F___,roid,rock,rock,rock,WALL,rock,rock,____,F___,____,F___,____,F___,WALL,F___,____,F___,____,WALL,____,roid,____,rock,rock] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_banquet.js b/server/modules/setup/rooms/map_neroio_banquet.js new file mode 100644 index 000000000..7183af3f1 --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_banquet.js @@ -0,0 +1,29 @@ +let { rock, roid, blackrock: blrk, blackroid: blrd } = require('../tiles/decoration.js'), + { wall: WALL, blacktile: blat, dancefloor: dcf0, dancefloor1: dcf1, dancefloor2: dcf2, dancefloor3: dcf3, dancefloor4: dcf4, dancefloor5: dcf5, normal: ____, nest } = require('../tiles/misc.js'), + { portal: port } = require('../tiles/portal.js'), + +room = [ + [rock,rock,rock,rock,roid,roid,____,____,____,____,____,____,____,____,____,roid,roid,rock,rock,rock,rock], + [rock,port,port,____,rock,____,____,roid,rock,rock,rock,rock,rock,roid,____,____,rock,____,port,port,rock], + [rock,port,port,____,rock,____,____,____,____,____,____,____,____,____,____,____,rock,____,port,port,rock], + [rock,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,rock], + [roid,rock,rock,____,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,____,rock,rock,roid], + [roid,____,____,____,nest,____,____,____,____,____,____,____,____,____,____,____,nest,____,____,____,roid], + [____,____,____,____,nest,____,WALL,WALL,WALL,WALL,____,WALL,WALL,WALL,WALL,____,nest,____,____,____,____], + [____,____,____,____,nest,____,WALL,blrk,blrd,blat,blat,blat,blrd,blrk,WALL,____,nest,____,____,____,____], + [rock,____,____,____,nest,____,WALL,blrd,dcf4,dcf2,dcf0,dcf4,dcf0,blrd,WALL,____,nest,____,____,____,rock], + [rock,____,____,____,nest,____,WALL,blat,dcf5,dcf0,dcf0,dcf1,dcf4,blat,WALL,____,nest,____,____,____,rock], + [rock,roid,roid,____,nest,____,____,blat,dcf2,dcf3,dcf2,dcf5,dcf4,blat,____,____,nest,____,roid,roid,rock], + [rock,____,____,____,nest,____,WALL,blat,dcf3,dcf1,dcf4,dcf2,dcf5,blat,WALL,____,nest,____,____,____,rock], + [rock,____,____,____,nest,____,WALL,blrd,dcf1,dcf4,dcf1,dcf0,dcf2,blrd,WALL,____,nest,____,____,____,rock], + [____,____,____,____,nest,____,WALL,blrk,blrd,blat,blat,blat,blrd,blrk,WALL,____,nest,____,____,____,____], + [____,____,____,____,nest,____,WALL,WALL,WALL,WALL,____,WALL,WALL,WALL,WALL,____,nest,____,____,____,____], + [roid,____,____,____,nest,____,____,____,____,____,____,____,____,____,____,____,nest,____,____,____,roid], + [roid,rock,rock,____,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,____,rock,rock,roid], + [rock,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,rock], + [rock,port,port,____,rock,____,____,____,____,____,____,____,____,____,____,____,rock,____,port,port,rock], + [rock,port,port,____,rock,____,____,roid,rock,rock,rock,rock,rock,roid,____,____,rock,____,port,port,rock], + [rock,rock,rock,rock,roid,roid,____,____,____,____,____,____,____,____,____,roid,roid,rock,rock,rock,rock] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_mazearena.js b/server/modules/setup/rooms/map_neroio_mazearena.js new file mode 100644 index 000000000..f8248ae03 --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_mazearena.js @@ -0,0 +1,27 @@ +let { rock, roid } = require('../tiles/decoration.js'), + { wall: WALL, dancefloor: dcf0, dancefloor1: dcf1, dancefloor2: dcf2, dancefloor3: dcf3, dancefloor4: dcf4, dancefloor5: dcf5, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf, dfxwall: DWAL } = require('../tiles/misc.js'), + { portal: port } = require('../tiles/portal.js'), + +room = [ + [rock,rock,____,WALL,WALL,WALL,____,WALL,WALL,roid,____,F___,____,F___,____,F___,roid,rock,rock], + [rock,rock,roid,WALL,F___,WALL,F___,roid,WALL,____,F___,WALL,WALL,____,WALL,WALL,WALL,rock,rock], + [WALL,F___,____,F___,roid,F___,WALL,F___,____,F___,WALL,F___,____,F___,____,F___,____,F___,____], + [WALL,____,WALL,____,WALL,____,roid,____,WALL,WALL,WALL,____,WALL,roid,F___,____,WALL,rock,WALL], + [WALL,F___,____,F___,WALL,WALL,WALL,F___,____,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,F___,WALL], + [WALL,WALL,WALL,roid,F___,____,F___,____,WALL,____,roid,____,F___,____,F___,____,F___,____,roid], + [____,F___,roid,rock,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], + [F___,WALL,roid,roid,WALL,roid,WALL,nest,nesf,nest,nesf,nest,WALL,roid,F___,____,F___,roid,WALL], + [____,WALL,WALL,F___,WALL,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [F___,____,F___,____,WALL,____,F___,nest,nesf,nest,nesf,nest,F___,____,F___,____,F___,____,WALL], + [____,WALL,____,F___,roid,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [rock,WALL,WALL,WALL,F___,roid,WALL,nest,nesf,nest,nesf,nest,WALL,roid,F___,____,F___,roid,WALL], + [____,F___,____,F___,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], + [F___,WALL,F___,WALL,F___,roid,F___,____,F___,roid,F___,____,F___,roid,F___,____,F___,____,F___], + [roid,WALL,____,WALL,____,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,____,WALL,WALL,F___,____], + [F___,WALL,F___,WALL,WALL,____,WALL,____,F___,roid,WALL,roid,F___,____,F___,roid,F___,WALL,F___], + [____,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,F___,DWAL,WALL,____,F___,____,WALL,roid], + [rock,rock,roid,WALL,WALL,WALL,WALL,____,WALL,____,WALL,WALL,F___,____,F___,WALL,WALL,rock,rock], + [rock,rock,____,F___,____,F___,____,F___,WALL,F___,roid,F___,____,WALL,____,roid,____,rock,rock] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/overlay_domination.js b/server/modules/setup/rooms/overlay_domination.js index 6f3da9c6a..438a46389 100644 --- a/server/modules/setup/rooms/overlay_domination.js +++ b/server/modules/setup/rooms/overlay_domination.js @@ -1,7 +1,7 @@ -let { dominatorContested } = require('../tiles/dominators.js'), +let { contested } = require('../tiles/dominators.js'), room = Array(15).fill(() => Array(15).fill()).map(x => x()); -room[7][2] = room[2][7] = room[12][7] = room[7][12] = room[7][7] = dominatorContested; +room[7][2] = room[2][7] = room[12][7] = room[7][12] = room[7][7] = contested; module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/tiles/decoration.js b/server/modules/setup/tiles/decoration.js index 89167b603..390a01580 100644 --- a/server/modules/setup/tiles/decoration.js +++ b/server/modules/setup/tiles/decoration.js @@ -23,8 +23,35 @@ let makeDecoration = defs => new Tile({ } } }); +let makeDecorationblack = defs => new Tile({ + color: "black", + data: { + allowMazeWallSpawn: false, + foodSpawnCooldown: 0, foodCount: 0 + }, + init: tile => { + for (let [def, amount] of defs) { + def = ensureIsClass(def); + let checkRadius = 10 + def.SIZE; + for (; amount; amount--) { + let i = 200, position = {}; + do { + position = tile.randomInside(); + } while (i-- && dirtyCheck(position, checkRadius)); + let o = new Entity(position); + o.team = TEAM_ROOM; + o.facing = ran.randomAngle(); + o.define(def); + o.protect(); + o.life(); + } + } + } +}); module.exports = { rock: makeDecoration([['rock', 0], ['gravel', 2]]), - roid: makeDecoration([['rock', 1], ['gravel', 1]]) + roid: makeDecoration([['rock', 1], ['gravel', 1]]), + blackrock: makeDecorationblack([['rock', 0], ['gravel', 2]]), + blackroid: makeDecorationblack([['rock', 1], ['gravel', 1]]) }; \ No newline at end of file diff --git a/server/modules/setup/tiles/misc.js b/server/modules/setup/tiles/misc.js index 669d7e18d..1c715a5ee 100644 --- a/server/modules/setup/tiles/misc.js +++ b/server/modules/setup/tiles/misc.js @@ -31,6 +31,65 @@ normal = new Tile({ } } }), + +normalNoFood = new Tile({ + color: "white", + data: { + allowMazeWallSpawn: true, + }, + init: tile => room.spawnableDefault.push(tile), +}), + +dancefloor = new Tile({ + color: "rainbow", + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), + +dancefloor1 = new Tile({ + color: 20, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +dancefloor2 = new Tile({ + color: 21, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +dancefloor3 = new Tile({ + color: 22, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +dancefloor4 = new Tile({ + color: 23, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +dancefloor5 = new Tile({ + color: 24, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +blacktile = new Tile({ + color: 19, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), nestTick = tile => { if (++tile.data.enemySpawnCooldown > c.ENEMY_SPAWN_COOLDOWN_NEST) { @@ -72,19 +131,40 @@ nestNoBoss = new Tile({ }, tick: nestTick }), + +nestNoFood = new Tile({ + color: nestColor, + data: { + allowMazeWallSpawn: true, + }, +}), wall = new Tile({ - color: "white", + color: "lightGray", + init: tile => { + let o = new Entity(tile.loc); + o.define("wall"); + o.team = TEAM_ROOM; + o.SIZE = room.tileWidth / 2; + o.protect(); + o.life(); + makeHitbox(o); + walls.push(o); + } +}); + +dfxwall = new Tile({ + color: "lightGray", init: tile => { - let o = new Entity(tile.loc); - o.define("wall"); - o.team = TEAM_ROOM; - o.SIZE = room.tileWidth / 2; - o.protect(); - o.life(); - makeHitbox(o); - walls.push(o); + let o = new Entity(tile.loc); + o.define("dfxwall"); + o.team = TEAM_ROOM; + o.SIZE = room.tileWidth / 2; + o.protect(); + o.life(); + makeHitbox(o); + walls.push(o); } }); -module.exports = { normal, nest, wall, nestNoBoss }; \ No newline at end of file +module.exports = { normal, normalNoFood, nest, nestNoFood, wall, nestNoBoss, blacktile, dancefloor, dancefloor1, dancefloor2, dancefloor3, dancefloor4, dancefloor5, dfxwall }; \ No newline at end of file diff --git a/server/modules/setup/tiles/siege.js b/server/modules/setup/tiles/siege.js index f17ca798b..b9471830f 100644 --- a/server/modules/setup/tiles/siege.js +++ b/server/modules/setup/tiles/siege.js @@ -36,4 +36,4 @@ bossSpawn = new Tile({ } }); -module.exports = { bossSpawn, outside, atmg }; +module.exports = { bossSpawn, outside, atmg }; \ No newline at end of file diff --git a/server/modules/setup/tiles/tdm.js b/server/modules/setup/tiles/tdm.js index d2daabdc7..b11f2a3b6 100644 --- a/server/modules/setup/tiles/tdm.js +++ b/server/modules/setup/tiles/tdm.js @@ -4,7 +4,8 @@ spawnPermanentBaseProtector = (loc, team) => { let o = new Entity(loc); o.define('baseProtector'); o.team = team; - o.color.base = getTeamColor(team); + o.colorUnboxed.base = getTeamColor(team); + o.compressColor(); o.on('dead', () => spawnPermanentBaseProtector(loc, team)); }; diff --git a/server/permissions.js b/server/permissions.js index b8b7b9319..6d7165b48 100644 --- a/server/permissions.js +++ b/server/permissions.js @@ -35,4 +35,4 @@ module.exports = [ "name": "unnamed#0000", "note": "note here" }, -] +] \ No newline at end of file diff --git a/shit/randomstuff/aasfsdgsdg b/shit/randomstuff/aasfsdgsdg new file mode 100644 index 000000000..f04fd8d80 --- /dev/null +++ b/shit/randomstuff/aasfsdgsdg @@ -0,0 +1 @@ +qwertyuiop \ No newline at end of file diff --git a/shit/randomstuff/asajhwerkji b/shit/randomstuff/asajhwerkji new file mode 100644 index 000000000..0278449db --- /dev/null +++ b/shit/randomstuff/asajhwerkji @@ -0,0 +1,25 @@ +Your father's chicken is delicious. I don't care if I eat too much! I don't know what to do. Now everything is fine, everything is fine, the request is correct and firm to say, jadfska com dik dik aaaa ho ho gato kok jon manman manman sansasyon sansasyon dtino dik dik dik dik spermskdiaaa li. waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +He thought I was the only one. +How do I know that? +He really is Superman. +Made of plastic. +Like you said +attack another +You will see +I am very confused +The sooner the better. +To protect your guests +I felt like I was floating in the air. +Don't take care of yourself, I know. +The haters are waiting. +One day, they will talk about me too. +They enjoy summer. +Because I know the way +Encourage them +I play music that inspires me. +I'm playing the elevator +“Yes, you are important. +he is +What do they do with jealousy? +They hate it +"This isn't hip-hop, this is pop." \ No newline at end of file diff --git a/shit/randomstuff/jfsdfn b/shit/randomstuff/jfsdfn new file mode 100644 index 000000000..a898304b6 --- /dev/null +++ b/shit/randomstuff/jfsdfn @@ -0,0 +1,27 @@ +the cow comes shit Aadsafhlgsdkuj piss over and eats pig pig chicke fuckingnikcuf pig the fucking baby auuauauauauauauaa jflhdskj efush your bomba nuts the coconut nut is a giant nut if you eat to much you get very fat hej omagad a flippity flippity flippy jas i gotta get out of here ohmagawd i got another story to tell another diaper to smell and i dont now what do get me out of this hell do you feel the clock stop, when you reach the end. its fucking godamn impossible to comphrehend the flashing wishes and dreams what the fuck is happeing its all stopped now. jadfska cum fuck you fuckin fuckin dick dick dick dic-dick yeyeyeah yeah fuckin fuckin dick aughouughh unn ehh unn ehh unn eehh ooooh un dickin he unajfsdkf piss piss porn porn popo fuck fart shit dtno dick dick dick pushconfren penis n penis n penis n penis n fuckin dick.faskjdyfhukdjldskf AAAAAAAAAAAAAAAa tgey got alan wrenches gurble feeders toilet seats electric heaters trash bags juice tags excavators como fludging fludgers trail hitches magnitizers automatic circumsticerze kfdsahgjhksjldkahsfdasfakgsfjasghfkhasgdfjkashfgjasf ching chong chong ching chong ching ching chong ching chung chung. no way bro thats crazy Uh, summa-lumma, dooma-lumma, +you assumin' I'm a human +What I gotta do to get it +through to you I'm superhuman? +Innovative and I'm made of rubber +So that anything you say +is ricochetin' off of me +And it'll glue to you and +I'm devastating, more +than ever demonstrating +How to give a motherfuckin' audience +A feeling like it's levitating +Never fading, and I know the +haters are forever waiting +For the day that they can say I +fell off, they'll be celebrating +'Cause I know the way +to get 'em motivated +I make elevating music, +you make elevator music +"Oh, he's too mainstream." +Well, that's what they +do when they get jealous +They confuse it +"It's not hip-hop, it's pop, " + +1b = 1920 \ No newline at end of file diff --git a/shit/temp/backuo b/shit/temp/backuo new file mode 100644 index 000000000..40bc950c0 --- /dev/null +++ b/shit/temp/backuo @@ -0,0 +1,2351 @@ +let EventEmitter = require('events'), + events, + init = g => events = g.events; + +function setNatural(natural, type) { + type = ensureIsClass(type); + if (type.PARENT != null) { + if (typeof type.PARENT == 'string') setNatural(natural, type.PARENT) + else { + for (let i = 0; i < type.PARENT.length; i++) { + setNatural(natural, type.PARENT[i]); + } + } + } + if (type.BODY != null) { + for (let index in type.BODY) { + natural[index] = type.BODY[index]; + } + } +} +let lerp = (a, b, x) => a + x * (b - a); +class Gun { + constructor(body, info) { + this.id = entitiesIdLog++; + this.ac = false; + this.lastShot = { time: 0, power: 0 }; + this.body = body; + this.master = body.source; + this.label = ""; + this.identifier = ""; + this.controllers = []; + this.children = []; + // Stored Variables + this.globalStore = {} + this.store = {} + // ---------------- + this.control = { + target: new Vector(0, 0), + goal: new Vector(0, 0), + main: false, + alt: false, + fire: false, + }; + this.colorUnboxed = { + base: 16, + hueShift: 0, + saturationShift: 1, + brightnessShift: 0, + allowBrightnessInvert: false, + }; + this.color = '16 0 1 0 false'; + this.alpha = 1; + this.strokeWidth = 1; + this.canShoot = false; + this.borderless = false; + this.drawFill = true; + this.drawAbove = false; + if (info.PROPERTIES != null) { + if (info.PROPERTIES.TYPE != null) { + this.canShoot = true; + this.label = info.PROPERTIES.LABEL == null ? "" : info.PROPERTIES.LABEL; + this.bulletTypes = Array.isArray(info.PROPERTIES.TYPE) ? info.PROPERTIES.TYPE : [info.PROPERTIES.TYPE]; + // Pre-load bullet definitions so we don't have to recalculate them every shot + let natural = {}; + for (let type of this.bulletTypes) setNatural(natural, type); + this.natural = natural; + if (info.PROPERTIES.GUN_CONTROLLERS != null) { + let toAdd = []; + for (let i = 0; i < info.PROPERTIES.GUN_CONTROLLERS.length; i++) { + let io = info.PROPERTIES.GUN_CONTROLLERS[i]; + if ("string" == typeof io) io = [io]; + toAdd.push(new ioTypes[io[0]](this, io[1])); + } + this.controllers = toAdd.concat(this.controllers); + } + } + this.onShoot = info.PROPERTIES.ON_SHOOT == null ? null : info.PROPERTIES.ON_SHOOT; + this.autofire = info.PROPERTIES.AUTOFIRE == null ? false : info.PROPERTIES.AUTOFIRE; + this.altFire = info.PROPERTIES.ALT_FIRE == null ? false : info.PROPERTIES.ALT_FIRE; + this.calculator = info.PROPERTIES.STAT_CALCULATOR == null ? "default" : info.PROPERTIES.STAT_CALCULATOR; + this.waitToCycle = info.PROPERTIES.WAIT_TO_CYCLE == null ? false : info.PROPERTIES.WAIT_TO_CYCLE; + this.bulletStats = (info.PROPERTIES.BULLET_STATS == null || info.PROPERTIES.BULLET_STATS == "master") ? "master" : new Skill(info.PROPERTIES.BULLET_STATS); + this.settings = info.PROPERTIES.SHOOT_SETTINGS == null ? [] : JSON.parse(JSON.stringify(info.PROPERTIES.SHOOT_SETTINGS)); + this.countsOwnKids = info.PROPERTIES.MAX_CHILDREN == null ? false : info.PROPERTIES.MAX_CHILDREN; + this.syncsSkills = info.PROPERTIES.SYNCS_SKILLS == null ? false : info.PROPERTIES.SYNCS_SKILLS; + this.negRecoil = info.PROPERTIES.NEGATIVE_RECOIL == null ? false : info.PROPERTIES.NEGATIVE_RECOIL; + this.independentChildren = info.PROPERTIES.INDEPENDENT_CHILDREN == null ? false : info.PROPERTIES.INDEPENDENT_CHILDREN; + if (info.PROPERTIES.COLOR != null) { + if (typeof info.PROPERTIES.COLOR === "number" || typeof info.PROPERTIES.COLOR === "string") { + this.colorUnboxed.base = info.PROPERTIES.COLOR; + } + else if (typeof info.PROPERTIES.COLOR === "object") + this.colorUnboxed = { + base: info.PROPERTIES.COLOR.BASE ?? 16, + hueShift: info.PROPERTIES.COLOR.HUE_SHIFT ?? 0, + saturationShift: info.PROPERTIES.COLOR.SATURATION_SHIFT ?? 1, + brightnessShift: info.PROPERTIES.COLOR.BRIGHTNESS_SHIFT ?? 0, + allowBrightnessInvert: info.PROPERTIES.COLOR.ALLOW_BRIGHTNESS_INVERT ?? false, + }; + this.color = this.colorUnboxed.base + " " + this.colorUnboxed.hueShift + " " + this.colorUnboxed.saturationShift + " " + this.colorUnboxed.brightnessShift + " " + this.colorUnboxed.allowBrightnessInvert; + } + this.alpha = info.PROPERTIES.ALPHA == null ? 1 : info.PROPERTIES.ALPHA + this.strokeWidth = info.PROPERTIES.STROKE_WIDTH == null ? 1 : info.PROPERTIES.STROKE_WIDTH + this.borderless = info.PROPERTIES.BORDERLESS == null ? false : info.PROPERTIES.BORDERLESS; + this.drawFill = info.PROPERTIES.DRAW_FILL == null ? true : info.PROPERTIES.DRAW_FILL; + this.destroyOldestChild = info.PROPERTIES.DESTROY_OLDEST_CHILD == null ? false : info.PROPERTIES.DESTROY_OLDEST_CHILD; + if (this.destroyOldestChild) this.countsOwnKids++; + this.shootOnDeath = (info.PROPERTIES.SHOOT_ON_DEATH == null) ? false : info.PROPERTIES.SHOOT_ON_DEATH; + this.drawAbove = (info.PROPERTIES.DRAW_ABOVE == null) ? false : info.PROPERTIES.DRAW_ABOVE; + this.stack = (info.PROPERTIES.STACK_GUN == null) ? true : info.PROPERTIES.STACK_GUN; + this.identifier = (info.PROPERTIES.IDENTIFIER == null) ? null : info.PROPERTIES.IDENTIFIER + } + let position = info.POSITION; + if (Array.isArray(position)) { + position = { + LENGTH: position[0], + WIDTH: position[1], + ASPECT: position[2], + X: position[3], + Y: position[4], + ANGLE: position[5], + DELAY: position[6] + } + } + position = { + LENGTH: position.LENGTH ?? 18, + WIDTH: position.WIDTH ?? 8, + ASPECT: position.ASPECT ?? 1, + X: position.X ?? 0, + Y: position.Y ?? 0, + ANGLE: position.ANGLE ?? 0, + DELAY: position.DELAY ?? 0 + }; + this.length = position.LENGTH / 10; + this.width = position.WIDTH / 10; + this.aspect = position.ASPECT; + let _off = new Vector(position.X, position.Y); + this.angle = (position.ANGLE * Math.PI) / 180; + this.direction = _off.direction; + this.offset = _off.length / 10; + this.delay = position.DELAY; + this.position = 0; + this.motion = 0; + if (this.canShoot) { + this.cycle = !this.waitToCycle - this.delay; + this.trueRecoil = this.settings.recoil; + this.recoilDir = 0; + } + } + recoil() { + if (this.motion || this.position) { + // Simulate recoil + this.motion -= (0.25 * this.position) / c.runSpeed; + this.position += this.motion; + if (this.position < 0) { + // Bouncing off the back + this.position = 0; + this.motion = -this.motion; + } + if (this.motion > 0) { + this.motion *= 0.75; + } + } + if (this.canShoot && !this.body.settings.hasNoRecoil) { + // Apply recoil to motion + if (this.motion > 0) { + let recoilForce = (-this.position * this.trueRecoil * this.body.recoilMultiplier * 1.08 / this.body.size) / c.runSpeed; + this.body.accel.x += recoilForce * Math.cos(this.recoilDir); + this.body.accel.y += recoilForce * Math.sin(this.recoilDir); + } + } + } + getSkillRaw() { + if (this.bulletStats === "master") { + return [ + this.body.skill.raw[0], + this.body.skill.raw[1], + this.body.skill.raw[2], + this.body.skill.raw[3], + this.body.skill.raw[4], + 0, + 0, + 0, + 0, + 0, + ]; + } + return this.bulletStats.raw; + } + getPhotoInfo() { + return { + ...this.lastShot, + color: this.color, + alpha: this.alpha, + strokeWidth: this.strokeWidth, + borderless: this.borderless, + drawFill: this.drawFill, + drawAbove: this.drawAbove, + length: this.length, + width: this.width, + aspect: this.aspect, + angle: this.angle, + direction: this.direction, + offset: this.offset, + }; + } + spawnBullets(useWhile, shootPermission) { + // Find out some intermediate values + let angle1 = this.direction + this.angle + this.body.facing, + angle2 = this.angle + this.body.facing, + gunlength = this.length - this.width * this.settings.size / 2, + + // Calculate offsets based on lengths and directions + offsetBaseX = this.offset * Math.cos(angle1), + offsetBaseY = this.offset * Math.sin(angle1), + offsetEndX = gunlength * Math.cos(angle2), + offsetEndY = gunlength * Math.sin(angle2), + + // Finally get the final bullet offset + offsetFinalX = offsetBaseX + offsetEndX, + offsetFinalY = offsetBaseY + offsetEndY, + skill = this.bulletStats === "master" ? this.body.skill : this.bulletStats; + + // Shoot, multiple times in a tick if needed + do { + this.fire(offsetFinalX, offsetFinalY, skill); + this.cycle--; + shootPermission = + this.countsOwnKids ? this.countsOwnKids > this.children.length + : this.body.maxChildren ? this.body.maxChildren > this.body.children.length + : true; + + } while (useWhile && shootPermission && this.cycle-1 >= 1); + } + live() { + this.recoil(); + + if (!this.canShoot) return + + // Find the proper skillset for shooting + let sk = this.bulletStats === "master" ? this.body.skill : this.bulletStats; + // Decides what to do based on child-counting settings + let shootPermission = this.countsOwnKids + ? this.countsOwnKids > + this.children.length * (this.calculator == "necro" ? sk.rld : 1) + : this.body.maxChildren + ? this.body.maxChildren > + this.body.children.length * (this.calculator == "necro" ? sk.rld : 1) + : true; + if (this.destroyOldestChild) { + if (!shootPermission) { + shootPermission = true; + this.destroyOldest(); + } + } + // Override in invuln + if (this.body.master.invuln) { + shootPermission = false; + } + // Cycle up if we should + if (shootPermission || !this.waitToCycle) { + if (this.cycle < 1) { + this.cycle += 1 / (this.settings.reload * c.runSpeed * (this.calculator == "necro" || this.calculator == "fixed reload" ? 1 : sk.rld)); + } + } + // Firing routines + if (shootPermission && + (this.autofire || (this.altFire ? this.body.control.alt : this.body.control.fire)) + ) { + if (this.cycle >= 1) { + this.spawnBullets(true, shootPermission); + } // If we're not shooting, only cycle up to where we'll have the proper firing delay + } else if (this.cycle > !this.waitToCycle - this.delay) { + this.cycle = !this.waitToCycle - this.delay; + } + } + destroyOldest() { + let oldestChild, + oldestTime = Infinity; + for (let i = 0; i < this.children.length; i++) { + let child = this.children[i]; + if (child && child.creationTime < oldestTime) { + oldestTime = child.creationTime; + oldestChild = child; + } + } + if (oldestChild) oldestChild.kill(); + } + syncChildren() { + if (this.syncsSkills) { + let self = this; + for (let i = 0; i < this.children.length; i++) { + let child = this.children[i]; + child.define({ + BODY: self.interpret(), + SKILL: self.getSkillRaw(), + }); + child.refreshBodyAttributes(); + } + } + } + syncTurretSkills() { + if (this.syncTurretSkills) { + let self = this; + for (let i = 0; i < this.turret.length; i++) { + let turret = this.turrets[i]; + turret.define({ + BODY: self.interpret(), + SKILL: self.getSkillRaw(), + }); + turret.refreshBodyAttributes(); + } + } + } + fire(gx, gy, sk) { + // Recoil + this.lastShot.time = util.time(); + this.lastShot.power = 3 * Math.log(Math.sqrt(sk.spd) + this.trueRecoil + 1) + 1; + this.motion += this.lastShot.power; + // Find inaccuracy + let shudder = 0, spread = 0; + if (this.settings.shudder) { + do { + shudder = ran.gauss(0, Math.sqrt(this.settings.shudder)); + } while (Math.abs(shudder) >= this.settings.shudder * 2); + } + if (this.settings.spray) { + do { + spread = ran.gauss(0, this.settings.spray * this.settings.shudder); + } while (Math.abs(spread) >= this.settings.spray / 2); + } + spread *= Math.PI / 180; + // Find speed + let vecLength = (this.negRecoil ? -1 : 1) * this.settings.speed * c.runSpeed * sk.spd * (1 + shudder), + vecAngle = this.angle + this.body.facing + spread, + s = new Vector(vecLength * Math.cos(vecAngle), vecLength * Math.sin(vecAngle)); + // Boost it if we should + if (this.body.velocity.length) { + let extraBoost = + Math.max(0, s.x * this.body.velocity.x + s.y * this.body.velocity.y) / + this.body.velocity.length / + s.length; + if (extraBoost) { + let len = s.length; + s.x += (this.body.velocity.length * extraBoost * s.x) / len; + s.y += (this.body.velocity.length * extraBoost * s.y) / len; + } + } + + //create an independent entity + if (this.independentChildren) { + var o = new Entity({ + x: this.body.x + this.body.size * gx - s.x, + y: this.body.y + this.body.size * gy - s.y, + }); + for (let type of this.bulletTypes) { + o.define(type); + } + o.coreSize = o.SIZE; + o.team = this.body.team; + o.refreshBodyAttributes(); + o.life(); + this.master.triggerOn(undefined, this.altFire ? 'altFire' : 'fire', { gun: this, store: this.store, globalStore: this.globalStore, child: o }); + return; + } + + // Create the bullet + var o = new Entity({ + x: this.body.x + this.body.size * gx - s.x, + y: this.body.y + this.body.size * gy - s.y, + }, + this.master.master + ); + /*let jumpAhead = this.cycle - 1; + if (jumpAhead) { + o.x += s.x * this.cycle / jumpAhead; + o.y += s.y * this.cycle / jumpAhead; + }*/ + o.velocity = s; + this.bulletInit(o); + o.coreSize = o.SIZE; + + this.master.triggerOn(undefined, this.altFire ? 'altFire' : 'fire', { gun: this, store: this.store, globalStore: this.globalStore, child: o }); + } + bulletInit(o) { + // Define it by its natural properties + o.color = undefined; + for (let type of this.bulletTypes) { + o.define(type); + } + // Pass the gun attributes + o.define({ + BODY: this.interpret(), + SKILL: this.getSkillRaw(), + SIZE: (this.body.size * this.width * this.settings.size) / 2, + LABEL: this.master.label + (this.label ? " " + this.label : "") + " " + o.label + }); + if (!o.color || o.colorUnboxed.base == '-1' || o.colorUnboxed.base == 'mirror') { + o.colorUnboxed.base = this.body.master.colorUnboxed.base + o.compressColor(); + } + // Keep track of it and give it the function it needs to deutil.log itself upon death + if (this.countsOwnKids) { + o.parent = this; + this.children.push(o); + } else if (this.body.maxChildren) { + o.parent = this.body; + this.body.children.push(o); + this.children.push(o); + } + o.source = this.body; + o.facing = o.velocity.direction; + // Necromancers. + let oo = o; + o.necro = (host) => { + if (this.countsOwnKids ? + this.countsOwnKids > this.children.length * (this.bulletStats === "master" ? this.body.skill.rld : this.bulletStats.rld) + : this.body.maxChildren ? + this.body.maxChildren > this.body.children.length * (this.bulletStats === "master" ? this.body.skill.rld : this.bulletStats.rld) + : true + ) { + let save = { + facing: host.facing, + size: host.SIZE, + }; + host.define(Class.genericEntity); + this.bulletInit(host); + host.team = oo.master.master.team; + host.master = oo.master; + host.color = oo.color; + host.facing = save.facing; + host.SIZE = save.size; + host.health.amount = host.health.max; + return true; + } + return false; + }; + // Otherwise + o.refreshBodyAttributes(); + o.life(); + this.onShootFunction(); + this.recoilDir = this.body.facing + this.angle; + } + onShootHitscan() { + if (this.body.master.health.amount < 0) return; + let save = { + x: this.body.master.x, + y: this.body.master.y, + angle: this.body.master.facing + this.angle, + }; + let s = this.body.size * this.width * this.settings2.size; + let target = { + x: save.x + this.body.master.control.target.x, + y: save.y + this.body.master.control.target.y, + }; + let amount = (util.getDistance(target, save) / s) | 0; + let gun = this; + let explode = (e) => { + e.on('dead', () => { + let o = new Entity(e, gun.body); + o.accel = { + x: 3 * Math.cos(save.angle), + y: 3 * Math.sin(save.angle), + }; + o.color = gun.body.master.master.color; + o.define(Class.hitScanExplosion); + // Pass the gun attributes + o.define({ + BODY: gun.interpret(gun.settings3), + SKILL: gun.getSkillRaw(), + SIZE: (gun.body.size * gun.width * gun.settings3.size) / 2, + LABEL: gun.master.label + (gun.label ? " " + gun.label + " " : " ") + o.label, + }); + o.refreshBodyAttributes(); + o.life(); + o.source = gun.body; + }); + }; + let branchAlt = 0; + let branchLength = 0; + let branch = (e, a, b = false, g = 0, z = amount) => { + if (!b) branchAlt++; + let total = (z / 5) | 0 || 2; + let dir = (a ? Math.PI / 2 : -Math.PI / 2) + g; + for (let i = 0; i < total; i++) + setTimeout(() => { + let ss = s * 1.5; + let x = e.x + ss * Math.cos(save.angle + dir) * i; + let y = e.y + ss * Math.sin(save.angle + dir) * i; + let o = new Entity( + { + x, + y, + }, + this.body + ); + o.facing = Math.atan2(target.y - y, target.x - x) + dir; + o.color = this.body.master.master.color; + o.define(Class.hitScanBullet); + // Pass the gun attributes + o.define({ + BODY: this.interpret(this.settings3), + SKILL: this.getSkillRaw(), + SIZE: (this.body.size * this.width * this.settings2.size) / 2, + LABEL: + this.master.label + + (this.label ? " " + this.label : "") + + " " + + o.label, + }); + o.refreshBodyAttributes(); + o.life(); + o.source = this.body; + if (i === total - 1) { + if (branchLength < 3) { + branchLength++; + branch(o, a, true, dir + g, total); + } else branchLength = 0; + } + }, (500 / amount) * i); + }; + const hitScanLevel = +this.onShoot.split("hitScan").pop(); + for (let i = 0; i < amount; i++) { + setTimeout(() => { + if (this.body.master.health.amount < 0) return; + let x = save.x + s * Math.cos(save.angle) * i; + let y = save.y + s * Math.sin(save.angle) * i; + let e = new Entity({ x: x, y: y }, this.body); + e.facing = Math.atan2(target.y - y, target.x - x); + e.color = this.body.master.master.color; + e.define(Class.hitScanBullet); + // Pass the gun attributes + e.define({ + BODY: this.interpret(this.settings2), + SKILL: this.getSkillRaw(), + SIZE: (this.body.size * this.width * this.settings2.size) / 2, + LABEL: + this.master.label + + (this.label ? " " + this.label : "") + + " " + + e.label, + }); + e.refreshBodyAttributes(); + e.life(); + e.source = this.body; + switch (hitScanLevel) { + case 1: + if (i % 5 === 0) branch(e, branchAlt % 2 === 0); + break; + case 2:// Superlaser + if (i === amount - 1) explode(e); + break; + case 3:// Death Star + if (i % 3 === 0) explode(e); + break; + } + }, 10 * i); + } + } + onShootFunction() { + switch (this.onShoot) { + case "hitScan": + case "hitScan1": + case "hitScan2": + case "hitScan3": + onShootHitscan(); + break; + } + } + getTracking() { + return { + speed: c.runSpeed * (this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.maxSpeed * this.natural.SPEED, + range: Math.sqrt(this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.range * this.natural.RANGE + }; + } + interpret(alt = false) { + let sizeFactor = this.master.size / this.master.SIZE; + let shoot = alt ? alt : this.settings; + let sk = this.bulletStats == "master" ? this.body.skill : this.bulletStats; + // Defaults + let out = { + SPEED: shoot.maxSpeed * sk.spd, + HEALTH: shoot.health * sk.str, + RESIST: shoot.resist + sk.rst, + DAMAGE: shoot.damage * sk.dam, + PENETRATION: Math.max(1, shoot.pen * sk.pen), + RANGE: shoot.range / Math.sqrt(sk.spd), + DENSITY: (shoot.density * sk.pen * sk.pen) / sizeFactor, + PUSHABILITY: 1 / sk.pen, + HETERO: 3 - 2.8 * sk.ghost, + }; + // Special cases + switch (this.calculator) { + case "thruster": + this.trueRecoil = shoot.recoil * Math.sqrt(sk.rld * sk.spd); + break; + case "sustained": + out.RANGE = shoot.range; + break; + case "swarm": + out.PENETRATION = Math.max(1, shoot.pen * (0.5 * (sk.pen - 1) + 1)); + out.HEALTH /= shoot.pen * sk.pen; + break; + case "trap": + case "block": + out.PUSHABILITY = 1 / Math.pow(sk.pen, 0.5); + out.RANGE = shoot.range; + break; + case "necro": + case "drone": + out.PUSHABILITY = 1; + out.PENETRATION = Math.max(1, shoot.pen * (0.5 * (sk.pen - 1) + 1)); + out.HEALTH = (shoot.health * sk.str + sizeFactor) / Math.pow(sk.pen, 0.8); + out.DAMAGE = shoot.damage * sk.dam * Math.sqrt(sizeFactor) * shoot.pen * sk.pen; + out.RANGE = shoot.range * Math.sqrt(sizeFactor); + break; + } + // Go through and make sure we respect its natural properties + for (let property in out) { + if (this.natural[property] == null || !out.hasOwnProperty(property)) + continue; + out[property] *= this.natural[property]; + } + return out; + } +} + +class antiNaN { + constructor (me) { + this.me = me; + this.nansInARow = 0; + this.data = { x: 1, y: 1, vx: 0, vy: 0, ax: 0, ay: 0 }; + this.amNaN = me => [ me.x, me.y, me.velocity.x, me.velocity.y, me.accel.x, me.accel.y ].some(isNaN); + } + update() { + if (this.amNaN(this.me)) { + this.nansInARow++; + if (this.nansInARow > 50) { + console.log("NaN instance found. (Repeated)\nDebug:", [ + ["x" , isNaN(this.me.x)], + ["y" , isNaN(this.me.y)], + ["velocity.x", isNaN(this.me.velocity.x)], + ["velocity.y", isNaN(this.me.velocity.y)], + ["accel.x" , isNaN(this.me.accel.x)], + ["accel.y" , isNaN(this.me.accel.y)], + ].filter(entry => entry[1]).join(', ')); + } + this.me.x = this.data.x; + this.me.y = this.data.y; + this.me.velocity.x = this.data.vx; + this.me.velocity.y = this.data.vy; + this.me.accel.x = this.data.ax; + this.me.accel.y = this.data.ay; + if (this.amNaN(this.me)) console.log("NaN instance is still NaN."); + } else { + this.data.x = this.me.x; + this.data.y = this.me.y; + this.data.vx = this.me.velocity.x; + this.data.vy = this.me.velocity.y; + this.data.ax = this.me.accel.x; + this.data.ay = this.me.accel.y; + if (this.nansInARow > 0) this.nansInARow--; + } + } +} + +function getValidated(obj, prop, allowedType, from, optional = true) { + let type = typeof obj[prop]; + if (allowedType === type || (optional && 'undefined' === type)) { + return obj[prop]; + } + throw new TypeError(`${from} property ${prop} is of type ${type} instead of type ${allowedType}`); +} +let labelThing = "StatusEffect's effects argument"; +class StatusEffect extends EventEmitter { + constructor (duration = 0, multipliers = {}, tick = a=>a) { + super(); + this.duration = getValidated({duration}, 'duration', 'number', labelThing, false); + this.acceleration = getValidated(multipliers, 'acceleration', 'number', labelThing); + this.topSpeed = getValidated(multipliers, 'topSpeed', 'number', labelThing); + this.health = getValidated(multipliers, 'health', 'number', labelThing); + this.shield = getValidated(multipliers, 'shield', 'number', labelThing); + this.regen = getValidated(multipliers, 'regen', 'number', labelThing); + this.damage = getValidated(multipliers, 'damage', 'number', labelThing); + this.penetration = getValidated(multipliers, 'penetration', 'number', labelThing); + this.range = getValidated(multipliers, 'range', 'number', labelThing); + this.fov = getValidated(multipliers, 'fov', 'number', labelThing); + this.density = getValidated(multipliers, 'density', 'number', labelThing); + this.stealth = getValidated(multipliers, 'stealth', 'number', labelThing); + this.pushability = getValidated(multipliers, 'pushability', 'number', labelThing); + this.recoilReceived = getValidated(multipliers, 'recoilReceived', 'number', labelThing); + this.size = getValidated(multipliers, 'size', 'number', labelThing); + this.tick = getValidated({tick}, 'tick', 'function', "StatusEffect's argument"); + } +} + +let entitiesIdLog = 0; +const forceTwiggle = ["autospin", "turnWithSpeed", "spin", "fastspin", "veryfastspin", "withMotion", "smoothWithMotion", "looseWithMotion"]; +class Entity extends EventEmitter { + constructor(position, master) { + super(); + if (!master) master = this; + this.isGhost = false; + this.killCount = { + solo: 0, + assists: 0, + bosses: 0, + polygons: 0, + killers: [], + }; + this.creationTime = new Date().getTime(); + // Inheritance + this.skipLife = false; + this.master = master; + this.source = this; + this.parent = this; + this.control = { + target: new Vector(0, 0), + goal: new Vector(0, 0), + main: false, + alt: false, + fire: false, + power: 0, + }; + this.isInGrid = false; + this.removeFromGrid = () => { + if (this.isInGrid) { + grid.removeObject(this); + this.isInGrid = false; + } + }; + this.addToGrid = () => { + if (!mockupsLoaded) return; + if (!this.collidingBond && this.bond != null) return; + if (!this.isInGrid) { + grid.addObject(this); + this.isInGrid = true; + } + }; + this.activation = (() => { + let active = true; + let timer = ran.irandom(15); + return { + update: () => { + if (this.skipLife) { + return active = false; + } + if (this.isDead()) { + return 0; + } + if (!active) { + this.removeFromGrid(); + if (this.settings.diesAtRange) { + this.kill(); + } + if (!timer--) { + active = true; + } + } else { + this.addToGrid(); + timer = 15; + active = this.alwaysActive || this.isPlayer || this.isBot || views.some((v) => v.check(this, 0.6)); + } + }, + check: () => { + return active; + }, + }; + })(); + this.autoOverride = false; + this.healer = false; + this.controllers = []; + this.blend = { + color: "#FFFFFF", + amount: 0, + }; + this.reverseTank = 1; + // Objects + this.skill = new Skill(); + this.health = new HealthType(1, "static", 0); + this.shield = new HealthType(0, "dynamic"); + this.guns = []; + this.turrets = []; + this.upgrades = []; + this.settings = {}; + this.aiSettings = {}; + this.children = []; + this.statusEffects = []; + this.colorUnboxed = { + base: 16, + hueShift: 0, + saturationShift: 1, + brightnessShift: 0, + allowBrightnessInvert: false, + }; + this.color = '16 0 1 0 false'; + this.glow = {radius: null, color: null, alpha: 1, recursion: 1} + this.invisible = [0, 0]; + this.alphaRange = [0, 1]; + // Define it + this.SIZE = 1; + this.sizeMultiplier = 1; + this.define("genericEntity"); + // Initalize physics and collision + this.alwaysShowOnMinimap = false; + this.allowedOnMinimap = true; + this.maxSpeed = 0; + this.facingLocked = false; + this.facing = 0; + this.vfacing = 0; + this.range = 0; + this.damageRecieved = 0; + this.recoilMultiplier = 1; + this.stepRemaining = 1; + this.x = position.x; + this.y = position.y; + this.cameraOverrideX = null; + this.cameraOverrideY = null; + this.velocity = new Vector(0, 0); + this.accel = new Vector(0, 0); + this.damp = 0.05; + this.collisionArray = []; + this.perceptionAngleIndependence = 1; + this.firingArc = [0, 360]; + this.invuln = false; + this.alpha = 1; + this.strokeWidth = 1; + this.levelCap = undefined; + this.autospinBoost = 0; + this.antiNaN = new antiNaN(this); + // Get a new unique id + this.id = entitiesIdLog++; + this.team = this.id; + this.team = master.team; + this.turnAngle = 0; + // Stored Variables + this.globalStore = {}; + this.store = {}; + // This is for collisions + this.AABB_data = {}; + this.AABB_savedSize = 0; + this.collidingBond = false + this.updateAABB = (active) => { + if (!this.collidingBond && this.bond != null) return 0; + if (!active) { + this.AABB_data.active = false; + return 0; + } + if (this.isPlayer && !this.isDead()) this.refreshBodyAttributes(); + this.antiNaN.update(); + // Get bounds + let x1 = Math.min(this.x, this.x + this.velocity.x + this.accel.x) - this.realSize - 5; + let y1 = Math.min(this.y, this.y + this.velocity.y + this.accel.y) - this.realSize - 5; + let x2 = Math.max(this.x, this.x + this.velocity.x + this.accel.x) + this.realSize + 5; + let y2 = Math.max(this.y, this.y + this.velocity.y + this.accel.y) + this.realSize + 5; + let size = Math.max(Math.abs(x2 - x1), Math.abs(y2 - y1)); + let sizeDiff = this.AABB_savedSize / size; + // Update data + this.AABB_data = { + min: [x1, y1], + max: [x2, y2], + active: true, + size: size, + }; + // Update grid if needed + if (sizeDiff > Math.SQRT2 || sizeDiff < Math.SQRT1_2) { + this.removeFromGrid(); + this.addToGrid(); + this.AABB_savedSize = size; + } + }; + this.getAABB = () => this.AABB_data; + this.updateAABB(true); + entities.push(this); + for (let v of views) v.add(this); + this.activation.update(); + events.emit('spawn', this); + } + addStatusEffect(effect) { + this.emit('newStatusEffect', effect); + this.statusEffects.push({ durationLeftover: effect.duration, effect }); + this.refreshBodyAttributes(); + } + life() { + // Size + this.coreSize = this.SIZE; + // Invisibility + if (!this.damageReceived && (this.velocity.x ** 2 + this.velocity.y ** 2 <= 0.1)) { + this.alpha = Math.max(this.alphaRange[0], this.alpha - this.invisible[1]); + } else { + this.alpha = Math.min(this.alphaRange[1], this.alpha + this.invisible[0]); + } + + let lastingEffects = [], needsBodyAttribRefresh = false; + for (let i = 0; i < this.statusEffects.length; i++) { + let entry = this.statusEffects[i]; + entry.durationLeftover -= 1 / c.runSpeed; + if (entry.durationLeftover > 0) { + lastingEffects.push(entry); + } else { + needsBodyAttribRefresh = true; + this.emit('expiredStatusEffect', entry.effect); + } + if (entry.effect.tick && entry.effect.tick(this, entry.effect, entry.durationLeftover)) { + needsBodyAttribRefresh = true; + } + } + this.statusEffects = lastingEffects; + + // Think + let faucet = this.settings.independent || this.source == null || this.source === this ? {} : this.source.control, + b = { + target: remapTarget(faucet, this.source, this), + goal: undefined, + fire: faucet.fire, + main: faucet.main, + alt: faucet.alt, + power: undefined, + }; + // Seek attention + if (this.settings.attentionCraver && !faucet.main && this.range) { + this.range -= 1; + } + // So we start with my master's thoughts and then we filter them down through our control stack + for (let i = 0; i < this.controllers.length; i++) { + let AI = this.controllers[i], + a = AI.think(b); + if (a != null) { + if (a.target != null && (b.target == null || AI.acceptsFromTop)) b.target = a.target; + if (a.goal != null && (b.goal == null || AI.acceptsFromTop)) b.goal = a.goal ; + if (a.fire != null && (b.fire == null || AI.acceptsFromTop)) b.fire = a.fire ; + if (a.main != null && (b.main == null || AI.acceptsFromTop)) b.main = a.main ; + if (a.alt != null && (b.alt == null || AI.acceptsFromTop)) b.alt = a.alt ; + if (a.power != null && (b.power == null || AI.acceptsFromTop)) b.power = a.power ; + } + } + this.control.target = b.target == null ? this.control.target : b.target; + this.control.goal = b.goal ? b.goal : { x: this.x, y: this.y }; + this.control.fire = b.fire; + this.control.main = b.main; + this.control.alt = b.alt; + this.control.power = b.power == null ? 1 : b.power; + + if (this.invuln && (this.control.goal.x !== this.x || this.control.goal.y !== this.y)) { + this.invuln = false; + } + + // React + this.move(); + this.face(); + // Handle guns and turrets if we've got them + for (let i = 0; i < this.guns.length; i++) this.guns[i].live(); + for (let i = 0; i < this.turrets.length; i++) this.turrets[i].life(); + if (this.skill.maintain()) needsBodyAttribRefresh = true; + if (needsBodyAttribRefresh) this.refreshBodyAttributes(); + } + addController(newIO) { + let listenToPlayer; + if (this.controllers && this.controllers[0] instanceof ioTypes.listenToPlayer) { + listenToPlayer = this.controllers.shift(); + } + if (!Array.isArray(newIO)) newIO = [newIO]; + for (let io of newIO) { + for (let i in this.controllers) { + let oldIO = this.controllers[i]; + if (io.constructor === oldIO.constructor) this.controllers.splice(i, 1); + } + } + this.controllers = newIO.concat(this.controllers); + if (listenToPlayer) this.controllers.unshift(listenToPlayer); + } + become(player, dom = false) { + this.addController(new ioTypes.listenToPlayer(this, { player, static: dom })); + this.sendMessage = (content, color) => player.socket.talk("m", content); + this.kick = (reason) => player.socket.kick(reason); + } + giveUp(player, name = "Mothership") { + if (!player.body.isMothership) { + player.body.controllers = [ + new ioTypes.nearestDifferentMaster(player.body), + new ioTypes.spin(player.body, { onlyWhenIdle: true }), + ]; + } else { + player.body.controllers = [ + new ioTypes.nearestDifferentMaster(player.body), + new ioTypes.wanderAroundMap(player.body, { lookAtGoal: true }), + new ioTypes.mapTargetToGoal(player.body), + ]; + } + player.body.name = player.body.label; + player.body.underControl = false; + player.body.sendMessage = () => {}; + let fakeBody = new Entity({ x: player.body.x, y: player.body.y }); + fakeBody.passive = true; + fakeBody.underControl = true; + player.body = fakeBody; + player.body.kill(); + } + compressColor() { + this.color = this.colorUnboxed.base + " " + this.colorUnboxed.hueShift + " " + this.colorUnboxed.saturationShift + " " + this.colorUnboxed.brightnessShift + " " + this.colorUnboxed.allowBrightnessInvert; + } + define(defs, emitEvent = true) { + if (!Array.isArray(defs)) defs = [defs]; + + // Define all primary stats + let set = ensureIsClass(defs[0]); + this.store = {}; + for (let gun of this.guns) gun.store = {}; + + if (set.PARENT != null) { + if (Array.isArray(set.PARENT)) { + for (let i = 0; i < set.PARENT.length; i++) { + this.define(set.PARENT[i], false); + } + } else { + this.define(set.PARENT, false); + } + } + if (set.LAYER != null) this.layerID = set.LAYER; + if (set.index != null) this.index = set.index.toString(); + if (set.NAME != null) this.name = set.NAME; + if (set.LABEL != null) this.label = set.LABEL; + if (set.ANGLE != null) this.angle = set.ANGLE; + if (set.UPGRADE_LABEL != null) this.upgradeLabel = set.UPGRADE_LABEL; + if (set.UPGRADE_TOOLTIP != null) this.upgradeTooltip = set.UPGRADE_TOOLTIP; + if (set.DISPLAY_NAME != null) this.displayName = set.DISPLAY_NAME; + if (set.TYPE != null) this.type = set.TYPE; + if (set.SHAPE != null) { + this.shape = typeof set.SHAPE === "number" ? set.SHAPE : 0; + this.shapeData = set.SHAPE; + } + this.imageInterpolation = set.IMAGE_INTERPOLATION != null ? set.IMAGE_INTERPOLATION : 'bilinear' + if (set.COLOR != null) { + if (typeof set.COLOR === "number" || typeof set.COLOR === 'string') + this.colorUnboxed.base = set.COLOR; + else if (typeof set.COLOR === "object") { + if (set.COLOR.BASE != null) this.colorUnboxed.base = set.COLOR.BASE; + if (set.COLOR.HUE_SHIFT != null) this.colorUnboxed.hueShift = set.COLOR.HUE_SHIFT; + if (set.COLOR.SATURATION_SHIFT != null) this.colorUnboxed.saturationShift = set.COLOR.SATURATION_SHIFT; + if (set.COLOR.BRIGHTNESS_SHIFT != null) this.colorUnboxed.brightnessShift = set.COLOR.BRIGHTNESS_SHIFT; + if (set.COLOR.ALLOW_BRIGHTNESS_INVERT != null) this.colorUnboxed.allowBrightnessInvert = set.COLOR.ALLOW_BRIGHTNESS_INVERT; + } + this.compressColor(); + } + this.upgradeColor = set.UPGRADE_COLOR == null ? null : set.UPGRADE_COLOR; + if (set.GLOW != null) { + this.glow = { + radius: set.GLOW.RADIUS ?? 0, + color: set.GLOW.COLOR ?? null, + alpha: set.GLOW.ALPHA ?? 1, + recursion: set.GLOW.RECURSION ?? 1 + }; + } + if (set.CONTROLLERS != null) { + let toAdd = []; + for (let i = 0; i < set.CONTROLLERS.length; i++) { + let io = set.CONTROLLERS[i]; + if ("string" == typeof io) io = [io]; + toAdd.push(new ioTypes[io[0]](this, io[1])); + } + this.addController(toAdd); + } + if (set.IGNORED_BY_AI != null) this.ignoredByAi = set.IGNORED_BY_AI; + if (set.MOTION_TYPE != null) this.motionType = set.MOTION_TYPE; + if (typeof this.motionType == "string") this.motionType = [this.motionType]; + if (set.FACING_TYPE != null) this.facingType = set.FACING_TYPE; + if (typeof this.facingType == "string") this.facingType = [this.facingType]; + if (set.MIRROR_MASTER_ANGLE != null) this.settings.mirrorMasterAngle = set.MIRROR_MASTER_ANGLE + if (set.DRAW_HEALTH != null) this.settings.drawHealth = set.DRAW_HEALTH; + if (set.DRAW_SELF != null) this.settings.drawShape = set.DRAW_SELF; + if (set.DAMAGE_EFFECTS != null) this.settings.damageEffects = set.DAMAGE_EFFECTS; + if (set.RATIO_EFFECTS != null) this.settings.ratioEffects = set.RATIO_EFFECTS; + if (set.MOTION_EFFECTS != null) this.settings.motionEffects = set.MOTION_EFFECTS; + if (set.ACCEPTS_SCORE != null) this.settings.acceptsScore = set.ACCEPTS_SCORE; + if (set.GIVE_KILL_MESSAGE != null) this.settings.givesKillMessage = set.GIVE_KILL_MESSAGE; + if (set.CAN_GO_OUTSIDE_ROOM != null) this.settings.canGoOutsideRoom = set.CAN_GO_OUTSIDE_ROOM; + if (set.HITS_OWN_TYPE != null) this.settings.hitsOwnType = set.HITS_OWN_TYPE; + if (set.DIE_AT_LOW_SPEED != null) this.settings.diesAtLowSpeed = set.DIE_AT_LOW_SPEED; + if (set.DIE_AT_RANGE != null) this.settings.diesAtRange = set.DIE_AT_RANGE; + if (set.INDEPENDENT != null) this.settings.independent = set.INDEPENDENT; + if (set.PERSISTS_AFTER_DEATH != null) this.settings.persistsAfterDeath = set.PERSISTS_AFTER_DEATH; + if (set.CLEAR_ON_MASTER_UPGRADE != null) this.settings.clearOnMasterUpgrade = set.CLEAR_ON_MASTER_UPGRADE; + if (set.HEALTH_WITH_LEVEL != null) this.settings.healthWithLevel = set.HEALTH_WITH_LEVEL; + if (set.ACCEPTS_SCORE != null) this.settings.acceptsScore = set.ACCEPTS_SCORE; + if (set.OBSTACLE != null) this.settings.obstacle = set.OBSTACLE; + if (set.NECRO != null) this.settings.necroTypes = Array.isArray(set.NECRO) ? set.NECRO : set.NECRO ? [this.shape] : []; + if (set.HAS_NO_RECOIL != null) this.settings.hasNoRecoil = set.HAS_NO_RECOIL; + if (set.CRAVES_ATTENTION != null) this.settings.attentionCraver = set.CRAVES_ATTENTION; + if (set.KILL_MESSAGE != null) this.settings.killMessage = set.KILL_MESSAGE === "" ? "Killed" : set.KILL_MESSAGE; + if (set.AUTOSPIN_MULTIPLIER != null) this.autospinBoost = set.AUTOSPIN_MULTIPLIER; + if (set.BROADCAST_MESSAGE != null) this.settings.broadcastMessage = set.BROADCAST_MESSAGE === "" ? undefined : set.BROADCAST_MESSAGE; + if (set.DEFEAT_MESSAGE) this.settings.defeatMessage = true; + if (set.HEALER) this.healer = true; + if (set.DAMAGE_CLASS != null) this.settings.damageClass = set.DAMAGE_CLASS; + if (set.BUFF_VS_FOOD != null) this.settings.buffVsFood = set.BUFF_VS_FOOD; + if (set.CAN_BE_ON_LEADERBOARD != null) this.settings.leaderboardable = set.CAN_BE_ON_LEADERBOARD; + if (set.INTANGIBLE != null) this.intangibility = set.INTANGIBLE; + if (set.IS_SMASHER != null) this.settings.reloadToAcceleration = set.IS_SMASHER; + if (set.STAT_NAMES != null) this.settings.skillNames = { + body_damage: set.STAT_NAMES?.BODY_DAMAGE ?? 'Body Damage', + max_health: set.STAT_NAMES?.MAX_HEALTH ?? 'Max Health', + bullet_speed: set.STAT_NAMES?.BULLET_SPEED ?? 'Bullet Speed', + bullet_health: set.STAT_NAMES?.BULLET_HEALTH ?? 'Bullet Health', + bullet_pen: set.STAT_NAMES?.BULLET_PEN ?? 'Bullet Penetration', + bullet_damage: set.STAT_NAMES?.BULLET_DAMAGE ?? 'Bullet Damage', + reload: set.STAT_NAMES?.RELOAD ?? 'Reload', + move_speed: set.STAT_NAMES?.MOVE_SPEED ?? 'Movement Speed', + shield_regen: set.STAT_NAMES?.SHIELD_REGEN ?? 'Shield Regeneration', + shield_cap: set.STAT_NAMES?.SHIELD_CAP ?? 'Shield Capacity', + }; + if (set.AI != null) this.aiSettings = set.AI; + if (set.INVISIBLE != null) this.invisible = set.INVISIBLE; + if (set.ALPHA != null) { + this.alpha = ("number" === typeof set.ALPHA) ? set.ALPHA : set.ALPHA[1]; + this.alphaRange = [ + set.ALPHA[0] || 0, + set.ALPHA[1] || 1 + ]; + } + if (set.STROKE_WIDTH != null) this.strokeWidth = set.STROKE_WIDTH + if (set.DANGER != null) this.dangerValue = set.DANGER; + if (set.SHOOT_ON_DEATH != null) this.shootOnDeath = set.SHOOT_ON_DEATH; + if (set.BORDERLESS != null) this.borderless = set.BORDERLESS; + if (set.DRAW_FILL != null) this.drawFill = set.DRAW_FILL; + if (set.TEAM != null) { + this.team = set.TEAM; + if (!sockets.players.length) { + const _entity = this; + for (let i = 0; i < sockets.players.length; i++) { + if (sockets.players[i].body.id == _entity.id) { + sockets.players[i].team = -_entity.team; + } + } + } + for (let child of this.children) child.team = set.TEAM + } + if (set.SYNC_TURRET_SKILLS != null) this.syncTurretSkills = set.SYNC_TURRET_SKILLS; + if (set.VARIES_IN_SIZE != null) { + this.settings.variesInSize = set.VARIES_IN_SIZE; + this.squiggle = this.settings.variesInSize ? ran.randomRange(0.8, 1.2) : 1; + } + if (set.RESET_UPGRADES || set.RESET_STATS) { + let caps = this.skill.caps.map(x=>x); + this.skill.setCaps(Array(10).fill(0)); + this.skill.setCaps(caps); + this.upgrades = []; + this.isArenaCloser = false; + this.ac = false; + this.alpha = 1; + this.reset(); + } + if (set.RESET_UPGRADE_MENU) this.upgrades = [] + if (set.ARENA_CLOSER != null) { + this.isArenaCloser = set.ARENA_CLOSER; + this.ac = set.ARENA_CLOSER; + } + if (set.BRANCH_LABEL != null) this.branchLabel = set.BRANCH_LABEL; + if (set.BATCH_UPGRADES != null) this.batchUpgrades = set.BATCH_UPGRADES; + for (let i = 0; i < c.MAX_UPGRADE_TIER; i++) { + let tierProp = 'UPGRADES_TIER_' + i; + if (set[tierProp] != null && emitEvent) { + for (let j = 0; j < set[tierProp].length; j++) { + let upgrades = set[tierProp][j]; + let index = ""; + if (!Array.isArray(upgrades)) upgrades = [upgrades]; + let redefineAll = upgrades.includes(true); + let trueUpgrades = upgrades.slice(0, upgrades.length - redefineAll); // Ignore last element if it's true + for (let k of trueUpgrades) { + let e = ensureIsClass(k); + index += e.index + "-"; + } + this.upgrades.push({ + class: trueUpgrades, + level: c.TIER_MULTIPLIER * i, + index: index.substring(0, index.length-1), + tier: i, + branch: 0, + branchLabel: this.branchLabel, + redefineAll, + }); + } + } + } + if (set.SIZE != null) { + this.SIZE = set.SIZE * this.squiggle; + if (this.coreSize == null) this.coreSize = this.SIZE; + } + if (set.LEVEL_CAP != null) { + this.levelCap = set.LEVEL_CAP; + } + if (set.LEVEL != null) { + this.skill.reset(); + while (this.skill.level < set.LEVEL) { + this.skill.score += this.skill.levelScore; + this.skill.maintain(); + } + this.refreshBodyAttributes(); + } + if (set.SKILL_CAP != null && set.SKILL_CAP != []) { + if (set.SKILL_CAP.length != 10) throw "Inappropiate skill cap amount."; + this.skill.setCaps(set.SKILL_CAP); + } + if (set.SKILL != null && set.SKILL != []) { + if (set.SKILL.length != 10) throw "Inappropiate skill raws."; + this.skill.set(set.SKILL); + } + if (set.VALUE != null) this.skill.score = Math.max(this.skill.score, set.VALUE * this.squiggle); + if (set.ALT_ABILITIES != null) this.abilities = set.ALT_ABILITIES; + if (set.GUNS != null) { + let newGuns = []; + for (let i = 0; i < set.GUNS.length; i++) { + newGuns.push(new Gun(this, set.GUNS[i])); + } + this.guns = newGuns; + } + if (set.MAX_CHILDREN != null) this.maxChildren = set.MAX_CHILDREN; + if (set.RESET_CHILDREN) this.destroyAllChildren(); + if ("function" === typeof set.LEVEL_SKILL_POINT_FUNCTION) { + this.skill.LSPF = set.LEVEL_SKILL_POINT_FUNCTION; + } + if (set.RECALC_SKILL != null) { + let score = this.skill.score; + this.skill.reset(); + this.skill.score = score; + while (this.skill.maintain()) {} + } + if (set.EXTRA_SKILL != null) { + this.skill.points += set.EXTRA_SKILL; + } + if (set.BODY != null) { + if (set.BODY.ACCELERATION != null) this.ACCELERATION = set.BODY.ACCELERATION; + if (set.BODY.SPEED != null) this.SPEED = set.BODY.SPEED; + if (set.BODY.HEALTH != null) this.HEALTH = set.BODY.HEALTH; + if (set.BODY.RESIST != null) this.RESIST = set.BODY.RESIST; + if (set.BODY.SHIELD != null) this.SHIELD = set.BODY.SHIELD; + if (set.BODY.REGEN != null) this.REGEN = set.BODY.REGEN; + if (set.BODY.DAMAGE != null) this.DAMAGE = set.BODY.DAMAGE; + if (set.BODY.PENETRATION != null) this.PENETRATION = set.BODY.PENETRATION; + if (set.BODY.RANGE != null) this.RANGE = set.BODY.RANGE; + if (set.BODY.FOV != null) this.FOV = set.BODY.FOV; + if (set.BODY.SHOCK_ABSORB != null) this.SHOCK_ABSORB = set.BODY.SHOCK_ABSORB; + if (set.BODY.RECOIL_MULTIPLIER != null) this.RECOIL_MULTIPLIER = set.BODY.RECOIL_MULTIPLIER; + if (set.BODY.DENSITY != null) this.DENSITY = set.BODY.DENSITY; + if (set.BODY.STEALTH != null) this.STEALTH = set.BODY.STEALTH; + if (set.BODY.PUSHABILITY != null) this.PUSHABILITY = set.BODY.PUSHABILITY; + if (set.BODY.HETERO != null) this.heteroMultiplier = set.BODY.HETERO; + this.refreshBodyAttributes(); + } + if (set.SPAWN_ON_DEATH) this.spawnOnDeath = set.SPAWN_ON_DEATH; + if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; + if (Array.isArray(this.rerootUpgradeTree)) { + let finalRoot = ""; + for (let root of this.rerootUpgradeTree) finalRoot += root + "\\/"; + this.rerootUpgradeTree = finalRoot.substring(0, finalRoot.length - 2); + } + if (set.ON_MINIMAP != null) this.allowedOnMinimap = set.ON_MINIMAP; + if (set.TURRETS != null) { + for (let i = 0; i < this.turrets.length; i++) { + this.turrets[i].destroy(); + } + this.turrets = []; + for (let i = 0; i < set.TURRETS.length; i++) { + let def = set.TURRETS[i], + o = new Entity(this, this.master), + turretDanger = false, + type = Array.isArray(def.TYPE) ? def.TYPE : [def.TYPE]; + for (let j = 0; j < type.length; j++) { + o.define(type[j]); + if (type.TURRET_DANGER) turretDanger = true; + } + if (!turretDanger) o.define({ DANGER: 0 }); + o.collidingBond = def.VULNERABLE + o.bindToMaster(def.POSITION, this, def.VULNERABLE); + } + } + if (set.ON != null) this.onDef = set.ON; + this.reverseTargetWithTank = set.REVERSE_TARGET_WITH_TANK ?? false; + if (set.mockup != null) { + this.mockup = set.mockup; + } + + if (emitEvent) { + this.emit('define', set); + } + + if (this.onDef != null) { + this.triggerOn(this.onDef, 'define') + } + + this.defs = []; + for (let def of defs) this.defs.push(def); + + // Define additional stats for other split upgrades + for (let branch = 1; branch < defs.length; branch++) { + set = ensureIsClass(defs[branch]); + + if (set.index != null) this.index += "-" + set.index; + if (set.PARENT != null) { + if (Array.isArray(set.PARENT)) { + for (let i = 0; i < set.PARENT.length; i++) { + this.branchLabel = ensureIsClass(set.PARENT[i]).BRANCH_LABEL; + } + } else { + this.branchLabel = ensureIsClass(set.PARENT).BRANCH_LABEL; + } + } + if (set.LABEL != null && set.LABEL.length > 0) this.label = this.label + "-" + set.LABEL; + if (set.MAX_CHILDREN != null) this.maxChildren += set.MAX_CHILDREN; + else this.maxChildren = null; // For bullet and drone combos so all parts remain functional + if (set.BODY != null) { + if (set.BODY.ACCELERATION != null) this.ACCELERATION *= set.BODY.ACCELERATION; + if (set.BODY.SPEED != null) this.SPEED *= set.BODY.SPEED; + if (set.BODY.HEALTH != null) this.HEALTH *= set.BODY.HEALTH; + if (set.BODY.RESIST != null) this.RESIST *= set.BODY.RESIST; + if (set.BODY.SHIELD != null) this.SHIELD *= set.BODY.SHIELD; + if (set.BODY.REGEN != null) this.REGEN *= set.BODY.REGEN; + if (set.BODY.DAMAGE != null) this.DAMAGE *= set.BODY.DAMAGE; + if (set.BODY.PENETRATION != null) this.PENETRATION *= set.BODY.PENETRATION; + if (set.BODY.RANGE != null) this.RANGE *= set.BODY.RANGE; + if (set.BODY.FOV != null) this.FOV *= set.BODY.FOV; + if (set.BODY.SHOCK_ABSORB != null) this.SHOCK_ABSORB *= set.BODY.SHOCK_ABSORB; + if (set.BODY.RECOIL_MULTIPLIER != null) this.RECOIL_MULTIPLIER *= set.BODY.RECOIL_MULTIPLIER; + if (set.BODY.DENSITY != null) this.DENSITY *= set.BODY.DENSITY; + if (set.BODY.STEALTH != null) this.STEALTH *= set.BODY.STEALTH; + if (set.BODY.PUSHABILITY != null) this.PUSHABILITY *= set.BODY.PUSHABILITY; + if (set.BODY.HETERO != null) this.heteroMultiplier *= set.BODY.HETERO; + this.refreshBodyAttributes(); + } + if (set.GUNS != null) { + let newGuns = []; + for (let i = 0; i < set.GUNS.length; i++) { + newGuns.push(new Gun(this, set.GUNS[i])); + } + this.guns.push(...newGuns); + } + if (set.TURRETS != null) { + for (let i = 0; i < set.TURRETS.length; i++) { + let def = set.TURRETS[i], + o = new Entity(this, this.master), + turretDanger = false, + type = Array.isArray(def.TYPE) ? def.TYPE : [def.TYPE]; + for (let j = 0; j < type.length; j++) { + o.define(type[j]); + if (type.TURRET_DANGER) turretDanger = true; + } + if (!turretDanger) o.define({ DANGER: 0 }); + o.bindToMaster(def.POSITION, this); + } + } + if (set.SIZE != null) { + this.SIZE *= set.SIZE * this.squiggle; + if (this.coreSize == null) this.coreSize = this.SIZE; + } + if (set.BATCH_UPGRADES != null) this.batchUpgrades = set.BATCH_UPGRADES; + for (let i = 0; i < c.MAX_UPGRADE_TIER; i++) { + let tierProp = 'UPGRADES_TIER_' + i; + if (set[tierProp] != null && emitEvent) { + for (let j = 0; j < set[tierProp].length; j++) { + let upgrades = set[tierProp][j]; + let index = ""; + if (!Array.isArray(upgrades)) upgrades = [upgrades]; + let redefineAll = upgrades.includes(true); + let trueUpgrades = upgrades.slice(0, upgrades.length - redefineAll); // Ignore last element if it's true + for (let k of trueUpgrades) { + let e = ensureIsClass(k); + index += e.index + "-"; + } + this.upgrades.push({ + class: trueUpgrades, + level: c.TIER_MULTIPLIER * i, + index: index.substring(0, index.length-1), + tier: i, + branch, + branchLabel: this.branchLabel, + redefineAll, + }); + } + } + } + if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; + if (Array.isArray(this.rerootUpgradeTree)) { + let finalRoot = ""; + for (let root of this.rerootUpgradeTree) finalRoot += root + "\\/"; + this.rerootUpgradeTree += finalRoot.substring(0, finalRoot.length - 2); + } + } + // Turret layer ordering + this.turrets.sort(this.turretSort); + + // Batch upgrades + if (this.batchUpgrades && emitEvent) { + this.tempUpgrades = []; + let numBranches = this.defs.length; + for (let i = 0; i < numBranches; i++) { // Create a 2d array for the upgrades (1st index is branch index) + this.tempUpgrades.push([]); + } + for (let upgrade of this.upgrades) { + let upgradeBranch = upgrade.branch; + this.tempUpgrades[upgradeBranch].push(upgrade); + } + + this.upgrades = []; + this.selection = JSON.parse(JSON.stringify(this.defs)); + this.chooseUpgradeFromBranch(numBranches); // Recursively build upgrade options + } + } + turretSort(a, b) { + return a.bound.layer - b.bound.layer; + } + chooseUpgradeFromBranch(remaining) { + if (remaining > 0) { // If there's more to select + let branchUgrades = this.tempUpgrades[this.defs.length - remaining]; + for (let i = 0; i < branchUgrades.length; i++) { // Pick all possible options and continue selecting + this.selection[this.defs.length - remaining] = branchUgrades[i]; + this.chooseUpgradeFromBranch(remaining - 1); + } + if (branchUgrades.length == 0) // For when the branch has no upgrades + this.chooseUpgradeFromBranch(remaining - 1); + } else { // If there's nothing more to select + let upgradeClass = [], + upgradeTier = 0, + upgradeIndex = ""; + for (let u of this.selection) { + upgradeClass.push(u.class); + upgradeIndex += u.index + '-'; + upgradeTier = Math.max(upgradeTier, u.tier); + } + this.upgrades.push({ + class: upgradeClass, + level: c.TIER_MULTIPLIER * upgradeTier, + index: upgradeIndex.substring(0, upgradeIndex.length-1), + tier: upgradeTier, + branch: 0, + branchLabel: "", + redefineAll: true, + }); + } + } + triggerOn(onDef = this.onDef, eventTriggered, value) { + if (onDef == null) return + const commonValues = { + body: this, + masterStore: this.store, + globalMasterStore: this.globalStore, + gunStore: value.store, + globalGunStore: value.globalStore + } + for (let onPairs of onDef) { + switch (onPairs.event) { + case 'fire': + if (eventTriggered == 'fire') onPairs.handler({ + ...commonValues, + gun: value.gun, + child: value.child, + }) + break; + case 'altFire': + if (eventTriggered == 'altFire') onPairs.handler({ + ...commonValues, + gun: value.gun, + child: value.child, + }) + case 'death': + if (eventTriggered == 'death') onPairs.handler({ + ...commonValues, + killers: value.killers, + killTools: value.killTools + }) + break; + case 'collide': + if (eventTriggered == 'collide') onPairs.handler({ + ...commonValues, + instance: value.instance, + other: value.other + }) + break; + case 'damage': + if (eventTriggered == 'damage') onPairs.handler({ + ...commonValues, + damageInflictor: value.damageInflictor, + damageTool: value.damageTool + }) + break; + case 'upgrade': + if (eventTriggered == 'upgrade') onPairs.handler({ + ...commonValues, + oldEntity: value.oldEntity + }) + break; + case 'tick': + if (eventTriggered == 'tick') onPairs.handler({ + ...commonValues + }) + break; + case 'define': + if (eventTriggered == 'define') onPairs.handler({ + ...commonValues + }) + break; + case 'trigger': + if (eventTriggered == 'trigger') onPairs.handler({ + ...commonValues, + info: value.info + }) + break; + case 'animationStart': + if (eventTriggered == 'animationStart') onPairs.handler({ + ...commonValues, + animationName: value.animationName, + time: value.time + }) + break; + case 'animationIteration': + if (eventTriggered == 'animationStart') onPairs.handler({ + ...commonValues, + animationName: value.animationName, + time: value.time + }) + break; + case 'animationEnd': + if (eventTriggered == 'animationStart') onPairs.handler({ + ...commonValues, + animationName: value.animationName, + time: value.time + }) + break; + } + } + } + refreshBodyAttributes() { + let accelerationMultiplier = 1, + topSpeedMultiplier = 1, + healthMultiplier = 1, + shieldMultiplier = 1, + regenMultiplier = 1, + damageMultiplier = 1, + penetrationMultiplier = 1, + rangeMultiplier = 1, + fovMultiplier = 1, + densityMultiplier = 1, + stealthMultiplier = 1, + pushabilityMultiplier = 1, + sizeMultiplier = 1, + recoilReceivedMultiplier = 1; + for (let i = 0; i < this.statusEffects.length; i++) { + let effect = this.statusEffects[i].effect; + if (effect.acceleration != null) accelerationMultiplier *= effect.acceleration; + if (effect.topSpeed != null) topSpeedMultiplier *= effect.topSpeed; + if (effect.health != null) healthMultiplier *= effect.health; + if (effect.shield != null) shieldMultiplier *= effect.shield; + if (effect.regen != null) regenMultiplier *= effect.regen; + if (effect.damage != null) damageMultiplier *= effect.damage; + if (effect.penetration != null) penetrationMultiplier *= effect.penetration; + if (effect.range != null) rangeMultiplier *= effect.range; + if (effect.fov != null) fovMultiplier *= effect.fov; + if (effect.density != null) densityMultiplier *= effect.density; + if (effect.stealth != null) stealthMultiplier *= effect.stealth; + if (effect.pushability != null) pushabilityMultiplier *= effect.pushability; + if (effect.recoilReceived != null) recoilReceivedMultiplier *= effect.recoilReceived; + if (effect.size != null) sizeMultiplier *= effect.size; + } + + let speedReduce = Math.pow(this.size / (this.coreSize || this.SIZE), 1); + this.acceleration = (accelerationMultiplier * c.runSpeed * this.ACCELERATION) / speedReduce; + if (this.settings.reloadToAcceleration) this.acceleration *= this.skill.acl; + this.topSpeed = (topSpeedMultiplier * c.runSpeed * this.SPEED * this.skill.mob) / speedReduce; + if (this.settings.reloadToAcceleration) this.topSpeed /= Math.sqrt(this.skill.acl); + this.health.set(((this.settings.healthWithLevel ? 2 * this.level : 0) + this.HEALTH) * this.skill.hlt * healthMultiplier); + this.health.resist = 1 - 1 / Math.max(1, this.RESIST + this.skill.brst); + this.shield.set(((this.settings.healthWithLevel ? 0.6 * this.level : 0) + this.SHIELD) * this.skill.shi, Math.max(0, ((this.settings.healthWithLevel ? 0.006 * this.level : 0) + 1) * this.REGEN * this.skill.rgn * regenMultiplier)); + this.damage = damageMultiplier * this.DAMAGE * this.skill.atk * !this.pacify; + this.penetration = penetrationMultiplier * (this.PENETRATION + 1.5 * (this.skill.brst + 0.8 * (this.skill.atk - 1))); + if (!this.settings.dieAtRange || !this.range) this.range = rangeMultiplier * this.RANGE; + this.fov = fovMultiplier * this.FOV * 275 * Math.sqrt(this.size); + this.density = densityMultiplier * (1 + 0.08 * this.level) * this.DENSITY; + this.stealth = stealthMultiplier * this.STEALTH; + this.pushability = pushabilityMultiplier * this.PUSHABILITY; + this.sizeMultiplier = sizeMultiplier; + this.recoilMultiplier = this.RECOIL_MULTIPLIER * recoilReceivedMultiplier; + } + bindToMaster(position, bond, isInvulnerable) { + this.bond = bond; + this.source = bond; + this.bond.turrets.push(this); + this.skill = this.bond.skill; + this.label = this.label.length ? this.bond.label + " " + this.label : this.bond.label; + // It will not be in collision calculations any more nor shall it be seen or continue to run independently. + if (!isInvulnerable) { + this.removeFromGrid(); + this.skipLife = true; + } + // TODO: FIX CLIENT MAKING EVERYTHING FLASH WHEN A VULN TURRET DIES, and display health + if (isInvulnerable) this.on('dead', () => {util.remove(this.master.turrets, this.master.turrets.indexOf(this))}) + this.settings.drawShape = false; + // Get my position. + if (Array.isArray(position)) { + position = { + SIZE: position[0], + X: position[1], + Y: position[2], + ANGLE: position[3], + ARC: position[4], + LAYER: position[5] + }; + } + position.SIZE ??= 10; + position.X ??= 0; + position.Y ??= 0; + position.ANGLE ??= 0; + position.ARC ??= 360; + position.LAYER ??= 0; + let _off = new Vector(position.X, position.Y); + this.bound = { + size: position.SIZE / 20, + angle: position.ANGLE * Math.PI / 180, + direction: _off.direction, + offset: _off.length / 10, + arc: position.ARC * Math.PI / 180, + layer: position.LAYER + }; + // Initalize. + this.activation.update(); + this.facing = this.bond.facing + this.bound.angle; + this.facingType = ["bound"]; + this.motionType = ["bound"]; + this.move(); + } + get level() { + return Math.min(this.levelCap ?? c.LEVEL_CAP, this.skill.level); + } + get size() { + return this.bond == null ? (this.coreSize || this.SIZE) * this.sizeMultiplier * (1 + this.level / 45) : this.bond.size * this.bound.size; + } + get mass() { + return this.density * (this.size ** 2 + 1); + } + get realSize() { + return this.size * lazyRealSizes[Math.floor(Math.abs(this.shape))]; + } + get xMotion() { + return (this.velocity.x + this.accel.x) / c.runSpeed; + } + get yMotion() { + return (this.velocity.y + this.accel.y) / c.runSpeed; + } + camera(tur = false) { + return { + type: 0 + tur * 0x01 + this.settings.drawHealth * 0x02 + (this.type === "tank" && this.displayName) * 0x04, + invuln: this.invuln, + id: this.id, + index: this.index, + label: this.label, + x: this.x, + y: this.y, + vx: this.velocity.x, + vy: this.velocity.y, + size: this.size, + realSize: this.realSize, + status: 1, + health: this.health.display(), + shield: this.shield.display(), + alpha: this.alpha, + facing: this.facing, + direction: this.bound ? this.bound.direction : 0, + angle: this.bound ? this.bound.angle : 0, + offset: this.bound ? this.bound.offset : 0, + sizeFactor: this.bound ? this.bound.size : 1, + mirrorMasterAngle: this.settings.mirrorMasterAngle ?? false, + perceptionAngleIndependence: this.perceptionAngleIndependence, //vfacing: this.vfacing, + defaultAngle: this.firingArc[0], + twiggle: forceTwiggle.includes(this.facingType[0]) || (this.facingType[0] === "locksFacing" && this.control.alt), + layer: this.layerID ? this.layerID : this.bond != null ? this.bound.layer : this.type === "wall" ? 11 : this.type === "food" ? 10 : this.type === "tank" ? 5 : this.type === "crasher" ? 1 : 0, + color: this.color, + strokeWidth: this.strokeWidth, + borderless: this.borderless, + drawFill: this.drawFill, + name: (this.nameColor || "#FFFFFF") + this.name, + score: this.skill.score, + guns: this.guns.map((gun) => gun.getPhotoInfo()), + turrets: this.turrets.map((turret) => turret.camera(true)), + glow: this.glow, + }; + } + syncTurrets() { + for (let i = 0; i < this.guns.length; i++) this.guns[i].syncChildren(); + for (let i = 0; i < this.turrets.length; i++) { + this.turrets[i].skill = this.skill; + this.turrets[i].refreshBodyAttributes(); + this.turrets[i].syncTurrets(); + } + } + skillUp(stat) { + let suc = this.skill.upgrade(stat); + if (suc) { + this.refreshBodyAttributes(); + for (let i = 0; i < this.guns.length; i++) this.guns[i].syncChildren(); + for (let i = 0; i < this.turrets.length; i++) this.turrets[i].syncTurrets(); + } + return suc; + } + upgrade(number) { + let old = this; + if ( + number < this.upgrades.length && + this.skill.level >= this.upgrades[number].level + ) { + let upgrade = this.upgrades[number], + upgradeClass = upgrade.class, + upgradeBranch = upgrade.branch, + redefineAll = upgrade.redefineAll; + if (redefineAll) { + for (let i = 0; i < upgradeClass.length; i++){ + upgradeClass[i] = ensureIsClass(...upgradeClass[i]); + } + this.upgrades = []; + this.define(upgradeClass); + this.triggerOn(this.onDef, "upgrade", { oldEntity: old }) + } else { + this.defs.splice(upgradeBranch, 1, ...upgradeClass); + this.upgrades = []; + this.define(this.defs); + this.triggerOn(this.onDef, "upgrade", { oldEntity: old }) + } + if (this.colorUnboxed.base == '-1' || this.colorUnboxed.base == 'mirror') { + this.colorUnboxed.base = getTeamColor((c.MODE == 'ffa' || c.GROUPS) ? TEAM_RED : this.team); + this.compressColor(); + } + this.sendMessage("You have upgraded to " + this.label + "."); + for (let def of this.defs) { + def = ensureIsClass(def); + if (typeof def.TOOLTIP == 'string' && def.TOOLTIP.length > 0) { + let tooltips = Array.isArray(def.TOOLTIP) ? def.TOOLTIP : [def.TOOLTIP]; + for (let i = tooltips.length; i--;) this.sendMessage(tooltips[i]); + } + } + this.destroyAllChildren(); + this.skill.update(); + this.syncTurrets(); + this.refreshBodyAttributes(); + } + } + destroyAllChildren() { + for (let instance of entities) { + if ( + instance.settings.clearOnMasterUpgrade && + instance.master.id === this.id + ) { + instance.kill(); + } + } + } + damageMultiplier() { + switch (this.type) { + case "swarm": + return 0.25 + 1.5 * util.clamp(this.range / (this.RANGE + 1), 0, 1); + default: + return 1; + } + } + move() { + let g = { + x: this.control.goal.x - this.x, + y: this.control.goal.y - this.y, + }, + gactive = g.x !== 0 || g.y !== 0, + engine = { + x: 0, + y: 0, + }, + a = this.acceleration / c.runSpeed; + if (c.SPACE_PHYSICS) { + this.maxSpeed = this.topSpeed; + this.damp = 100; + } + let type = this.motionType[0], + args = this.motionType[1] ?? {}; + switch (type) { + case "grow": + this.SIZE += args.growSpeed ?? 1; + break; + case "fastgrow": + this.SIZE += args.growSpeed ?? 5; + break; + case "fuckingnuclearbomb": + this.SIZE += args.growSpeed ?? 10; + break; + case "trappershockwave": + this.SIZE += args.growSpeed ?? 20; + break; + case "glide": + this.maxSpeed = this.topSpeed; + this.damp = args.damp ?? 0.05; + break; + case "motor": + this.maxSpeed = 0; + if (this.topSpeed) { + this.damp = Math.abs(a) / this.topSpeed; + } + if (gactive) { + let len = Math.sqrt(g.x * g.x + g.y * g.y); + engine = { + x: (a * g.x) / len, + y: (a * g.y) / len, + }; + } + break; + case "spgw": + this.SIZE += args.growSpeed ?? 0.75; + this.maxSpeed = this.topSpeed; + this.damp = args.damp ?? -0.025; + break; + case "chonk": + this.SIZE += args.growSpeed ?? 50; + this.maxSpeed = this.topSpeed; + this.damp = args.damo ?? -0.025; + break; + case "swarm": + this.maxSpeed = this.topSpeed; + let l = + util.getDistance( + { + x: 0, + y: 0, + }, + g + ) + 1; + if (gactive && l > this.size) { + let XvelDesired = (this.topSpeed * g.x) / l, + YvelDesired = (this.topSpeed * g.y) / l, + turning = Math.sqrt( + (this.topSpeed * Math.max(1, this.range) + 1) / a + ); + engine = { + x: (XvelDesired - this.velocity.x) / Math.max(5, turning), + y: (YvelDesired - this.velocity.y) / Math.max(5, turning), + }; + } else { + if (this.velocity.length < this.topSpeed) { + engine = { + x: (this.velocity.x * a) / 20, + y: (this.velocity.y * a) / 20, + }; + } + } + break; + case "chase": + if (gactive) { + let l = util.getDistance({ x: 0, y: 0, }, g); + if (l > this.size * 2) { + this.maxSpeed = this.topSpeed; + let XvelDesired = (this.topSpeed * g.x) / l, + YvelDesired = (this.topSpeed * g.y) / l; + engine = { + x: (XvelDesired - this.velocity.x) * a, + y: (YvelDesired - this.velocity.y) * a, + }; + } else { + this.maxSpeed = 0; + } + } else { + this.maxSpeed = 0; + } + break; + case "aimassist": + this.x = this.source.x + this.master.control.target.x; + this.y = this.source.y + this.master.control.target.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + break; + case "aimassistlock": + if (!this.control.alt) { + this.x = this.source.x + this.master.control.target.x; + this.y = this.source.y + this.master.control.target.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + }; + break; + case "drift": + this.maxSpeed = 0; + engine = { + x: g.x * a, + y: g.y * a, + }; + break; + case "bound": + let bound = this.bound, + ref = this.bond; + this.x = ref.x + ref.size * bound.offset * Math.cos(bound.direction + bound.angle + ref.facing); + this.y = ref.y + ref.size * bound.offset * Math.sin(bound.direction + bound.angle + ref.facing); + ref.velocity.x += bound.size * this.accel.x * ref.recoilMultiplier; + ref.velocity.y += bound.size * this.accel.y * ref.recoilMultiplier; + this.velocity = ref.velocity; + this.firingArc = [ref.facing + bound.angle, bound.arc / 2]; + this.accel.null(); + this.blend = ref.blend; + break; + case "withMaster": + this.x = this.source.x; + this.y = this.source.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + break; + case 'assembler': + this.alpha -= 0.02; + this.SIZE += 0.17; + if (this.alpha <= 0) { + this.kill(); + if (this.SIZE > 50) { + this.destroy(); + } + } + break; + case "desmos": + this.damp = 0; + if (this.waveReversed == null) this.waveReversed = this.master.control.alt ? -1 : 1; + if (this.waveAngle == null) { + this.waveAngle = this.master.facing; + this.velocity.x = this.velocity.length * Math.cos(this.waveAngle); + this.velocity.y = this.velocity.length * Math.sin(this.waveAngle);; + } + let waveX = this.maxSpeed * 5 * Math.cos((this.RANGE - this.range) / (args.period ?? 4) * 2); + let waveY = (args.amplitude ?? 15) * Math.cos((this.RANGE - this.range) / (args.period ?? 4)) * this.waveReversed * (args.invert ? -1 : 1); + this.x += Math.cos(this.waveAngle) * waveX - Math.sin(this.waveAngle) * waveY; + this.y += Math.sin(this.waveAngle) * waveX + Math.cos(this.waveAngle) * waveY; + break; + + } + this.accel.x += engine.x * this.control.power; + this.accel.y += engine.y * this.control.power; + } + reset(keepPlayerController = true) { + this.controllers = keepPlayerController ? [this.controllers.filter(con => con instanceof ioTypes.listenToPlayer)[0]] : []; + } + face() { + let t = this.control.target, + tactive = t.x !== 0 || t.y !== 0, + oldFacing = this.facing, + oldVFacing = this.vfacing; + let type = this.facingType[0], + args = this.facingType[1] ?? {}; + switch (type) { + case "autospin": + this.facing += (args.speed ?? 0.02) / c.runSpeed; + break; + case "turnWithSpeed": + this.facing += ((this.velocity.length / 90) * Math.PI) / c.runSpeed; + break; + case "spin": + this.facing += (args.speed ?? 0.05) / c.runSpeed; + break; + case "fastspin": + this.facing += (args.speed ?? 0.1) / c.runSpeed; + break; + case "veryfastspin": + this.facing += (args.speed ?? 1) / c.runSpeed; + break; + case "withMotion": + this.facing = this.velocity.direction; + break; + case "smoothWithMotion": + case "looseWithMotion": + this.facing += util.loopSmooth(this.facing, this.velocity.direction, (args.speed ?? 4) / c.runSpeed); + break; + case "withTarget": + case "toTarget": + let reverse = this.reverseTargetWithTank ? 1 : this.reverseTank; + this.facing = Math.atan2(t.y * reverse, t.x * reverse); + break; + case "locksFacing": + if (!this.control.alt) this.facing = Math.atan2(t.y, t.x); + break; + case "looseWithTarget": + case "looseToTarget": + case "smoothToTarget": + this.facing += util.loopSmooth(this.facing, Math.atan2(t.y, t.x), (args.speed ?? 4) / c.runSpeed); + break; + case "noFacing": + this.facing = args.angle ?? 0; + break; + case "bound": + let givenangle, + reduceIndependence = false, + slowness = this.settings.mirrorMasterAngle ? 1 : (args.slowness ?? 4) / c.runSpeed; + if (this.control.main) { + givenangle = Math.atan2(t.y, t.x); + let diff = util.angleDifference(givenangle, this.firingArc[0]); + if (Math.abs(diff) >= this.firingArc[1]) { + givenangle = this.firingArc[0]; + reduceIndependence = true; + } + } else { + givenangle = this.firingArc[0]; + reduceIndependence = true; + } + if (reduceIndependence) { + this.perceptionAngleIndependence -= 0.3 / c.runSpeed; + if (this.perceptionAngleIndependence < 0) { + this.perceptionAngleIndependence = 0; + } + } else { + this.perceptionAngleIndependence += 0.3 / c.runSpeed; + if (this.perceptionAngleIndependence > 1) { + this.perceptionAngleIndependence = 1; + } + } + this.facing += util.loopSmooth(this.facing, givenangle, slowness); + if (this.bond.syncTurretSkills) this.skill.set(this.bond.skill.raw); + break; + } + this.facing += this.turnAngle; + // Loop + const TAU = 2 * Math.PI; + if (this.facingLocked) { + this.facing = oldFacing; + this.vfacing = oldVFacing; + } else { + this.facing = ((this.facing % TAU) + TAU) % TAU; + this.vfacing = util.angleDifference(oldFacing, this.facing) * c.runSpeed; + } + } + + takeSelfie() { + this.flattenedPhoto = null; + this.photo = this.settings.drawShape + ? this.camera() + : (this.photo = undefined); + } + physics() { + if (this.accel.x == null || this.velocity.x == null) { + util.error("Void Error!"); + util.error(this.collisionArray); + util.error(this.label); + util.error(this); + this.accel.null(); + this.velocity.null(); + } + // Apply acceleration + this.velocity.x += this.accel.x; + this.velocity.y += this.accel.y; + // Reset acceleration + this.accel.null(); + // Apply motion + this.stepRemaining = 1; + if (c.SPACE_PHYSICS) this.stepRemaining = 2; + this.x += (this.stepRemaining * this.velocity.x) / c.runSpeed; + this.y += (this.stepRemaining * this.velocity.y) / c.runSpeed; + } + friction() { + var motion = this.velocity.length, + excess = motion - this.maxSpeed; + if (excess > 0 && this.damp) { + var k = this.damp / c.runSpeed, + drag = excess / (k + 1), + finalvelocity = this.maxSpeed + drag; + if (c.SPACE_PHYSICS) + finalvelocity *= this.type === "bullet" ? 1.005 : 1.1; + this.velocity.x = (finalvelocity * this.velocity.x) / motion; + this.velocity.y = (finalvelocity * this.velocity.y) / motion; + } + } + confinementToTheseEarthlyShackles() { + if (this.x == null || this.x == null) { + util.error("Void Error!"); + util.error(this.collisionArray); + util.error(this.label); + util.error(this); + this.accel.null(); + this.velocity.null(); + return 0; + } + if (!this.settings.canGoOutsideRoom) { + if (c.ARENA_TYPE === "circle") { + let centerPoint = { + x: room.width / 2, + y: room.height / 2, + }, dist = util.getDistance(this, centerPoint); + if (dist > room.width / 2) { + let strength = (dist - room.width / 2) * c.ROOM_BOUND_FORCE / (c.runSpeed * 750); + this.x = lerp(this.x, centerPoint.x, strength); + this.y = lerp(this.y, centerPoint.y, strength); + } + } else { + let padding = this.realSize - 50; + this.accel.x -= Math.max(this.x + padding - room.width, Math.min(this.x - padding, 0)) * c.ROOM_BOUND_FORCE / c.runSpeed; + this.accel.y -= Math.max(this.y + padding - room.height, Math.min(this.y - padding, 0)) * c.ROOM_BOUND_FORCE / c.runSpeed; + } + } + } + contemplationOfMortality() { + if (this.invuln || this.godmode) { + this.damageRecieved = 0; + return 0; + } + + if (this.damageRecieved > 0) { + let damageInflictor = [] + let damageTool = [] + + for (let i = 0; i < this.collisionArray.length; i++) { + let instance = this.collisionArray[i]; + if (instance.type === 'wall' || !instance.damage) continue; + damageInflictor.push(instance.master) + damageTool.push(instance) + } + this.onDef != null ? this.triggerOn(undefined, 'damage', { damageInflictor, damageTool }) : null + // TODO: find out how to fix 'collide' and 'damage' + } + // Life-limiting effects + if (this.settings.diesAtRange) { + this.range -= 1 / c.runSpeed; + if (this.range < 0) { + this.kill(); + } + } + if (this.settings.diesAtLowSpeed) { + if ( + !this.collisionArray.length && + this.velocity.length < this.topSpeed / 2 + ) { + this.health.amount -= this.health.getDamage(1 / c.runSpeed); + } + } + // Shield regen and damage + if (this.shield.max) { + if (this.damageRecieved) { + let shieldDamage = this.shield.getDamage(this.damageRecieved); + this.damageRecieved -= shieldDamage; + this.shield.amount -= shieldDamage; + } + } + // Health damage + if (this.damageRecieved) { + let healthDamage = this.health.getDamage(this.damageRecieved); + this.blend.amount = 1; + this.health.amount -= healthDamage; + } + this.damageRecieved = 0; + // Check for death + if (this.isDead()) { + + this.emit('dead'); + + //Shoot on death + for (let i = 0; i < this.guns.length; i++) { + let gun = this.guns[i]; + if (gun.shootOnDeath && gun.body != null) { + gun.spawnBullets(); + } + } + + // MEMORY LEAKS ARE BAD!!!! + for (let i = 0; i < this.turrets.length; i++) { + this.turrets[i].kill(); + } + + // Initalize message arrays + let killers = [], + killTools = [], + notJustFood = false; + // If I'm a tank, call me a nameless player + let name = this.master.name == "" + ? this.master.type === "tank" + ? "an unnamed " + this.label : this.master.type === "miniboss" + ? "a visiting " + this.label : this.label.substring(0, 3) == 'The' + ? this.label : util.addArticle(this.label) + : this.master.name + "'s " + this.label; + // Calculate the jackpot + let jackpot = util.getJackpot(this.skill.score) / this.collisionArray.length; + // Now for each of the things that kill me... + for (let i = 0; i < this.collisionArray.length; i++) { + let instance = this.collisionArray[i]; + if (instance.type === 'wall' || !instance.damage) continue; + if (instance.master.settings.acceptsScore) { + // If it's not food, give its master the score + if (instance.master.type === "tank" || instance.master.type === "miniboss") { + notJustFood = true; + } + instance.master.skill.score += jackpot; + killers.push(instance.master); // And keep track of who killed me + } else if (instance.settings.acceptsScore) { + instance.skill.score += jackpot; + } + killTools.push(instance); // Keep track of what actually killed me + } + // Remove duplicates + killers = killers.filter((elem, index, self) => index == self.indexOf(elem)); + this.onDef != null ? this.triggerOn(this.onDef, 'death', { killers, killTools }) : null + // If there's no valid killers (you were killed by food), change the message to be more passive + let killText = notJustFood ? "" : "You have been killed by ", + dothISendAText = this.settings.givesKillMessage; + + for (let i = 0; i < killers.length; i++) { + let instance = killers[i]; + + switch (this.type) { + case "tank": + killers.length > 1 ? instance.killCount.assists++ : instance.killCount.solo++; + if (instance.killCount.solo == 5) { + if (instance.socket) instance.socket.talk("achieve"); + }; + if (instance.killCount.solo == 10) { + if (instance.socket) instance.socket.talk("achieve2"); + sockets.broadcast(instance.name + "is on a kill streak of 10!"); + }; + if (instance.socket) instance.socket.talk("killgained"); + break; + + case "food": + case "crasher": + instance.killCount.polygons++; + break + + case "miniboss": + instance.killCount.bosses++; + break; + } + + this.killCount.killers.push(instance.index); + }; + // Add the killers to our death message, also send them a message + if (notJustFood) { + for (let i = 0; i < killers.length; i++) { + let instance = killers[i]; + if (instance.master.type !== "food" && instance.master.type !== "crasher") { + killText += instance.name == "" ? killText == "" ? "An unnamed player" : "an unnamed player" : instance.name; + killText += " and "; + } + // Only if we give messages + if (dothISendAText) { + instance.sendMessage("You killed " + name + (killers.length > 1 ? " (with some help)." : ".")); + } + if (this.settings.killMessage) { + instance.sendMessage("You " + this.settings.killMessage + " " + name + (killers.length > 1 ? " (with some help)." : ".")); + } + } + // Prepare the next part of the next + killText = killText.slice(0, -4) + "killed you with "; + } + // Broadcast + if (this.settings.broadcastMessage) { + sockets.broadcast(this.settings.broadcastMessage); + } + if (this.settings.defeatMessage) { + let text = util.addArticle(this.label, true); + if (notJustFood) { + text += " has been defeated by"; + for (let { name } of killers) { + text += " "; + text += name === "" ? "an unnamed player" : name; + text += " and"; + } + text = text.slice(0, -4); + text += "!"; + } else { + text += " fought a polygon... and the polygon won."; + } + sockets.broadcast(text); + } + // Add the implements to the message + for (let i = 0; i < killTools.length; i++) { + killText += util.addArticle(killTools[i].label) + " and "; + } + // Prepare it and clear the collision array. + killText = killText.slice(0, -5); + if (killText === "You have been kille") { + killText = "You have died a stupid death"; + } + this.sendMessage(killText + "."); + // If I'm the leader, broadcast it: + if (this.id === room.topPlayerID) { + let usurptText = this.name === "" ? "The leader" : this.name; + if (notJustFood) { + usurptText += " has been usurped by"; + for (let i = 0; i < killers.length; i++) { + usurptText += " "; + usurptText += killers[i].name === "" ? "an unnamed player" : killers[i].name; + usurptText += " and"; + } + usurptText = usurptText.slice(0, -4) + "!"; + } else { + usurptText += " fought a polygon... and the polygon won."; + } + sockets.broadcast(usurptText); + } + this.setKillers(killers); + // Kill it + return 1; + } + return 0; + } + protect() { + entitiesToAvoid.push(this); + this.isProtected = true; + } + say(message, duration = c.CHAT_MESSAGE_DURATION) { + if (!chats[this.id]) { + chats[this.id] = []; + } + chats[this.id].unshift({ message, expires: Date.now() + duration }); + } + sendMessage(message) {} // Dummy + setKillers(killers) {} // Dummy + kill() { + this.invuln = false; + this.health.amount = -100; + } + destroy() { + // Remove from the protected entities list + if (this.isProtected) { + util.remove(entitiesToAvoid, entitiesToAvoid.indexOf(this)); + } + // Remove from minimap + let i = minimap.findIndex(entry => entry[0] === this.id); + if (i != -1) { + util.remove(minimap, i); + } + // Remove this from views + for (let view of views) { + view.remove(this); + } + // Remove from parent lists if needed + if (this.parent != null) + util.remove(this.parent.children, this.parent.children.indexOf(this)); + // Kill all of its children + for (let instance of entities) { + if (instance.source.id === this.id) { + if (instance.settings.persistsAfterDeath) { + instance.source = instance; + } else { + instance.kill(); + } + } + if (instance.parent && instance.parent.id === this.id) { + instance.parent = null; + } + if (instance.master.id === this.id) { + instance.kill(); + instance.master = instance; + } + } + // Remove everything bound to it + for (let i = 0; i < this.turrets.length; i++) this.turrets[i].destroy(); + // Remove from the collision grid + this.removeFromGrid(); + this.isGhost = true; + } + isDead() { + return this.health.amount <= 0; + } +} +module.exports = { init, StatusEffect, Gun, Entity }; \ No newline at end of file diff --git a/shit/temp/changelog template b/shit/temp/changelog template new file mode 100644 index 000000000..66f07ac46 --- /dev/null +++ b/shit/temp/changelog template @@ -0,0 +1,26 @@ +
    +

    Update

    + [20] +
      +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    +
    \ No newline at end of file diff --git a/shit/temp/changes b/shit/temp/changes new file mode 100644 index 000000000..42472a1d5 --- /dev/null +++ b/shit/temp/changes @@ -0,0 +1,512 @@ +exports.laser = { + PARENT: ["bullet"], + SHAPE: -1, + BODY: { + PENETRATION: 0.7, + SPEED: 5.2, + RANGE: 100, + DENSITY: 0.85, + HEALTH: 0.1, + DAMAGE: 4.65, + } +} +exports.revolutionist = { + PARENT: ["genericTank"], + LABEL: "Revolutionist", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flank]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBase", + }, + ], +}; +exports.revoception = makeCeption(exports.revolutionist, "revoception"); +exports.hivemind = { + PARENT: ["genericTank"], + LABEL: "Hivemind", + //CONTROLLERS: ['nearestDifferentMaster'], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 90, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "hiveprobe", + MAX_CHILDREN: 1 + } + }, + { + POSITION: [0, 20, 1, 0, 0, 270, 3.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "hiveprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [25, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; +exports.cloner = { + PARENT: ["genericTank"], + LABEL: "Cloner", + //CONTROLLERS: ['nearestDifferentMaster'], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 180, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "clonerprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [22, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; + + + +exports.hiveprobe = { + PARENT: ["genericTank"], + LABEL: "Probe", + TYPE: "drone", + HITS_OWN_TYPE: "hardWithBuffer", + DRAW_HEALTH: true, + BODY: { + FOV: 0.5, + SPEED: 3, + ACCELERATION: 0.4, + HEALTH: 2.5, + SHIELD: 0, + DAMAGE: 1.2, + RESIST: 1, + PENETRATION: 1, + DENSITY: 0.4 + }, + AI: { + BLIND: true + }, + CLEAR_ON_MASTER_UPGRADE: true, + GIVE_KILL_MESSAGE: false, + ACCEPTS_SCORE: false, + CONTROLLERS: [ + "nearestDifferentMaster", + "mapAltToFire", + "minion", + "canRepel", + "hangOutNearMaster" + ], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lowpower]), + TYPE: "bullet" + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [25, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; +exports.clonerprobe = { + PARENT: ["hiveprobe"], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lowpower]), + TYPE: "bullet" + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [22, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +} + +//wait whats stuff +exports.placeableWall = { + PARENT: ["rock"], + LABEL: "Wall", + SIZE: 30, + SHAPE: 4, + CLEAR_ON_MASTER_UPGRADE: true, + TEAM: TEAM_ENEMIES, + VARIES_IN_SIZE: false, +}; +exports.placeableWallSmall = { + PARENT: ["rock"], + LABEL: "Wall", + SIZE: 15, + SHAPE: 4, + CLEAR_ON_MASTER_UPGRADE: true, + TEAM: TEAM_ENEMIES, + VARIES_IN_SIZE: false, +}; +exports.wallPlacerThing = { + PARENT: ["genericTank"], + SHAPE:0, + MIRROR_MASTER_ANGLE: true, + INTANGIBLE: true, + DRAW_SELF:false, + COLOR: 16, + CLEAR_ON_MASTER_UPGRADE: true, + BODY: { + ACCELERATION: 0.1, + SPEED: true, + HEALTH: 340282366920938463463374607431768211455, + RESIST: 1, + SHIELD: 340282366920938463463374607431768211455, + REGEN: 340282366920938463463374607431768211455, + DAMAGE: false, + PENETRATION: true, + RANGE: true, + FOV: true, + SHOCK_ABSORB: 340282366920938463463374607431768211455, + RECOIL_MULTIPLIER: false, + DENSITY: 340282366920938463463374607431768211455, + STEALTH: true, + PUSHABILITY: false, + HETERO: false, + }, + MOTION_TYPE: "withMouse", + GUNS: [ + { + POSITION: [0, 20, 1, 10, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([{reload:10, speed:0, maxSpeed:0, shudder:0.0001, spray:0.0001}]), + TYPE: "placeableWall", + COLOR: 16, + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 0, + ALT_FIRE: false, + NEGATIVE_RECOIL: false, + DRAW_FILL:false, + BORDERLESS:true, + }, + }, + ], + +}; +exports.wallPlacer = { + PARENT: ["genericTank"], + LABEL: "Messin' Around", + BODY: { + ACCELERATION: base.ACCEL * 1, + SPEED: base.SPEED * 1, + HEALTH: base.HEALTH * 1, + DAMAGE: base.DAMAGE * 1, + PENETRATION: base.PENETRATION * 1, + SHIELD: base.SHIELD * 1, + REGEN: base.REGEN * 1, + FOV: base.FOV * 1, + DENSITY: base.DENSITY * 1, + PUSHABILITY: 1, + HETERO: 3, + }, + GUNS: [ + { + POSITION: [16, 20, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic,{reload:1/8}]), + TYPE: "wallPlacerThing", + COLOR: 16, + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 1, + ALT_FIRE: false, + NEGATIVE_RECOIL: false, + }, + }, + ], +}; + +// TANK UPGRADE PATHS +exports.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "autoBasic"/*, "desmos"*/]; + exports.basic.UPGRADES_TIER_2 = ["smasher", "cloner"]; + exports.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "autoSmasher", "landmine"]; + exports.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] + + exports.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "autoTwin"]; + exports.twin.UPGRADES_TIER_3 = ["dual", "bulwark", "musket"]; + exports.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble"]; + exports.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentHybrid", "bentDouble", "triplet", "autoTripleShot"]; + + exports.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "autoSniper"]; + exports.sniper.UPGRADES_TIER_3 = ["bushwhacker"]; + exports.assassin.UPGRADES_TIER_3 = ["ranger", "falcon", "stalker", "autoAssassin", "single"]; + exports.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "dual","autoHunter"]; + exports.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman", "autoRifle"]; + + exports.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "autoMach"]; + exports.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture", "autoMini"]; + exports.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner"]; + exports.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "autoSprayer"]; + + exports.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank"]; + exports.flankGuard.UPGRADES_TIER_3 = ["tripleTwin"]; + exports.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper", "autoHexaTank"]; + exports.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "surfer", "eagle", "phoenix", "vulture"]; + exports.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee", "autoAuto3"]; + + exports.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "spawner", "autoDirector"]; + exports.director.UPGRADES_TIER_3 = ["manager", "bigCheese"]; + exports.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "overdrive", "commander"]; + exports.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "autoCruiser", "commander"]; + exports.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor", "autoUnderseer"]; + exports.spawner.UPGRADES_TIER_3 = ["factory", "autoSpawner"]; + + exports.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher", "autoPound"/*, "volute"*/]; + exports.pounder.UPGRADES_TIER_3 = ["shotgun", "eagle"]; + exports.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct", "autoDestroy"]; + exports.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun", "autoArtillery"]; + exports.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "sidewinder", "fieldGun", "autoLaunch"]; + + exports.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "autoTrap"]; + exports.trapper.UPGRADES_TIER_3 = ["barricade", "overtrapper"]; + exports.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror"]; + exports.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "autoTriTrapper"]; + exports.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "autoTrapGuard"]; + + exports.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "revolutionist", "basicCeption"]; + exports.autoBasic.UPGRADES_TIER_3 = ["autoSmasher", "autoCloner"]; + exports.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "twinCeption"]; + exports.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "snipeCeption"]; + exports.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "machCeption"]; + exports.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "autoTriTrapper", "flankCeption"]; + exports.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoSpawner", "directCeption"]; + exports.autoPound.UPGRADES_TIER_3 = ["autoDestroy", "autoBuilder", "autoArtillery", "autoLaunch", "poundCeption"]; + exports.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "autoTriTrapper", "autoTrapGuard", "trapCeption"]; + exports.revolutionist.UPGRADES_TIER_3 = ["autoRevolutionist"]; + exports.basicCeption.UPGRADES_TIER_3 = ["twinCeption", "snipeCeption", "machCeption", "flankCeption", "directCeption", "poundCeption", "trapCeption"]; + + + exports.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner"]; + + exports.desmos.UPGRADES_TIER_2 = ["helix", "volute"]; + exports.helix.UPGRADES_TIER_3 = ["triplex"]; + exports.volute.UPGRADES_TIER_3 = ["sidewinder"]; + +exports.minilaser = { + PARENT: ["genericTank"], + LABEL: "Plasma SMG", + DANGER: 6, + BODY: { + FOV: 1.2, + }, + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [21, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.mini, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 1 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.mini, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 2 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.mini, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + ], +}; +exports.autoBasic = makeAuto(exports.basic, "Auto-Basic"); +exports.autoRevolutionist = makeAuto(exports.revolutionist, "Auto-Revolutionist"); + +exports.autoTwin = makeAuto(exports.twin, "Auto-Twin"); +exports.autoMach = makeAuto(exports.machineGun, "Auto-Mach"); +exports.autoSniper = makeAuto(exports.sniper, "Auto-Sniper"); +exports.autoFlank = makeAuto(exports.flankGuard, "Auto-Flank"); +exports.autoDirector = makeAuto(exports.director, "Auto-Director"); +exports.autoPound = makeAuto(exports.pounder, "Auto-Pounder"); +exports.autoTrap = makeAuto(exports.trapper, "Auto-Trapper"); +exports.autoCloner = makeAuto(exports.cloner, "Auto-Cloner"); + +exports.autoTripleShot = makeAuto(exports.tripleShot, "Auto-Triple Shot"); + +exports.autoHunter = makeAuto(exports.hunter, "Auto-Hunter"); +exports.autoRifle = makeAuto(exports.rifle, "Auto-Rifle"); + +exports.autoMini = makeAuto(exports.minigun, "Auto-Minigun"); +exports.autoSprayer = makeAuto(exports.sprayer, "Auto-Sprayer"); + +exports.autoHexaTank = makeAuto(exports.hexaTank, "Auto-HexaTank"); +exports.autoAuto3 = makeAuto(exports.auto3, "Auto-Auto3"); + +exports.autoUnderseer = makeAuto(exports.underseer, "Auto-Underseer"); + +exports.autoDestroy = makeAuto(exports.destroyer, "Auto-Destroyer"); +exports.autoArtillery = makeAuto(exports.artillery, "Auto-Artillery"); +exports.autoLaunch = makeAuto(exports.launcher, "Auto-Launcher"); + +exports.autoTriTrapper = makeAuto(exports.triTrapper, "Auto-Tri Trapper"); +exports.autoTrapGuard = makeAuto(exports.trapGuard, "Auto-TrapGuard"); + + +exports.basicCeption = makeCeptionNerf(exports.basic, "Basic-Ception"); + +exports.twinCeption = makeCeptionNerf(exports.twin, "Twin-Ception"); +exports.twinCeption.BODY = { SPEED: base.SPEED }; +exports.snipeCeption = makeCeptionNerf(exports.sniper, "Snipe-Ception"); +exports.machCeption = makeCeptionNerf(exports.machineGun, "Mach-Ception"); +exports.flankCeption = makeCeptionNerf(exports.flankGuard, "Flank-Ception"); +exports.directCeption = makeCeptionNerf(exports.director, "Drone-Ception"); +exports.poundCeption = makeCeptionNerf(exports.pounder, "Pound-Ception"); +exports.trapCeption = makeCeptionNerf(exports.trapper, "Trap-Ception"); + +// ??? it still dont spin i think lol +exports.turretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: "autoTurret", + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: "autoTurret", + }] +}; + + if (gui.class === "Winsor") { + PlaySound169(); + } + //just some code to make the sound work + var playbuttonsound = new Audio(); + playbuttonsound.src = + "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/op1.wav?v=1675463613542"; + function PlaySound69() { + playbuttonsound.play(); + } + var clicked = false; + + var slap = new Audio(); + slap.src = + "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/(Audio)%20videoplayback.m4a?v=1675999054321"; + function PlaySound68() { + slap.play(); + } + var clicked = false; + + var clicksound = new Audio(); + clicksound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/sysse_ok.ogg"; + function PlaySound210() { + clicksound.play(); + } + var clicked = false; + + function doSomething() { + if (clicked) { + var optionclicksound = new Audio(); + optionclicksound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/cancel.wav"; + optionclicksound.load(); + optionclicksound.play(); + } else { + clicksound.load(); + clicksound.play(); + } + clicked = !clicked; + } + var smallaudio2 = new Audio(); + smallaudio2.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/error.ogg"; + function PlaySound211() { + smallaudio2.play(); + } + var smallaudio3 = new Audio( + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/socket.wav" + ); + smallaudio3.loop = false; + function PlaySound212() { + smallaudio3.loop = false; + smallaudio3.play(); + } + var grubhub = new Audio(); +grubhub.src = ("https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/d318bd1e-5162-4fae-a757-5c350b16ccc9.mp3?v=1700153738394"); +function PlaySound169() { + grubhub.load(); + grubhub.play(); +} + var smallaudio5 = new Audio(); + smallaudio5.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/poka.wav"; + function PlaySound214() { + smallaudio5.play(); + } + var smallaudio6 = new Audio(); + smallaudio6.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/finish.wav"; + function PlaySound215() { + smallaudio6.play(); + } + var camerasound = new Audio(); + camerasound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/camera.wav"; + function PlaySound213() { + camerasound.play(); + }; \ No newline at end of file diff --git a/shit/temp/gifbackround b/shit/temp/gifbackround new file mode 100644 index 000000000..0211166f5 --- /dev/null +++ b/shit/temp/gifbackround @@ -0,0 +1,33 @@ + \ No newline at end of file diff --git a/shit/temp/music b/shit/temp/music new file mode 100644 index 000000000..46fe5ec52 --- /dev/null +++ b/shit/temp/music @@ -0,0 +1,20 @@ + + \ No newline at end of file diff --git a/shit/temp/mytankcount b/shit/temp/mytankcount new file mode 100644 index 000000000..ae2963ea7 --- /dev/null +++ b/shit/temp/mytankcount @@ -0,0 +1,13 @@ +auto branch + +railgun +hivemind +cloner +plasma smg +scanner +dictator +revolutionist +revo +bacrid +auto +ception \ No newline at end of file diff --git a/shit/temp/stuff b/shit/temp/stuff new file mode 100644 index 000000000..520100d43 --- /dev/null +++ b/shit/temp/stuff @@ -0,0 +1,137 @@ + //Class.unfinishedtesting.UPGRADES_TIER_0 = ["testing", "aimassisttest", "toxic", "autoboosttest"] +Class.toxic = { + PARENT: "genericTank", + LABEL: "Intoxicator", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "poisonbullet", + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ] +}; +Class.poisonbullet = { + PARENT: "bullet", + LABEL: "posonio", + TURRETS: [ + { + POSITION: [0, 0, 0, 0, 360, 1], + TYPE: "recangluhitbox" + } + ] +}; +Class.aimassistbullet = { + PARENT: "bullet", + LABEL: "Bullet", + SHAPE: "M 1 1 l -2 0 L -1 -1 L 1 -1 L -1 -1 L -1 1 L 1 1 L 1 -1 L 1 1", + CONTROLLERS: ["nearestDifferentMaster"], + ACCEPTS_SCORE: false, + BODY: { + PENETRATION: 0.1, + SPEED: 99999, + DENSITY: 0.1, + HEALTH: 5, + DAMAGE: 0, + PUSHABILITY: 0.1, + SIZE: 18, + }, + MOTION_TYPE: "aimassistlock", + CAN_GO_OUTSIDE_ROOM: true, + HITS_OWN_TYPE: "never", + DIE_AT_RANGE: true, + TURRETS: [ + { + POSITION: [25, 0, 0, 0, 360, 1], + TYPE: "crosshair1" + } + ] +}; +Class.aimassisttest = { + PARENT: "genericTank", + LABEL: "Aim Assist", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet", + HAS_NO_RECOIL: true + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "aimassistbullet", + HAS_NO_RECOIL: true + } + }, + ], + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "autoTankGunLock" + } + ] +} +Class.autoboosttest = { + PARENT: "genericTank", + LABEL: "Aim Assist", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet", + } + }, + ], + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "autoTankGunLockRecoil" + } + ] +} +Class.autoTankGunLock = { + PARENT: "autoTankGun", + MOTION_TYPE: "aimassistlock", + BODY: { + FOV: 1 + }, + CONTROLLERS: ["nearestDifferentMasterAltAlt", "AimAssistLock"], + AI: { + FARMER: true, + BLIND: true, + }, +} +Class.autoTankGunLockRecoil = { + PARENT: "autoTankGun", + MOTION_TYPE: "aimassistlock", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.tonsmorerecoil, g.tonsmorerecoil, g.halfreload, g.halfreload, g.halfreload, g.fakewithrecoil]), + TYPE: "bullet", + }, + }, + ], + CONTROLLERS: ["nearestDifferentMasterAlt", "AimAssistLock"], + AI: { + FARMER: true, + }, +} + +Class.unfinishedtesting = { + PARENT: ["menu"], + LABEL: "Unfinished tanks", +}; \ No newline at end of file diff --git a/shit/temp/woomycolorname b/shit/temp/woomycolorname new file mode 100644 index 000000000..2b674856a --- /dev/null +++ b/shit/temp/woomycolorname @@ -0,0 +1,3 @@ +yeah no, +anyways so basically what im gonna say is +2019/april/24/11/45/32 \ No newline at end of file From 115dbed7770cbcf5b82e6fd7794adc202f84ba8f Mon Sep 17 00:00:00 2001 From: "Glitch (neroio2)" Date: Sat, 27 Apr 2024 22:35:45 +0000 Subject: [PATCH 02/15] =?UTF-8?q?=F0=9F=8F=BA=E2=9C=A8=20Updated=20with=20?= =?UTF-8?q?Glitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- animation.d.ts | 144 ------------ package.json | 1 + server/lib/hshg.js | 2 +- server/modules/definitions/addons/dreadv1.js | 62 ++--- server/modules/definitions/addons/dreadv2.js | 212 +++++++++--------- server/modules/definitions/groups/bosses.js | 64 +++--- server/modules/definitions/groups/dev.js | 133 ++++++++--- server/modules/definitions/groups/food.js | 157 ++++++------- server/modules/definitions/groups/misc.js | 23 +- .../modules/definitions/groups/projectiles.js | 37 +-- server/modules/definitions/groups/tanks.js | 153 ++++++------- server/modules/definitions/groups/turrets.js | 69 +++--- server/modules/gamemodes/maze.js | 2 +- server/modules/live/entity.js | 15 +- server/modules/network/sockets.js | 2 +- 15 files changed, 483 insertions(+), 593 deletions(-) delete mode 100644 animation.d.ts diff --git a/animation.d.ts b/animation.d.ts deleted file mode 100644 index d7d2359f3..000000000 --- a/animation.d.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { Entity, Gun } from "./server/modules/live/entity"; - -type TankShape = number | string | Array - -type TankColor = number | string | { - BASE: number | string; - HUE_SHIFT?: number; - SATURATION_SHIFT?: number; - BRIGHTNESS_SHIFT?: number; - ALLOW_BRIGHTNESS_INVERT?: boolean; - } - -type AnimationEasingValues = 'linear' | 'easeIn' | 'easeOut' | 'easeInOut' | 'step' | ((x: number) => number) -type AnimationTypeValues = 'body' | 'gun' | 'turret' - -type AnimationSpec = Record -type AnimationPreset = Array - -type AnimationKeyframe = { - TIME: number; // Percentage - EASING: AnimationEasingValues; - TYPE: AnimationTypeValues; - MOTION: AnimationMotion; -}; - -type AnimationMotion = { - MOVE?: [number, number]; - SCALE?: [number, number] | number; // 2D Vector for guns, 1 number for Turrets and Bodies. - ROTATE?: number; // In Degrees - COLOR?: TankColor; - ASPECT?: number; // Errors if used for any other types except 'gun' - SHAPE?: TankShape; // Errors if used for type 'gun' - ALPHA?: number; -} - -// ------------------------------- - -type OnTriggers = 'fire' | 'altFire' | 'death' | 'collide' | 'damage' | 'upgrade' | 'tick' | 'define' | 'animationStart' | 'animationKeyframe' | 'animationEnd' | 'trigger' -type OnSpec = Array - -type OnEventHandler = { - event: OnTriggers; - handler: (values: TriggerValues) => any; -}; - -interface CommonOnEventHandlerTriggerValues { - body?: Entity; - masterStore?: Entity['store']; - gunStore?: Gun['store']; - globalGunStore?: Gun['globalStore']; - globalMasterStore?: Entity['globalStore']; -} - -interface FireTriggerValues extends CommonOnEventHandlerTriggerValues { - gun?: Gun; - child?: Entity; -} - -interface AltFireTriggerValues extends CommonOnEventHandlerTriggerValues { - gun?: Gun; - child?: Entity; -} - -interface DeathTriggerValues extends CommonOnEventHandlerTriggerValues { - killers?: Array; - killTools?: Array; -} - -interface CollideTriggerValues extends CommonOnEventHandlerTriggerValues { - instance?: Entity; - other?: Entity; -} - -interface DamageTriggerValues extends CommonOnEventHandlerTriggerValues { - damageInflictor?: Entity; - damageTool?: Entity; -} - -interface UpgradeTriggerValues extends CommonOnEventHandlerTriggerValues { - oldEntity?: Entity -} - -interface AnimationStartTriggerValues extends CommonOnEventHandlerTriggerValues { - animationName?: string; - time?: number; -} - -interface AnimationKeyframeTriggerValues extends CommonOnEventHandlerTriggerValues { - animationName?: string; - time?: number; -} - -interface AnimationEndTriggerValues extends CommonOnEventHandlerTriggerValues { - animationName?: string; - time?: number; -} - -interface ManualTriggerValues extends CommonOnEventHandlerTriggerValues { - info?: any; -} - -type TriggerValues = { - fire: FireTriggerValues; - altFire: AltFireTriggerValues; - death: DeathTriggerValues; - collide: CollideTriggerValues; - damage: DamageTriggerValues; - upgrade: UpgradeTriggerValues; - animationStart: AnimationStartTriggerValues; - animationKeyframe: AnimationKeyframeTriggerValues; - animationEnd: AnimationEndTriggerValues; - trigger: ManualTriggerValues; -}; - -/* - Intended Use: - ON: [{ - event: 'animationStart', - handler: ({ body, animationName, time }) => { - //code - } - }, { - event: 'fire', - handler: ({ body, gun, globalMasterStore }) => { - //code - } - }, { - event: 'define', - handler: ({ body, gun, animationName }) => { // Error, no parameter 'animationName' for event 'define' - //code - } - }] - - ANIMATION: { - gunOut: [{ - TIME: 1, - TYPE: 'gun', - EASING: 'linear', - MOTION: { - MOVE: [0, 10] - } - }] - } -*/ \ No newline at end of file diff --git a/package.json b/package.json index b24fc1371..2987dcd79 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "startOptimized": "node --optimize-for-size --no-lazy --gc_interval=120 server/index", "restartOnSaveOptimized": "node --optimize-for-size --no-lazy --gc_interval=120 --watch server/index", "start": "node server/index", + "startClient": "node public/index", "restartOnSave": "node --watch server/index", "host": "node standaloneClient/index", "build": "node standaloneClient/build minify" diff --git a/server/lib/hshg.js b/server/lib/hshg.js index 9374fdf4c..3d6b7a59c 100644 --- a/server/lib/hshg.js +++ b/server/lib/hshg.js @@ -627,4 +627,4 @@ you never will because we fired you lol testAABBOverlap: testAABBOverlap, getLongestAABBEdge: getLongestAABBEdge, }; -})(this); +})(this); \ No newline at end of file diff --git a/server/modules/definitions/addons/dreadv1.js b/server/modules/definitions/addons/dreadv1.js index 3df30c13b..498b50431 100644 --- a/server/modules/definitions/addons/dreadv1.js +++ b/server/modules/definitions/addons/dreadv1.js @@ -41,7 +41,7 @@ const enableHealers = true; // Misc Class.genericDreadnought1 = { - PARENT: ["genericTank"], + PARENT: "genericTank", BODY: dreadnoughtBody, SHAPE: 6, COLOR: 'hexagon', @@ -50,7 +50,7 @@ Class.genericDreadnought1 = { REROOT_UPGRADE_TREE: "dreadOfficialV1", }; Class.mechanismMainTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", CONTROLLERS: ["nearestDifferentMaster"], INDEPENDENT: true, @@ -67,7 +67,7 @@ Class.mechanismMainTurret = { }] }; Class.automationMainTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", CONTROLLERS: ["onlyAcceptInArc", "nearestDifferentMaster"], INDEPENDENT: true, @@ -84,7 +84,7 @@ Class.automationMainTurret = { }] }; Class.automationSecondaryTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", CONTROLLERS: ["onlyAcceptInArc", "nearestDifferentMaster"], INDEPENDENT: true, @@ -101,7 +101,7 @@ Class.automationSecondaryTurret = { }] }; Class.medicareTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", CONTROLLERS: [ ["spin", {speed: 0.04}] ], INDEPENDENT: true, @@ -126,7 +126,7 @@ for(let i = 0; i < 3; i++) { }) } Class.medicaidTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", CONTROLLERS: [ ["spin", {speed: 0.04}] ], INDEPENDENT: true, @@ -150,7 +150,7 @@ for(let i = 0; i < 5; i++) { }, }) } -Class.turretedTrap = makeAuto(Class.trap, "Auto-Trap", {size: 7.5, type: 'droneAutoTurret'}); +Class.turretedTrap = makeAuto("trap", "Auto-Trap", {size: 7.5, type: 'droneAutoTurret'}); Class.turretedTrap.BODY.RECOIL_MULTIPLIER = 0; Class.weakMinion = { PARENT: "minion", @@ -168,7 +168,7 @@ Class.weakMinion = { // T0 Class.dreadOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Dreadnought", UPGRADE_LABEL: "Dreads V1", LEVEL: 150, @@ -177,7 +177,7 @@ Class.dreadOfficialV1 = { // T1 Class.swordOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Sword", UPGRADE_TOOLTIP: "Snipers", GUNS: [], @@ -193,7 +193,7 @@ for (let i = 0; i < 3; i++) { } Class.pacifierOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Pacifier", UPGRADE_TOOLTIP: "Bullet Spam", GUNS: [], @@ -209,7 +209,7 @@ for (let i = 0; i < 3; i++) { } Class.invaderOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Invader", UPGRADE_TOOLTIP: "Drones", GUNS: [], @@ -230,7 +230,7 @@ for (let i = 0; i < 3; i++) { } Class.centaurOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Centaur", UPGRADE_TOOLTIP: "Traps", GUNS: [], @@ -249,7 +249,7 @@ for (let i = 0; i < 3; i++) { } Class.automationOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Automation", UPGRADE_TOOLTIP: "Auto Turrets", TURRETS: [], @@ -266,7 +266,7 @@ Class.automationOfficialV1.TURRETS.push({ }); Class.juggernautOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Juggernaut", UPGRADE_TOOLTIP: "Health Buff", BODY: { @@ -281,7 +281,7 @@ Class.juggernautOfficialV1 = { }] } Class.medicareOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Medicare", UPGRADE_TOOLTIP: "Healing", TURRETS: [{ @@ -292,7 +292,7 @@ Class.medicareOfficialV1 = { // T2 Class.sabreOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Sabre", UPGRADE_TOOLTIP: "Assassins", GUNS: [], @@ -309,7 +309,7 @@ for (let i = 0; i < 3; i++) { }); } Class.gladiusOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Gladius", UPGRADE_TOOLTIP: "Rifles", GUNS: [], @@ -327,7 +327,7 @@ for (let i = 0; i < 3; i++) { } Class.appeaserOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Appeaser", UPGRADE_TOOLTIP: "Machine Guns", GUNS: [], @@ -348,7 +348,7 @@ for (let i = 0; i < 3; i++) { }); } Class.peacekeeperOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Peacekeeper", UPGRADE_TOOLTIP: "Heavy Bullets", GUNS: [], @@ -363,7 +363,7 @@ for (let i = 0; i < 3; i++) { }); } Class.diplomatOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Diplomat", UPGRADE_TOOLTIP: "Triplets", GUNS: [], @@ -391,7 +391,7 @@ for (let i = 0; i < 3; i++) { } Class.inquisitorOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Inquisitor", UPGRADE_TOOLTIP: "Drones", GUNS: [], @@ -411,7 +411,7 @@ for (let i = 0; i < 3; i++) { }); } Class.assailantOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Assailant", UPGRADE_TOOLTIP: "Minions", GUNS: [], @@ -434,7 +434,7 @@ for (let i = 0; i < 3; i++) { }); } Class.infiltratorOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Infiltrator", UPGRADE_TOOLTIP: "Swarms", GUNS: [], @@ -465,7 +465,7 @@ for (let i = 0; i < 3; i++) { } Class.cerberusOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Cerberus", UPGRADE_TOOLTIP: "Trap Spam", GUNS: [], @@ -501,7 +501,7 @@ for (let i = 0; i < 3; i++) { }); } Class.minotaurOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Minotaur", UPGRADE_TOOLTIP: "Blocks", GUNS: [], @@ -519,7 +519,7 @@ for (let i = 0; i < 3; i++) { }); } Class.sirenOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Siren", GUNS: [], } @@ -537,7 +537,7 @@ for (let i = 0; i < 3; i++) { } Class.mechanismOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Mechanism", UPGRADE_TOOLTIP: "Auto Turrets", TURRETS: [], @@ -554,7 +554,7 @@ Class.mechanismOfficialV1.TURRETS.push({ }) Class.behemothOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Behemoth", UPGRADE_TOOLTIP: "Health Buff", BODY: { @@ -569,7 +569,7 @@ Class.behemothOfficialV1 = { }], } Class.medicaidOfficialV1 = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", LABEL: "Medicaid", UPGRADE_TOOLTIP: "Healing", TURRETS: [{ @@ -635,7 +635,7 @@ for (let primary of Class.dreadOfficialV1.UPGRADES_TIER_1) { // Actually make that guy Class[definitionName] = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", UPGRADES_TIER_2: [], BODY, LABEL, UPGRADE_TOOLTIP, GUNS, TURRETS, }; @@ -682,7 +682,7 @@ for (let primary of Class.dreadOfficialV1.UPGRADES_TIER_1) { // Actually make that guy Class[definitionName2] = { - PARENT: ["genericDreadnought1"], + PARENT: "genericDreadnought1", BODY, LABEL, UPGRADE_TOOLTIP, GUNS, TURRETS }; Class[definitionName].UPGRADES_TIER_2.push(definitionName2); diff --git a/server/modules/definitions/addons/dreadv2.js b/server/modules/definitions/addons/dreadv2.js index 2ad820da2..aada00165 100644 --- a/server/modules/definitions/addons/dreadv2.js +++ b/server/modules/definitions/addons/dreadv2.js @@ -62,12 +62,12 @@ const hexnoughtScaleFactor = 0.9; // Misc Class.genericDreadnoughtOfficialV2 = { - PARENT: ["genericTank"], + PARENT: "genericTank", SKILL_CAP: Array(10).fill(smshskl), REROOT_UPGRADE_TREE: ["dreadWeaponOfficialV2", "dreadBodyOfficialV2"], } Class.genericEggnought = { - PARENT: ["genericDreadnoughtOfficialV2"], + PARENT: "genericDreadnoughtOfficialV2", BODY: eggnoughtBody, SHAPE: 0, COLOR: 'egg', @@ -75,7 +75,7 @@ Class.genericEggnought = { DANGER: 8, } Class.genericSquarenought = { - PARENT: ["genericDreadnoughtOfficialV2"], + PARENT: "genericDreadnoughtOfficialV2", BODY: squarenoughtBody, SHAPE: 4, COLOR: 'square', @@ -83,7 +83,7 @@ Class.genericSquarenought = { DANGER: 9, } Class.genericTrinought = { - PARENT: ["genericDreadnoughtOfficialV2"], + PARENT: "genericDreadnoughtOfficialV2", BODY: trinoughtBody, SHAPE: 3.5, COLOR: 'triangle', @@ -91,7 +91,7 @@ Class.genericTrinought = { DANGER: 10, } Class.genericPentanought = { - PARENT: ["genericDreadnoughtOfficialV2"], + PARENT: "genericDreadnoughtOfficialV2", BODY: pentanoughtBody, SHAPE: 5.5, COLOR: 'pentagon', @@ -99,7 +99,7 @@ Class.genericPentanought = { DANGER: 11, } Class.genericHexnought = { - PARENT: ["genericDreadnoughtOfficialV2"], + PARENT: "genericDreadnoughtOfficialV2", BODY: hexnoughtBody, SHAPE: 6, COLOR: 'hexagon', @@ -108,7 +108,7 @@ Class.genericHexnought = { } Class.spamAutoTurret = { - PARENT: ["autoTankGun"], + PARENT: "autoTankGun", INDEPENDENT: true, GUNS: [ { @@ -121,7 +121,7 @@ Class.spamAutoTurret = { ], } Class.supermissile = { - PARENT: ["bullet"], + PARENT: "bullet", LABEL: "Missile", INDEPENDENT: true, BODY: { @@ -157,7 +157,7 @@ Class.supermissile = { ], }; Class.betadrone = { - PARENT: ["drone"], + PARENT: "drone", TURRETS: [ { POSITION: [10, 0, 0, 180, 0, 1], @@ -168,9 +168,9 @@ Class.betadrone = { // T0 Class.dreadOfficialV2 = { - PARENT: ["genericEggnought"], - LABEL: "Dreadnought", - UPGRADE_LABEL: "Dreads V2", + PARENT: "genericEggnought", + LABEL: "Dreadnought", + UPGRADE_LABEL: "Dreads V2", LEVEL: 90, EXTRA_SKILL: 18, } @@ -187,7 +187,7 @@ Class.dreadBodyOfficialV2 = { // T1 Weapons Class.swordOfficialV2 = { - PARENT: ["genericEggnought"], + PARENT: "genericEggnought", LABEL: "Sword", GUNS: [], } @@ -207,7 +207,7 @@ Class.sword2OfficialV2 = { BATCH_UPGRADES: true, } Class.pacifierOfficialV2 = { - PARENT: ["genericEggnought"], + PARENT: "genericEggnought", LABEL: "Pacifier", GUNS: [], } @@ -227,7 +227,7 @@ Class.pacifier2OfficialV2 = { BATCH_UPGRADES: true, } Class.peacekeeperOfficialV2 = { - PARENT: ["genericEggnought"], + PARENT: "genericEggnought", LABEL: "Peacekeeper", GUNS: [], } @@ -247,7 +247,7 @@ Class.peacekeeper2OfficialV2 = { BATCH_UPGRADES: true, } Class.invaderOfficialV2 = { - PARENT: ["genericEggnought"], + PARENT: "genericEggnought", LABEL: "Invader", GUNS: [], } @@ -272,7 +272,7 @@ Class.invader2OfficialV2 = { BATCH_UPGRADES: true, } Class.centaurOfficialV2 = { - PARENT: ["genericEggnought"], + PARENT: "genericEggnought", LABEL: "Centaur", GUNS: [], } @@ -298,7 +298,7 @@ Class.centaur2OfficialV2 = { // T1 Bodies Class.byteTurretOfficialV2 = { - PARENT: ["autoTankGun"], + PARENT: "autoTankGun", INDEPENDENT: true, GUNS: [ { @@ -311,7 +311,7 @@ Class.byteTurretOfficialV2 = { ], } Class.byteOfficialV2 = { - PARENT: ["genericEggnought"], + PARENT: "genericEggnought", LABEL: "Byte", TURRETS: [ { @@ -326,7 +326,7 @@ Class.byteOfficialV2 = { } Class.atmosphereAuraOfficialV2 = addAura(1, 1, 0.15); Class.atmosphereOfficialV2 = { - PARENT: ["genericEggnought"], + PARENT: "genericEggnought", LABEL: "Atmosphere", TURRETS: [ { @@ -340,7 +340,7 @@ Class.atmosphereOfficialV2 = { ], } Class.juggernautOfficialV2 = { - PARENT: ["genericEggnought"], + PARENT: "genericEggnought", LABEL: "Juggernaut", BODY: { HEALTH: 1.6, @@ -362,7 +362,7 @@ Class.juggernautOfficialV2 = { // T2 Weapons Class.sabreOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Sabre", GUNS: [], } @@ -381,7 +381,7 @@ for (let i = 0; i < 4; i++) { ) } Class.gladiusOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Gladius", GUNS: [], } @@ -400,7 +400,7 @@ for (let i = 0; i < 4; i++) { ) } Class.mediatorOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Mediator", GUNS: [], } @@ -423,7 +423,7 @@ for (let i = 0; i < 4; i++) { ) } Class.negotiatorOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Negotiator", GUNS: [], } @@ -439,7 +439,7 @@ for (let i = 0; i < 4; i++) { ) } Class.enforcerOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Enforcer", GUNS: [], } @@ -455,7 +455,7 @@ for (let i = 0; i < 4; i++) { ) } Class.executorOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Executor", GUNS: [], } @@ -475,7 +475,7 @@ for (let i = 0; i < 4; i++) { ) } Class.inquisitorOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Inquisitor", GUNS: [], } @@ -496,7 +496,7 @@ for (let i = 0; i < 4; i++) { ) } Class.assailantMinionOfficialV2 = { - PARENT: ["minion"], + PARENT: "minion", BODY: { SPEED: 0.5, }, @@ -517,7 +517,7 @@ for (let i = 0; i < 4; i++) { ) } Class.assailantOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Assailant", GUNS: [], } @@ -544,7 +544,7 @@ for (let i = 0; i < 4; i++) { ) } Class.daemonOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Daemon", GUNS: [], } @@ -575,7 +575,7 @@ for (let i = 0; i < 4; i++) { ) } Class.minotaurOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Minotaur", GUNS: [], } @@ -597,7 +597,7 @@ for (let i = 0; i < 4; i++) { // T2 Bodies Class.automationOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Automation", TURRETS: [ { @@ -615,7 +615,7 @@ for (let i = 0; i < 4; i++) { ) } Class.kilobyteTurretOfficialV2 = { - PARENT: ["autoTankGun"], + PARENT: "autoTankGun", INDEPENDENT: true, GUNS: [ { @@ -628,7 +628,7 @@ Class.kilobyteTurretOfficialV2 = { ], } Class.kilobyteOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Kilobyte", TURRETS: [ { @@ -643,7 +643,7 @@ Class.kilobyteOfficialV2 = { } Class.coronaAuraOfficialV2 = addAura(1.5, 0.8, 0.15); Class.coronaOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Corona", TURRETS: [ { @@ -658,7 +658,7 @@ Class.coronaOfficialV2 = { } Class.thermosphereAuraOfficialV2 = addAura(-1, 1.5); Class.thermosphereOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Thermosphere", TURRETS: [ { @@ -672,7 +672,7 @@ Class.thermosphereOfficialV2 = { ], } Class.jumboOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "Jumbo", BODY: { HEALTH: 2.4, @@ -692,7 +692,7 @@ Class.jumboOfficialV2 = { ], } Class.colossusTopOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", GUNS: [], } for (let i = 0; i < 4; i++) { @@ -704,7 +704,7 @@ for (let i = 0; i < 4; i++) { ) } Class.colossusBottomOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", GUNS: [], } for (let i = 0; i < 4; i++) { @@ -724,7 +724,7 @@ for (let i = 0; i < 4; i++) { ) } Class.colossusOfficialV2 = { - PARENT: ["genericSquarenought"], + PARENT: "genericSquarenought", LABEL: "colossus", BODY: { SPEED: 1.75, @@ -744,7 +744,7 @@ Class.colossusOfficialV2 = { } // T3 Weapons Class.bayonetOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Bayonet", GUNS: [], } @@ -763,7 +763,7 @@ for (let i = 0; i < 3; i++) { ) } Class.bladeOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Blade", GUNS: [], } @@ -792,7 +792,7 @@ for (let i = 0; i < 3; i++) { ) } Class.mitigatorOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Mitigator", GUNS: [], } @@ -815,7 +815,7 @@ for (let i = 0; i < 3; i++) { ) } Class.appeaserOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Appeaser", GUNS: [], } @@ -838,7 +838,7 @@ for (let i = 0; i < 3; i++) { ) } Class.suppressorOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Suppressor", GUNS: [], } @@ -854,7 +854,7 @@ for (let i = 0; i < 3; i++) { ) } Class.inhibitorOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Inhibitor", GUNS: [], } @@ -874,7 +874,7 @@ for (let i = 0; i < 3; i++) { ) } Class.infiltratorOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Infiltrator", GUNS: [], } @@ -919,7 +919,7 @@ for (let i = 0; i < 3; i++) { ) } Class.aggressorMinionOfficialV2 = { - PARENT: ["minion"], + PARENT: "minion", SHAPE: 3.5, COLOR: 2, BODY: { @@ -940,7 +940,7 @@ for (let i = 0; i < 3; i++) { ) } Class.aggressorOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Aggressor", GUNS: [], } @@ -967,7 +967,7 @@ for (let i = 0; i < 3; i++) { ) } Class.hydraOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Hydra", GUNS: [], } @@ -1009,7 +1009,7 @@ for (let i = 0; i < 3; i++) { ) } Class.beelzebubOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Beelzebub", GUNS: [], } @@ -1031,7 +1031,7 @@ for (let i = 0; i < 3; i++) { // T3 Bodies Class.mechanismOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Mechanism", TURRETS: [ { @@ -1054,7 +1054,7 @@ for (let i = 0; i < 3; i++) { } Class.trinoughtBigAura = addAura(2, 1.5); Class.fusionOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Fusion", TURRETS: [ { @@ -1076,7 +1076,7 @@ for (let i = 0; i < 3; i++) { ) } Class.binaryOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Binary", TURRETS: [ { @@ -1101,7 +1101,7 @@ Class.binaryOfficialV2.TURRETS.push( ) Class.trinoughtBigHealAura = addAura(-1.5, 1.5); Class.exosphereOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Exosphere", TURRETS: [ { @@ -1123,7 +1123,7 @@ for (let i = 0; i < 3; i++) { ) } Class.megabyteTurretOfficialV2 = { - PARENT: ["autoTankGun"], + PARENT: "autoTankGun", INDEPENDENT: true, GUNS: [ { @@ -1136,7 +1136,7 @@ Class.megabyteTurretOfficialV2 = { ], } Class.megabyteOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Megabyte", TURRETS: [ { @@ -1151,7 +1151,7 @@ Class.megabyteOfficialV2 = { } Class.trinoughtSmallAura = addAura(1, 2.1, 0.15); Class.trojanOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Trojan", TURRETS: [ { @@ -1176,7 +1176,7 @@ Class.trojanOfficialV2.TURRETS.push( ) Class.trinoughtSmallHealAura = addAura(-2/3, 2.1, 0.15); Class.hardwareOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Hardware", TURRETS: [ { @@ -1200,7 +1200,7 @@ Class.hardwareOfficialV2.TURRETS.push( }, ) Class.chromosphereOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Chromosphere", TURRETS: [ { @@ -1222,7 +1222,7 @@ for (let i = 0; i < 3; i++) { ) } Class.mesosphereOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Mesosphere", TURRETS: [ { @@ -1244,7 +1244,7 @@ for (let i = 0; i < 3; i++) { ) } Class.goliathOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Goliath", BODY: { HEALTH: 3.2, @@ -1264,7 +1264,7 @@ Class.goliathOfficialV2 = { ], } Class.planetOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Planet", BODY: { HEALTH: 2.4, @@ -1292,7 +1292,7 @@ for (let i = 0; i < 3; i++) { ) } Class.moonOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Moon", BODY: { HEALTH: 2.4, @@ -1320,7 +1320,7 @@ for (let i = 0; i < 3; i++) { ) } Class.titanTopOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", GUNS: [], } for (let i = 0; i < 3; i++) { @@ -1332,7 +1332,7 @@ for (let i = 0; i < 3; i++) { ) } Class.titanOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Titan", BODY: { SPEED: 2.15, @@ -1351,7 +1351,7 @@ Class.titanOfficialV2 = { ], } Class.sirenOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Siren", BODY: { SPEED: 1.75, @@ -1378,7 +1378,7 @@ for (let i = 0; i < 3; i++) { ) } Class.harpyOfficialV2 = { - PARENT: ["genericTrinought"], + PARENT: "genericTrinought", LABEL: "Harpy", BODY: { SPEED: 1.75, @@ -1407,7 +1407,7 @@ for (let i = 0; i < 3; i++) { // T4 Weapons Class.javelinOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Javelin", GUNS: [], } @@ -1426,7 +1426,7 @@ for (let i = 0; i < 5; i++) { ) } Class.rapierOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Rapier", GUNS: [], } @@ -1455,7 +1455,7 @@ for (let i = 0; i < 5; i++) { ) } Class.diplomatOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Diplomat", GUNS: [], } @@ -1485,7 +1485,7 @@ for (let i = 0; i < 5; i++) { ) } Class.arbitratorOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Arbitrator", GUNS: [], } @@ -1515,7 +1515,7 @@ for (let i = 0; i < 5; i++) { ) } Class.retardantOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Retardant", GUNS: [], } @@ -1531,7 +1531,7 @@ for (let i = 0; i < 5; i++) { ) } Class.tyrantOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Tyrant", GUNS: [], } @@ -1551,7 +1551,7 @@ for (let i = 0; i < 5; i++) { ) } Class.raiderOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Raider", GUNS: [], } @@ -1596,7 +1596,7 @@ for (let i = 0; i < 5; i++) { ) } Class.gladiatorGenericMinionOfficialV2 = { - PARENT: ["minion"], + PARENT: "minion", BODY: { SPEED: 1, }, @@ -1605,23 +1605,23 @@ Class.gladiatorGenericMinionOfficialV2 = { GUNS: [], } Class.gladiatorTritankMinionOfficialV2 = { - PARENT: ["gladiatorGenericMinionOfficialV2"], + PARENT: "gladiatorGenericMinionOfficialV2", GUNS: [], } Class.gladiatorTritrapMinionOfficialV2 = { - PARENT: ["gladiatorGenericMinionOfficialV2"], + PARENT: "gladiatorGenericMinionOfficialV2", GUNS: [], } Class.gladiatorTriswarmMinionOfficialV2 = { - PARENT: ["gladiatorGenericMinionOfficialV2"], + PARENT: "gladiatorGenericMinionOfficialV2", GUNS: [], } Class.gladiatorAutoMinionOfficialV2 = makeAuto({ - PARENT: ["gladiatorGenericMinionOfficialV2"], + PARENT: "gladiatorGenericMinionOfficialV2", }, "Minion", {size: 12, angle: 0}); Class.gladiatorAuraMinionAuraOfficialV2 = addAura(1, 1.2); Class.gladiatorAuraMinionOfficialV2 = { - PARENT: ["gladiatorGenericMinionOfficialV2"], + PARENT: "gladiatorGenericMinionOfficialV2", TURRETS: [ { POSITION: [12, 0, 0, 0, 360, 1], @@ -1631,7 +1631,7 @@ Class.gladiatorAuraMinionOfficialV2 = { } Class.gladiatorHealAuraMinionAuraOfficialV2 = addAura(-2/3, 1.2); Class.gladiatorHealAuraMinionOfficialV2 = { - PARENT: ["gladiatorGenericMinionOfficialV2"], + PARENT: "gladiatorGenericMinionOfficialV2", TURRETS: [ { POSITION: [12, 0, 0, 0, 360, 1], @@ -1675,7 +1675,7 @@ for (let i = 0; i < 3; i++) { ); } Class.gladiatorOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Gladiator", GUNS: [], } @@ -1707,7 +1707,7 @@ Class.gladiatorOfficialV2.GUNS[7].PROPERTIES.TYPE = "gladiatorTriswarmMinionOffi Class.gladiatorOfficialV2.GUNS[10].PROPERTIES.TYPE = "gladiatorAutoMinionOfficialV2"; Class.gladiatorOfficialV2.GUNS[13].PROPERTIES.TYPE = "gladiatorAuraMinionOfficialV2"; Class.cerberusOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Cerberus", GUNS: [], } @@ -1749,7 +1749,7 @@ for (let i = 0; i < 5; i++) { ) } Class.luciferOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Lucifer", GUNS: [], } @@ -1771,7 +1771,7 @@ for (let i = 0; i < 5; i++) { // T4 Bodies Class.skynetOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Skynet", TURRETS: [ { @@ -1798,7 +1798,7 @@ for (let i = 0; i < 5; i++) { } Class.pentanoughtBigAura = addAura(2.5, 1.45); Class.supernovaOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Supernova", TURRETS: [ { @@ -1820,7 +1820,7 @@ for (let i = 0; i < 5; i++) { ) } Class.cipherOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Cipher", TURRETS: [ { @@ -1845,7 +1845,7 @@ Class.cipherOfficialV2.TURRETS.push( ) Class.pentanoughtBigHealAura = addAura(-2, 1.45); Class.interstellarOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Interstellar", TURRETS: [ { @@ -1867,7 +1867,7 @@ for (let i = 0; i < 5; i++) { ) } Class.gigabyteTurretOfficialV2 = { - PARENT: ["autoTankGun"], + PARENT: "autoTankGun", INDEPENDENT: true, GUNS: [ { @@ -1880,7 +1880,7 @@ Class.gigabyteTurretOfficialV2 = { ], } Class.gigabyteOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Gigabyte", TURRETS: [ { @@ -1894,7 +1894,7 @@ Class.gigabyteOfficialV2 = { ], } Class.malwareOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Malware", TURRETS: [ { @@ -1920,7 +1920,7 @@ Class.malwareOfficialV2.TURRETS.push( ) Class.pentanoughtSmallHealAura = addAura(-2/3, 1.6, 0.15); Class.softwareOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Software", TURRETS: [ { @@ -1948,7 +1948,7 @@ if (useOldPhotosphere) { Class.photosphereBigAuraOfficialV2 = addAura(1.5, 4); } Class.photosphereOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Photosphere", TURRETS: [ { @@ -1991,7 +1991,7 @@ if (useOldPhotosphere) { ) } Class.stratosphereOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Stratosphere", TURRETS: [ { @@ -2013,7 +2013,7 @@ for (let i = 0; i < 5; i++) { ) } Class.behemothOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Behemoth", BODY: { HEALTH: 4, @@ -2033,7 +2033,7 @@ Class.behemothOfficialV2 = { ], } Class.astronomicOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Astronomic", BODY: { HEALTH: 3.2, @@ -2061,7 +2061,7 @@ for (let i = 0; i < 5; i++) { ) } Class.grandioseOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Grandiose", BODY: { HEALTH: 3.2, @@ -2089,13 +2089,13 @@ for (let i = 0; i < 5; i++) { ) } Class.pentagonLeviathanTopOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Leviathan", MIRROR_MASTER_ANGLE: true, GUNS: [], } Class.pentagonLeviathanBottomOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Leviathan", MIRROR_MASTER_ANGLE: true, GUNS: [], @@ -2115,13 +2115,13 @@ for (let i = 0; i < 5; i++) { ); } Class.hexagonLeviathanTopOfficialV2 = { - PARENT: ["genericHexnought"], + PARENT: "genericHexnought", LABEL: "Leviathan", MIRROR_MASTER_ANGLE: true, GUNS: [], } Class.hexagonLeviathanBottomOfficialV2 = { - PARENT: ["genericHexnought"], + PARENT: "genericHexnought", LABEL: "Leviathan", MIRROR_MASTER_ANGLE: true, GUNS: [], @@ -2141,7 +2141,7 @@ for (let i = 0; i < 6; i++) { ) } Class.leviathanOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Leviathan", GUNS: [], BODY: { @@ -2160,7 +2160,7 @@ Class.leviathanOfficialV2 = { ], } Class.valrayvnOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Valrayvn", GUNS: [], BODY: { @@ -2187,7 +2187,7 @@ for (let i = 0; i < 5; i++) { ) } Class.pegasusOfficialV2 = { - PARENT: ["genericPentanought"], + PARENT: "genericPentanought", LABEL: "Pegasus", GUNS: [], BODY: { diff --git a/server/modules/definitions/groups/bosses.js b/server/modules/definitions/groups/bosses.js index f7147e97d..da1007643 100644 --- a/server/modules/definitions/groups/bosses.js +++ b/server/modules/definitions/groups/bosses.js @@ -15,7 +15,7 @@ Class.ramMiniboss = { // ELITE CRASHERS Class.elite = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Elite Crasher", COLOR: "pink", SHAPE: 3, @@ -30,7 +30,7 @@ Class.elite = { }, }; Class.eliteDestroyer = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Elite Destroyer", UPGRADE_COLOR: "pink", GUNS: [ @@ -74,7 +74,7 @@ Class.eliteDestroyer = { ], }; Class.eliteGunner = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Elite Gunner", UPGRADE_COLOR: "pink", FACING_TYPE: "toTarget", @@ -106,7 +106,7 @@ Class.eliteGunner = { ], }; Class.eliteSprayer = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Elite Sprayer", UPGRADE_COLOR: "pink", SKILL: [0, 9, 3, 9, 2, 9, 9, 9, 9, 0], @@ -139,7 +139,7 @@ Class.eliteSprayer = { ], }; Class.eliteBattleship = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Elite Battleship", UPGRADE_COLOR: "pink", GUNS: [ @@ -222,7 +222,7 @@ Class.eliteBattleship = { ], }; Class.eliteSpawner = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Elite Spawner", UPGRADE_COLOR: "pink", MAX_CHILDREN: 9, @@ -272,7 +272,7 @@ Class.eliteSpawner = { ], }; Class.eliteTrapGuard = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Elite Trap Guard", UPGRADE_COLOR: "pink", AI: { STRAFE: false }, @@ -308,7 +308,7 @@ for (let i = 0; i < 3; i++) { ) }; Class.eliteSpinner = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Elite Spinner", UPGRADE_COLOR: "pink", AI: { STRAFE: false }, @@ -349,7 +349,7 @@ for (let i = 0; i < 3; i++) { // OLD ELITE Class.oldEliteSprayer = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Elite Sprayer (Old)", UPGRADE_COLOR: "pink", AI: { NO_LEAD: false }, @@ -369,7 +369,7 @@ Class.oldEliteSprayer = { // Legionary Crasher Class.legionaryCrasherTop = { - PARENT: ["elite"], + PARENT: "elite", AI: { STRAFE: false, NO_LEAD: false }, CONTROLLERS: [ ["spin", { independent: true, speed: -0.005 }] ], INDEPENDENT: true, @@ -405,7 +405,7 @@ for (let i = 0; i < 3; i++) { ) } Class.legionaryCrasher = { - PARENT: ["elite"], + PARENT: "elite", LABEL: "Legionary Crasher", UPGRADE_COLOR: "pink", AI: { STRAFE: false, NO_LEAD: false }, @@ -455,7 +455,7 @@ for (let i = 0; i < 3; i++) { } Class.sprayerLegion = { - PARENT: ["elite"], + PARENT: "elite", UPGRADE_LABEL: "Sprayer Legion", UPGRADE_COLOR: "pink", AI: { NO_LEAD: false }, @@ -475,7 +475,7 @@ Class.sprayerLegion = { // STRANGE BOSSES Class.sorcerer = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Sorcerer", DANGER: 7, SHAPE: 0, @@ -503,7 +503,7 @@ Class.sorcerer = { })) }; Class.summoner = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Summoner", DANGER: 8, SHAPE: 4, @@ -531,7 +531,7 @@ Class.summoner = { })) }; Class.enchantress = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Enchantress", DANGER: 8, SHAPE: 3.5, @@ -559,7 +559,7 @@ Class.enchantress = { })) }; Class.exorcistor = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Exorcistor", DANGER: 8, SHAPE: 5.5, @@ -615,7 +615,7 @@ Class.shaman = { })) }; Class.eliteSkimmer = { - PARENT: ["elite"], + PARENT: "elite", LABEL: "Elite Skimmer", COLOR: "orange", UPGRADE_COLOR: "orange", @@ -635,7 +635,7 @@ Class.eliteSkimmer = { // Nesters Class.nestKeeper = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Nest Keeper", COLOR: "purple", UPGRADE_COLOR: "purple", @@ -722,7 +722,7 @@ Class.nestKeeper = { ], }; Class.nestWarden = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Nest Warden", COLOR: "purple", UPGRADE_COLOR: "purple", @@ -766,7 +766,7 @@ for(let i = 0; i < 5; i++) { ); }; Class.nestGuardian = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Nest Guardian", COLOR: "purple", UPGRADE_COLOR: "purple", @@ -810,7 +810,7 @@ for(let i = 0; i < 5; i++) { // Rogues Class.roguePalisade = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Rogue Palisade", COLOR: "darkGrey", UPGRADE_COLOR: "darkGrey", @@ -873,7 +873,7 @@ Class.rogueArmada = (() => { }); } return { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: 'Rogue Armada', COLOR: "darkGrey", UPGRADE_COLOR: "darkGrey", @@ -894,7 +894,7 @@ Class.rogueArmada = (() => { // Bob. Class.bob = { - PARENT: ["ramMiniboss"], + PARENT: "ramMiniboss", LABEL: "Bob", SHAPE: 0, COLOR: "aqua", @@ -924,7 +924,7 @@ Class.bob = { ], }; Class.nemesis = { - PARENT: ["bob"], + PARENT: "bob", LABEL: "Nemesis", COLOR: "red", UPGRADE_COLOR: "red", @@ -939,7 +939,7 @@ Class.nemesis = { // DIEP BOSSES Class.guardian = { - PARENT: ["elite"], + PARENT: "elite", LABEL: "Guardian of the Pentagons", UPGRADE_LABEL: "Guardian", UPGRADE_COLOR: "pink", @@ -957,7 +957,7 @@ Class.guardian = { AI: { NO_LEAD: false }, }; Class.defenderAutoTankGun = { - PARENT: ["autoTankGun"], + PARENT: "autoTankGun", GUNS: [ { POSITION: [22, 10, 1, 0, 0, 0, 0], @@ -969,7 +969,7 @@ Class.defenderAutoTankGun = { ], }; Class.defender = { - PARENT: ["elite"], + PARENT: "elite", LABEL: "Defender", COLOR: "orange", UPGRADE_COLOR: "orange", @@ -1020,7 +1020,7 @@ Class.defender = { // CELESTIALS Class.terrestrial = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Terrestrial", SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], VALUE: 5e5, @@ -1036,7 +1036,7 @@ Class.terrestrial = { }, }; Class.celestial = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Celestial", SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], VALUE: 1e6, @@ -1052,12 +1052,12 @@ Class.celestial = { }, }; Class.rogueCelestial = { - PARENT: ["celestial"], + PARENT: "celestial", LABEL: "Rogue Celestial", COLOR: "darkGrey", }; Class.eternal = { - PARENT: ["miniboss"], + PARENT: "miniboss", LABEL: "Eternal", SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], VALUE: 4e6, @@ -2341,7 +2341,7 @@ Class.frostAuraLargeOutline = { "M 0 0 L 0.293 0.902 M 0 0 L -0.768 0.558 M 0 0 L -0.768 -0.558 M 0 0 L 0.293 -0.902", } Class.frostAuraSymbol = { - PARENT: ["genericTank"], + PARENT: "genericTank", CONTROLLERS: [["spin", { speed: -0.04 }]], INDEPENDENT: true, BORDERLESS: true, diff --git a/server/modules/definitions/groups/dev.js b/server/modules/definitions/groups/dev.js index 4a8071a2f..0eac57216 100644 --- a/server/modules/definitions/groups/dev.js +++ b/server/modules/definitions/groups/dev.js @@ -675,9 +675,9 @@ Class.auraHealer = { }; Class.ghoster_ghosted = { - PARENT: 'genericTank', + PARENT: "genericTank", TOOLTIP: 'You are now hidden, roam around and find your next target. You will be visible again in 5 seconds', - LABEL: "Ghoster", + LABEL: 'Ghoster', BODY: { SPEED: 20, ACCELERATION: 10, @@ -690,8 +690,8 @@ Class.ghoster_ghosted = { } Class.ghoster = { - PARENT: 'genericTank', - LABEL: "Ghoster", + PARENT: "genericTank", + LABEL: 'Ghoster', TOOLTIP: 'Shooting will hide you for 5 seconds', BODY: { SPEED: base.SPEED, @@ -701,7 +701,7 @@ Class.ghoster = { { event: 'fire', handler: ({ body }) => { - body.define(Class.ghoster_ghosted) + body.define("ghoster_ghosted") setTimeout(() => { body.SPEED = 1e-99 body.ACCEL = 1e-99 @@ -710,7 +710,7 @@ Class.ghoster = { }, 2000) setTimeout(() => { body.SPEED = base.SPEED - body.define(Class.ghoster) + body.define("ghoster") }, 2500) } } @@ -990,6 +990,31 @@ Class.propTest = { } ] } +Class.weaponArrayTest = { + PARENT: 'genericTank', + LABEL: 'Weapon Array Test', + GUNS: weaponArray([ + { + POSITION: [20, 8, 1, 0, 0, 25, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: 'bullet' + } + }, { + POSITION: [17, 8, 1, 0, 0, 25, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: 'bullet' + } + } + ], 5), + TURRETS: weaponArray( + { + POSITION: [7, 10, 0, -11, 180, 0], + TYPE: 'autoTankGun' + } + , 5), +} Class.levels = menu("Levels") Class.levels.UPGRADES_TIER_0 = [] @@ -1041,6 +1066,75 @@ Class.goofytanks.UPGRADE_TOOLTIP = "The Funny v3" Class.addons = menu("Addon Entities") Class.addons.UPGRADES_TIER_0 = [] +Class.volute = { + PARENT: "genericTank", + LABEL: "Volute", + DANGER: 6, + STAT_NAMES: statnames.desmos, + GUNS: [ + { + POSITION: [20, 13, 0.8, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.pounder]), + TYPE: ["bullet", {MOTION_TYPE: "desmos"}] + }, + }, + { + POSITION: [5, 10, 2.125, 1, -6.375, 90, 0], + }, + { + POSITION: [5, 10, 2.125, 1, 6.375, -90, 0], + }, + ], +} +Class.snakeOld = { + PARENT: "missile", + LABEL: "Snake", + GUNS: [ + { + POSITION: [6, 12, 1.4, 8, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.snake, g.snakeskin]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + }, + }, + { + POSITION: [10, 12, 0.8, 8, 0, 180, 0.5], + PROPERTIES: { + AUTOFIRE: true, + NEGATIVE_RECOIL: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.snake]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + }, + }, + ], +} +Class.sidewinderOld = { + PARENT: "genericTank", + LABEL: "Sidewinder (old)", + DANGER: 7, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.3 * base.FOV, + }, + GUNS: [ + { + POSITION: [10, 11, -0.5, 14, 0, 0, 0], + }, + { + POSITION: [21, 12, -1.1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder]), + TYPE: "snakeOld", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + ], +} + Class.whirlwindDeco = makeDeco(6) Class.whirlwindDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]] Class.whirlwind = { @@ -2130,28 +2224,6 @@ Class.wallPlacer = { }, ], }; -Class.legacysidewinder = { - PARENT: "genericTank", - LABEL: "Sidewinder", - DANGER: 7, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.3 * base.FOV, - }, - GUNS: [ - { - POSITION: [10, 11, -0.5, 14, 0, 0, 0], - }, - { - POSITION: [21, 12, -1.1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder]), - TYPE: "oldsnake", - STAT_CALCULATOR: gunCalcNames.sustained, - }, - }, - ], -} Class.imagetest = { PARENT: "genericTank", UPGRADE_COLOR: "black", @@ -2383,7 +2455,8 @@ Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons Class.tanks.UPGRADES_TIER_0 = ["developer", "overpowered", "testing", "unavailable", "features"] Class.AIT.UPGRADES_TIER_0 = ["developer", "bosses", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun", "arenaCloser"] Class.utilities.UPGRADES_TIER_0 = ["developer", "levels", "teams", "eggGenerator", "spectator", "wallPlacer"] - Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "flail", "doubleFlail", "winsor0", "legacysidewinder"] + Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "doubleFlail", "winsor0", "volute"] + Class.volute.UPGRADES_TIER_3 = ["sidewinderOld"] //Class.flail.UPGRADES_TIER_2 = ["doubleFlail"] Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] Class.testing.UPGRADES_TIER_0 = ["tanks", "vanquisher", "mummifier", "tracker3", ["grappletest", "basic"], "brella"] @@ -2402,7 +2475,7 @@ Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons Class.eternals.UPGRADES_TIER_0 = ["bosses", "odin", "kronos"] Class.devBosses.UPGRADES_TIER_0 = ["taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss"] - Class.features.UPGRADES_TIER_0 = ["tanks", "diamondShape", "rotatedTrap", "colorMan", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "switcheroo", ["developer", "developer"]] + Class.features.UPGRADES_TIER_0 = ["tanks", "diamondShape", "rotatedTrap", "colorMan", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight"] Class.goofytanks.UPGRADES_TIER_0 = ["overpowered", "pisseroo", "papyrus", "Trapper_guy", "watertank", "piszerbeam", "baseThrowerDelta", "pouner", "adsfoipuasdfiopu", "goofywhirlwind"] diff --git a/server/modules/definitions/groups/food.js b/server/modules/definitions/groups/food.js index edafbcfe2..ffaa8cb09 100644 --- a/server/modules/definitions/groups/food.js +++ b/server/modules/definitions/groups/food.js @@ -3,6 +3,7 @@ const { basePolygonDamage, basePolygonHealth } = require('../constants.js'), // Code by Damocles (https://discord.com/channels/366661839620407297/508125275675164673/1090010998053818488) // Albeit heavily modified because the math in the original didn't work LOL makeRelic = (type, scale = 1, gem, SIZE) => { + type = ensureIsClass(type); let relicCasing = { PARENT: 'genericEntity', LABEL: 'Relic Casing', @@ -102,29 +103,33 @@ makeCrasher = type => ({ } }), -makeRare = (type, level) => ({ - PARENT: "food", - LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Transgender"][level] + " " + type.LABEL, - VALUE: [100, 500, 2000, 4000, 5000][level] * type.VALUE, - SHAPE: type.SHAPE, - SIZE: type.SIZE + level, - COLOR: ["lightGreen", "teal", "pureBlack", "rainbow", "animatedTrans"][level], - ALPHA: level == 2 ? 0.25 : 1, - BODY: { - DAMAGE: type.BODY.DAMAGE + level, - DENSITY: type.BODY.DENSITY + level, - HEALTH: [10, 20, 40, 80, 100][level] * type.BODY.HEALTH, - PENETRATION: type.BODY.PENETRATION + level, - ACCELERATION: type.BODY.ACCELERATION - }, - DRAW_HEALTH: true, - INTANGIBLE: false, - GIVE_KILL_MESSAGE: true, -}), +makeRare = (type, level) => { + type = ensureIsClass(type); + return { + PARENT: "food", + LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Transgender"][level] + " " + type.LABEL, + VALUE: [100, 500, 2000, 4000, 5000][level] * type.VALUE, + SHAPE: type.SHAPE, + SIZE: type.SIZE + level, + COLOR: ["lightGreen", "teal", "pureBlack", "rainbow", "trans"][level], + ALPHA: level == 2 ? 0.25 : 1, + BODY: { + DAMAGE: type.BODY.DAMAGE + level, + DENSITY: type.BODY.DENSITY + level, + HEALTH: [10, 20, 40, 80, 100][level] * type.BODY.HEALTH, + PENETRATION: type.BODY.PENETRATION + level, + ACCELERATION: type.BODY.ACCELERATION + }, + DRAW_HEALTH: true, + INTANGIBLE: false, + GIVE_KILL_MESSAGE: true, + } +}, lerp = (a, b, t) => a + (b - a) * t, makeLaby = (type, level) => { + type = ensureIsClass(type); let usableSHAPE = Math.max(type.SHAPE, 3), downscale = Math.cos(Math.PI / usableSHAPE), strenghtMultiplier = 6 ** level; @@ -157,7 +162,7 @@ makeLaby = (type, level) => { // EGGS Class.egg = { - PARENT: ["food"], + PARENT: "food", LABEL: "Egg", VALUE: 10, SHAPE: 0, @@ -174,7 +179,7 @@ Class.egg = { DRAW_HEALTH: false, }; Class.gem = { - PARENT: ["food"], + PARENT: "food", LABEL: "Gem", VALUE: 2e3, SHAPE: 6, @@ -194,7 +199,7 @@ Class.gem = { GIVE_KILL_MESSAGE: true, }; Class.jewel = { - PARENT: ["food"], + PARENT: "food", LABEL: "Jewel", VALUE: 1e5, SHAPE: 6, @@ -213,15 +218,15 @@ Class.jewel = { INTANGIBLE: false, GIVE_KILL_MESSAGE: true, }; -Class.shinyEgg = makeRare(Class.egg, 0); -Class.legendaryEgg = makeRare(Class.egg, 1); -Class.shadowEgg = makeRare(Class.egg, 2); -Class.rainbowEgg = makeRare(Class.egg, 3); -Class.transEgg = makeRare(Class.egg, 4); //ironic +Class.shinyEgg = makeRare("egg", 0); +Class.legendaryEgg = makeRare("egg", 1); +Class.shadowEgg = makeRare("egg", 2); +Class.rainbowEgg = makeRare("egg", 3); +Class.transEgg = makeRare("egg", 4); //ironic // SQUARES Class.square = { - PARENT: ["food"], + PARENT: "food", LABEL: "Square", VALUE: 30, SHAPE: 4, @@ -237,15 +242,15 @@ Class.square = { DRAW_HEALTH: true, INTANGIBLE: false, }; -Class.shinySquare = makeRare(Class.square, 0); -Class.legendarySquare = makeRare(Class.square, 1); -Class.shadowSquare = makeRare(Class.square, 2); -Class.rainbowSquare = makeRare(Class.square, 3); -Class.transSquare = makeRare(Class.square, 4); +Class.shinySquare = makeRare("square", 0); +Class.legendarySquare = makeRare("square", 1); +Class.shadowSquare = makeRare("square", 2); +Class.rainbowSquare = makeRare("square", 3); +Class.transSquare = makeRare("square", 4); // TRIANGLES Class.triangle = { - PARENT: ["food"], + PARENT: "food", LABEL: "Triangle", VALUE: 120, SHAPE: 3, @@ -261,15 +266,15 @@ Class.triangle = { }, DRAW_HEALTH: true, }; -Class.shinyTriangle = makeRare(Class.triangle, 0); -Class.legendaryTriangle = makeRare(Class.triangle, 1); -Class.shadowTriangle = makeRare(Class.triangle, 2); -Class.rainbowTriangle = makeRare(Class.triangle, 3); -Class.transTriangle = makeRare(Class.triangle, 4); +Class.shinyTriangle = makeRare("triangle", 0); +Class.legendaryTriangle = makeRare("triangle", 1); +Class.shadowTriangle = makeRare("triangle", 2); +Class.rainbowTriangle = makeRare("triangle", 3); +Class.transTriangle = makeRare("triangle", 4); // PENTAGONS Class.pentagon = { - PARENT: ["food"], + PARENT: "food", LABEL: "Pentagon", VALUE: 400, SHAPE: 5, @@ -285,15 +290,15 @@ Class.pentagon = { }, DRAW_HEALTH: true, }; -Class.shinyPentagon = makeRare(Class.pentagon, 0); -Class.legendaryPentagon = makeRare(Class.pentagon, 1); -Class.shadowPentagon = makeRare(Class.pentagon, 2); -Class.rainbowPentagon = makeRare(Class.pentagon, 3); -Class.transPentagon = makeRare(Class.pentagon, 4); +Class.shinyPentagon = makeRare("pentagon", 0); +Class.legendaryPentagon = makeRare("pentagon", 1); +Class.shadowPentagon = makeRare("pentagon", 2); +Class.rainbowPentagon = makeRare("pentagon", 3); +Class.transPentagon = makeRare("pentagon", 4); // BETA PENTAGONS Class.betaPentagon = { - PARENT: ["food"], + PARENT: "food", LABEL: "Beta Pentagon", VALUE: 2500, SHAPE: 5, @@ -312,15 +317,15 @@ Class.betaPentagon = { DRAW_HEALTH: true, GIVE_KILL_MESSAGE: true, }; -Class.shinyBetaPentagon = makeRare(Class.betaPentagon, 0); -Class.legendaryBetaPentagon = makeRare(Class.betaPentagon, 1); -Class.shadowBetaPentagon = makeRare(Class.betaPentagon, 2); -Class.rainbowBetaPentagon = makeRare(Class.betaPentagon, 3); -Class.transBetaPentagon = makeRare(Class.betaPentagon, 4); +Class.shinyBetaPentagon = makeRare("betaPentagon", 0); +Class.legendaryBetaPentagon = makeRare("betaPentagon", 1); +Class.shadowBetaPentagon = makeRare("betaPentagon", 2); +Class.rainbowBetaPentagon = makeRare("betaPentagon", 3); +Class.transBetaPentagon = makeRare("betaPentagon", 4); // ALPHA PENTAGONS Class.alphaPentagon = { - PARENT: ["food"], + PARENT: "food", LABEL: "Alpha Pentagon", VALUE: 15e3, SHAPE: 5, @@ -339,15 +344,15 @@ Class.alphaPentagon = { DRAW_HEALTH: true, GIVE_KILL_MESSAGE: true, }; -Class.shinyAlphaPentagon = makeRare(Class.alphaPentagon, 0); -Class.legendaryAlphaPentagon = makeRare(Class.alphaPentagon, 1); -Class.shadowAlphaPentagon = makeRare(Class.alphaPentagon, 2); -Class.rainbowAlphaPentagon = makeRare(Class.alphaPentagon, 3); -Class.transAlphaPentagon = makeRare(Class.alphaPentagon, 4); +Class.shinyAlphaPentagon = makeRare("alphaPentagon", 0); +Class.legendaryAlphaPentagon = makeRare("alphaPentagon", 1); +Class.shadowAlphaPentagon = makeRare("alphaPentagon", 2); +Class.rainbowAlphaPentagon = makeRare("alphaPentagon", 3); +Class.transAlphaPentagon = makeRare("alphaPentagon", 4); // HEXAGONS Class.hexagon = { - PARENT: ["food"], + PARENT: "food", LABEL: "Hexagon", VALUE: 500, SHAPE: 6, @@ -364,15 +369,15 @@ Class.hexagon = { }, DRAW_HEALTH: true, }; -Class.shinyHexagon = makeRare(Class.hexagon, 0); -Class.legendaryHexagon = makeRare(Class.hexagon, 1); -Class.shadowHexagon = makeRare(Class.hexagon, 2); -Class.rainbowHexagon = makeRare(Class.hexagon, 3); -Class.transHexagon = makeRare(Class.hexagon, 4); +Class.shinyHexagon = makeRare("hexagon", 0); +Class.legendaryHexagon = makeRare("hexagon", 1); +Class.shadowHexagon = makeRare("hexagon", 2); +Class.rainbowHexagon = makeRare("hexagon", 3); +Class.transHexagon = makeRare("hexagon", 4); // 3D POLYGONS Class.sphere = { - PARENT: ["food"], + PARENT: "food", LABEL: "The Sphere", FACING_TYPE: "noFacing", VALUE: 1e7, @@ -413,7 +418,7 @@ Class.sphere = { }] }; Class.cube = { - PARENT: ["food"], + PARENT: "food", LABEL: "The Cube", VALUE: 2e7, SIZE: 10, @@ -432,7 +437,7 @@ Class.cube = { GIVE_KILL_MESSAGE: true, }; Class.tetrahedron = { - PARENT: ["food"], + PARENT: "food", LABEL: "The Tetrahedron", VALUE: 3e7, SIZE: 12, @@ -450,7 +455,7 @@ Class.tetrahedron = { GIVE_KILL_MESSAGE: true }; Class.octahedron = { - PARENT: ["food"], + PARENT: "food", LABEL: "The Octahedron", VALUE: 4e7, SIZE: 13, @@ -468,7 +473,7 @@ Class.octahedron = { GIVE_KILL_MESSAGE: true }; Class.dodecahedron = { - PARENT: ["food"], + PARENT: "food", LABEL: "The Dodecahedron", VALUE: 5e7, SIZE: 18, @@ -486,7 +491,7 @@ Class.dodecahedron = { GIVE_KILL_MESSAGE: true, }; Class.icosahedron = { - PARENT: ["food"], + PARENT: "food", LABEL: "The Icosahedron", VALUE: 1e8, SIZE: 20, @@ -524,17 +529,17 @@ for (let [gemColor, name] of [ } } - Class[name + "EggRelic"] = makeRelic(Class.egg, 0.5, gem, 7); - Class[name + "SquareRelic"] = makeRelic(Class.square, 1, gem); - Class[name + "TriangleRelic"] = makeRelic(Class.triangle, 1.45, gem); - Class[name + "PentagonRelic"] = makeRelic(Class.pentagon, -0.6, gem); - Class[name + "BetaPentagonRelic"] = makeRelic(Class.betaPentagon, -0.6, gem); - Class[name + "AlphaPentagonRelic"] = makeRelic(Class.alphaPentagon, -0.6, gem); + Class[name + "EggRelic"] = makeRelic("egg", 0.5, gem, 7); + Class[name + "SquareRelic"] = makeRelic("square", 1, gem); + Class[name + "TriangleRelic"] = makeRelic("triangle", 1.45, gem); + Class[name + "PentagonRelic"] = makeRelic("pentagon", -0.6, gem); + Class[name + "BetaPentagonRelic"] = makeRelic("betaPentagon", -0.6, gem); + Class[name + "AlphaPentagonRelic"] = makeRelic("alphaPentagon", -0.6, gem); } // 4D Class.tesseract = { - PARENT: ["food"], + PARENT: "food", LABEL: "The Tesseract", VALUE: 42e7, SIZE: 25, diff --git a/server/modules/definitions/groups/misc.js b/server/modules/definitions/groups/misc.js index 41ef0c754..1832360f1 100644 --- a/server/modules/definitions/groups/misc.js +++ b/server/modules/definitions/groups/misc.js @@ -232,7 +232,7 @@ for (let tier of sancTiers) { }, { POSITION: {LENGTH: 1.5, WIDTH: 4, ASPECT: 1.7, X: 12, ANGLE: (360/tier)*i}, PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, {shudder: 0.15, spray: 1.2, speed: 0.8, reload: 1.5}]), + SHOOT_SETTINGS: combineStats([g.trap, {shudder: 0.15, speed: 0.8, health: 3, reload: 1.5}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, AUTOFIRE: true, @@ -280,7 +280,7 @@ Class.crasher = { DRAW_HEALTH: true, }; Class.crasherSpawner = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Spawned", STAT_NAMES: statnames.drone, CONTROLLERS: ["nearestDifferentMaster"], @@ -354,7 +354,7 @@ Class.sentry = { GIVE_KILL_MESSAGE: true, }; Class.sentrySwarm = { - PARENT: ["sentry"], + PARENT: "sentry", UPGRADE_LABEL: "Swarm Sentry", UPGRADE_COLOR: "pink", GUNS: [ @@ -368,18 +368,18 @@ Class.sentrySwarm = { }, ], }; -Class.sentryGun = makeAuto(Class.sentry, "Sentry", { +Class.sentryGun = makeAuto("sentry", "Sentry", { type: "megaAutoTankGun", size: 12, }); Class.sentryGun.UPGRADE_LABEL = "Gun Sentry"; -Class.sentryTrap = makeAuto(Class.sentry, "Sentry", { +Class.sentryTrap = makeAuto("sentry", "Sentry", { type: "trapTurret", size: 12, }); Class.sentryTrap.UPGRADE_LABEL = "Trap Sentry"; Class.shinySentry = { - PARENT: ["sentry"], + PARENT: "sentry", COLOR: "lightGreen", UPGRADE_COLOR: "lightGreen", DANGER: 4, @@ -391,7 +391,7 @@ Class.shinySentry = { }, }; Class.shinySentrySwarm = { - PARENT: ["shinySentry"], + PARENT: "shinySentry", UPGRADE_LABEL: "Shiny Swarm Sentry", UPGRADE_COLOR: "lightGreen", GUNS: [ @@ -405,12 +405,12 @@ Class.shinySentrySwarm = { }, ], }; -Class.shinySentryGun = makeAuto(Class.shinySentry, "Sentry", { +Class.shinySentryGun = makeAuto("shinySentry", "Sentry", { type: Class.artilleryAutoTankgun, size: 12, }); Class.shinySentryGun.UPGRADE_LABEL = "Shiny Gun Sentry"; -Class.shinySentryTrap = makeAuto(Class.shinySentry, "Sentry", { +Class.shinySentryTrap = makeAuto("shinySentry", "Sentry", { type: "barricadeTurret", size: 12, }); @@ -418,7 +418,7 @@ Class.shinySentryTrap.UPGRADE_LABEL = "Shiny Trap Sentry"; // SENTINELS (by ranar) Class.sentinel = { - PARENT: ["genericTank"], + PARENT: "genericTank", TYPE: "crasher", LABEL: "Sentinel", DANGER: 7, @@ -566,7 +566,7 @@ Class.sentinelMinigun = { // MISCELLANEOUS TANKS Class.baseProtector = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Base", UPGRADE_LABEL: "Base Protector", ON_MINIMAP: false, @@ -835,4 +835,5 @@ Class.bot = { Class.tagMode = { PARENT: "bullet", LABEL: "Players", + SHAPE: "" }; \ No newline at end of file diff --git a/server/modules/definitions/groups/projectiles.js b/server/modules/definitions/groups/projectiles.js index 6ffbbdfb4..1768a1b53 100644 --- a/server/modules/definitions/groups/projectiles.js +++ b/server/modules/definitions/groups/projectiles.js @@ -49,15 +49,15 @@ Class.superSplitterBullet = { } Class.turretedBullet = makeAuto('bullet', "Auto-Bullet", {size: 14, color: "veryLightGrey", angle: 0}); Class.speedBullet = { - PARENT: ["bullet"], + PARENT: "bullet", MOTION_TYPE: "accel", } Class.growBullet = { - PARENT: ["bullet"], + PARENT: "bullet", MOTION_TYPE: "grow", } Class.flare = { - PARENT: ["growBullet"], + PARENT: "growBullet", LABEL: "Flare", SHAPE: 4, } @@ -278,7 +278,7 @@ Class.hive = { ], } Class.protoHive = { - PARENT: ["bullet"], + PARENT: "bullet", LABEL: "Proto-Hive", BODY: { RANGE: 90, @@ -456,7 +456,7 @@ Class.surgeonPillbox = { // Drones Class.turretedDrone = makeAuto('drone', "Auto-Drone", {type: 'droneAutoTurret'}) Class.gemDrone = { - PARENT: ["drone"], + PARENT: "drone", COLOR: "aqua", DRAW_HEALTH: true, SHAPE: 6, @@ -1128,29 +1128,4 @@ Class.nuke = { DAMAGE: 999999, PUSHABILITY: -99999999, }, -}; -Class.oldsnake = { - PARENT: "missile", - LABEL: "Snake", - GUNS: [ - { - POSITION: [6, 12, 1.4, 8, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.snake, g.snakeskin]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - }, - }, - { - POSITION: [10, 12, 0.8, 8, 0, 180, 0.5], - PROPERTIES: { - AUTOFIRE: true, - NEGATIVE_RECOIL: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.hunterSecondary, g.snake]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - }, - }, - ], -} \ No newline at end of file +}; \ No newline at end of file diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 3c4090376..6afc808fc 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -2910,7 +2910,7 @@ Class.architect = { } // Trap Guard upgrades -Class.bushwhacker = makeGuard(Class.sniper, "Bushwhacker") +Class.bushwhacker = makeGuard("sniper", "Bushwhacker") Class.gunnerTrapper = { PARENT: "genericTank", LABEL: "Gunner Trapper", @@ -3824,27 +3824,6 @@ Class.minilaser = { } ], } -Class.volute = { - PARENT: "genericTank", - LABEL: "Volute", - DANGER: 6, - STAT_NAMES: statnames.desmos, - GUNS: [ - { - POSITION: [20, 13, 0.8, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.pounder]), - TYPE: ["bullet", {MOTION_TYPE: "desmos"}] - }, - }, - { - POSITION: [5, 10, 2.125, 1, -6.375, 90, 0], - }, - { - POSITION: [5, 10, 2.125, 1, 6.375, -90, 0], - }, - ], -} Class.cruiserdrive = { PARENT: "genericTank", LABEL: "Swarmdrive", @@ -4810,7 +4789,7 @@ Class.triContagion = makeMulti({ } }] }, 3, "Tri-Contagion"); -Class.autoContagion = makeAuto(Class.contagion); +Class.autoContagion = makeAuto("contagion"); Class.fort = { PARENT: "genericTank", LABEL: "Fort", @@ -5345,18 +5324,18 @@ Class.autoinceptionistbody = { } // Auto tanks -Class.autoBasic = makeAuto(Class.basic, "Auto-Basic"); -Class.autoTwin = makeAuto(Class.twin, "Auto-Twin"); -Class.autoMach = makeAuto(Class.machineGun, "Auto-Mach"); -Class.autoSniper = makeAuto(Class.sniper, "Auto-Sniper"); -Class.autoFlank = makeAuto(Class.flankGuard, "Auto-Flank"); -Class.autoDirector = makeAuto(Class.director, "Chairman"); -Class.autoPound = makeAuto(Class.pounder, "Scratcher"); -Class.autoTrap = makeAuto(Class.trapper, "Auto-Trapper"); -Class.autoDesmos = makeAuto(Class.desmos, "Auto-Desmos"); -Class.autolittleHunter = makeAuto(Class.littleHunter, "Auto-Subduer") -Class.autoinception = makeAuto(Class.inception, "Auto-inception"); -Class.autoauto2 = makeAuto(Class.auto2, "Auto-Auto-2"); +Class.autoBasic = makeAuto("basic", "Auto-Basic"); +Class.autoTwin = makeAuto("twin", "Auto-Twin"); +Class.autoMach = makeAuto("machineGun", "Auto-Mach"); +Class.autoSniper = makeAuto("sniper", "Auto-Sniper"); +Class.autoFlank = makeAuto("flankGuard", "Auto-Flank"); +Class.autoDirector = makeAuto("director", "Chairman"); +Class.autoPound = makeAuto("pounder", "Scratcher"); +Class.autoTrap = makeAuto("trapper", "Auto-Trapper"); +Class.autoDesmos = makeAuto("desmos", "Auto-Desmos"); +Class.autolittleHunter = makeAuto("littleHunter", "Auto-Subduer") +Class.autoinception = makeAuto("inception", "Auto-inception"); +Class.autoauto2 = makeAuto("auto2", "Auto-Auto-2"); Class.autoCloner = makeAuto({ PARENT: "genericTank", GUNS: [ @@ -5385,44 +5364,44 @@ Class.autoCloner = makeAuto({ } ] }, "Auto-Cloner"); -Class.autoDouble = makeAuto(Class.doubleTwin, "Auto-Double") -Class.autoAssassin = makeAuto(Class.assassin) -Class.autoGunner = makeAuto(Class.gunner) -Class.autoTriAngle = makeAuto(Class.triAngle) -Class.autoOverseer = makeAuto(Class.overseer) -Class.autoRevolutionist = makeAuto(Class.revolutionist, "Audioboard"); -Class.autoCruiser = makeAuto(Class.cruiser) -Class.autoSpawner = makeAuto(Class.spawner) -Class.autoBuilder = makeAuto(Class.builder) -Class.autoBinary = makeAuto(Class.binary, "Auto-Binary") -Class.autoinceptionist = makeAuto(Class.autoinceptionistbody, "Auto-Inceptionist", {type: 'ceptionistturret'}); -Class.autoGundirector = makeAuto(Class.gundirector, "Auto-Pathogen") -Class.autoBigSubduer = makeAuto(Class.bigSubduer, "Auto-Mitochondrion") -Class.autoFlankdue = makeAuto(Class.flankdue, "Auto-Flankduer") -Class.autoTripleShot = makeAuto(Class.tripleShot, "Auto-Triple Shot"); -Class.autoHunter = makeAuto(Class.hunter, "Auto-Hunter"); -Class.autoRifle = makeAuto(Class.rifle, "Auto-Rifle"); -Class.autoTwinsniper = makeAuto(Class.twinsniper, "Auto-Twiper"); -Class.autoAcid = makeAuto(Class.acid, "Cyanide"); -Class.autoChill = makeAuto(Class.chiller, "Auto-Chiller"); -Class.autoMini = makeAuto(Class.minigun, "Auto-Minigun"); -Class.autoSprayer = makeAuto(Class.sprayer, "Auto-Sprayer"); -Class.autoHexaTank = makeAuto(Class.hexaTank, "Auto-HexaTank"); -Class.autoAuto3 = makeAuto(Class.auto3, "Auto-Auto3"); -Class.autoUnderseer = makeAuto(Class.underseer, "Auto-Underseer"); -Class.autoDestroy = makeAuto(Class.destroyer, "Auto-Destroyer"); -Class.autoArtillery = makeAuto(Class.artillery, "Auto-Artillery"); -Class.autoLaunch = makeAuto(Class.launcher, "Auto-Launcher"); -Class.autoTriTrapper = makeAuto(Class.triTrapper, "Auto-Tri Trapper"); -Class.autoTrapGuard = makeAuto(Class.trapGuard, "Auto-TrapGuard"); -Class.autoSidewinder = makeAuto(Class.sidewinder, "Auto-Sidewinder"); -Class.autoHelix = makeAuto(Class.helix, "Auto-Helix"); -Class.autoUndertow = makeAuto(Class.undertow, "Auto-Undertow"); -Class.autoRepeater = makeAuto(Class.repeater, "Auto-Repeater"); -Class.automachinception = makeAuto(Class.machinception, "Auto-Machceptioner"); -Class.autotailgator = makeAuto(Class.tailgator, "Auto-Tailgator"); -Class.autoflankinception = makeAuto(Class.flankinception, "Auto-Flankceptioner"); -Class.autoBackShield = makeAuto(Class.backShield, "Auto-BackShield"); +Class.autoDouble = makeAuto("doubleTwin", "Auto-Double") +Class.autoAssassin = makeAuto("assassin") +Class.autoGunner = makeAuto("gunner") +Class.autoTriAngle = makeAuto("triAngle") +Class.autoOverseer = makeAuto("overseer") +Class.autoRevolutionist = makeAuto("revolutionist", "Audioboard"); +Class.autoCruiser = makeAuto("cruiser") +Class.autoSpawner = makeAuto("spawner") +Class.autoBuilder = makeAuto("builder") +Class.autoBinary = makeAuto("binary", "Auto-Binary") +Class.autoinceptionist = makeAuto("autoinceptionistbody", "Auto-Inceptionist", {type: 'ceptionistturret'}); +Class.autoGundirector = makeAuto("gundirector", "Auto-Pathogen") +Class.autoBigSubduer = makeAuto("bigSubduer", "Auto-Mitochondrion") +Class.autoFlankdue = makeAuto("flankdue", "Auto-Flankduer") +Class.autoTripleShot = makeAuto("tripleShot", "Auto-Triple Shot"); +Class.autoHunter = makeAuto("hunter", "Auto-Hunter"); +Class.autoRifle = makeAuto("rifle", "Auto-Rifle"); +Class.autoTwinsniper = makeAuto("twinsniper", "Auto-Twiper"); +Class.autoAcid = makeAuto("acid", "Cyanide"); +Class.autoChill = makeAuto("chiller", "Auto-Chiller"); +Class.autoMini = makeAuto("minigun", "Auto-Minigun"); +Class.autoSprayer = makeAuto("sprayer", "Auto-Sprayer"); +Class.autoHexaTank = makeAuto("hexaTank", "Auto-HexaTank"); +Class.autoAuto3 = makeAuto("auto3", "Auto-Auto3"); +Class.autoUnderseer = makeAuto("underseer", "Auto-Underseer"); +Class.autoDestroy = makeAuto("destroyer", "Auto-Destroyer"); +Class.autoArtillery = makeAuto("artillery", "Auto-Artillery"); +Class.autoLaunch = makeAuto("launcher", "Auto-Launcher"); +Class.autoTriTrapper = makeAuto("triTrapper", "Auto-Tri Trapper"); +Class.autoTrapGuard = makeAuto("trapGuard", "Auto-TrapGuard"); +Class.autoSidewinder = makeAuto("sidewinder", "Auto-Sidewinder"); +Class.autoHelix = makeAuto("helix", "Auto-Helix"); +Class.autoUndertow = makeAuto("undertow", "Auto-Undertow"); +Class.autoRepeater = makeAuto("repeater", "Auto-Repeater"); +Class.automachinception = makeAuto("machinception", "Auto-Machceptioner"); +Class.autotailgator = makeAuto("tailgator", "Auto-Tailgator"); +Class.autoflankinception = makeAuto("flankinception", "Auto-Flankceptioner"); +Class.autoBackShield = makeAuto("backShield", "Auto-BackShield"); Class.autoSmasher = makeAuto({ PARENT: "genericSmasher", DANGER: 6, @@ -5565,26 +5544,26 @@ Class.trackerAcid = makeTracker(Class.acid, "Acidilizer"); Class.trackerChill = makeTracker(Class.chiller, "Icilizer"); //Homing Auto Tanks -Class.homingautoBasic = makeAuto(Class.basic, "Homing Auto-Basic", {type: 'homingAutoTurret'}); -Class.homingautoTwin = makeAuto(Class.twin, "Homing Auto-Twin", {type: 'homingAutoTurret'}); -Class.homingautoMach = makeAuto(Class.machineGun, "Homing Auto-Mach", {type: 'homingAutoTurret'}); -Class.homingautoSniper = makeAuto(Class.sniper, "Homing-Auto Sniper", {type: 'homingAutoTurret'}); -Class.homingautoFlank = makeAuto(Class.flankGuard, "Homing Auto-Flank", {type: 'homingAutoTurret'}); -Class.homingautoDirector = makeAuto(Class.director, "Homing Auto-Director", {type: 'homingAutoTurret'}); -Class.homingautoPound = makeAuto(Class.pounder, "Homing Auto-Pounder", {type: 'homingAutoTurret'}); -Class.homingautoTrap = makeAuto(Class.trapper, "Homing Auto-Trapper", {type: 'homingAutoTurret'}); -Class.homingautoDesmos = makeAuto(Class.desmos, "Homing Auto-Desmos", {type: 'homingAutoTurret'}); -Class.homingautobascrid = makeAuto(Class.bascrid, "Homing Auto-Bascrid", {type: 'homingAutoTurret'}) -Class.homingautolittleHunter = makeAuto(Class.littleHunter, "Homing Auto-Subduer", {type: 'homingAutoTurret'}) -Class.homingautoinception = makeAuto(Class.inception, "Auto Inception", {type: 'homingAutoTurret'}); -Class.homingautoauto2 = makeAuto(Class.auto2, "Auto-2", {type: 'homingAutoTurret'}); +Class.homingautoBasic = makeAuto("basic", "Homing Auto-Basic", {type: 'homingAutoTurret'}); +Class.homingautoTwin = makeAuto("twin", "Homing Auto-Twin", {type: 'homingAutoTurret'}); +Class.homingautoMach = makeAuto("machineGun", "Homing Auto-Mach", {type: 'homingAutoTurret'}); +Class.homingautoSniper = makeAuto("sniper", "Homing-Auto Sniper", {type: 'homingAutoTurret'}); +Class.homingautoFlank = makeAuto("flankGuard", "Homing Auto-Flank", {type: 'homingAutoTurret'}); +Class.homingautoDirector = makeAuto("director", "Homing Auto-Director", {type: 'homingAutoTurret'}); +Class.homingautoPound = makeAuto("pounder", "Homing Auto-Pounder", {type: 'homingAutoTurret'}); +Class.homingautoTrap = makeAuto("trapper", "Homing Auto-Trapper", {type: 'homingAutoTurret'}); +Class.homingautoDesmos = makeAuto("desmos", "Homing Auto-Desmos", {type: 'homingAutoTurret'}); +Class.homingautobascrid = makeAuto("bascrid", "Homing Auto-Bascrid", {type: 'homingAutoTurret'}) +Class.homingautolittleHunter = makeAuto("littleHunter", "Homing Auto-Subduer", {type: 'homingAutoTurret'}) +Class.homingautoinception = makeAuto("inception", "Auto Inception", {type: 'homingAutoTurret'}); +Class.homingautoauto2 = makeAuto("auto2", "Auto-2", {type: 'homingAutoTurret'}); //Reveries Class.reverie = addBackTurret(Class.basic, "Reverie", {type: 'autoTankGun'}); Class.twinreverie = addBackTurret(Class.basic, "Tyverie", {type: 'fastbigauto4gun'}); Class.poundreverie = addBackTurret(Class.basic, "Pyverie", {type: 'megaAutoTankGun'}); Class.dualreverie = addBackTurret(Class.basic, "Douverie", {type: 'dualAutoTankGun'}); -Class.autoReverie = makeAuto(Class.inception, "Auto-Reverie"); +Class.autoReverie = makeAuto("reverie", "Auto-Reverie"); Class.reveriebrid = makeHybrid('reverie', "Reverie-Hybrid"); //Auras diff --git a/server/modules/definitions/groups/turrets.js b/server/modules/definitions/groups/turrets.js index 62dc14371..c88b37572 100644 --- a/server/modules/definitions/groups/turrets.js +++ b/server/modules/definitions/groups/turrets.js @@ -147,7 +147,7 @@ Class.trapTurret = { ], }; Class.baseTrapTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", INDEPENDENT: true, COLOR: "grey", @@ -166,7 +166,7 @@ Class.baseTrapTurret = { ], } Class.terrestrialTrapTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", INDEPENDENT: true, COLOR: "grey", @@ -191,7 +191,7 @@ let makeshottrapTurretProps = () => ({ STAT_CALCULATOR: gunCalcNames.block, }); Class.shottrapTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: 'Turret', BODY: { FOV: 0, @@ -240,7 +240,7 @@ Class.shottrapTurret = { } ] } Class.machineTripleTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Machine Gun", BODY: { FOV: 2 }, CONTROLLERS: [ ["spin", {speed: 0.04}] ], @@ -272,7 +272,7 @@ Class.machineTripleTurret = { ], }; Class.launcherTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Launcher", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -292,7 +292,7 @@ Class.launcherTurret = { ], }; Class.skimmerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Skimmer", BODY: { FOV: 2 * base.FOV }, COLOR: -1, @@ -311,7 +311,7 @@ Class.skimmerTurret = { ], }; Class.kronosSkimmerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Skimmer", BODY: { FOV: 10 }, COLOR: "grey", @@ -330,7 +330,7 @@ Class.kronosSkimmerTurret = { ], } Class.autosmashTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Launcher", BODY: { FOV: 10 }, COLOR: "grey", @@ -349,7 +349,7 @@ Class.autosmashTurret = { ], } Class.twisterTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Twister", BODY: { FOV: 2 }, COLOR: -1, @@ -368,7 +368,7 @@ Class.twisterTurret = { ], }; Class.hyperTwisterTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Twister", BODY: { FOV: 2 }, COLOR: -1, @@ -387,7 +387,7 @@ Class.hyperTwisterTurret = { ], }; Class.rocketeerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Rocketeer", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -406,7 +406,7 @@ Class.rocketeerTurret = { ], }; Class.boomerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Boomer", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -430,7 +430,7 @@ Class.boomerTurret = { ], }; Class.triTrapGuardTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", COLOR: -1, CONTROLLERS: [["spin", { independent: true }]], GUNS: [], @@ -456,7 +456,7 @@ for(let i = 0; i < 3; i++) { ) }; Class.eliteSpinnerCyclone = { - PARENT: ["genericTank"], + PARENT: "genericTank", COLOR: -1, CONTROLLERS: [["spin", { speed: 0.1, independent: true }]], GUNS: [], @@ -488,7 +488,7 @@ for (let i = 0; i < 12; i++) { ) }; Class.barricadeTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", BODY: { FOV: 0.5, @@ -531,7 +531,7 @@ Class.barricadeTurret = { ], }; Class.artilleryAutoTankgun = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Artillery", BODY: { FOV: 2, @@ -570,7 +570,7 @@ Class.artilleryAutoTankgun = { ], } Class.artilleryTurret = { // This one has half the dps of the one above - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Artillery", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -601,7 +601,7 @@ Class.artilleryTurret = { // This one has half the dps of the one above ], }; Class.legionaryTwin = { - PARENT: ["auto4gun"], + PARENT: "auto4gun", COLOR: "grey", INDEPENDENT: true, GUNS: [ @@ -621,7 +621,7 @@ Class.legionaryTwin = { ], } Class.nailgunTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Nailgun", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -651,7 +651,7 @@ Class.nailgunTurret = { ], }; Class.crowbarTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", COLOR: "grey", LABEL: "Crowbar", BODY: { FOV: 2 }, @@ -679,7 +679,7 @@ Class.crowbarTurret = { ], }; Class.wrenchTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", COLOR: "grey", LABEL: "Wrench", BODY: { FOV: 2 }, @@ -706,7 +706,7 @@ Class.wrenchTurret = { ], }; Class.protoSwarmerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Swarmer", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -724,7 +724,7 @@ Class.protoSwarmerTurret = { ], } Class.swarmTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Swarm", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -741,7 +741,7 @@ Class.swarmTurret = { ], }; Class.napoleonLowerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -765,7 +765,7 @@ Class.napoleonLowerTurret = { ], }; Class.genghisLowerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "", MAX_CHILDREN: 4, BODY: { FOV: 2 }, @@ -787,7 +787,7 @@ Class.genghisLowerTurret = { }; Class.cruiserTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Cruiser", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -811,7 +811,7 @@ Class.cruiserTurret = { ], }; Class.carrierTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Carrier", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -843,7 +843,7 @@ Class.carrierTurret = { ], } Class.gunnerCruiserTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Launcher", BODY: { FOV: 10 }, COLOR: "grey", @@ -880,7 +880,7 @@ Class.gunnerCruiserTurret = { ], } Class.juliusLowerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "", MAX_CHILDREN: 3, BODY: { FOV: 2 }, @@ -898,7 +898,7 @@ Class.juliusLowerTurret = { ], }; Class.swarmerTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Swarmer", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -916,7 +916,7 @@ Class.swarmerTurret = { ], }; Class.basicTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Turret", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -932,7 +932,7 @@ Class.basicTurret = { ], }; Class.napoleonUpperTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -1026,7 +1026,7 @@ Class.pillboxTurret = { ], } Class.tripletTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Triplet", BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], @@ -1122,7 +1122,7 @@ Class.surgeonPillboxTurret = { // Miscellaneous Class.baseSwarmTurret = { - PARENT: ["genericTank"], + PARENT: "genericTank", LABEL: "Protector", COLOR: "grey", BODY: { @@ -1238,7 +1238,6 @@ Class.assemblerDot = { INDEPENDENT: true } Class.healerSymbol = { - PARENT: ["genericEntity"], SHAPE: [[0.3, -0.3],[1,-0.3],[1,0.3],[0.3,0.3],[0.3,1],[-0.3,1],[-0.3,0.3],[-1,0.3],[-1,-0.3],[-0.3,-0.3],[-0.3,-1],[0.3,-1]], SIZE: 13, COLOR: "red", diff --git a/server/modules/gamemodes/maze.js b/server/modules/gamemodes/maze.js index 5aa014cef..5f78d1b7d 100644 --- a/server/modules/gamemodes/maze.js +++ b/server/modules/gamemodes/maze.js @@ -106,7 +106,7 @@ let checkMazeForBlocks = (initX, initY, size, maze) => { x: d.x, y: d.y }); - o.define(Class.wall); + o.define("wall"); o.SIZE = d.s * 0.5 - 2; o.team = TEAM_ENEMIES; o.protect(); diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index f0b2a3a0a..d013b25ed 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -426,7 +426,7 @@ class Gun extends EventEmitter { facing: host.facing, size: host.SIZE, }; - host.define(Class.genericEntity); + host.define("genericEntity"); this.bulletInit(host); host.team = oo.master.master.team; host.master = oo.master; @@ -466,7 +466,7 @@ class Gun extends EventEmitter { y: 3 * Math.sin(save.angle), }; o.color = gun.body.master.master.color; - o.define(Class.hitScanExplosion); + o.define("hitScanExplosion"); // Pass the gun attributes o.define({ BODY: gun.interpret(gun.settings3), @@ -499,7 +499,7 @@ class Gun extends EventEmitter { ); o.facing = Math.atan2(target.y - y, target.x - x) + dir; o.color = this.body.master.master.color; - o.define(Class.hitScanBullet); + o.define("hitScanBullet"); // Pass the gun attributes o.define({ BODY: this.interpret(this.settings3), @@ -531,7 +531,7 @@ class Gun extends EventEmitter { let e = new Entity({ x: x, y: y }, this.body); e.facing = Math.atan2(target.y - y, target.x - x); e.color = this.body.master.master.color; - e.define(Class.hitScanBullet); + e.define("hitScanBullet"); // Pass the gun attributes e.define({ BODY: this.interpret(this.settings2), @@ -1035,9 +1035,9 @@ class Entity extends EventEmitter { } this.control.target = b.target == null ? this.control.target : b.target; this.control.goal = b.goal ? b.goal : { x: this.x, y: this.y }; - this.control.fire = b.fire; - this.control.main = b.main; - this.control.alt = b.alt; + this.control.fire = b.fire ?? false; + this.control.main = b.main ?? false; + this.control.alt = b.alt ?? false; this.control.power = b.power == null ? 1 : b.power; if (this.invuln && (this.control.goal.x !== this.x || this.control.goal.y !== this.y)) { @@ -1948,6 +1948,7 @@ class Entity extends EventEmitter { } break; case "desmos": + this.damp = 0; let save = { x: this.master.x, y: this.master.y, diff --git a/server/modules/network/sockets.js b/server/modules/network/sockets.js index c74a7f684..7390ff54b 100644 --- a/server/modules/network/sockets.js +++ b/server/modules/network/sockets.js @@ -629,6 +629,7 @@ if (player.body != null && socket.permissions) { case "H": if (player.body == null) return 1; let body = player.body; + body.emit("control", { body }) if (body.underControl) { if (c.DOMINATOR_LOOP) { player.body.sendMessage("You have relinquished control of the dominator."); @@ -1055,7 +1056,6 @@ const spawn = (socket, name) => { util.remove(disconnections, disconnections.indexOf(recover)); clearTimeout(recover.timeout); body = recover.body; - body.controllers = body.controllers.filter(con => !(con instanceof ioTypes.listenToPlayer)); body.become(player); player.team = body.team; } else { From 6e12d7c8f0d4fe5ce76c6c775fbf025b32d98a32 Mon Sep 17 00:00:00 2001 From: "Glitch (purring-rhetorical-drink)" Date: Thu, 2 May 2024 13:18:56 +0000 Subject: [PATCH 03/15] Fixed Desmos' static Velocity & Nerfed Quadruplex --- .glitch-assets | 190 - LICENSE | 4 +- README.md | 5 +- changelog preview | 499 -- features.md | 4 +- images/favicon.png | Bin 81775 -> 0 bytes images/girb.jpg | Bin 327303 -> 0 bytes images/lratio.png | Bin 66360 -> 0 bytes images/neroshitpost.png | Bin 192370 -> 0 bytes images/othergirb.jpg | Bin 48408 -> 0 bytes install.sh | 2 +- neroplayer/script.js | 86 - neroplayer/stylesheet.css | 14 - neroplayer/visual.html | 15 - package.json | 7 +- public/app.js | 1411 +--- public/changelog.html | 524 +- public/credits.html | 104 - public/favicon.ico | Bin 225726 -> 21654 bytes public/icon32x32.png | Bin 0 -> 1898 bytes public/index.html | 549 +- public/lib/canvas.js | 93 +- public/lib/color.js | 58 +- public/lib/gameDraw.js | 48 +- public/lib/global.js | 134 +- public/lib/json/color.json | 29 - public/lib/json/manifest.json | 10 +- public/lib/settings.js | 2 +- public/lib/socketInit.js | 28 +- public/lib/tankdesc.js | 545 -- public/lib/util.js | 21 +- public/main.css | 1194 +--- public/osa_background_tile.png | Bin 0 -> 748 bytes public/round.png | Bin 0 -> 25179 bytes public/run.bat => run.bat | 0 server/config.js | 66 +- server/index.js | 28 +- server/lib/hshg.js | 2 +- server/lib/random.js | 22 +- server/modules/debug/speedLoop.js | 3 - server/modules/definitions/addons/amongus.js | 108 - .../definitions/addons/basicChatModeration.js | 3 +- server/modules/definitions/addons/cooper.js | 30 - .../modules/definitions/addons/dailyTanks.js | 1687 ----- server/modules/definitions/addons/dreadv1.js | 489 +- server/modules/definitions/addons/dreadv2.js | 2 +- .../definitions/addons/exampleAddon.js | 2 +- .../definitions/addons/geometryDashDart.js | 72 - server/modules/definitions/addons/labyFood.js | 61 +- server/modules/definitions/addons/lancer.js | 663 -- .../modules/definitions/addons/playerskins.js | 175 - .../definitions/addons/revolutionistPack.js | 186 - .../definitions/addons/woomeraddonmeow.js | 64 - server/modules/definitions/combined.js | 2 +- server/modules/definitions/constants.js | 6 - server/modules/definitions/facilitators.js | 799 +-- server/modules/definitions/groups/bosses.js | 5886 ++++++++--------- server/modules/definitions/groups/dev.js | 1492 +---- server/modules/definitions/groups/food.js | 45 +- server/modules/definitions/groups/generics.js | 17 +- server/modules/definitions/groups/misc.js | 13 +- .../modules/definitions/groups/projectiles.js | 388 +- server/modules/definitions/groups/tanks.js | 2748 +------- server/modules/definitions/groups/turrets.js | 364 +- server/modules/definitions/gunvals.js | 67 +- server/modules/global.js | 8 +- server/modules/live/controllers.js | 130 +- server/modules/live/entity.js | 92 +- server/modules/network/sockets.js | 260 +- server/modules/physics/collisionFunctions.js | 138 +- server/modules/setup/rooms/map_apspp_maze.js | 26 - .../modules/setup/rooms/map_apspp_tiletest.js | 42 + .../modules/setup/rooms/map_neroio_arena.js | 27 - .../modules/setup/rooms/map_neroio_banquet.js | 29 - .../setup/rooms/map_neroio_mazearena.js | 27 - .../modules/setup/rooms/overlay_domination.js | 4 +- server/modules/setup/tiles/decoration.js | 29 +- server/modules/setup/tiles/misc.js | 102 +- server/modules/setup/tiles/siege.js | 2 +- server/modules/setup/tiles/tdm.js | 3 +- server/permissions.js | 2 +- shit/randomstuff/aasfsdgsdg | 1 - shit/randomstuff/asajhwerkji | 25 - shit/randomstuff/jfsdfn | 27 - shit/temp/backuo | 2351 ------- shit/temp/changelog template | 26 - shit/temp/changes | 512 -- shit/temp/gifbackround | 33 - shit/temp/music | 20 - shit/temp/mytankcount | 13 - shit/temp/stuff | 137 - shit/temp/woomycolorname | 3 - 92 files changed, 4400 insertions(+), 20735 deletions(-) delete mode 100644 .glitch-assets delete mode 100644 changelog preview delete mode 100644 images/favicon.png delete mode 100644 images/girb.jpg delete mode 100644 images/lratio.png delete mode 100644 images/neroshitpost.png delete mode 100644 images/othergirb.jpg mode change 100644 => 100755 install.sh delete mode 100644 neroplayer/script.js delete mode 100644 neroplayer/stylesheet.css delete mode 100644 neroplayer/visual.html delete mode 100644 public/credits.html create mode 100644 public/icon32x32.png delete mode 100644 public/lib/tankdesc.js create mode 100644 public/osa_background_tile.png create mode 100644 public/round.png rename public/run.bat => run.bat (100%) delete mode 100644 server/modules/definitions/addons/amongus.js delete mode 100644 server/modules/definitions/addons/cooper.js delete mode 100644 server/modules/definitions/addons/dailyTanks.js delete mode 100644 server/modules/definitions/addons/geometryDashDart.js delete mode 100644 server/modules/definitions/addons/lancer.js delete mode 100644 server/modules/definitions/addons/playerskins.js delete mode 100644 server/modules/definitions/addons/revolutionistPack.js delete mode 100644 server/modules/definitions/addons/woomeraddonmeow.js delete mode 100644 server/modules/setup/rooms/map_apspp_maze.js create mode 100644 server/modules/setup/rooms/map_apspp_tiletest.js delete mode 100644 server/modules/setup/rooms/map_neroio_arena.js delete mode 100644 server/modules/setup/rooms/map_neroio_banquet.js delete mode 100644 server/modules/setup/rooms/map_neroio_mazearena.js delete mode 100644 shit/randomstuff/aasfsdgsdg delete mode 100644 shit/randomstuff/asajhwerkji delete mode 100644 shit/randomstuff/jfsdfn delete mode 100644 shit/temp/backuo delete mode 100644 shit/temp/changelog template delete mode 100644 shit/temp/changes delete mode 100644 shit/temp/gifbackround delete mode 100644 shit/temp/music delete mode 100644 shit/temp/mytankcount delete mode 100644 shit/temp/stuff delete mode 100644 shit/temp/woomycolorname diff --git a/.glitch-assets b/.glitch-assets deleted file mode 100644 index d84afb22e..000000000 --- a/.glitch-assets +++ /dev/null @@ -1,190 +0,0 @@ -{"name":"2023_10_10_0rf_Kleki.png","date":"2023-10-10T18:58:08.611Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_10_0rf_Kleki.png","type":"image/png","size":30464,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_10_0rf_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"UP44Oex8WvGywkCD"} -{"name":"6avWH55.jpg","date":"2023-10-25T12:45:16.390Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6avWH55.jpg","type":"image/jpeg","size":327303,"imageWidth":2500,"imageHeight":1667,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6avWH55.jpg","thumbnailWidth":330,"thumbnailHeight":221,"uuid":"o6pEXEUSnOPqm4bg"} -{"name":"4073e372df1399336a01c51052a1bbd8.jpg","date":"2023-10-25T13:01:09.623Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4073e372df1399336a01c51052a1bbd8.jpg","type":"image/jpeg","size":48408,"imageWidth":960,"imageHeight":649,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4073e372df1399336a01c51052a1bbd8.jpg","thumbnailWidth":330,"thumbnailHeight":224,"uuid":"w9ZO2wxV83aWhelI"} -{"name":"58563194-553c-49ae-95db-441b06bf9bef.image.png","date":"2023-10-25T13:19:20.463Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/58563194-553c-49ae-95db-441b06bf9bef.image.png","type":"image/png","size":76850,"imageWidth":360,"imageHeight":240,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F58563194-553c-49ae-95db-441b06bf9bef.image.png","thumbnailWidth":330,"thumbnailHeight":220,"uuid":"RsOUyfm1cBYSqbw0"} -{"uuid":"o6pEXEUSnOPqm4bg","deleted":true} -{"name":"girb.jpg","date":"2023-10-25T12:45:16.390Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/girb.jpg","type":"image/jpeg","size":327303,"imageWidth":2500,"imageHeight":1667,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6avWH55.jpg","thumbnailWidth":330,"thumbnailHeight":221,"uuid":"o6pEXEUSnOPqm4bg"} -{"uuid":"w9ZO2wxV83aWhelI","deleted":true} -{"name":"othergirb.jpg","date":"2023-10-25T13:01:09.623Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/othergirb.jpg","type":"image/jpeg","size":48408,"imageWidth":960,"imageHeight":649,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4073e372df1399336a01c51052a1bbd8.jpg","thumbnailWidth":330,"thumbnailHeight":224,"uuid":"w9ZO2wxV83aWhelI"} -{"name":"131107152744-mona-lisa.jpg","date":"2023-10-26T11:10:16.817Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/131107152744-mona-lisa.jpg","type":"image/jpeg","size":747095,"imageWidth":2000,"imageHeight":3000,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F131107152744-mona-lisa.jpg","thumbnailWidth":220,"thumbnailHeight":330,"uuid":"YM7ULs8ieFPfkHTh"} -{"name":"2022_06_23_11e_Kleki.png","date":"2023-10-26T11:10:22.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2022_06_23_11e_Kleki.png","type":"image/png","size":66360,"imageWidth":1009,"imageHeight":601,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2022_06_23_11e_Kleki.png","thumbnailWidth":330,"thumbnailHeight":197,"uuid":"CKrqEXVr9r1fWHQ6"} -{"name":"84812d435b246f4edffe887c5f755008.jpg","date":"2023-10-26T11:10:27.584Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/84812d435b246f4edffe887c5f755008.jpg","type":"image/jpeg","size":111067,"imageWidth":924,"imageHeight":1000,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F84812d435b246f4edffe887c5f755008.jpg","thumbnailWidth":305,"thumbnailHeight":330,"uuid":"iKniUyyIl8sambKK"} -{"name":"videoplayback.mp4","date":"2023-10-26T11:10:49.863Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp4","type":"video/mp4","size":2106277,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"txSk7RsRJ33ZgL0R"} -{"name":"IMG_0316.webp","date":"2023-10-26T11:20:34.628Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_0316.webp","type":"image/webp","size":12986,"imageWidth":640,"imageHeight":494,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_0316.webp","thumbnailWidth":330,"thumbnailHeight":255,"uuid":"ULDBE338jPz5CztZ"} -{"name":"devil vortex.jpg","date":"2023-10-26T11:23:31.448Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/devil%20vortex.jpg","type":"image/jpeg","size":70977,"imageWidth":2048,"imageHeight":1070,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdevil%20vortex.jpg","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"rwxaYBQQ3Vdh4GOB"} -{"uuid":"CKrqEXVr9r1fWHQ6","deleted":true} -{"name":"lratio","date":"2023-10-26T11:10:22.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/lratio","type":"image/png","size":66360,"imageWidth":1009,"imageHeight":601,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2022_06_23_11e_Kleki.png","thumbnailWidth":330,"thumbnailHeight":197,"uuid":"CKrqEXVr9r1fWHQ6"} -{"name":"mqdefault.jpg","date":"2023-10-26T15:51:05.241Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/mqdefault.jpg","type":"image/jpeg","size":8165,"imageWidth":320,"imageHeight":180,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/mqdefault.jpg","thumbnailWidth":320,"thumbnailHeight":180,"uuid":"vUoqYUUmAaCJlbFE"} -{"name":"e4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","date":"2023-10-26T15:52:48.829Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","type":"image/png","size":667529,"imageWidth":970,"imageHeight":750,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fe4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","thumbnailWidth":330,"thumbnailHeight":256,"uuid":"2TdCgTp1qJy5VpQF"} -{"name":"4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","date":"2023-10-26T15:56:52.346Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","type":"image/png","size":13711,"imageWidth":295,"imageHeight":247,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","thumbnailWidth":295,"thumbnailHeight":247,"uuid":"vB57dbf5e3LDGNTc"} -{"name":"9fbac25f-6710-4a95-b963-502275ff8728.image.png","date":"2023-10-26T16:03:48.998Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/9fbac25f-6710-4a95-b963-502275ff8728.image.png","type":"image/png","size":5638,"imageWidth":218,"imageHeight":157,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/9fbac25f-6710-4a95-b963-502275ff8728.image.png","thumbnailWidth":218,"thumbnailHeight":157,"uuid":"AUYt8QpAyhIjzDDo"} -{"uuid":"AUYt8QpAyhIjzDDo","deleted":true} -{"name":"2023_10_26_0ml_Kleki.png","date":"2023-10-26T16:04:27.088Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_26_0ml_Kleki.png","type":"image/png","size":6063,"imageWidth":218,"imageHeight":157,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_26_0ml_Kleki.png","thumbnailWidth":218,"thumbnailHeight":157,"uuid":"XrOWUvHhmVrkljWG"} -{"name":"b6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","date":"2023-10-26T16:06:40.232Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/b6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","type":"image/png","size":155677,"imageWidth":480,"imageHeight":480,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fb6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"ctTmChYwrALlsYSY"} -{"name":"asda.gif","date":"2023-10-26T16:07:13.205Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/asda.gif","type":"image/gif","size":2414319,"imageWidth":1160,"imageHeight":653,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fasda.gif","thumbnailWidth":330,"thumbnailHeight":186,"uuid":"DrNyvjoahVRfPqfc"} -{"name":"freddy.gif","date":"2023-10-26T16:07:33.397Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/freddy.gif","type":"image/gif","size":3807320,"imageWidth":480,"imageHeight":480,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffreddy.gif","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"JZgBnLYoTvZmoiEm"} -{"name":"poop-emoji.jpg","date":"2023-11-27T16:55:26.682Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/poop-emoji.jpg","type":"image/jpeg","size":277135,"imageWidth":1200,"imageHeight":1200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fpoop-emoji.jpg","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"Cb4D9nc5184NLZWn"} -{"name":"Screen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","date":"2023-11-27T16:55:33.660Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","type":"image/webp","size":34994,"imageWidth":1400,"imageHeight":788,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","thumbnailWidth":330,"thumbnailHeight":186,"uuid":"ZVERuCeCDI11tY8f"} -{"name":"videoplayback (5).mp4","date":"2023-11-30T20:09:06.159Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(5).mp4","type":"video/mp4","size":5225498,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(5).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"x22blklePMGQRwIA"} -{"name":"afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","date":"2023-12-01T17:04:48.242Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","type":"image/jpeg","size":673888,"imageWidth":2048,"imageHeight":1365,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fafg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","thumbnailWidth":330,"thumbnailHeight":220,"uuid":"DjbeeYPv58kWZxGT"} -{"name":"Papyrus.webp","date":"2023-12-01T17:04:54.185Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp","type":"image/webp","size":22528,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FPapyrus.webp","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"1oCUTGTCUHSm6Rht"} -{"name":"videoplayback (6).mp4","date":"2023-12-04T12:01:19.895Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(6).mp4","type":"video/mp4","size":107238,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(6).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sKgj926hemecxf1z"} -{"name":"nerd-emoji.gif","date":"2023-12-04T12:10:45.734Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nerd-emoji.gif","type":"image/gif","size":58415,"imageWidth":200,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nerd-emoji.gif","thumbnailWidth":200,"thumbnailHeight":200,"uuid":"IEWg3jT2scnmIEBa"} -{"name":"IMG_20231204_144411762_LAYER.jpg","date":"2023-12-04T18:20:34.323Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144411762_LAYER.jpg","type":"image/jpeg","size":4291465,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144411762_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"kHofB34sB8zK8ghc"} -{"name":"IMG_20231204_144409218_LAYER.jpg","date":"2023-12-04T18:20:37.274Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144409218_LAYER.jpg","type":"image/jpeg","size":4649997,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144409218_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"wy3sATUDmtO4UKav"} -{"name":"IMG_20231204_144406913_LAYER.jpg","date":"2023-12-04T18:20:40.278Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144406913_LAYER.jpg","type":"image/jpeg","size":4663414,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144406913_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"VVnb7tpycOZ96wIM"} -{"name":"IMG_20231204_144358408_LAYER.jpg","date":"2023-12-04T18:20:43.765Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144358408_LAYER.jpg","type":"image/jpeg","size":4910430,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144358408_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"298PzLlhaFIqxxcq"} -{"name":"2023_12_05_0sn_Kleki.png","date":"2023-12-05T20:41:21.532Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_05_0sn_Kleki.png","type":"image/png","size":9872,"imageWidth":91,"imageHeight":93,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_05_0sn_Kleki.png","thumbnailWidth":91,"thumbnailHeight":93,"uuid":"lzgyLwxKAAQT4aRa"} -{"name":"2023_12_06_0yp_Kleki.png","date":"2023-12-07T00:24:27.560Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yp_Kleki.png","type":"image/png","size":70691,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yp_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"lq8MCR84TekmbueY"} -{"name":"2023_12_06_0yt_Kleki.png","date":"2023-12-07T00:24:47.196Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yt_Kleki.png","type":"image/png","size":81775,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yt_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"ggXSa8BNzRjqSBnD"} -{"name":"2023_12_06_0yl_Kleki.png","date":"2023-12-07T00:25:10.293Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png","type":"image/png","size":84439,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"YAFhahkJBvHvomAo"} -{"name":"2023_12_06_0yi_Kleki.png","date":"2023-12-07T00:30:14.507Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yi_Kleki.png","type":"image/png","size":87010,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yi_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"dvm2XAnEJNmrlaoJ"} -{"name":"2023_12_06_0yh_Kleki.png","date":"2023-12-07T00:30:19.835Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yh_Kleki.png","type":"image/png","size":87060,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yh_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"RakITIBsTZAoxn6J"} -{"name":"2023_12_06_0yb_Kleki.png","date":"2023-12-07T00:30:29.284Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yb_Kleki.png","type":"image/png","size":75357,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yb_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"EvxT6uRiwx18Z2e8"} -{"name":"2023_12_06_0za_Kleki.png","date":"2023-12-07T00:49:05.704Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png","type":"image/png","size":72696,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"aoroY4SW6zapPfOE"} -{"name":"2023_12_08_0g8_Kleki.png","date":"2023-12-08T13:15:13.341Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_08_0g8_Kleki.png","type":"image/png","size":142882,"imageWidth":1117,"imageHeight":607,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2023_12_08_0g8_Kleki.png","thumbnailWidth":330,"thumbnailHeight":180,"uuid":"iRH2k0fN1Gx4DUk1"} -{"name":"MOSHED-2023-11-2-9-15-39.gif","date":"2023-12-12T12:59:58.261Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-15-39.gif","type":"image/gif","size":9742202,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-15-39.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"52P1expoZSM3Z2bZ"} -{"name":"MOSHED-2023-11-2-9-16-18.jpg","date":"2023-12-12T13:00:04.817Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-16-18.jpg","type":"image/jpeg","size":122406,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-16-18.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"VyBWbHyBZeQDkCqK"} -{"name":"MOSHED-2023-11-2-9-16-30.jpg","date":"2023-12-12T13:00:12.253Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-16-30.jpg","type":"image/jpeg","size":194318,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-16-30.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"ccSREI092qAxPu6K"} -{"name":"MOSHED-2023-11-2-9-17-44.gif","date":"2023-12-12T13:00:21.674Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-17-44.gif","type":"image/gif","size":8254208,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-17-44.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"vThvLihG3U4Tva8u"} -{"name":"MOSHED-2023-11-2-9-18-42.gif","date":"2023-12-12T13:00:29.800Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-18-42.gif","type":"image/gif","size":22820370,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-18-42.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"Aei1r7CUxV9JTPGZ"} -{"name":"MOSHED-2023-11-2-9-19-19.jpg","date":"2023-12-12T13:00:34.450Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-19-19.jpg","type":"image/jpeg","size":102760,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-19-19.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"lp7GBZ7NYag3ZEM5"} -{"name":"MOSHED-2023-11-2-9-22-40.gif","date":"2023-12-12T13:00:45.756Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-22-40.gif","type":"image/gif","size":13789663,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-22-40.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"b3XRVsDg7Qv5QFYZ"} -{"name":"MOSHED-2023-11-2-9-24-47.gif","date":"2023-12-12T13:00:51.248Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-24-47.gif","type":"image/gif","size":6092682,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-24-47.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"9TjxQT7jJYwEwQZb"} -{"uuid":"Aei1r7CUxV9JTPGZ","deleted":true} -{"name":"MOSHED-2023-11-2-9-18-42.gif","date":"2023-12-12T13:07:15.262Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-18-42.gif","type":"image/gif","size":22820370,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-18-42.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"mFh1JnSydzXR12gh"} -{"uuid":"mFh1JnSydzXR12gh","deleted":true} -{"name":"MOSHED-2023-12-12-10-47-6.gif","date":"2023-12-12T14:17:22.498Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-47-6.gif","type":"image/gif","size":11089695,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-47-6.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"kEzXuIpHEELcAuHJ"} -{"name":"MOSHED-2023-12-12-10-46-41.gif","date":"2023-12-12T14:17:26.360Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-46-41.gif","type":"image/gif","size":12491342,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-46-41.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"MjoGdc3z87JYHYl4"} -{"name":"MOSHED-2023-12-12-10-42-0.gif","date":"2023-12-12T14:17:29.599Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-42-0.gif","type":"image/gif","size":8559279,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-42-0.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"orEDVirkk7HGAjwX"} -{"name":"MOSHED-2023-12-12-10-39-41.gif","date":"2023-12-12T14:17:33.878Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-39-41.gif","type":"image/gif","size":6042203,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-39-41.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"soSGGxLRe87PpUyB"} -{"name":"MOSHED-2023-12-12-10-37-55.gif","date":"2023-12-12T14:17:36.549Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-37-55.gif","type":"image/gif","size":1825419,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-37-55.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"suIcEXpXCuqgBnhb"} -{"uuid":"suIcEXpXCuqgBnhb","deleted":true} -{"uuid":"soSGGxLRe87PpUyB","deleted":true} -{"uuid":"orEDVirkk7HGAjwX","deleted":true} -{"uuid":"MjoGdc3z87JYHYl4","deleted":true} -{"uuid":"kEzXuIpHEELcAuHJ","deleted":true} -{"uuid":"9TjxQT7jJYwEwQZb","deleted":true} -{"uuid":"b3XRVsDg7Qv5QFYZ","deleted":true} -{"uuid":"lp7GBZ7NYag3ZEM5","deleted":true} -{"uuid":"vThvLihG3U4Tva8u","deleted":true} -{"uuid":"ccSREI092qAxPu6K","deleted":true} -{"uuid":"VyBWbHyBZeQDkCqK","deleted":true} -{"uuid":"52P1expoZSM3Z2bZ","deleted":true} -{"name":"fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","date":"2024-01-14T21:10:07.867Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","type":"image/png","size":2376,"imageWidth":96,"imageHeight":96,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","thumbnailWidth":96,"thumbnailHeight":96,"uuid":"uuaOAwjEVYE8UjTl"} -{"name":"oioioi.mp3","date":"2024-01-15T02:47:10.033Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3","type":"audio/mpeg","size":7221396,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Foioioi.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"TLbSQQprOSopfHoY"} -{"name":"Depredation.mp3","date":"2024-01-15T02:47:46.890Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation.mp3","type":"audio/mpeg","size":8288129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"XfFWeHV5t1gcuE4J"} -{"name":"World's End.wav","date":"2024-01-15T02:48:09.038Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav","type":"audio/wav","size":33800236,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FWorld's%20End.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"nFvYO1N5f6xH8PgY"} -{"name":"4Miklipi (Dejected) Preview.mp3","date":"2024-01-15T02:50:22.417Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3","type":"audio/mpeg","size":4125377,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4Miklipi%20(Dejected)%20Preview.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"b0959XaAUwrm5DBm"} -{"name":"nero shitpost.png","date":"2024-01-15T03:46:10.363Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nero%20shitpost.png","type":"image/png","size":192370,"imageWidth":500,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fnero%20shitpost.png","thumbnailWidth":330,"thumbnailHeight":264,"uuid":"27bMMsSzzePzc4gx"} -{"name":"6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","date":"2024-01-15T04:04:38.159Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","type":"image/png","size":151618,"imageWidth":498,"imageHeight":498,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"BS5SvNlFUKcj0C0u"} -{"name":"look_closely.mp3","date":"2024-01-15T04:09:46.778Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/look_closely.mp3","type":"audio/mpeg","size":20922,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flook_closely.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"VlbLJHd2YrAkE8oQ"} -{"name":"e304fc26-480b-47b5-8270-949f7df44d92.image.png","date":"2024-01-15T04:58:22.951Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png","type":"image/png","size":85814,"imageWidth":298,"imageHeight":397,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fe304fc26-480b-47b5-8270-949f7df44d92.image.png","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"JndrzAvoYpyDCqAG"} -{"name":"toilet_flush.mp3","date":"2024-01-15T05:28:22.578Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/toilet_flush.mp3","type":"audio/mpeg","size":94293,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftoilet_flush.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"8EtOGgdbXaVQRsG2"} -{"name":"y2mate_HOnnyD0.mp3","date":"2024-01-15T05:28:25.126Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/y2mate_HOnnyD0.mp3","type":"audio/mpeg","size":50684,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fy2mate_HOnnyD0.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"gZIE2RUndOaeOkpY"} -{"name":"flowing-water-sound-effect.mp3","date":"2024-01-15T06:24:21.150Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/flowing-water-sound-effect.mp3","type":"audio/mpeg","size":164603,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fflowing-water-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"lFzb954crqkjqSxU"} -{"name":"pew_pew-dknight556-1379997159.mp3","date":"2024-01-15T06:26:15.747Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/pew_pew-dknight556-1379997159.mp3","type":"audio/mpeg","size":7551,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fpew_pew-dknight556-1379997159.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"wbsUbQ176JelACja"} -{"name":"2024_01_15_05q_Kleki.png","date":"2024-01-15T06:57:08.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png","type":"image/png","size":20218,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_15_05q_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"FSqPDlLinpE8Loxx"} -{"name":"chipi-chipi-chapa-chapa.mp3","date":"2024-01-15T07:13:52.837Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chipi-chipi-chapa-chapa.mp3","type":"audio/mpeg","size":192826,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchipi-chipi-chapa-chapa.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"yz3SmgjTHe6LnBrF"} -{"name":"neko-arc.mp3","date":"2024-01-15T07:13:55.953Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/neko-arc.mp3","type":"audio/mpeg","size":17901,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fneko-arc.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"u3PHWM6bxDbQa4Z4"} -{"name":"bwomp.mp3","date":"2024-01-15T07:13:59.344Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bwomp.mp3","type":"audio/mpeg","size":6765,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fbwomp.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ORPQeX8y3fWoNeC1"} -{"name":"nfl.mp3","date":"2024-01-15T07:14:03.389Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nfl.mp3","type":"audio/mpeg","size":300347,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fnfl.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ll5dGpaMX1dkzUAc"} -{"name":"Gear-icon-transparent-background.png","date":"2024-01-18T11:59:38.381Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png","type":"image/png","size":14537,"imageWidth":512,"imageHeight":512,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FGear-icon-transparent-background.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"kK6xzuT7nN8es5J9"} -{"name":"Untitled979_20240120123618.png","date":"2024-01-20T17:38:31.845Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled979_20240120123618.png","type":"image/png","size":14246,"imageWidth":350,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FUntitled979_20240120123618.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"izP72RmZ8nLYsSdc"} -{"name":"74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","date":"2024-01-20T17:39:19.444Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","type":"image/png","size":17060,"imageWidth":215,"imageHeight":196,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","thumbnailWidth":215,"thumbnailHeight":196,"uuid":"bJt3vCO1iQJAcPkv"} -{"name":"videoplayback.mp3","date":"2024-01-21T03:17:37.028Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3","type":"audio/mpeg","size":3451436,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"hFAccqiGuKtlcJVr"} -{"name":"jake-chudnow-edited_y1t8j5q.mp3","date":"2024-01-23T13:54:17.534Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jake-chudnow-edited_y1t8j5q.mp3","type":"audio/mpeg","size":340823,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fjake-chudnow-edited_y1t8j5q.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"KsmNUXrjFBTR9nnt"} -{"name":"MemeFeedBot_5.mp4","date":"2024-01-30T20:25:51.474Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MemeFeedBot_5.mp4","type":"video/mp4","size":1311719,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMemeFeedBot_5.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"reUPECkwcraGwOc3"} -{"name":"4 2.wav","date":"2024-01-31T15:49:21.860Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4%202.wav","type":"audio/wav","size":248118,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4%202.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"1E7gld9pLGXWDUC8"} -{"name":"Screen recording 2024-01-23 9.38.41 AM.webm","date":"2024-02-02T01:45:08.442Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screen%20recording%202024-01-23%209.38.41%20AM.webm","type":"video/webm","size":1616860,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreen%20recording%202024-01-23%209.38.41%20AM.webm","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"Lp97bNs9HjhFIlKp"} -{"name":"2024_02_01_112_Kleki.png","date":"2024-02-02T01:45:11.256Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_112_Kleki.png","type":"image/png","size":84804,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_112_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"QZfJ4aPwLpj3gxD9"} -{"name":"2024_02_01_10z_Kleki.png","date":"2024-02-02T01:45:15.168Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_10z_Kleki.png","type":"image/png","size":84316,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_10z_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"nDK0YapB9Y94CjO7"} -{"name":"2024_02_09_11n_Kleki.png","date":"2024-02-10T02:06:04.886Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_09_11n_Kleki.png","type":"image/png","size":53374,"imageWidth":218,"imageHeight":143,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_09_11n_Kleki.png","thumbnailWidth":218,"thumbnailHeight":143,"uuid":"KkGODJKzVOA9trS5"} -{"name":"2024_02_15_0qs_Kleki.png","date":"2024-02-15T19:34:53.434Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","type":"image/png","size":2051,"imageWidth":100,"imageHeight":100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","thumbnailWidth":100,"thumbnailHeight":100,"uuid":"b7U68EwE9UUNAsv8"} -{"uuid":"b7U68EwE9UUNAsv8","deleted":true} -{"name":"Trophy.png","date":"2024-02-15T19:34:53.434Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png","type":"image/png","size":2051,"imageWidth":100,"imageHeight":100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","thumbnailWidth":100,"thumbnailHeight":100,"uuid":"b7U68EwE9UUNAsv8"} -{"name":"download.mp3","date":"2024-02-18T01:07:44.295Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3","type":"audio/mpeg","size":9263777,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdownload.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"cCo9wkdNbXgR9VRm"} -{"name":"download (1).mp3","date":"2024-02-18T01:07:55.743Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3","type":"audio/mpeg","size":6227366,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdownload%20(1).mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"GUN6DCqlRr6SCsv0"} -{"name":"Untitled Project (22).jpg","date":"2024-02-19T15:27:04.097Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg","type":"image/jpeg","size":34686,"imageWidth":159,"imageHeight":159,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg","thumbnailWidth":159,"thumbnailHeight":159,"uuid":"QzQilm4F3P6jalgR"} -{"uuid":"x22blklePMGQRwIA","deleted":true} -{"name":"videoplayback (5).mp4","date":"2024-02-21T15:51:31.894Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(5).mp4","type":"video/mp4","size":2213386,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(5).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"q6L0WZWbnI2dyDzS"} -{"name":"arrow.png","date":"2024-02-21T17:00:37.425Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/arrow.png","type":"image/png","size":20446,"imageWidth":500,"imageHeight":500,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Farrow.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"ZUGJVJXduGCYUybX"} -{"name":"arrow2.png","date":"2024-02-21T17:00:40.066Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/arrow2.png","type":"image/png","size":20272,"imageWidth":500,"imageHeight":500,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Farrow2.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"vTxD8Cdq5AZzpZHG"} -{"name":"2024_01_29_0rx_Kleki.png","date":"2024-02-21T17:30:37.147Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0rx_Kleki.png","type":"image/png","size":44308,"imageWidth":512,"imageHeight":362,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0rx_Kleki.png","thumbnailWidth":330,"thumbnailHeight":234,"uuid":"RyxRk17SDpdmFzRs"} -{"uuid":"RyxRk17SDpdmFzRs","deleted":true} -{"name":"2024_01_29_0ry_Kleki.png","date":"2024-02-21T17:30:52.978Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png","type":"image/png","size":78166,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0ry_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"02ssJF2Tzrmn3sTQ"} -{"uuid":"02ssJF2Tzrmn3sTQ","deleted":true} -{"name":"2024_01_29_0rs_Kleki.png","date":"2024-02-21T17:31:06.919Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0rs_Kleki.png","type":"image/png","size":49959,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0rs_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"HqLijl5c1PuEAXz6"} -{"uuid":"HqLijl5c1PuEAXz6","deleted":true} -{"name":"2024_01_29_0ry_Kleki.png","date":"2024-02-21T17:31:20.813Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png","type":"image/png","size":78166,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0ry_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"teEHfjowTA5oXZNX"} -{"uuid":"ULDBE338jPz5CztZ","deleted":true} -{"name":"onetransparentsingulardamnfuckingpixel.png","date":"2024-02-22T02:16:19.353Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png","type":"image/png","size":81,"imageWidth":1,"imageHeight":1,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png","thumbnailWidth":1,"thumbnailHeight":1,"uuid":"ckPJEBh7eEJWdxnK"} -{"name":"primal.webp","date":"2024-02-22T11:52:43.032Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp","type":"image/webp","size":56824,"imageWidth":350,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fprimal.webp","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"cfHcvjVbbDfZh8xc"} -{"name":"image.webp","date":"2024-02-22T11:52:45.689Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","type":"image/webp","size":59336,"imageWidth":281,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fimage.webp","thumbnailWidth":265,"thumbnailHeight":330,"uuid":"9yXl5YIjYKceliFg"} -{"uuid":"ctTmChYwrALlsYSY","deleted":true} -{"name":"locked.png","date":"2024-02-22T11:55:29.342Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked.png","type":"image/png","size":18202,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"n8yNyvfqwb7DnXAi"} -{"name":"tv.png","date":"2024-02-22T15:17:55.011Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png","type":"image/png","size":106896,"imageWidth":600,"imageHeight":600,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftv.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"IZOWYASNX0WOguf8"} -{"name":"MOSHED-2023-12-14-17-8-14.gif","date":"2024-02-22T16:22:04.966Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif","type":"image/gif","size":710884,"imageWidth":182,"imageHeight":182,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif","thumbnailWidth":182,"thumbnailHeight":182,"uuid":"zoDYKbRylm4uPSua"} -{"name":"skype.png","date":"2024-02-22T16:23:57.464Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png","type":"image/png","size":135963,"imageWidth":2400,"imageHeight":2435,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fskype.png","thumbnailWidth":326,"thumbnailHeight":330,"uuid":"H8TxN9mqnMgaTfLw"} -{"name":"2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","date":"2024-02-22T16:25:46.196Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","type":"image/png","size":163198,"imageWidth":1200,"imageHeight":1200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"BETXanMl4Oa3nyk2"} -{"uuid":"9yXl5YIjYKceliFg","deleted":true} -{"uuid":"H8TxN9mqnMgaTfLw","deleted":true} -{"name":"skype.png","date":"2024-02-22T17:39:54.494Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png","type":"image/png","size":37427,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fskype.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"f8Ge23pxSgxIHP3y"} -{"name":"image.webp","date":"2024-02-22T17:39:56.560Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","type":"image/webp","size":76573,"imageWidth":300,"imageHeight":300,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","thumbnailWidth":300,"thumbnailHeight":300,"uuid":"T4mvFRGVmo7ZSS3r"} -{"name":"locked2.png","date":"2024-02-23T18:43:14.287Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked2.png","type":"image/png","size":17278,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked2.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"M9o7ylMUafge5ugm"} -{"name":"select.png","date":"2024-02-23T19:54:31.992Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png","type":"image/png","size":8705,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fselect.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"VUgg69AS6qvPYYm2"} -{"name":"locked!.png","date":"2024-02-23T19:54:35.601Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png","type":"image/png","size":9307,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked!.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"9TbrgbxQ4qWp7wo8"} -{"name":"selected.png","date":"2024-02-23T19:57:48.075Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png","type":"image/png","size":10342,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fselected.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"FOpbj7lZQ46siJhg"} -{"name":"Coca_Cola_Espuma.mp4","date":"2024-02-25T21:05:14.047Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Coca_Cola_Espuma.mp4","type":"video/mp4","size":104064,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FCoca_Cola_Espuma.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"FGE2VR7615Lfujp8"} -{"name":"channels4_profile.jpg","date":"2024-03-01T20:16:47.088Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/channels4_profile.jpg","type":"image/jpeg","size":99589,"imageWidth":900,"imageHeight":900,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchannels4_profile.jpg","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"jd7joNLFJLt9pfED"} -{"name":"2024_03_02_0yw_Kleki.png","date":"2024-03-03T00:26:41.538Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki.png","type":"image/png","size":2141,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"th3bRPzSTorKXKDi"} -{"name":"2024_03_02_0yw_Kleki (1).png","date":"2024-03-03T00:26:52.528Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki%20(1).png","type":"image/png","size":7139,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki%20(1).png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"p9YoKuARaRk3B841"} -{"uuid":"txSk7RsRJ33ZgL0R","deleted":true} -{"name":"videoplayback.mp4","date":"2024-03-03T01:45:53.601Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp4","type":"video/mp4","size":2796319,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"NKyN5jkpsVkhg3Yl"} -{"uuid":"q6L0WZWbnI2dyDzS","deleted":true} -{"name":"undertakers-bell_2UwFCIe.mp3","date":"2024-03-12T18:42:39.839Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/undertakers-bell_2UwFCIe.mp3","type":"audio/mpeg","size":68055,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fundertakers-bell_2UwFCIe.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"u6xFAcMANHBQhPTB"} -{"name":"aaaaaaaa-online-audio-converter_r9waVUO.mp3","date":"2024-03-12T19:17:49.219Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/aaaaaaaa-online-audio-converter_r9waVUO.mp3","type":"audio/mpeg","size":17807,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Faaaaaaaa-online-audio-converter_r9waVUO.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"aNcuRqu2nQzZStT2"} -{"name":"metal-pipe-clang.mp3","date":"2024-03-12T19:17:53.637Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/metal-pipe-clang.mp3","type":"audio/mpeg","size":45694,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fmetal-pipe-clang.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ro1Gfn5NPJDSpUUK"} -{"name":"vine-boom.mp3","date":"2024-03-12T22:02:49.499Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/vine-boom.mp3","type":"audio/mpeg","size":21230,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvine-boom.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ebMorJE4l2U0t6ec"} -{"name":"tmp_7901-951678082.mp3","date":"2024-03-12T22:02:54.624Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tmp_7901-951678082.mp3","type":"audio/mpeg","size":16425,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftmp_7901-951678082.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ApoIUl7SyuyEaopN"} -{"name":"emotional-damage-meme.mp3","date":"2024-03-12T22:02:59.660Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/emotional-damage-meme.mp3","type":"audio/mpeg","size":54262,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Femotional-damage-meme.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"UNGgdWN3md0VrWpz"} -{"name":"discord-notification.mp3","date":"2024-03-12T22:03:03.356Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/discord-notification.mp3","type":"audio/mpeg","size":8301,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdiscord-notification.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"NCiDWuamdHpEV71a"} -{"name":"wrong-answer-sound-effect.mp3","date":"2024-03-12T22:03:15.813Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/wrong-answer-sound-effect.mp3","type":"audio/mpeg","size":19479,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fwrong-answer-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"cvaZ88hmjymDoYyl"} -{"name":"clash-royale-hog-rider.mp3","date":"2024-03-12T22:03:19.656Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/clash-royale-hog-rider.mp3","type":"audio/mpeg","size":70145,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fclash-royale-hog-rider.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"58kvJm1P0eAgy2zu"} -{"name":"goofy-ahh-car-horn-sound-effect.mp3","date":"2024-03-12T22:03:24.188Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/goofy-ahh-car-horn-sound-effect.mp3","type":"audio/mpeg","size":49456,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fgoofy-ahh-car-horn-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sqlTlpMYSaoC5Ibw"} -{"name":"tf_nemesis.mp3","date":"2024-03-12T22:03:29.502Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tf_nemesis.mp3","type":"audio/mpeg","size":73813,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftf_nemesis.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"pQcX3TfMLczzdXm0"} -{"name":"chinese-rap-song.mp3","date":"2024-03-12T22:03:35.151Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chinese-rap-song.mp3","type":"audio/mpeg","size":160451,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchinese-rap-song.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"UG4BHOkrbtySjMoI"} -{"name":"fire-in-the-hole-geometry-dash.mp3","date":"2024-03-12T22:03:40.367Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fire-in-the-hole-geometry-dash.mp3","type":"audio/mpeg","size":31680,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffire-in-the-hole-geometry-dash.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"RxWARK12ebQVuh9e"} -{"name":"water-on-the-hill.mp3","date":"2024-03-12T22:03:47.326Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/water-on-the-hill.mp3","type":"audio/mpeg","size":13100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fwater-on-the-hill.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"6lJLNPCsgJCtbgrd"} -{"name":"taco-bell-bong-sfx.mp3","date":"2024-03-12T22:03:52.201Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/taco-bell-bong-sfx.mp3","type":"audio/mpeg","size":31599,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftaco-bell-bong-sfx.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"wdvpWAE7Px1X3Z6R"} -{"name":"dun_dun_1.mp3","date":"2024-03-14T15:54:39.063Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/dun_dun_1.mp3","type":"audio/mpeg","size":21607,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdun_dun_1.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"RukfNSPWQfBw87v2"} -{"name":"holy-moly-emoji.mp3","date":"2024-03-14T15:54:42.780Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/holy-moly-emoji.mp3","type":"audio/mpeg","size":22567,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fholy-moly-emoji.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"B3qwwfOmo4IqDjky"} -{"name":"spongebob-boowomp.mp3","date":"2024-03-14T15:54:49.245Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spongebob-boowomp.mp3","type":"audio/mpeg","size":23751,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fspongebob-boowomp.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"WKAEtNX56P5Yjl6G"} -{"name":"bad-to-the-bone-meme.mp3","date":"2024-03-14T15:54:54.343Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bad-to-the-bone-meme.mp3","type":"audio/mpeg","size":41346,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fbad-to-the-bone-meme.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"GE5BxezBXE6OeL3d"} -{"name":"feet-gd.mp3","date":"2024-03-14T15:54:59.794Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/feet-gd.mp3","type":"audio/mpeg","size":8352,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffeet-gd.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"8mtGRsAwmu5czOoy"} -{"name":"5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","date":"2024-03-20T22:15:57.366Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","type":"image/png","size":66868,"imageWidth":1536,"imageHeight":951,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","thumbnailWidth":330,"thumbnailHeight":205,"uuid":"XP09HX2tGTiXNXFs"} -{"name":"2024_03_26_0zp_Kleki.png","date":"2024-03-26T23:55:49.798Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_26_0zp_Kleki.png","type":"image/png","size":8852,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_26_0zp_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"xFkrHKnI6qOjWIB7"} -{"name":"image_2024-04-11_161031965.ico","date":"2024-04-11T18:41:32.273Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image_2024-04-11_161031965.ico","type":"image/x-icon","size":225726,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image_2024-04-11_161031965.ico","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"b73O6MpXAdhV1Rur"} -{"uuid":"XfFWeHV5t1gcuE4J","deleted":true} -{"name":"Action Agenda - Killa DFX Edit.mp3","date":"2024-04-17T11:10:44.240Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3","type":"audio/mpeg","size":7596960,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FAction%20Agenda%20-%20Killa%20DFX%20Edit.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"goq6Nz3Otdd2T6CZ"} -{"uuid":"RsOUyfm1cBYSqbw0","deleted":true} -{"name":"Apotheosis.wav","date":"2024-04-17T11:13:48.783Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.wav","type":"audio/wav","size":33796140,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FApotheosis.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sdKc4c16V8kOoffG"} -{"name":"Depredation.wav","date":"2024-04-17T11:51:30.584Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation.wav","type":"audio/wav","size":39784492,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"vMjHBJ94XqKWFz9b"} -{"name":"2024_04_17_0gh_Kleki.png","date":"2024-04-17T12:23:56.170Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png","type":"image/png","size":2144,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"dAHNcl4YUXtrnYNr"} -{"uuid":"sdKc4c16V8kOoffG","deleted":true} -{"uuid":"vMjHBJ94XqKWFz9b","deleted":true} -{"name":"8mb.video-tQi-0UoaHVvl.mp4","date":"2024-04-18T22:14:20.996Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/8mb.video-tQi-0UoaHVvl.mp4","type":"video/mp4","size":18092799,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F8mb.video-tQi-0UoaHVvl.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"qbGOtBvcJcjg37V9"} -{"uuid":"qbGOtBvcJcjg37V9","deleted":true} -{"name":"Screenshot_2024-04-12_at_2.52.02_PM.png","date":"2024-04-19T10:54:45.626Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screenshot_2024-04-12_at_2.52.02_PM.png","type":"image/png","size":72691,"imageWidth":272,"imageHeight":366,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreenshot_2024-04-12_at_2.52.02_PM.png","thumbnailWidth":246,"thumbnailHeight":330,"uuid":"UmCvpyaMKwvJtjI9"} -{"name":"videoplayback (4).mp4","date":"2024-04-19T10:56:39.084Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(4).mp4","type":"video/mp4","size":258165,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(4).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"DGrL98ImDItr7mJG"} -{"name":"Depredation V2.mp3","date":"2024-04-19T11:12:12.474Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3","type":"audio/mpeg","size":8288129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation%20V2.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"6LtgWCgUdzzqE3hr"} -{"name":"Apotheosis (1).mp3","date":"2024-04-19T11:16:59.376Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis%20(1).mp3","type":"audio/mpeg","size":7040129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FApotheosis%20(1).mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ku50xwnoZ8ABjNcJ"} -{"name":"2024_04_22_0ep_Kleki.png","date":"2024-04-22T11:40:03.892Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0ep_Kleki.png","type":"image/png","size":2169,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0ep_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"KtLhCRh5D7z40ufq"} -{"uuid":"KtLhCRh5D7z40ufq","deleted":true} -{"name":"2024_04_22_0fb_Kleki.png","date":"2024-04-22T11:43:54.204Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0fb_Kleki.png","type":"image/png","size":2165,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0fb_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"Zq5aBpo0JAKsFPSd"} -{"name":"Voicy_Slap Battles Killstreak Kill.mp3","date":"2024-04-25T11:47:23.190Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Voicy_Slap%20Battles%20Killstreak%20Kill.mp3","type":"audio/mpeg","size":45171,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FVoicy_Slap%20Battles%20Killstreak%20Kill.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"YE7Wbxb7eY4uN03N"} -{"name":"1165825970528325682.webp","date":"2024-04-26T18:39:24.280Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp","type":"image/webp","size":1098,"imageWidth":45,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp","thumbnailWidth":45,"thumbnailHeight":48,"uuid":"bAX0kJLTMphe3F8v"} -{"name":"1165934432608321546.webp","date":"2024-04-26T18:39:28.932Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp","type":"image/webp","size":968,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"Ci3JnJpEDmg4VF1c"} -{"name":"1165934167280848969.webp","date":"2024-04-26T18:39:33.284Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp","type":"image/webp","size":1582,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"HTqsPOJz4I9rlBGh"} -{"name":"1165826077843796018.webp","date":"2024-04-26T18:39:38.841Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp","type":"image/webp","size":950,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"eV1sBWslSmqgAf1m"} -{"name":"1165825970528325682l.webp","date":"2024-04-26T18:40:07.621Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp","type":"image/webp","size":864,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"neN7tKpXt8DS0TpV"} diff --git a/LICENSE b/LICENSE index f901c2e81..791d0c458 100644 --- a/LICENSE +++ b/LICENSE @@ -1,12 +1,12 @@ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE Version 2, December 2004 - + Copyright (C) 2004 Sam Hocevar Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. - + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION diff --git a/README.md b/README.md index 2b6481f00..fa25247ae 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Open Source Arras +Logo ![GitHub Release](https://img.shields.io/github/v/release/Taureon/aps-plus-plus) ![Discord](https://img.shields.io/discord/1004907608018264094) @@ -31,7 +32,7 @@ Create a new project and choose to import one from GitHub. When prompted for the Navigate to `server/config.js` and replace `localhost:26301` with the URL for your project. (For Glitch users, it's `your-project.glitch.me` (replace `your-project` with the actual name of your project, it should be above settings)). -**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"`. Glitch doesn't currently support Node 18.** +**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"` and change your port to something more generic like 3000 or 8080.** After doing that, your server should be ready! @@ -44,4 +45,4 @@ After doing that, your server should be ready! ## Other Links - [Our Discord server](https://discord.gg/kvCAZfUCjy) -*p.s. if something goes terribly wrong it's not our fault* \ No newline at end of file +*p.s. if something goes terribly wrong it's not our fault* diff --git a/changelog preview b/changelog preview deleted file mode 100644 index b15127bb8..000000000 --- a/changelog preview +++ /dev/null @@ -1,499 +0,0 @@ -
    -

    Update 3.1

    - [2024] -
      -
    • fixed date since counter
    • -
    • Added BackShield & Mirror Shield
    • -
    • Fixed Tag Gamemode
    • -
    • Removed Stats Temporarily
    • -
    • Changed Bot Leveling
    • -
    • Nerfs & Buffs
    • -
    • Reorganized Entities
    • -
    • Added New Color System
    • -
    • Fixed Color System
    • -
    • New DFX Maze Map
    • -
    • Added Apotheosis V2 & Depredation Remastered V2 By Deltafyrex and Killa By Action Agenda (DFX Edit) To OST
    • -
    • Fixed Siege
    • -
    • Fixed Movement System
    • -
    • Fixed Death Sounds
    • -
    • Revamped Menu Popups
    • -
    • Added TwinSniper Branch And More to Acid And Chiller Branch
    • -
    • Fixed Music Bug, And Added Aura Basic, Jump Smasher And Whirlwind To The Main game
    • -
    • Fixed Shields
    • -
    • -

      Holay Molay

      -
    -
    -
    -

    Update 3.0

    - [2024] -
      -
    • Added Clubbin
    • -
    • Testing Achievements
    • -
    • Added Reset Achievements Button
    • -
    • Added Start Achievement
    • -
    • Added and Fixed Achievement Details
    • -
    • Added Disconnect, Lag, And Killstreak Achievement
    • -
    • Removed Kill Achievement cuz it dont work
    • -
    • Added New Special Achievement Type
    • -
    • Added Special Piss.io Achievement And Funny Skype Achievement
    • -
    • Re-Added And Fixed 5 Killstreak Achievement Again
    • -
    • Added Server to Client Functions
    • -
    • Added 10 Killstreak Achievement
    • -
    • Changed Debug Menu
    • -
    • Added Kill Amount In Debug
    • -
    • Added Audio Visualizer in the title screen
    • -
    • Fixed Embed Not Working Properly
    • -
    • Fixed Bug Where Audio Visualizer Appears In Game
    • -
    • Added Token And Discord Achievement
    • -
    • Added Achievements Tab
    • -
    • Removed Ach Testing
    • -
    • Added Credits Button
    • -
    • fixed credits interfering with changelog
    • -
    • added credits-changelog animation transition
    • -
    • moved credits button (its 1:08 am im soooooo tired)
    • -
    • Fixed Game Breaking Bug
    • -
    • Added Contagion Branch To Subduer & Trapper
    • -
    • Added Longing And Resurgam By Amaryllis To The OST
    • -
    • added credits ach
    • -
    • Added 2 New Branches For Desmos
    • -
    • Testing Skins
    • -
    • Added Beta Skin Menu
    • -
    • Fixed Skin Bug
    • -
    • Fixed Crashing On Respawn
    • -
    • Added More Detail To Skin Menu
    • -
    • Added Cat Code and Chickensandwhichman Skin
    • -
    • Added Daily Tanks
    • -
    • Added Plenty New Skins, New Achievements And Made Achievements Unlockable
    • -
    • Added Skater & Hitman
    • -
    • Added New "Duality" Map
    • -

      Update 2.93 [2024]

      -
    • David Goggins Event
    • -
    • Updated Menu
    • -
    • Added Marksman Branch To Sniper And Car Branch To
    • -
    • Added Trollface Emote (add --troll to the end of a chat message)
    • -
    • Added Waterfall, Acid, Cooler, Rainmaker And New Options Layout
    • -
    • Added Notes Tab + Live Counter
    • -
    • Added More Customization, Graphics, Helecopter And Fixed Music Bug
    • -
    • Added Reverie Branch And Injector
    • -
    • Added Debugger Menu
    • -
    • You Can Now Color Messages With §
    • -

      Niners fucking lost Again Bruh...Fuck Taylor Swift

      -
    -
    -
    -

    Update 2.9

    - [2024] -
      -
    • Added Motor
    • -
    • Added Kivaaharatedas (i did not spell that right)
    • -
    • Added Equilibrium, Revobrid, Subverter
    • -
    • shrapnel testing
    • -
    • removed unfinished aimbot/boosting testing
    • -
    • Added Basic Hybrid Tier 3 branch
    • -
    • Bug Fixed Colors
    • -
    • Added Tanks of my friends and tank soundboard support
    • -
    • Added the rest of the Basic Hybrid branch (tier 4)
    • -
    • Fixed changelog not appearing
    • -
    • Added beta music support including 5 songs
    • -
    • changed start button look to not shade out and actually work like a button
    • -
    • fixed debug key (again)
    • -
    • fixed screen tearing
    • -
    • worked bullet spawn position
    • -
    • Better organized dev menu and changed the way utilities looks
    • -
    • Added music recognition in the debug key to see the song name & artist
    • -
    • Added new song (Anybody can find Love (except You) by hkmori
    • -
    • fixed debug not recognizing a song and not updating after a song is finished
    • -
    • Testing wall colors/effects
    • -
    • Added Shield Turrets
    • -
    • Added new tiles (dance floor+black)
    • -
    • added new "banquet" map
    • -
    • Finished Revolutionist Branch
    • -
    • Added Inception & Albuquerque
    • -
    • im a fucking moron
    • -
    • Added Machceptioner & Tailgator
    • -
    • Added Interceptor, Twinceptioner, Inceptionist branch, hybrid/auto ver of inception branch
    • -
    • Added Desmos/Inception/Bascrid Ception
    • -
    • fixed the ceptionist turrets/autobullet turrets
    • -
    • nerfed shit
    • -
    • fixed some upgrades not appearing
    • -
    • no players (dead game and nobody plays is sadly)
    • -
    • so it turns out i forgot to give twinceptionist the right bullets so i fixed that :/
    • -
    • fixed flankcept branch turrets
    • -

      Update 2.91 [2024]

      -
    • Added the subduer branch
    • -
    • Fixed The Rest of the menu buttons and fixed sound effects
    • -
    • Added flankduer
    • -
    • Added Binary branch, Pathogen branch, mitochondrion branch, Subduer-Hybrid branch and Auto-Subduer Branch
    • -
    • fixed missing upgrades
    • -

      Hey! vsauce, Michael here. the game is stable and non buggy...or is it?

      -
    -
    -
    -

    Update 2.8

    - [2023] -
      -
    • Tank Adding Wave Two (ex. hadron, dictator, railgun + more)
    • -
    • Debug Key Bug Fix (how ironic)
    • -
    • Fixed Rng Images Bugging Out
    • -
    • Testing Whirlwind Branch
    • -
    • Fixed Maze Gamemode
    • -
    • Added Tooltips (beta)
    • -
    • Added Status Effects (beta+devevent)
    • -
    • Added Addon Support
    • -
    • Fixed button Shadows
    • -
    • Upgraded APS++ Updating Speed
    • -
    • New Mouse Controller
    • -
    • Keybind Fix
    • -
    • Enter can cancel a chat message being sent
    • -
    • CoNgReGaTiOn JuMpScArEs
    • -
    • Images on Tanks/Sound Effects For Tanks (dev)
    • -
    • Blackhole (dont ask just roll with it)
    • -
    • P A P Y R U S
    • -
    • Fixed Some Lag Holding Down Server Speed
    • -
    • 109.43.21.5.14
    • -
    • Added Desmos Branch
    • -
    • Theres Prob More But I Forgor
    • -

      wahhh... (i forgor why im crying)

      -
    -
    -
    -

    Update 2.7

    - [2023] -
      -
    • Debuffed Many Tanks
    • -
    • Migrated to new host
    • -
    • Removed all Nero Exclusive Tanks From The Game (for now anyway, dont worry)
    • -
    • Added "revolutionist" to testbed"
    • -
    • Massive Testbed overhaul
    • -
    • Added a funny randomly generated image on the start screen
    • -
    • Readded Sounds, design and other previous widgets
    • -
    • Hired new devs
    • -
    • did some tweaks to bots
    • -
    • got rid of the "nero" theme and the server list
    • -
    • added easter eggs
    • -
    • added random funny image
    • -

      Update 2.71 [2023]

      -
    • Tank Adding Wave One (ex. auto branch, revolutionist, cloner + more)
    • -
    • plenty of new dev features
    • -
    • added gamemode polls (once theres enough people)
    • -

      There are Easter Eggs All Over The Main Menu, You Might Find Something...

      -
    -
    -
    -

    Update 2.6

    - [2023] -
      -
    • replaced smashers origional upgrade path with the "armoury" tree -added lancer and smasher upgrades to armoury tree
    • -
    • added "Sword", "Injector" and "Fencer" to lancer upgrades
    • -
    • buffed drone tanks, twin tanks & tank health
    • -
    • added "Dictator" -added "Tripwire"
    • -
    • added "Barricade", "Twister", "Cyclone" and "Architect" -added "Tri-Trapper" tree -added "auto tritrapper", "auto armour" and "autolancer"
    • -
    • added "eagle" and "bulwark"
    • -
    • updated debug menu
    • -
    • removed hivemind from basic
    • -
    • added cloner upgrade
    • -
    • added hivemind and "splitter" to cloner upgrade
    • -
    • added "auto cloner", "auto flamethrower", "flamethrower hybrid" and "lancer hybrid"
    • -
    • updated colorscheme and other color related things
    • -
    • updated teams on 2tdm after 3 team bug -added all new Rock Maze gamemode
    • -

      Ryerson Loves Burger King

      -
    -
    -
    -

    Update 2.5

    - [2023] -
      -
    • added new tanks into beta for further testing
    • -
    • hired new devs
    • -
    • neroio discord is up
    • -
    • added new mascallenus tank and section
    • -
    • hired new beta testers
    • -
    • added new easter eggs
    • -
    • tested 2nd server opening
    • -
    • added "Scanner" and "hadoken"
    • -
    • nerfed Hahaugobrr
    • -
    • promoted lucas medieros to co-owner of the game
    • -
    • demoted a few staff
    • -
    • added 2TDM game mode
    • -
    • woomy event is back! now with free access to testbed
    • -
    • added "flankdrive", "twindrive" and "machinedrive"
    • -
    • fixed trapper look
    • -
    • added "infantry", "musket", "Traprid", "Auto Traprid", "Snigrav", "AsWdragafora", "Assasolak", "Builifacate", "Rifagiulus", "Auto Snigrav"
    • -
    • added "flamethrower", "Baker", "Wildfire" and "Equinox"
    • -
    • new nero.io default theme instead of using arras's
    • -
    • added insane af tanks to testbed
    • -
    • added "lancer"
    • -

      Open Na Noor

      -
    -
    -
    -

    Update 2.4

    - [2023] -
      -
    • added 2 new admin commands
    • -
    • added homing auto Basic
    • -
    • added bosses tab to AIT
    • -
    • bwomp AA $$ €€
    • -
    • added easter egg name colors
    • -
    • added the tanks "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", and "neptune"
    • -
    • added a new boss
    • -
    • added more natural spawning bosses
    • -
    • added "SpawnTrap"
    • -
    • updated bot names
    • -
    • ended woomy event
    • -

      Oh great red Text of the Changelog, What is your Wisdom?

      -
    -
    -
    -

    Update 2.3

    - [2023] -
      -
    • added "maleficator", "stalker", "landmine", "jumpsmash", "speedbent", "heavy3", and re-added "twindrive", "interceptioner", the "drive" subtree to autobasic, plus increased map size
    • -
    • fixed and debuffed jumpsmash
    • -
    • debuffed speedbent
    • -
    • added a public changelog (the one your looking at now)
    • -
    • added the red text
    • -
    • updated sounds and styles
    • -
    • added the "corrupted" button
    • -

      So Hows Ur Day?

      - -
    -
    -
    -

    Update 2.2

    - [2023] -
      -
    • added more tanks into beta
    • -
    • added sounds and updated client backround
    • -
    • Decoration finished
    • -
    • started decoration on migration host
    • -
    • added chat feature
    • -
    • migration big fixes
    • -
    • WE DID IT! MIGRATION COMPLETE!
    • -
    • during migration found multiple small bugs that was fixed
    • -
    • 2nd failed migrating attempt, starting yet another
    • -
    • fixed crashing bug
    • -
    • 2nd attempt at migrating
    • -
    • added random bot and skill classes
    • -
    • made bots more op
    • -
    • fixed a bot bug
    • -
    • downgraded bots
    • -
    • added tank visualizers
    • -
    • buffed bots a tiny bit more
    • -
    • fixed visualizer bug
    • -
    • added "rifle"
    • -
    • fixed "lilfact" upgrade path
    • -
    • added auto "lilfact"
    • -
    • renamed "lilfact" to "spawner"
    • -
    • added secret tanks for update 2.3
    • -
    • minor crash bug fixes
    • -
    • removed "rifle" and "autospawner" from beta
    • -
    • fixed smasher bug
    • -
    • failed "lancer" class attempt
    • -
    • secret tank updates
    • -
    • major bug fixes
    • -
    • rainbow color old client fix
    • -
    • last patches before big update
    • -
    • fixed tiny bug
    • -

      I Know Where You Live

      -
    -
    -
    -

    Update 2.1

    - [2022] -
      -
    • fixed the 2 game crashing bugs
    • -
    • tried to migrate to another server host but yet failed due to unknown reasons
    • -
    • added "speedbent" to beta
    • -
    • updated messages
    • -

      tbh im sad the 49ers missed the super bowl :/

      -
    -
    -
    -

    Update 2.0

    - [2021] -
      -
    • brought the ception tree into beta tanks
    • -
    • figured out that the "ceptions" arent really ceptions
    • -
    • forgot to add the actual way to access it LOL, also added a REAL machine ceptionist as a test
    • -
    • removed ceptionist and drive tanks as they are too overpowered
    • -
    • added lazer guns
    • -
    • stole code from someone elses server
    • -
    • added beta shock and burn
    • -
    • added some secret really stupid tanks
    • -
    • fixed a tank
    • -
    • removed revolutionist for being too buggy
    • -
    • added new auto class branch
    • -
    • added hivemind
    • -
    • bug fixes
    • -
    • major bug that caused no tanks to be added or bugs fixed causing confusion
    • -
    • crashing bug made game unplayable for large amount of time (like a whole 9 months)
    • -

      Whats Up Guys Quandale Dingle Here

      -
    -
    -
    -

    Update 1.9

    - [2021] -
      -
    • testing in progress
    • -
    • approved multiple tanks into the game
    • -
    • did some stupidity and added random stuff and figured out that there is indeed, 12882 lines of code in this project
    • -
    • added some dumb tanks like "mInIfLyInGfAsTeRtHiNgY"
    • -
    • added some cool colored objects on the "AsWdWsA" branch
    • -
    • added a secret tank
    • -
    • messed with some things like homing bullets
    • -
    • removed the homing stuff due to bugs
    • -
    • tried to recreate the "revolutionist" tank from woomy arras
    • -
    • more tests
    • -
    • added auto bullets
    • -
    • added drive tanks into beta testing phase
    • -
    • moved where the secret tank is
    • -
    • debuffed "single"
    • -
    • added "Cascal", "Gunto", "Catalyst", And "Cescav" to beta tanks
    • -
    • added a beta version of the drive tree into the game after some testing
    • -

      What A Dumb Fucking Game!

      -
    -
    -
    -

    Update 1.8

    - [2021] -
      -
    • completed and put the poison function into the game
    • -
    • completed and put the freeze function into the game
    • -
    • created a seprate freeze and poison bullets
    • -
    • added a stun function
    • -
    • added a healing and speed function
    • -
    • added a stun, healing and speed bullet shooting tanks
    • -
    • added the "AsWdWsA" branch
    • -
    • fixed poison cannon
    • -
    • renamed the bullets to respected name
    • -
    • renamed the cannons to a respected name
    • -
    • created a page 2 for the mascallenus
    • -
    • put multitanks into testbed
    • -
    • put multitanks into testbed
    • -
    • organized the tanks
    • -
    • removed public testbed
    • -

      :skull:

      -
    -
    -
    -

    Update 1.7

    - [2020] -
      -
    • added an admin logger
    • -
    • changed the AI color to pink
    • -
    • changed AI to have twin upgrade instead of basic
    • -
    • expanded the map
    • -
    • changed the colors of the spawning player to be random instead of always red or blue
    • -
    • added the tanks "oof" and "oof2" to mascallenus
    • -
    • added the tank "minibee" to testbed
    • -
    • added the tank "hexa trapper" into the game
    • -
    • added the tank "Paint Brush" into the crayon tree
    • -
    • added the tank "brutalizer"
    • -
    • added the premade tank "sidewinder"
    • -

      Share with your friends!

      -
    -
    -
    -

    Update 1.6

    - [2020] -
      -
    • added the tank "tower mech"
    • -
    • added the "AIT" category into testbed
    • -
    • added a way to get back to a basic tank after becoming testbed
    • -
    • added the tank "crayon"
    • -
    • added the two tanks "marker" and "pastel"
    • -
    • added the tank "pen"
    • -
    • added a kill button to testbed
    • -
    • added the tank "highlighter"
    • -
    • added a way to immediatly upgrade into a basic trapper
    • -
    • invited some friends to help code my game
    • -

      Yo shout out to Lucas Medeiros

      -
    -
    -
    -

    Update 1.5

    - [2020] -
      -
    • removed jesus donut
    • -
    • removed DeltaCannon
    • -
    • fixed some bugs with AI's
    • -
    • fixed some bugs with crashers and bosses
    • -
    • added a bunch of testbed tanks into the real thing
    • -
    • removed fairsquare
    • -
    • added flame killa to testbed
    • -
    • removed access to the recently added tanks from testbed to save space
    • -
    • added Boxer to testbed
    • -
    • removed every testbed tank
    • -
    • added categories to test bed like "beta" and "mascallenus"
    • -

      come down today and try some corn, or we will sacrifice your newborn

      -
    -
    -
    -

    Update 1.4

    - [2020] -
      -
    • added Lottery to testbed
    • -
    • added hellblazer and Rocketer to testbed
    • -
    • added Nautilus to testbed
    • -
    • added jesus donut to testbed
    • -
    • experimented with bullet effects
    • -
    • added SleamShot
    • -
    • added TrapHard into testbed
    • -

      LMFAO WHAT A BOZO

      -
    -
    -
    -

    Update 1.3

    - [2020] -
      -
    • added master
    • -
    • added lilfact
    • -
    • fixed bug with bots
    • -
    • fixed bug with lilfact
    • -
    • ADDED PUBLIC TESTBED
    • -
    • fixed some bugs
    • -
    • fixed testbed problems
    • -
    • fixed testbed key errors regarding platform
    • -
    • added helltank to testbed
    • -
    • added DeltaCannon to testbed
    • -

      DrUgS aRe BaD fOr YoU1!1!

      -
    -
    -
    -

    Update 1.2

    - [2020] -
      -
    • server shutdown due to server problems
    • -
    • fixed problem
    • -
    • fixed some more bugs
    • -
    • fixed bug with the upgrades
    • -
    • added 3 pre-made extra tanks (hive shooter, auto assassin, auto cruiser)
    • -
    • added Unlocked
    • -
    • added more ways to get hive shooter
    • -
    • added more ways to get unlocked
    • -
    • added bots
    • -
    • fixed bad bug with Unlocked
    • -

      tbh play a better game than this

      -
    -
    -
    -

    Update 1.1

    - [2019] -
      -
    • added revix
    • -
    • added DeltaGunner
    • -

      OH BABY A TRIPLE

      -
    -
    -
    -

    Update 1.0

    - [2019] -
      -
    • just opened server
    • -
    • testing new tanks
    • -

      Bwomp

      -
    -
    -You've Reached The End UwU ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file diff --git a/features.md b/features.md index cbd7d12bc..0ffa3a086 100644 --- a/features.md +++ b/features.md @@ -174,7 +174,7 @@ It includes all features up to the latest release version. * Definitions Management * Split up into numerous other files, all located in `server/modules/definitions`. * Entity definitions are in `/groups`. - * "Facilitators" (makeHybrid, combineStats, etc.), constants and gun values are in their own files. + * "Facilitators" (makeAuto, combineStats, etc.), constants and gun values are in their own files. * As a requirement, you can now put `"strings"` as references instead of `Class.entity` references. * Added definition flattening, which would improve performance a bit by applying `PARENT`'s definitions directly to the definition. * Definition flattening also checks for entities that do not exist. @@ -275,4 +275,4 @@ It includes all features up to the latest release version. * Dominator Game Mode. * Doesn't kick for invalid tokens, instead just does not give any perms. * Level Bar now shows max level if you have exactly enough score to reach that level. -* Large `SHAPE`s now work. \ No newline at end of file +* Large `SHAPE`s now work. diff --git a/images/favicon.png b/images/favicon.png deleted file mode 100644 index 9f5538b6397aef7d893a22383aa4842892441986..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 81775 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≪+IpQdu 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%0A{#}+RO zc$d%%l~r!8zfFgQ_f{PXu@1MIJxc2pICUOknpuk3YA+Jj%zF+|sFOu!O;7A@V*ZG> zT<0Gscs@Y52gNe)Epf9{-Bq?^qgiS?=9r}R*++(gcsh^DDGIuc z6oi|5N^Fq^#)r!vLil#hwx&ZN(H@8>mi_$%x3=LQg`J$9rD5FkmK~#AE{8Tz z9+9W+hcAK@)~jl|yXWBr*l$1~He7ATdmRM7OlNueKx0ZIrIk$(wSKdl_K zSushkQry*SJRUB1t7hyuvCU}eLG~I?>?xt+YHVFlx*XwdYa6xnr1=uwtQ~Sf@T=E7 zhW_MET@KQEBeQtLO)?a^!c}x8{fz4(L(2;}7a^R~y^BB24(otlQz3btW81zCgTdgN z(P}sB?uCS27AdV(5waBj01WcJq@rCJ2}V_FsK}?Pcg7pP9~RqRH4^ZE=5CTwmro z%S1a~w=5?53cln+lXD)#{=+Kv-@v4>L_%qZc*NJUB2V2+?BV#K*}v3(3}Y4=m!$c7 z`V~qADY;mrTC@0so{7~SCbJ-G=MVPT>>(|*TQ*iLaa#~LdaD&g4PfVl`Z6Y>%yU^2 zpzvjpW?%K@i=M+Y#+HzdT9HXSwh?R>yB%KV(pz&_7FrC26CdD{A^Af~ExTLU{a~jS zT}UmM{{YL$%!+Yruk{CYoKvZg>$}Se#i3%$1+nsnG|S-HVws(OM3=P)=h2XUM9~t% zB{lVfsv?-SY2Jj~*Oo=df5T_ypp=EVw(^hqx|C|`4^p-lTQDX>(Gr$)uhq)uc~hE4 zck?4b8SmY z-iL0~oYR=sZ#Lht-Q2pxFWB!g?!R%T<(lZoWc0{&*Na;Z&HCeK&tEch6p`4B?=Rr* z4`KfRrF5DnOGtI(FXtvIVRg?JJA1F5E7PmX43$?-RQXE!CX%;am|9bXa%3;D*|+dO z{=(Q;E(LuzWuAX0x_p%m>UJI-nxC-)Uc_>UjSxSCc5yF(a4YHBLzw8)`6APB&gz=# zj>#tUL~(APC_~~tIUA*t>dTk@KOzf8<)fSRE7BhPZF>Gn{zMMb*+2Oo5f&c&j diff --git a/images/lratio.png b/images/lratio.png deleted file mode 100644 index d9c07b64be08ff05f5a549c776aeee6932e58103..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 66360 zcmeFYXCPc%*FLVs2%;s79t?vBBVn}BJJAzSqDM_R+v-DpFEU_?pOs3Fm7w5UP! zK6)J`I{(Ri-_P^D&+qy8|N4HKvd`IPt-Z>%_O;iE)X`F*xXE}E4-bz*O;u43504Ow zheu!pxPkj;;j}6n_kr)Kry`G6($Bn(hj$lGO;PSK!fY#p44)3>Ik~yTtQ|gA+hx>ai%r!vM2t_4nC!JJU6^ zwLY`n==153Vbe>4KDP{sRo~U?@7(yLs)Vs|8d-A{UK!yY=U#Q;bar*B^2rp(3{)ae! z?g&bt8jN7;mYvZ2FKGjn>s|j_P6!PFBbJkar;hi(^c#%uy!HR897v=rFU#oOiXU^5K%O*{^zVuPrKWwm zB+0*5|KFpW>>sFQP(c-G|GMmdgpNV1{`<0jkN%$#{%3)3Uh;oN_&XN=FB1NDX#M|B zN6mu(i@b~7K?$1x5QGSq929`W=l?t0gJ#$RDfTtgv@$ToYFckG^ohRrx>pl@g}aYE zNy0t(f-b2CBj(ryokKA znLFd&cK?odT+#z_1TBGU9-)f3#5uazGqn79x(TC&;_R*h!VrYN)d;3=>9_M>tsO6gK|-gS*M3Wk=~>H>D`d4}w7) z!pZo@gNws)km>!++u&b@Nd~`q2RhbrQ61pjYnQ1*EZu1|MwgfV1usDfICo)NZ=P`c z`|9Qp(rIw_rDV3pkpXpsw{YQy6T!VMYYn@RfhljU0 z(TqQVSl<`zlpbQ+DSyinjgzIe%iHYVvar9p08y&Bd}UC+&`7Mm+kG$5*Dsaqgz=yG zQ%G@O>2)C@j#Rb z|9FQ5CsBU}2KrI@!nq%^m}!JO@dTarD|;_1{S)4V95}fA&{B5q?*Iv60q>owu|8A( zk?}l?`nq24-c^iRW7Sf9z29FljmzQ8CMmWyTk(%bABaj)Fx_hXkeq;!VSP^Y16OBg zy8nk9`>%gJz~VE`m&T&T5;gu58_hQX7xFai{ju+IrN2T}t|YtT5K2`ZAR=8 z3*1NGuhQlR?O=pCI^!SbIieBc@6N!bpkxqOVBs)iz`88wQLNDQ8Aw}m|MbYCv$8Y+ zj|rNm?s5sDoNl8nEt_E^Y1RLGW%h8UrVK!CW#QBeGUaTpTz`jp_6g{=no5XgeI=#F znuxhm_%_a?5HdRw4o+uvz96-oCPgFU*RKV-P3}}PZ6l^$|79XEJY1j_SKO}jk47}c991vaO_J#Q&DYN%FY?y;N@VQ^=?gZn z_%^HQ_XzOD;;EWhB8I80QN-u#5)n^~TI8d~Lj3;YGf@t$2-u>}{VXGy0kN>AOCHi8 z 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

    hcY(-Z|f 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%0DCMsWA*%R8y=hcM2;LtOxVZb36_sI?bf&-1 z?0)>BtVD)XiAS=J{7M%pVyr^CyO+TVgn5YqB}KS z`r)eE%GUAa5&5q5gAE;DhV+^JKC&gqTZq>RD>M@~wxA1lGKr4gH+?y}dwJ{Aqv{vU z(tu??NCyC@-3ST*q`?f_k{@l;OXN&0_jx{CnGzAp7?c8VSc7*CYE~4W`CixXG$#PS zGIgz#w6~*wy4_l3mwdpzMIjoJ%K~A(_ql}3(MX2+nL)RAFI+%14O>MT%9667WyT?E zncFRw!6T)2eDBWrUXV?iC7#?L%$6^(EQ79_*OZ7X(>;ybvfK){Q;LVY=K~-eKoHK& zM93H(F#r&wHh+J-=y&hr<5yQ>)?&H~KP(M*ER7=(r`rlk-E5B|@?Cn!D0bYv`VT8? z82YI(76}D_JY{77k$}Fm=6^2nq3>v2FIW&{{67l@Ny`PDH&2*U4xa!DGAIZD2)pG_ zgHQzjPUJ&woGrd7X3}i!Yj=HOQnNW>S6-=aJ!=Ln8FIAM%9|T!XKJyHPUZB2{1*inSe7raL4?{P+n!|-1cA~N zHUKJPI2C}dCM^gmO2?m>l}{f`&wnRBvv^wV!?v;bMT$uAl8T>36j_h8@?VKN zOpb0%S-Z#$Q)%lQ$rXn4S7aCo2ry&hxI?=!(qT)HQYxc6Z#)rQBM@NhAM_+QjT;;& z6IR!TGC@oCP=O*UB{&X)k&-Z8x|@@bA1zVl+LWjxso2Fg(~d6#mn$=djoVrz9GNrk zwS*yt>Z2k!gvww>D=8VAQR!ZWK-EH-$VwKCE=o{`$8)Yk5+iiMhi#zGl z%2`-~KydhrplkFFR5$>D!2+O3U(-RU9K?c~Ilk$Le|{MP*nvF^fHXRQ5gY`dfm%WW zp|lUsa!^@@yfGwr{9pIU)xXEq2g29G*r( zB#nmED6F=9*|qtEH%RbQS{}p(-co|jt24+7!~viLU0=KPVqY+TdgyI9wt38k#s{Ft zNi$%K@uPvkh$4srO}dC{>7iZy(eCR>FGa~m?RbyAjCjDur&nftM5gbNnjmzh^u4(jgxy5^5yLAQ~RCTm)CYN4+qHDiC6JykOg z<=V+;`#n~%)NGy9Jg9(AtpX>A!IaZ9LlqS19Y^|0HjY?v+ zB1Yv(WERM-|MIl*%W%Br;0<1Bfbc~SN{}E)$IaJ27e*E=&=rBcIVN{>YazuBkOlz! z>-`5bM5~XIPAqI^`}w^cMjr2a?zXYL`QUl)OJPbnvx^|}gNV(sUvIMHj(MWq^yv4A zY-s8^u6ms{nLp^hEFNt=FT9M2X?s8ZvAFVcU%rHf&X0hK7TS+gTjQor=uAo56z=)I zYa%D#T&8YUo_L~lxQ_aVAZg(G*$0Z;wTt{yPyq-4UTt=1HSy3ukrd+!< zl>3v45nudX`_!+Li7EVk5~^!!#9jA+V**|bO|1Hm_cVRd;~lkyMVkE&+K+wM;Qb8) zDEA-;3Xx2D*JUWJ#fMiVN9JuGzn)BDo!(O4);&^v+Z4NP{Y~7<@JIG&w5jLVPxgZ# z!tM?f5FJQY5a1Z}ho}x>hydYxJSa2h&w>Edmw|HW1+6rf;VCxPx90d`k zS@OwY1z|s<0#NcOu9bWYbf_JPfTc75#8ClqDuSnrr>z#CtzlqDgHMt0wV353PLE+_q_85!(%)yG;${O5gY$_PGbfUF+vS-6l-r7pKc?kiP8AcW-!%2<751ri93Ae@IxS)fXmWR0e8qd)S5C!4 zf~V?yb9j4gI+fvW2Y?QeC#?l;{EgoLzono+j8I{vI6Xup<=zut_P!kZoY7o{@nJ}V zt`wYi*W-M)bzj~4@t#R0_gOpQ^V)Bbta~W2p!%W$j?XBS0MOYzerKcqa~GdKQ`g44 z^r^qVtSKwBP9lE(uBO_v22OVm&dfQ7&}a`Mp>$`v1TLge7MTUD#%tch&BR_g64l+2(jGTB>nx@^+kVs)wX%+A4OG0<%=hM zpC+Yp8@glGXwT4Zy7wV-%+HMD>xBEbX?4_&(yT`WzTnLMEP2CdI#i$=pO3JcPfi*T z?Dzw*dkcWzNwb7fBBEGHs>ozZ%g*XYhj%=G`DcQ+upn(XYG8(FqW{jibc#dLaHixS ztI2bmuLCuR;RXPBfnbUM%3XP2%FO1o&9PrrnaE}QZK!O>bR(U{{}4J=5yh>jtJ|6P zwYojS^JTPAPe~LjzQL+3*Q|Z&r};G>_YbJjfFm*pK+gab0+fC46gIba2sf^S09qmN-99+-B|x(18x zEOOQwd#_H~O+ZJ2IaytdnZIaL|44Bvqi}4K%;>ZA(J$i_7!3brD0}9K_p4Xv=iRq0 zA-6@q=mO#gP-FQ4{JYZEO%?zh`*SLfO=XBP-A_v)uP4B*nhR15@=m##k_F zf=>B*E|7wq_(D2`0d44U_U%fK6&JHsqR7Spc3Xp}v>!s_cFw!{WCg8W(wn2)KQ;PC ziH4kCGFLZdayu1f9PF1LEt(T@zGV3%vw4BuFXVv+`Y$lg1Zh%Hk^}DouCd${RLd7o zc&X>(jIZ>Hn9_2LAZk#B|D&K%Vx}Fxvo~JrLil^-%sZ#-O{0JL-$cD^UADepEhvnlh%yvtRoPXeS3xeQ-z$k+e z3glR^;DF7W1l=coD`4;O>v7hR++*#dk|!hqJM{AOqG98_n_6dVr&E#MBeR~Jz4nse)<&Mhhwh}gVb+_{WJ8g3Ry<;>J4eYq4@tS%crmg3jZfA_=d-RBG zF-(xr_s7ad)lZ1t`FMkknrog&!A8p;=4ifk;(&(~{Dc4s1U#0&L`MOxk20=(IVu_y zLd1wp$WKfH6BLrxB4ywckh#qSmu1GV1P?E;z*#8hs4H`KU#@)8?6T18GV8+k#S>cM zn|13l>x25z$S=8*yLVqV@#O#XcHuvf`rp)lt?I&lA_Z0u4D&w={yp|@;Qt2mXa4`Z z{%?@nfE8NeCwJ>sM1#`M=r7e6di0nLk@|9h%~zhiW}}q8;x>HWwK{v`FhTMWd~VmA z+%R=~&isFGI#)#@8R4;M<@QY|fHMosW=jx8ny?8n-(sa%`w5Q*@utK=uY`{68S)iDvy1 zQPTO;S9OIHd**TnBP`ziUHH$(VT04x92% zuF0D&H$25*-+!QB?&u-#uza(<&-ok#3v{@Hf zY%dCCqNe?Zr$@-gz64UoC~|w^ophJ~a9M76a%ktwzpiG>*jSbnf&TPM3~YT9q7rnH z_Lxv%< zPgKE8BQR*-R-*6f_HZO>1+aPMM8{j*4I385LPKQjy0jUnnJLugXZYK|FF5>4rF zEl_&;o%bZKfN(zo`gN`IJNu*m1)lxD{2IB7({b2a6;&o1bMl!+e1=FhmuMcRsR|g5 z7`dxVwWid5WqYi0;c{L!^W5ZpTWf5~M5T}R%inJ?2CoM)mm9oZq;DMO__P0x;ZNE> z@^ZJANtjJY(c~7x{DxER4V&fgR1+>s)mwTy`bxXpE^l=$8~v4FHt-WqXNOopfGOZ1 z@|=mGVb=QNAE5Z^2K)bSXHVI zR|*p0-<_5hb8B}pA~<5_?|8Wq)BMbjtJ12e5vBCL^glnnR7C5)#0BkZ-f8;!^V$F| z!VV@1RgyfNu%4ujj-%}fPZOmr*W>yxQ{`;T_5TXTp|!q{5nh*#Yw9Nomfly&pH0wJ z=q(*TdC|$5dDqi1;p65h%`K*%H^yX8>13Q-_*ZA0F5YtJmFhfX9C-yz-i%v}8z{Gm zF%wlYPH5CVNscfxs2r4_ZKWn|74HNXP_Y(#28U|~F^z(Me)7v+cMFJr=K~TLXnT(T znq4YXi z$otY_-6tOdSV4+KXP=9;bzDSK5$ZqV_#PP^kc2Z-)XT7i_^>x zvfP5HlK@ALTv#6>_EOwGI)8a9{#52Cu^jVqL19CG$S&?{4!w4L@1IQx=}iY&20@=< zJ*p!+zv>ooP!tV3Wrg6drBeJ#y;Q^;2*~+;dwr6uKO4V{Incov>rrUpB!X$yD}dt% zr^S%QMewI9KrU%pBhE?Ao5t0@`h-tgVJ`h!-3?0VF!8=ryZkbvAHxv6|oC&&tv!5bavnuLjY*SO@28US)l7ij8~( z2_7i@GRz%b;J{Q^n)vMPWTm6V#yJk-+M|Zs#KtM?Z+Lh{=|BIWR`zobS5;yVYTTyA zXR#l+zl*J#cp}dhLcgd9>k1gtK8eUr=4IP(hd^mpGDVr>4aq)*T%z0z_dOL+Xe_y!*MzT+W zn!jHGU4OB&+fLjUm@D=X+ewCO3mPo!-*v0I^UaDeVNIK?TI~$woj@? ze!|4}OmW!&TrWWn%;YlZs?u@R5OVp)L0c+fOtW#gnrzDjJ?toTE_lPyzMsjcKg8aU zVy?QDA#Efgn#t(y?%G?WNfe^vDIBR2S2$2vSc{re>D9oXGUcZ<1aXuqd+=`}$x6ag^%-GIc;R8B4^ zqF=nU9q^ahEU66AG?xQ$W@O+=PUqZ@XC3ZB@Jlt%D-j;TBBaVoeJmx>WIJ)^V${`P zpHISy!Cj7IRmsvXC1)?p!A>3H6OM^Tee{bZxkmF#ACYOuH+fv4zTywsH!I` zO3c+@;3~8@p|=_nXGLaYv!UsDlQ6MYVt+YZ@Napp{HB5T+X1Z7LXsBqQ9pok4dWy* z_5@ixkty6HvDiG3bX*YoPR(H(B-;(iuo&?mbcg|XG?Hd=50)Xj6TZP%IJ<|DR4$kL z8}$k}awk4G{{z9#t|4~wZVV1J9x|QE{}cO54mE0+u5pH+lcvXHN&Uo9EU9r0R5(K~ zCPzK@7lA>0yQL|1X7;TU*PD18z|O#4#48}B#1hNN#1k7maaRF#@&jZw2vM9S?Zg_3 ztHOhC=-8VWgV;GY{H561X%}VjVpTG`>#fuZ%~zPRP^lemeGAL0C%j2mY10>9#wrc= zm&I(TZS`}et2MlHh?hX$BK#x_C$eG0VR5B7rug8S=En;9ZbNsGn4VO{dvid-D-vYz<# z4;1Cx%oHk?!GMvTp4yqMTL~VktNpX~jd8As1qW#zwnSZD&j@B6?2!VEDh=P-m6Nmi z_ciryUm_lMeW%x4`Ivoh%gtd`Ts~Suz^0v=Tm{0XENY|q*hc!+lv#12meYLcXuYY> z-C_y(Gg8$&&p6=-_urVGrM&oC73)a4f@WSct=_$n#;-$hg^$eLpEz@R14d$KYf72% z5d*jLLZgI{h`fzyeO4u;yFwaTsS}T!=lQ(IF;bo=@@>#MIokV4N|*HjO)xQ|-M$3V z5COH^nCGkU4xcgnnAJn#`?pI+@G&01a~gDNR~<{<_S_9ZHhASay7M58JmaK-Jlfk& z$O)dmu@%a#q$j;jt{w-zi@n#MZgL1uGn9M5B%doJnpV({kEvJ2M-|Fx26bm&FwSIT z$b6j`m^YE(D6;ii10`}^{(HcUD*k#){6{G%d^#JpMw9WPUZ|b?CaJsi$e>VgrF5Uiu!PEKxywW*Avb=R7GsAk zb4s?_D0N0MODZVDIC3N~$1zn| zEkkoT0UudE<oefaI|#VO>5jHUEB>^!p#X`{hT>PVaD%T(F73t)o;B;8toMZ(CSt zoS`pNGT0DbU)*aD3-zt1catj;=gD%Wv0IZlKN-0(82<{Sif2M*LFTN(CQ}}%uyuj4 zLAf4PR7g&zp4)<}m@zGraY6Dp>)vZu!rhL8HjDt@KeT?R#bD32GbF*8KuzakB~m~9 zPBIr^C&DJcHd#xOU<}Xheo~Cy^^NHGU)?*_|pZr9AWx*H;wMW0P(nuRh z=kc91vnWP+;bWnUT~ykdX7_OOtapvPu8fIRFd6w zUT9kWT_`ym>r%9#qgv?At++qdw;=MqoRy))W?d-!m6C&y)0AbeF`z@%%aZaY^9sOc zyB|=*0~JeL64r`z*ydDufEyRxakT8no`YWgwaR<21!#Us?z)xltaf^RM<6zNk-kJF zPzz8RRr%K!E4?VCMMg1c3Kl#Hty8h_{iLc=7}{0XfA^958oxwx*ZWnTgfJngu)vwV z4m{)>9$tUn#1SdOpkC&EqSt%TC&MokAyj280x-4aHF~Os$5qyOTa8^PAY!;QH-K=w*PLKO!$V4g1xW7D6h`%D zzv!e7>R?%sZdCe&mW7sBofH}FL4S-SQ@|VJSQoyh)yHHnb!cTxX%_Z^$*AT9i=d{| ztzN>O!)vPmQBvACJCCfQ4=V2e`ownM>vdnBGd`WibtUcV1L5spt-lT=u>V0F+8CZn_4efO2<=c-FoA6a=y z?`n|69cKK&gqIOaI5N!3o09eDK-B&{G5@@sp^XjJf~lzr%|fTf9h_vFC9VL4jSazY z{=%WBWO$F(<~H5N)@fJq3AoY%tm9($O8MQWOfuhhQIBOV;)-i;3{kC&@gHGqpMp^n z+^Z`<(p=Tb)z#5Ix-CnbAa!^g;{UO~W*= z%*kZ-;}xBnrg|1D9b+Qh+I^`4SH*_O=+yZ-DY2#pKKd=5shl6-_r8wNCU7~XI_EeC zgb^OnT(iVur|UkSns^>o;?A70a-cP}KSU({CZDM>+Qx&R4Vip#T>;fm4;0n zMNNL>g3Zvp0E@C%TSD1G>~i-P$?{3KZHg(!v>I=HXo<~D(5Zpgg$McV=RXrGQoak| zrp()FJT-kl_pZctQd1k()>1?KM0m0k-&U8} z@G>xP13AGH?O|?TI$nIr&Le;r^Pngv_A+I(t$qu|>nuu|R1)xNdaLXqnzi?AR*`?4 zYbMv`ZHaeLY^}G@+x2F|nr88>^Pi8?`jtSJvCLm&t{?>rfmO!YLlD<)!KlL`j9>>;)9Pr-ZQ}=5s$jZ1s<_2 zIM}~2#JWl`D<2q7%(59#CstZgxL6Ma2ibI>_>81n0sS;%b>hy>s&$MCUq8_1=Xq6l zGJK8D3%B9 zxGcW+^o6%5(~1=Jb(3ftz0(AP+LzH`XS_5sJ0t8b=q35^gG-9Ev63b4EVs$}c*N2B(#RTjH-ra?#j&{V5 z)9f2_9bD3ECrgT1+Sjk56Du#~WS`ynK`kV9Y`4YT=^Z;+J#Vu=pot9jmMeN+A)FDm z^K2(WT*r%+@@y^ebq~qEh>f|;-aKw=Bk6l^NwvLXLI4*zB^XGXAw*)R=EtMYH#lhlWoo8)+vm+Y$pRD$DCzc z+YrfNGH-FKBXuYizJtT+cXffz6|$P|Rzdy&-+r>*M-+KW7z=|b3Pl7hubURNEtss> z7HMfblB>kTsZn}bu_-&!zyETG{z8)LurNbv``QiYf2#{zI=0tp|JjNf;6j!rSk|Do zP)|K1cCI|vg8$*ciD(NyT8mth0w#fIH_7ig1gLRGX*; zEG(3u9O)8M7JFe*R5g>C&)(x?D1U)kIm(JoFcILw!?^y)xASOfI zfwuZG(2Qgj)G0HrC_kvyD!0_!F7J@?AU}ZRUtEfTk9@ATANuODkmTc=%&}}@Uq<5{ zsbhj2PtP5)i%FA0RF`E6aj^!-WoW)Km9`|c`fjOp_Nk;;`01aOsh2O;kJK+;zTR5R zS1dKdJT8_@FTYe5%^VjrnlDM5TyfI?y>0H7jP`>-1Ktan%WT>|DO$H(V15?bkC3ym z*~YG}sF(5s@j&E)jGNO#b(yMoyX}DBfo`8sx8^gS;pz+J3EY>Mit^Dj_(uOA)(mggrI{BZ7pkcmcZAl$m`x}P zMFld80E{ z*XpDeQuQ_e3Q+!)Z2T>F#!`r;tvt@G_-Hhr~ zM&T7;AWll_^Vy_OhuSNX;o{xDNFBOZVNz3f4vs;YOCMSIx-4sER;4Qy;JGqcTBp1I zO8w>VD8^yyhMKSEZ=*vTPZKJF0|o0!l%YE8=`zXT(dhRvVZPMim9^Qg?gZk+4%${D;cLgj3f`<_>D1eFrK?VO)aeZiWQ=llQe9~Hk3`G2lmTqV_ zrw`yUg%rvKvy-(SMMC&#pv)7BUjB@@LzSfWD`n)(Er3F8HQaCt%g^CD{F+awMc)OFAfmKpIE_r%y=Ulqlu2M~*(h_lh zB=f%16#aOk?`>gNZ)5*B$k0_X~QhtZ{&b_BL{)YpMjbpLmLpAk;j|L z@OVvhsWFmxkAiq*xcu4xJfTCzn8R*3p5>i~dfh8H*c-15vwK}L0J&-2bijU-#0L~y zS7)&EjX5uo(lcAu=k=u5lmAqzcRdz1@yf#g?tw4D<6#RQE>w^>8V|f_-VMOh!Pm|F z+5pxbZY%qit!0%YUK0_QDW5lf4O~U@#6qLNKV}g^vl6W@XCo!q@=YFDyM9qBROC1? zX~BFjSg7I+Em_9*%zTaB7VERGc+NhaiBKAeq#%4JC&tp?=m)Pej(Bo@?a$k}cB7PP=vbmPb)m&Be;pT~+T+T$Y~y;w8uwa+_h& z4gaNbFyDgdYECMuTQZaHwW{aETEzr{9C}}@arm1mu6wKmOxdnGI*Nw6Ot6zgyq%u7 zo0JhOwVZ9~IJ-X(-EmI`0hoS$LQ-nBruSsysuVYMocAhu!xNro1 zyq!$w@zH3lNsqRT2VSW96%n$gAAsz$Tc>Sfmq^@}ZXu@1hGEskqyPk4Yra2-%6 zuVApUHe{4GT!#dEQ|9LdcZ=Rlv;a zgY2!dg3)vfG>-fWwlmIhgh!or1GFn%HEz$4<25@d&5a{OTvRmry(vZYTFD9rb3?3k zhbsMn=JK3q4?O+g0obJ8STXAqt~`2?cRxs9OF+XhKaW58q15wxJCPhhP%iyvg(fWG zIiZq5x~tmtYuc<^8s`#=k8%538MSHqTua0}P8pdwbR2j3B)8699TI=aErmpw^O8sQ ztbPx8WAXe8uTqR2t(oE#5U(t5umet?C}v4B(kUJ*E014R?l&Qcg#TnK?^dNQ`8u?r zk-hM;)K?~wZmQJ4OJai|nY)DTSvYUR_r>c`KZL%F`Nqt^pbVD<*~=Qu8b9@^ryHxn z-Q)wxq?&CcGE3K6zzanmlL;V<>wLrxAEmt(!YXS>q!kYDGaR-IpM9CdW@Kz*Wwf?D z@yq3Y-nGG<`)z#7DXt&x*iqNv&%fB~^7()4uzx>);1fWb@^tih-O8Q{Z8oOW<$qh2 zi9C7xe+TMc$XM58cdotQUGPX26%`W$9Tgq@@4v@DFTjWfAtd7WtYLr&YH26%2}sM_ zcMm3()rpH|x@~FYkt_H2WEMjTwX9{@7~NxBNZ%k@l!n=&F$~-AYi_6hZwI%erwcU9 zm@Wil&l|&VWftW^bHITypRpAOF$cGL+WNc31mJ}KvEu)K9skLb5XdxD*a>5o))fG` z>qP%K3}5b?aAhm-8I8oP1G%u=ODwlzsrP^91VU~E!F?^M*Nbu?eUL*pJV{C8M>L0#4N*urH9R6>VQ)M(Hib(*|Hc z<@Fd<-%Pq6Z4c}kX^fR^+|fLsXi?H0xE24v=7VsaH?u;4uJar0uh`()`Pvh#EcppYV6@>XN_Wyfg9IjL!e5yeBtz z1?cfK&BdttYP6#&5+TUo70FAFjWDhEWacuTVx8@bnACHex=dzC%xDbWBM5Ab;O&1^ z@peyvYz5a{QmNGp>f_lA5zEkIc`yx`F2ugrv*ofjB$Flj`ng;j?P zunVS2Ae}#SL>R|OO1M~aFOUW_ZjX$&7u)+2J)(XlFHaHytz}dA6i5C(DelK~)E~x0 zJr2>J2jFJ&V4EW>(gVG0BBN!f66 zqDS*$#9f+p-VD8?uNkk2dY!y1(lc|K*uBj9IUs@mPE9Qx-q&ZRx=^ZlR@gri>WAuW zcNq|Uc4V;2F9(f7)c5Nnk^|x{bl1KAq7jOSeUC-xD0Gla;UDY!4#Jfb7ZXyZ{X~TJ zFH>o&@_JDLN=2wjnRVo)NAUKRvUk3APJ zh2KEcvTf41PYRdkmvm14FuWXPXXzSi!tC@&fI;3)VXyzSxuOxM2N)(^8%GQiWIQv% zRw|#OLmSOWu;NK25|$n^Rc!o`j+fpElT~+8+|OEt?{K)H6B$qU8;K1)YDGl+FKw!< zr5oBnRo$p#4aSne--v6KDZ-$>OVsEys5l@+2ZyrA53~<(ifD|LZ!~F`z&LHDt^l)C z>h3peao^(zm4?rg>k@C2eZ!Nv2GSAqmMfwnoaMvUSCO=ZiBrxx4+hHrE;ba$HbSAA z;C$JQmENYyfLs~s$bVSN)z3ncb`7EtB!W*CisWS4Q$_U`V0C^gw@nUusq59CG_)~Z z8Mk}j*FAc6zm7ILy7aN|6;RukFyryZairPKe3ogRC*>I*R-MWs>GyXY9nbS-OCJ}J zum@eBbK~}aRl)iMexrx1i4Lp)2{lW7Y%F{jG4jX1#Umo(OtJ6VD7y^cubM;NGA(@* zU}dY=5RYqi9S!L!kN1Ra@+_}1ZPsOKHHr;g1_y>!hoVcuH3rUXiVD=+c>P&u%5Eg4 z>$Og?ocHiDV$)Jq@put(dMBAfZCRFgAq!qDx=6~rLp8djP~60M!$D-N=f{xZ7TlNTt(StH;?rzNvE_gEvBPnVcO(wLhM~)XgJwB)up2 zT!%wrAid}?J!Hmbq`THUwNg!@+sQJc_V4EXm}HpX)wxFxUk{-aVp6J>C2`Os_KHk= zj`dav9+O#m=09@Omi%|WvKnownUQalE;L{ptrK5~)FM7>49~=Q4CTT_Usoye#uX3~ znEZA7j|Zr`*C%$RJRXorsnD9LqVjYv$Gxe6hZK18*P7Q*d~&Dw)Xwt{kH&dM(@Jk` z$3lse-YRXCVkm>?`97t^Itm~hNtQL+tKv>xAMx`3GhMIej_sjqfnh0?BDurl{zEQh zV&>3H>Lx%`+lxG>wDu6UAM6e-XOb{Kewp)+OietnR7qzId5iy#?ysU8x4wnmg#4mCPXn z4}n@Wsy$a~BZ8bO@xva%vGSC$<3cLpiPc*kRX%L`0qZIoeh(WcD<`2I%pQSBa!j!E!oa7Us62lK1^uf zP^smM&QU_zji!L|LE5P-FNwx#EWB!>asW`4Y4&|5@&!@8rHnYmA)rq_p#Bn;4JJ!1;^A*AxK&D-(4nYZmLHP&o!3g0 z!1~(9o3OV&nlxLn4o$CwPL)fB#1Y0^(j!&sw(Ho#&n)Ji+uD#?PAE$$A94}z7pGY@ zxZkm{V&3iut7)^LQMQz2vc3ZHTA||AI$RxRap4tjQL$=xIbd@X*^cwgrpplnvZ5jnynd-*NyKP>f$p-q7i zI%$q|9z@&3adjiSUsZH;bj0KOp)bS7$DQc3kqX&5yN|=8gVMt-W#PzDvUli%dJ*0{ z5lkTnqwupkYHiA!8YY@xG;P%NIwm^u;?*HHfzL;R-r)(J{5@ENl?<7ku(Wz=e9Z`% zFgLPBT!{rWZ(&`BulBc}i_|&KjWmCm+Bd z(n$o>z3<}wvj(w|cm*7^-t4gI2Xl{MA78DA0<&$xq#CA~>Dqf)MhOj)1=RL^NaC+U z+wCh}*LiZ!y;TeM)(G<=v!m5+L*)XhtfbP~bavZ~M!RiN=G6e~f6eUfwJ}6JTJPjj z#ywNw&*SDAo;v<;hQm$|hH;z5r!&&etgB-WsE5Eus((OtJtwj~>na>WG>1UpvN3}S zsrbFcCBN@A%1$@hC{>n!eu6!h&OWq#xP0waGK%-u8d;`(>M0R6${M#h4((F9-ozJ! zM%K{VJ1|yN)*5Qt`iyti$rvcjjraqt%xFi6q=WRKU6DUibsArXiV=Qfc5c+6R{mG7 zadN+Uc*0!rAhd?CRrS8elfU*qm}|3_4D&A)3`&;H5?gCWJ1azO znf)TeegkWRW)eC>;Q7?Qv#|n<6hergba{nwl6n7HoLF-B`_-OIsW&?9F;q`q^FH`n zq=X&jl}a^?bL!>r#YRZNII<_ZJzh7L? zZ~XWh=h@wbV--3gh!Dt)RLpu0?fM<1d!M;KdF&Pisxz3=l+DNb`zi@RmODC>iCrSS zhe#QYkr?U2jM#(-!g%a!5lx%1FpBqkX_|-Nry z|1AQZeP&ZpNVT8`(UCLx)%8PP2jn>)bXRh zt%ECI{2u^emodB-bo6K9fya+N{YBFaf(pKjLA#*CJQHs^mXf#vFxT2wKGPq>3|xk7 zd|Fxmlt0j}`21-M9f-TVtG8YD`|E@6cTW6v&&4?}aYqBYdO%KY-Ei{ksQus?A^1DC z8;YM_#@xC=_=l9hn}Hz^v+`{~HL9X3Pt^TW8|*$N!71 z_W*0+iTXxS0fT^qUV=dANDIXv(j*DJ2}lzJNdQ6VBGM5Ez4wj+QdCd^NbiAAr78sJ zMGcBHBM1n7i~slio_p_ehddjyJ3D7)PTAR+-#O!_M%oFTSO&`O28sa6{=XOgYv%t@ zMaVp$HQcN5b8k`M=zsMQggClg;wY6-HX)m#4_Ycp;^$qd1PrIHF$lq4d~(So!_~EnY(mmkr(|Z9p2l!- zjpuPidP!>zh>XuM`?^sm#m7aqyzEFkEDxQ&x0qzKELG?l*Jh|Y^X23M6)SNR(<>9x+)+t9 zRl_~{%}?ygwCU_J-dZK0@)IvC!s$~%U_Xwj;P>AK2RfX8q(>Ua2!L-8}p3&1a z?*8btWpZvu2~PdPYR%jGOkU`Fw!KDg@q-h z-cH)b-PI`8pn4uoYpho-nqBM7ZU?EG3r8_2NiIJU@Y&Phj;;{eH9^$2G64`t-TqW-vzVwwyLnf5kR zMNE@0WRl^5f(FUOPgEkLl2sQRBAJsp$sC8J{wGqC6Qr@4kceg%Hl5oeNp z$0VcFuPvE%3c;2TkkS#4ab%v%HVoDxVHmt{ow@)oWMmw!N0yMqxe{nvM{nN_-uH~0 zpT`vOMbZWA=ifA3$-iWfKqt(FSwT6CsBAPJGSUbez}X`)eA7pWJc+DNdOdNr+eh0^|P6W`FYPTs7$-KMd`$m z`Ri%2%+W^hIp-AHa4XQm&1l?^#`Ugz(RjmS`nxH09|dKiPvWv|R);JGu3epNKA}!d z3DzX#D=b&>3}2xWK$u!KAci5q`kmNSbLGU(v-sa z&SXSx)0?n&uOcf(-_I*SqC1acGp>Ayz8%}1aE)hG`kdo!!}SAZQ!im*(faiIFG)tr zJx6&ew@cV!&a9%Yic3g#_@@6>I5RU~ESbenzt|%GSrO4Ql?Bw50O5%G#V|cfJs$Zg zP)RWOS=zkV#dUdzcvH)>7U}zzth0-lxFVhb4}m}^#~Z#+y`U~o%nN4HU$|CSWwr@9R1vR-F{g*;?f@Hgr zFTs$f0AQ#zXQ;u_=$71tl*G6|lf=ZtZ#g+RfEH+oX_CtTLm8@+x^lw>1?Zh?00^*W z!RNCl^vIf`MB=AzetLT5Nf6=^UtV$LFVwJO%k|Y*!Zt=mSFo1IDLFK#P#Ht#Kzqf_ zCNb^CESvd2V}g}aBb8Umr@s{H1UW{l8u~Evt-EWh(DjvBCYW;1q-E)K`?)yVw#{#!s6DbjXN|nQcEc% zx;iC{%)1MVci^PA&YqU{FPQyUb~BrbZ1NU zmxEE7xVwU_;8xMR4-mv>W=l0GkJxwt?`&%R+A z{!yDbBD|mLK0_&mZ z);$D7y9Re8Z^LNtF%eH(k~t+fCW8AUW01pMCW3GIxvZ*!FjsP_T}Ai!6IfN|y|#JI zn|nfCRijMs^RMVzVijsMck4R&Mb(j3?y2dM9dkXt$|6RnN%~-+4cpiI;^PScqIV>Z z-TJ?p#lEs)4)Pe7hBee;PBW(MB7`gnifK<`UuKGoNId`FB|?7B*YCep|l&~jiv_LQ9-KvBy`pG%|~j5rei z!Si|wF}1W!xzh%EZjizD2$PI;>f4Zb1O6Elfk3$iO;2vpAJ^bBX48P zi`E`ziQ}w7p6@^`TY|ImRNVXR`ZsP zq5F+o{(U67z1sQV*)6-&l4fh!Mm^f*cdneVJH!W}$bBw6eseG~II;X&F<0aM6$A}S zVk@ef75g}C;0?oUW4K)Mm5p8Uy;PNl-~HVCb2eU)aYuZSB?Kbg^b+lW3`Eycaq;L z${5v)R;Lt^$M9*nRodNQ)_F1ETwm0n9<-(Plq6ka*CTo{5}hPF@+A-#KP7CalA2j# zfhuqx)g~IR>*i>C9#;**H>CNUqA@g^S z<5l|DUj^8o!4WSZ55duID_2~YS%qjWxomlnrZF1uNCIM(zg#dpM@--~`23&H-li@N&W zhkZw?1`AdF`QBIgqJeq*cj?NGDyTg6`n(MTKX$qd7sQ}p4^v{Xmvks42FNShr$Y}Z zT`_Leq#4PPsanb6>?V&?gyj9ADp|v9aIRNPK#i+ZSF^ex1^v}{<1HdKHD5!iOAKC{RcANd|A@Bc+u(iUEu4D14Ys5bJU&u4RAV_s&zxzpq`;ko?6KW`hmUyqAX{P z!u`AumI0S^rFn7ZQ0ko%?9O$Xe=r%Kfi5&J$UVRh`Ec791URqzBQ@)(fNpf*h1YU_ z^0y}E({+EWx=n?@Z*3k})EQ!X!L);qDx6}IFm!k#cFsv75f|jAU{(j4dNFjL`kNdT zH4is;zR}=-w`urY{YPCP2d4}}`|JbD2!P-;K!!2~5#W?QrHU0Pj@QriW)c~&ItF#F z2{1jZIZ?yqyJ06vQ#a*=whDr}WpuJcD(jpF-RSuwMzLSrt+O@*X;V$OV|of0VE5MM zOIsjpjmSWr-sKv*RuW=Ky!5N|ZzEcw5hM(BMh*&6=YNn2JeEjCFE2Gfa@-+Whj9F~AZCz3 zDV7!!070ZD2*zwp+RB{#*Mhw;Gr_&&tTh#~zeO zH*BB%b}2Zgdn=2zzkg?u9ryJpl&(=3VzueS;P>tjobIiSD_xbMK8d^vbudBXI>b5V zLV25pT;W~1n?`QEvF3sVE2|7RrF80uG~%NysRT3eXj9y0tM`J{iQ_&{;L1_x#p(Dt zFrkT;tgb9-$BTQ&LU{kCPO5G`SZ7P~efyAOqG>Muo|c~!b&|ddqdwsOs|ZQL?}2-U z`Q8frAceCf*k)EV-be015&b+^yJg`b_L?H;^PyDTHhl zQY;4h2j1=o(OUM1oOVBvA(S{j5sWGcqYYb!%hVKVlsrCSl-FD(RN6+CSgd1SJ1cJT7fymX-aAbn zv$HXRgPN?DgV%&`Bm`d+mpew2pXO2{+h?-(spi|SJM6nWK;r{KDI3jGeeqa}7cn10 zR;&@8u1qBl6~z=nOXvuC_fB0&W3BvnfjpjR7KBs!4(H0W`vJ2exYTMPYLp&apC@XW zNF4t#6Kp#x@&0T*;#di%1=1osMf)oUX@Xgce_{X*J-U^k`w}O)+;{>mK-u9X zgT^pD^C%Xy=XpQfO9(k)IOX zBPL1@ms{=(=)@~hFu zcPfS8<8w|v;XFNEx`fx3R=aw?& zBM!O^(zQg~Xr?YqY)Pi0p0@k&2u_nx)mI}h&$|!7+dp?KT2a!^;jDG8w~f?wmvk}I zD)98}yB4H&Az=%5@cLU_&%W|s3Zo7;k!H8Q6z9Tv5Ff>q_`VP1lHSY*y{CWptT|R( zV;n2*n!RVx%BFGJXYC#>0FG?^GUX8RBThTYi{J{3D#<4giQn`G4+*qYhA2ECG~(^T18ZrxNP zM*U?H^h~c%OdjoAT-!X;|7on&_AM>(=ZWfWN*TtyhF)R}$2e2v!UlEd7);$v6@DV@ z$i}3c6Xq{8at?jEZec<4RW}briFKK8Sp^mg&YJP4I zg;$U*t89m~(Vxap$AIYuYBd?)&n`44DAPfF_8WuG5bEC?P^FN4NI(0w_yz*{8Fmkp z5aTrGG2fF<(n+Ll4N6dMXQbNKg_~qxM9X`%T3zxV?Z4g%lE#dYkDpY&?;lLtE*F~|$Fs;^0T$Qv(^m1+x< zn|d^{jk~ApxV58TM{+YbHl2$yc@xT%>cjWIuEs6vhAe(5VRn5Z*;n%E60R|Oerbv9 zuJP7arLT#sciSXEn^+R6q&&=Pk} zR6ja6G)|#7MJy+*m+e9B#QdI0H;YH5ln;B|9P5|0?+D6Y^X0QDh)Q4t!DXP^r4z@I z4Qwv*>)M2PjjXi!+xNETp2pzVwFFPq0GX9GD(^`9ibc$Q8eZI(qIZ1_A#h}ihlyR4 zYuAQ^Ep`N(sNuD#;-INacEiq7dhzZ2$yTp=S*L){> z5J@un@j}D|$1T*RdHXV04H_5->#!R<1O@l2Jpm}PSIoXjFvxvQ{yc7w7;x3FI{%8Q zexrv(=qq=)`89+yHi`SQJE~c{DOa^v!i1z^(KS=Ez_W#F&j!MVBRb}CDMP++-;krN zyk;P@%<3}o;EXdW@7OdnFNJ3qX@%EMlr>sC6AIn|6}x# zI4LNRCV4iGj|2aB&5KiMODJROdU`qsuT5voXK=U%W36x~diSDC=8p)S=TXr2c80#H z#JkCtUd*EdTZ#;&p6#>V?xCZLzZ zvGt7XbE4BTPael_SI|2=yI}oOe*LkSb=E09F0yMRqNymi^vjOm5|*I3K9?$1^v0C6 zt$5+kv+tgc^eU8wT)C(w&_g~FpWaD9DIH$P%t>4Jxn=!?NmkeW7$PZtPezj^5DC38 zZ}Nf^7i}cW(>#FAaStNR!B?OX6K)r`0r!Fa&(8DM>L$kHd}dmzj}}PLxCo^O&XInR z^Qr^lQu@q%iZwIo&ed^{7@mp06m%VBQ}6ec-x^hqQfp%SdF-=RR(i0B8w7f>m4Sww zKM@`jnzKA?k-UafSVTug-_TzQXzE`I=i(F8RoHO+-o%LivEKRT@8|rkrtNb^mV?VbVm?)dYkPlF=})QnB1O) z;PYkFRi9|Cs(B#zHa2+}Na2I+clmhZb)7@SnDs~OUxjhW)N+;uqA!!<{T$trYQ z78ljbk4B~T;S$kbWGr!|PZW?$f2#WgZQL*WDWvj>T#C(q{3e8CU z=UFDdF(%=X2~$wYov+`en=#|~^-$i_m4M)f@cBn>7Zu8j-^2?P3P`Cpbau-#1!o_W zuOjc=zc$4Ek`NJ*t8QSkiOr>I*=Lkp)}`5P;JK`+saDuZ*DFc1Hhtvs!u`^6!v$4} zsBJ;1iyySLoIYQ0oU?Q}w78xLei{=hxIHPCltyuB4=G%dK>h<1E>a|mT zT|Du5r@i1a$APT&m?`e9k@x05IKxHuKntRkIy;wjE6GdeAN{4+RHnx$aO{c*t!P3j zgh~2$iTMVVj24;`E~4tL*VVc~X|z|`V$;>?)9PzI;5~Vo>^sR8rM$(zL;52(e!+pD zP{x_tK~PQ=f1a(!CbD^q(SvH9w@nJUJ8L(d6;68eqK~`t%Lc=jKv@n8$H~-`R}Gp2 zvnC#eCw-H%et)Ib**P$#QP`sX4fyuSK*#ded%BTL>p2eY%1j8xu0@PP9$m%_fTX5O z^7t*ge?6#Y?+5>djxW2fg z(9<-yRF_j|cZ1PIM4~3P!NapJ_Jjb>rnsA+87HjKJ$zn^OItbf2KD@MpL~KU!-_57 zZ_*1!4jlr|oTF`xIKs|kWOVsZ8(OqV=49O8!RVMhzD(Rk1(Gb7lITLPOXIq zT)a%9`R(_(d`Yg5L7O1lY2X>A4IA6?{Bty8owi4C%FYr}XR}+IXn5h~Fa2jf4h~2% zBm$O;W7kkCa)Z1&YxS2Rn434b@w2mty1UHN;cVRUp&)@`nm@vP-SQi|B`(U~nZxa# zRf8eF_A2`4{_4|QoOY@DjIZ?>Ateh8^WFDGTzUFwNz$DmQPIUK+`x;%hj#I8e^e*P zExL;Za$!>sHV8@!qAQ^Vq2OzRhrD}iN~xE7x?wQqNZp09A&(AhLdt@^KZHlCM!%N0 zV0h8k`IH}+I+?}-OD60UyWIH^#BYZzG*>t0qjl4!znoa{UiDIxh0M}qO=@KP<_qg3 z7JJS1DmkWFIwdfdyE?_Wh-wt6yQh{O;-H-_T?}|{rY!Cq$sOxox!Lnh#^vF@klbl^@!LJgEF-^- z_+KuqL|b2;p1%}-=+gZtWA8L|3%h)5`m(fc?O7vC&#Jce=PhQGd@3|KU?v7{C^KYO z8C0~9hW>b%@x|U+cWuf-qG~pN+ZvJdn zfniT+zQ48ifK#Hr9Vbp($DtIOEgm|e`v>$sS6oHXxvPv=4n3?vSMYCBt?lq?a^g7H zNb?-nJgEtHc}thuT=_(KEsjswuETM%kIe5S!sjme50$$4*2f;^dpzAkpHhRL836;) zZKJA=@Q=Yy>aHlnz3ZUv=Tg^?czHsI+g#hZtg{?`#gmaXC9~)P+-v?0q=%#Jz?6dv zLFrjGs==B^x*^$Q0!*7$4$gL&uFNy%ckxW7go-skWbco3yAb&VG;`@D;`I*Xe91XSnn%$2zW#oIRO9I* z01)zTE24kyX5exFu^YU3dAILsEhS~DlygZRYghE;?jirQwyI@y`KWYI`m*fuX4WuY zIAl4;qGg6Crfqil5|sP4mQ6%tR!~ZbQL#br$H+9s-9s7)I>hUzb(eYfm3O&{P2V=tLdb9fm&Pi5?B-ZNI zC+gEfuB)-po3v6U%+n7CMi;&eQ)@?+eT{!9-&u0}{kqY2N@SD^_lbT*-4`lPZ#7)s zlX3K*@MVEX>+?O2Ss!A-6#mq$9X(AQAhf9Yub-C9>I{#Z!zx2Qo~qx?((Z&CxQ$hz>7XEnMuhx;g0 zu*p%{s$xE|v%pQira@BjJl^m)0rxmOVr*%mf`20|>BJqL2Q7OU6`0t0kg_yFfBA?Q zY@OV}GUGX>eA80O?3W#~`C9M?PlbGLTOMxr@+{=3!Vb{~w3v1})qymv7Nq|5Qw{q3VdjA7ko$&P8Sm1+f;L z*4$*MJo@mq4?8GiRw*S>zegjUJc1eNa+69zzEGja66KS7ZJ$4MuVrYno=f?skJYF4 zX~is*BDHggOy<3@=H#)^q88tyQ{GMIKa{;TF!}>!L7^Xlj3I$#U;a{1oEm5_3;4t- zZfh?}=*ffBd*~=`jXgX4N&oZOL0cW^u&d|K@m~sF*jG4nReWW#;d!%jj#-tE zQ@{t~_N(@S@K2-Qv;+{vEqOf8u#V3~4(9OC*^6m%T;&#aUjUJa<$FqTF&wfMCvmXt zGe#+!0K-$t2+*nct=%tBJrzSVRNQi_zj=@rcfET|`6nIhC!V_o&*fldQ!~b0ho_Sn z5tNCl-Ee+7+HiI1#O_0uxySADns`bWp6=0@at)AyBy3J0NC7&Jq*DGlro4jbdd(BQ zT3B-m4pv~-vydCM?^E7;3WO-8IE(W7HBFOJRc4T`brgobET1*eFqpmNg2!2@(Ku8X zh+JEhJ98tIrJ#h3^M!-xTc1;adi#TZ4#*yViz@!vwnO!laaW^EU)ieG%2A&L`>OnN zu;6DuEQNwX249He_L5#wX#l%W(p9~+uMEHHXqKuWNMvo~_WJQ4VQ-WVPXmJWDC@A^Wyrel8b?@u^|c`qvGX?#R2xj)tP zRE&~u*8L8W2$%h#EVf=dEKxfwdj9*EI0ERwn@FllrUEVYI_g?pzu)K8Hy$sJ3B}kR z|LDk@-;3V@GItz*A3R{WfK>iDLkE-C(|gErZEAc%^n?#KYMP$ z!lq$=Da`0#U7-6%zHemG%WTH4Q_m~eCFli&&#|ej-L3h$3856{3)epweey|&de`Fx zB?VL8<%&~&YzOJE+QbLipdf#F4{37aO>Gg}QmDV0WT zrw~smPL!1!m_i=RykN}v0A5Gf%wc~H^N{*0_iOO|0_xH#0$)L}9xc15yp*0ZsZrC8 z_M}mafIS^MW+nZ`gE8-wpX2FZXbK7j(QS@9bbP`R=d#v}cq%CSdH-Ol^jJn`z&Iy!m0k@DO(m6ghXdIE*v9^`TfN&w)7 zM+|1D?KuVih1j+@U-$cTFg$(L4qgHm!GRP3F~8-ecBj=#yUgbMDhCk`dRRh3p98}y z|HOlCiZLyX(K(;h_P-=6sz==X#Jbh})so{T1kgX=GbD=lkjK;UQBbhieNS4WlaLva zFxCh34J<#Xm{>R$6Y7ywva-G1alGB}-6N)l5CJOf|;+Ya!5yf!J$F@pJ^GBChZ z^Oo^H?B$v3I`}U|_`BWEJaEL}krr8_*Cea($5&OA!oqKWpRBnWUKein%-^>VNZCwK zki7nOhGh&w0%a7g$LaO+&aXc+0*7xTIw^;gk!u?up=7%ukd0B?pS~S;dsXbNu3e$9 zNcTFFYDd2eG6Xk%RJOkBC^Z{rvPbo?`!fW<#{kojC61!AR+>Y?(j`0q(yi?Oo@M^; za_fH>njw?e*bL;%UijT)j@h%@&R}V(gx(#j z{+3u4L+$E5sU|L=9Yu3BhvWX;Xp)%W!2;m@p7?c0v$6<1l$eJoB&YSgRbiM=K0^S) zjlEsV0KA;(R2?qy12TR+O`4R-@j)TmNg@Wj47klf8bm6q%Ea6y{g*DLn~IatNOoV@ z4*4&leCfdjj57-HQ&a5S_d`VyG^Vw6rByc2uYyXP^}8XPP>><5t+ZyVFan%Q6Z>!N ztynTKjW^P-oiJqFIw*sbaP!sIA)MhuKtjZmk2N{i-#zHt%~Mcn+#fdK@%7ldyd}qP zHCq900IO6$E(F*L)cX>8U7`%~yT>u&fPLj*JGS@iJQfPlN+TmDi*fYxWrI5PWka`B zcCZeAKv_ojnh}7AbsBMjL17RX{vUGU<0iFK)x7huV(=1g$iIRrs01nVCP(R}w%c z{_APedDqTD22wUTELJyacY8VHG<)xEEW=K?1{dSBEY8+3GEA^7>X`8m1hQb**$3&g-oEa89rtJK*D3!toifLc zaa&p6_{S68zZC!edMQK!h5p}o6#ui0C!o+!89vy`j(V|I>P=&NT-d~apz5<&4B$R7 zU6CoheC$6y*p|EcR2fXjV2|eh7vQ?Gno<6qENqeuXDNfb&el2gPYsHQ2=b-(pp0d| zV)~@StaQyyGW5&vj?B#M@~(iMF0z#M3ft)kxW$5V^m{u6g~c?7Yyfl_Kti-=7-!!g zAq*fM0|CuUtO2mTjHriY4T3_E*wm8oMF<1{!tJ$)=|v5R)cII2q&j6wIQ2!TVte~^ zvd4R)$Kw>Dp4|ixsJbSZ4A5m_d~JpY+L5_gzZ5`CiV^`O7v`(E3MjjEBoR?D5M_XC z?@7!kbp-M+FETto6w}-{iKl|}0QN+Z2LfS1*M408nr69Vf?iZTSMBK^=u4r@72&pC z;>aw0M#j?*LK2s;*LY2mO!0STzhwL!Q@%dWgV?yRL7lw5xbZ-uaq8|A?&uD_1o2eQwL!RdVpK(eGn z1ZBpbd@F0#5S@MGhcLCuEsTvpZqXlKvRkh2ym*|T8ek3;wukL%?sz;~2@Ve>%R5iJ zNd&fbDbQ3#J72LctSqn!|})Ja*^bzt;OhRmlT4Zo5nbaw!G$B^8i)m;q-vw-NIT_)lVlACi7 zzUXzGh(m?~V`aDrt%l-88A*Gt&9KsNgefPK7(BXnTXDqLGqlOCY}-{MYWzQ2MR=f5^S{K?WEG&Bj^>V&D^S?8jZuCx6)2{c+;rpZz>+Th zQEIO)^lkbdMx1?o5Q9x7|9T*YYqbjRW@uBytQ%Y;Le+0bST_h13TvePOYwZ4Ps4%RCz7TNJfPJ!|Ph`I?e85ld>SdX=+)#aG@(Y(;=4wO??k1OMOFHY0|6Ub|n4!FlnG_F-DU}?u;3cuKO&7Cvy$iM9 z=-Gnk@>g)^CPEy}DYO7O;4^y0Y|OEhx9ve6VyO$dy0xwFwDw-_B(p+sa17-xq;K zN%#r%@*VdP_4R{|n);H{vRqvcxo(f%_T13eY`@a2;B#%=#j%B7U|G-cg~&Y(AGm_n zbnTIaiRjTO>LlFKIU%``S4*||0m$Hxc!gt;9hB95Tf6U`Y&nZ#7Ggo zMgHc}Ujhk(wEMeqadqJan16!@>X?}57z8*bCg(U>;cM~1#6X#7N=*@gBNNk2BKAQV zgFdhLs;)|@{oV^S5~=@xAKLZ;$Ii};iTv+>|Bo#E0Cc!N{gXe7AH%Hw6+eIWT9smk zb3pL1Wz6oL1pt{7d9nAX^XIxN5dQ0#!2PxLCu{4;$-oUN75~47MSqpA>HnX@S?1JZ zX`l|;p}Xs6;f(${CQ$)T(f=J710&*pj!E`>USY7*o#LCg?v;t%TmRQD2^>N$bb{Y- zYxp_Z6n9;dr;_<1Cytku>@?CXX%zwnhuKqelaZ0EC5$r252!@eb;OqsHy@!vXQteO(WyN|Ypz4V6q;h4T#LZ-`+SCbA6jAZ47w@Kz=kO#zZR zq_W;PWBw>g7dC0JOh0cS-$5k zDvIm`8(9vlQIU)ivNoDe%91gqf9c}7V`%-1@>8brZ>f=n-`25jWsW1Z&}KtSzCw(8 z3hcE?JOLq}R4a(byy)>~_)TfYeQ5_pHf)d*Gm^Y@C>MqrAnXh*@I72TZKWMm=?9CrPd$bii)_kD)S<0yS0JeV2i`fjuO0+Yj zk%xBdqq(-^E9OfF#}#3ifxMOg2?)j=4kIq(6w$>wM8c4$r^4pFB}xvd_nh*v!2AeTZ7>>A*}P=mYfS6^db8@a12Xd&-IUm*z50$-?zhN3c<9YoURq zO0UtVPY|*Pzw0qgMu2QjV#0N~tpL*U$TJG?`!q_~Qj%)_taGQvk(2^5Br&nSIFmcg z=DG(7UBA*{Ir@0m+N;O9k9BHpi>9_hC&@5}U;NzU2WEbEm)k6biR-xrE8hCQmi>w9 z!VR|&ZS)-~_molm+I2_Jj-rSigz0_S^gUTTIfMbFxc=B5BBlAn`GvR-Gr5Kgn+i@O zp8!0NUQzAEpvch??u17HcfG(!mOp&vbl@0zNjbX7o(Rnw@c0?#9+Dz)n$gPhC*5&& zv4yEq1V>LIP^L>hi%9pBsY&rIAaGR5J*%0$9fsC1yv{s4^OqtvBC%J4GfQT$v=fmc z;?YzaZkFNYeJ~NN$B|2y@G4SD4b}KyKO3bq#a^f!A>qNza%{`H4Y`uZI2o$tu1r;e5;*6bXTBd1a*-?evbp+085&yotXK!h z3&ZLp$aoCl3Oi(+u-pgX7>^kDPoGT^Ym4SL-!w%SW(h<;5>BJRnz593W51ZZ|1};} zIoQP#8FRDh>lMx+83yaJ0;Zic!x;C3%yol1x2BpI={OOTy~IjWmF#TN(6g362BV!e zPDQ)YnpZMP=D)dw9)h*Gl$d#j=iHFSYT5V4pS^E;gW+;^%IRZsV|A71OGycb(8=U@ z)r)DBi8a%dk&TOmDwZ3j*aSyaL2t-)`5Wu=&_+##Qjfw*(synJB-+QEuCX8?hzeAMmiivCsx8r3u*THW7f43u0Rqnb^$uEnMW3+d=L4Dipi9b4$}(v#|KNU zudpiO0rld3r5xUsK7T)Rc2BH6?Icd){PRqVr(Mio*6?^k=?~3o9-SBuqs{t)QETGp zM!r#&stwL2cV{dj%K>gpuEo6}j6~iD%Fn(s-HX!Iz_W^90p69`2S^d)*zs_*b3{no zT~=25Z|#@vYTO8QoUt^zbq%pR;b1`DQQfQ05Qf7EV{=}n3qNLm;g)a%!pu!c%=d9g z%%m$|NX=mF`ms`Jl3?I1i@;D9m0wF|7FwPGmMnAnq;%UMwZ$jVVs1YEdc`m0KP?;2 zxiwj7BsNIq>~jVPNt(5Cn=VajMy9HaIB@o~I&^u5YT7f!X4edP2d>{odAcxFxZsMJ zedgvp(vpNVyo~eVN!NKbB?Qa`VJ%Z5=v=)ae5f`8AyJ!nN`L8ETV4~fMy|MyF{zG! zWPV{#BR}^NxOT_EOkP-+uhM5r-k{!sGX!ekD4=Q0y07j|(9j((e;-DM;@Wuy9K5#f z-|8vHV-i#ISzMbT3dX&JZmm*WakWK9g1kanaa)GIk?GT4qS1tK#mCGx?vDKEoEk@0 zQ|+9F(+OtZ&Sl5j(sUv}vR3qjaC1yt@-_k?M?3G7p9s#bFbVtOA{09`*o?RRz{#&2 z_;lodLm`4IPi@u2q7%S4V z?zO(Ed2cAfUBdk&KBUvv zYN2RjzuC`+WKJe*q90o%{DwcZtZUu4Y^@y0SouMv&tN59DV2>&@BpIkonT*@xZ5q; ziyoiPcFN_6PQaHMdOQx~otf1oJCcX3^XvEIeqFNyCW|yq9^*wLf)rWnb4xQNsuG24+LP89mrBAv$PrytHywl2@6ayOVaisON6_9- zT*}b;9me73%k~AA9O>NXN=@Cd{Myg#J+7%8U3eYN$k}r>Lx!I)SKJFkk1B6J16 zC99lE>uZW0HhHNc8&!^+H+5%97atQ1Ai4?;RAyemOUkdbQBT~NYpxT$PY%T-p+H0? zEmp!H??vkHsRFLyg4qOz7pX?}RIUAX$ zu)ZfcrO}aHMrPuad0y0;Cdz9PnG|O`l(yYvJyf#N1bF-x^C`D(h{Qwj8uCU+9_r8+*+E*Iw;?<$` z85HKCcKS4-8;9fbK~_O~pNP>I+|hf)Jw58=me#5q^V6Gc9bCBxPFP-5fLJ243+v|t z1CM!EQt9V|dtch2uh>GQap~~X%6KFKaYqrPZ;&8q*&@j`nxTI((G=(P{L5ASFwMd| zy5L>}Rn%&B>v+Bp?f5U%9%p6y-+Bip1+^ihohZmLgf$+4#q$WCh-;CgyZ70s zcm&yc{G=&)dR|NgqE_Q*R^#qA{5I(pMhz4qq}5YV=^oUdd}dh(Q?piFmB)DL5VaL% zZAqNs7V=~A-A8=lPj*CAp76JBid<-hByMQ{I}o5nlWctDoLX}XwcdFqpPPL((<9i& z^8WrsF)Dst2yHMOs_VzzaELB=Zb>Nk_A=t?H@jaW#&u3TT562+#WE_u6mvkkRGUk) zn4tbb>KuFB);)-KaP;>Za?HhwNN-`9B#-YQ5Y2ioA4Z#cE2#Ozw#&Qo1H%6p!^yqPDX zO;2#>y=>32={CPV-K3?}m3M-NoKE1XT{X*SQ%CncmL@^{^lCp5t>#%wG{`fv#Z_4A zQp!TUMycOb0Dh}e?5x3|uV1NcS39AYWk$-g&Xl1Wq$-^>mAN#V2G=4MePa>qjX}sj zp?>2JIfVXF);Cr*%x`gm!cuPkrb517;UP zn#R<3TyWvrdZiLP!=!=9AkIgI3(Z%=O24e#aP?)UTOnv`A>NLo%k%g7X*PooIH7Eb z7B0&v>{sVMH^@D1L>o&+NL1^~+^+SOnmcc{?uM6*d_?^#l$iU!vd9W~_NHydPfBaIvmltdu&6ug3Vit!4t2Z& zAHi4@QadJu!5)M{X{?9QKJt(HWWJd2g!PDS%!M0DH@YdGrt!;N$=CS2LHogSro}Yn z;VkK`*uoJFE9v6*h|=>f%lz_-jh=H~8ctm*QBdnZ)t0Z>%jbong$i4_!R%LOlML#w zxHEHL+@o$-BFkVPP`9 zgbva{DVxxn2+~6*H0g+lfFKY`=%F`3dKC%1NC~}HMIs=@prFW(iiouRF5LJ1JUnU$6Nn3>EqbCvTthiTfWH#{~l*?@mL?Y7mX-5UJ!muvLL5Mt3Pf24II0}Z>B z{&#+g&!dI8;M5vcANcP!kPtv+0S=~w!(mjK2z4+L4vs_~F&`CfuKC2@RAU#lP4NT4 zWLCmxQTbD~0Pzzt&$P~7*KDlltR}#=3)M5AlY9w-`DD;xr zLSKZ#F~@fB_YGAu3*)gT-{QS8_V3y$NX62wcV_QkO|s7jqWOSq#ax;sM#1(vnTRI( z@YU|2osY+oueZq3jpTcAyQ@=4#>lJJQm(_ee)s?xB;#*YQs(l}xpNSkgczCiELrro z^xc#Sz70v0QZmX@^k6QIFDa&3X;3`<2%4Zv(Z-EqU0`RJhi;^2B}G>CB&?cY(f7r} zDB@IMqRazxpAY8tM9e z97?IsPOiV=FOsY^Qu6!rqXsqmZvUyl?~>@z?NOwJ8zvwTD3SLaL1;aSV}7FYsA{nY zwf<9`H233DH8o48rIUFo5-cGJN(iumxn8nO&6^X21 zz12+x(u*{2ip5Rk_mqidWmjO1&#d?No z?BU2vXtlW#XuLTTV}UJe=t&eQ3twu%jN+6KDQaK;xd6fe(7z{fykQWms))N1f7!m? zJRQS}kPC){^$3AQ@LU@<;hSx zk$v?#{^sk!lo1q}O?$WTu$KzGtMqJDzkUf`M-)aGvCie>(azC1(*}Kw@z3u&rcOav ziG}`!uM9t-eVviE;9w+ULjXlOL|Ys)>({h0v%zNHu{^87hI)&tJ)+>BU_x9!qoPW$ z`nJpC_2rLekOEsxf60m$duTf^5?pn%p(_UY8fgI%fOtP_Dza{DJ zOEMLjm@Am~p~zS}Xj-H8@gF2X1lycBFbcebdZt3htd&PnnQ+2W0ZbIo2P3M{(Ie%A zO-4~FUYIhbX}AG{NS~)etGV2C8{OB}H@H8~&aR-q1DOL2o9?7mq?j1F2k@1MrK_;u zi`H|+tXOq)@sf)C{6Uz0?-HFw>G)+SoJYcvZjjG*I56{B(;;xv%6;jWnNmEB{M!#a z8BGT!2yrgQ=S}UoLtQJwEtRXIIzk?oN}IaIr5J9I@8tLF^7)f|i32;c4IN$kGg4cD ziM(SOUW%O>*krdYK1260%hI|)G)WQv<_eoXQO55Q#4X#g=OU0R>JbUXXi{nN@*Y6| zNdZEtz~FdBUs^sj!VE*jk5V*|EbEP<_R*#DAg)M@B@DANUt2!|ZeMG5G3=6C5YroV zdF%G-WUa&|4z_zf6kTGyiZvWYinOKDx8%St0|?_7&W# z-+M{8F+z-H3`D+faq9MZn~=PN7D^!q&0f$mD4ZeF=Bb-H$U#?j7OivCJ?r}-uQl^q zg@xcZ>9*+Vn4REzB@q;JY;3GR?&*1~S|&|W0uI*W<;JnGu~Dhk#fi)WQ2ZzXpwW!yR8ydNcXM%7Ln>!nO|lj)V-vL+Xq!sF~=fV!l1z z_1Wi0a_goa<4^iv!gXn~pRBm4&4H$3+^3&_Mo3e5F<}LT31Wpdf8st8_Wp!WqVxsrdI5VV+GTytAmTs{Frappur}*qB4eDbWw3mksm`wLe(MJ@w-v>&kqFQIys5Vo4Yf6XUdK{fuolBgJIm<(^4UIQJo&bD5u& z7AUsL47evX60w~Udk`Y89+xBI&UOIi)~Ck%uaZtFhuO;pH;(M%{F4O%823LH?wSWy z_jN*E5GT4p>SzEwLBT#fNG^o-2N{Ak6k&?||KcftwWu1$J4gnS;8_tQyZEAJo>GzNyu`35MTWyPUS&?O7nE145+cH6!tyukbaU zhWi9(ueIWqG`~4D4$vbTyHiF|x#^Kc&Rbr(P82vK9|@{$U%RcT;PtmUua_(k;2Di+ z=bP=wT;aU(G5&1RaiGmg(}1B!CuwZELDx`c=lpCbOrH-n)Y-=W{UhFpQuWHES-T4{ z8*T#Jk&!f)z?icOP)#HhZh1%nP<-j{`o-HjT1Ow;#Ud6ohuQ}ta_Uz(&^$GFG<(WK9WB(_{h z%Y`i7G_^4Oh!J+{r&Ib$q+GF>W#+3PRx1YkoMn;`CZ+(d+mnQXHFxsJy~A^K}c5KER@JIJ1ser@9S%@(>D_Pm-=TYIEaJH4 znQI5!QkU(oGDl`lZ^T~K7xI$IOhKz#_*6a{6m7G{uGypxuSLLDqm&2I1?fJUxFB_d zia(Efb=f)fqz45eoe45BH@}Ygs{p|JGN5Mwp#RsO=DaGpU^1SQ1Zn{;?+HSX>r>wp z3m_9;K6M0pSZJ+dc*rUJDijR>aY9@)%{{q>y__SVj)v7dkRC1&?;~p}(zyM`;Ev^< z|6Wa!Xls9@0!!a~&aTgAwy4u9dLHUk`m5M$s0>@va7Tz&x&I(>dUQ3$HG6$*?Xqk0 z+me`@7xEcVK_b|Yn0Uz!cH%*)M`TIP=kC-jUrz^6JHrcX5@MXKDmFN`y#MItb*~>c zUhA4P^y>(;+OYzW#WFNH7@e}gNdWd^pl}fyv67M!qN*s7X6{rR)#$iNL?Kjb7Wf+w z0TNV-DydJoTR8aTIES3~2mhwhTvtP2gjFW`pLc*4^H#Ctd}B`c#QpP#s=EGNlDWLY zQaJxpxy?ZBTk(NgzLJiXqAux67Jo;9sHHrc3bL7QX37uobMOc#$k=XHyPN7y1iBbM zmd~=Ktx0Yq=F{Na(f5MT?Op3n-ZX7vu4(Z8I26LhO#@7>R)|b+I9~X>lE`52`xK|3;o2?SAf+0 z#RPDznK6EcYd^nDk-wzTZs+@A)Wy5Pj;Av1+vt|2f?wXY9suk^NDlYu^g~rc*pZ6X7bI941Cun2M_Qb* zkt5Y8X|EftqchV2hi(s}c41SbHoiO2gF0u6I<+5HhLVcAgmH1wB;9ng#=-i!^v9~n z6FdboyB__;bw5E)*qGF!B5 zxX*tSYKsL9HGt~DxU5l&$c27_`$bMM0q&*-M~;y3ZbRe(h8FPfY&P!qE56&OairjQ z|AMAj2zZv*1)iT>HRx-nsPI?20-h6|xJmfJtYs_HcQ7%1WehFMm+5}t7j4}3v@d{; z%H+RmLz7|tCe4cjD`BHnS}H)qrfUz`lXipmpREX_p)A8>|1t)ykX|gyWlguLEn2S| zP|Dq%aS4$k79?yulRA-gzG%{m9H0LK#tY>T>?J>_83W09#CV@E)V!bI=~|H8Mc?1x z59{C2{kW%he|X>aW){R6|M1itZW85BEIGO-zl?ar>%Fdvw+PpoBhVFcXMrAeG*XcC zV$-CGYkZ6Ly>pQH_PT5P?f}%3WDMcn{RVFD0Ju%_rEDcA|K5@Z5; z%F&mNtNMnM^V>04B8^$3F}?*|?avoH@bs3}nq9%LkojpgLdB!WJ&blEha%n3xrgIA zU>t=SJ216#sie5v^F$DPBhY!Txzpbrw-*Sv&E)Jz4IDbR)gRo%2lt`H&vMj>l@ zwLx~u+G+v?f)C37xnM`i@M^=z)SY(cWcBB`Z(I|+%{nGh-Pj%p(J{OX^~f19cfTDW z`ik-~kDKDorE#u`uZhKd7|gW!!L6DYXzS8zKOk)tNpZ6*(Q}!Pt&<*CyHs)SOlp#a z(3pLy)tbE#{@U(vV!MZ>|Ij#Pq!@XJDVSfcWUld_3)SIot?ar5ecop=(HtH;X!82a z^*5yBvE;_&iUHk5FIAl;V?#&}xXyJdH)COlEub<)_108B4fwJCvLWRnwgWey`J+$b zwHG-?cV!}34{a6fofMzAglL0dhak7yTbY}}ooI!xvVj*o&N973EtqYBB^ev^-&5e( zez8{5)n!boE9wi?r__o# znkrvI{Fk+F;stMtp6^4>1!EGaR(U!wDD zkY95WRvt5#Fr@FN`JNOWb~jdGD+grol_&`(q560;4DR-S%1m~uI0SFi7CXyxq8v%@ z;*he;`*$QnCvbttuIPxd#Tfn==T}Jqu7O*^&ZR-=ZeM-|7#%-frJl||b-*UI*ye0+ z6@)|P8yg$(ik~*~g#KF~vKj(MThtll^BHvjZU_)w0GpXsKWFZ21<>P_Ub_CGk>MA9 z3%VZ*Ui;_55+>7FAag6ZEKnWF?%iYT0*0*1C8yaFC>84#M79mNd zeFGel!`jQlOp4Ib=b5iT+_mU~tS@%? z`s|A@i<1rbP7@yq(ed9|o?zel`1T^d$5EW-fqY!Q>r%$fp;ChT+GTddO9hs@rk&!K zH5Z_dOGa+#t(QUe3lsdbrN3g^otu=BjKoV_CWqr%ax~9!oD^7H# zypfsO z(*yhwE9`f=tK?t2mxFciY&lT@R>;Y3yGZWLx#Tl90>i&0Dl6xvJwatCs}iq^5Meph zJL|pj4Y|fgehd*Q8~2P|X2CoA?9*xCRsc3*2Jp$EXKqw!-WyFN!bVL};k4M*y7A$^ zOM~t#EH{b$*h=TTx?=w%eU<)O_;XYC5vw%GL#SJ%1p+H8EzMUt03Ev$qgV%$Ye+NL zo4#f-F!m@Q&wzhIidgGqvP9^2|EqQ_eEpN@H#^~t&^d2Aij#AM?KuiFqns;c-3mt~ zZJ5VT2!`K}ZZ8y=OWd@^Cvw=(J}O)q8u*$e6xEC|sAs}y==m>S3s4~(liYI|rvq6c zhICwd)q7WL=`9}l}zw@||#`j4$U6KD9c=e0_t-orO_5_K?r-DW!y_#41D9Vj867TD$ z9m~ui(K3pO<~V`oBzh`K2tm@`k1-f&PeOtEvGLL-WT8N}sFw0(W>b0}%^nUmq$QvE zt?o1N%^u(L{(w#z$`Ac*gvQuF8&sn}7ysDS&;^8g{oS)s$5JIzJP^iROnw_dz4I_)scT%wJ1`92AXGXAof8uB zL`c{7SF)xB@OgFUw7*`-cBq=zUJQlaOfcD_C|!C zSvI}Y&@gdT7qPPm51u>`3={ldTC>KhsX`8yK0P!uv)wDJfk6pI!Pt#+kH)!g0H*ZE zYS=B1-3_@9SI^ho+?7@e8<3n*pMnadh3?ep*=xeC%Iv&)g=fo{0`4icT(6)caTn zltW#Y92Zzlu5qB>o^tHbRPcmQI6QAmf!~f00m%^>YSw3(C=HT|iI)}}K6&EyMH3`Z zX{{I|b7v`;K)P~u&pCXrq&$A9&b=m;1lmm)UBp=`Gjx#V3n2B=g41GXk(AJ8D&v zeK|iqEItJvGH#2D(jg8Y_s|@A-C!SX9KM9rmGWDh-O1x&^R+|I7M zB89j$U>r-Q{@Vy|G7zXLj`?AMq&~^|+v>k^1qfFz5JL!6l{X%{@;y&jx_mxZrsSC4 z3)>ZOxvI-qtFpD?F73|SCe{?h9x!S3lWp&YE9G3sD64RqcsG0yVmYTE>rPm_&y3@S zrtr+tS4U&Pw3h9)Inc(3ASr=L#{lBS&!wdz;Q)Cq7l`K|V-}b=7(h^e7{T`#TEZWV zk_<>afP-^Av2{%9UAzN4Z1?6W){uspB@JdJ`GFE2K+ZiQ)dvPX;7B!4Kg2S8U|0RW zUXzo+Lscie^~SOPY$+Yh)xZPU(yn1}d>c#PdIjqDp3<=ld(0&wG@-jBOp) zR-~FSkI;~N63rO%o`zZyMOi)k3zNO^%9Bv(D-=gu_ir{4x{&pWsugTjY;>>aYjo9A zOyb6XV>w^LI|aP&8|r81T@GzIR4&{?Rv7b@1Kbio3s>_+Lcj z;d$y73+{L3Bp77#IRkHtZ@?rgu!Xy5#Z{tI6Fv&9`dd*F8MojY%%7l>#d11qPlNOoh<$xVEm5xzM_5%s{19Mf)i~ zg13U=dG2WB5X?jVa)p!yB#Zy&C|M+vw@O{Mu5t7Os&c7YI-9khPD$5Vb*Vh-h=FcU zqztxp@dGctW3wu1Sw~h@Z+epG(S*l*Jm{Mw#T85^O*FWz7bBMMzb?rRZlV|*$$gS| zyZ=2*ux5EZBvWD`Kj&9CL|fL%qUbVAtiKMAHD~oii0!%ZYXJ68Ir&^=w*!nLjvKwP z8;9bNjQ@RcZY}-iyFZTv_roxHCo(GZv42u3peK(GC9w>gaV0*=)62RY07>Dw*0Jma zSqJRP=mD>`zAmeYZR;0VHmO5vPu?>`4W&*yOxtJyfZeL5Gs6ikg%|a%~73)=ZBK3x+Y)*F~zGaUb97mMP+_L{A{zkg^Vh zTKku$ihDlS1;Sq=0yYiWmasBKQTHp4yB2ww-&tB(aLA?XJ z##1cm&%a$V^G)^hzSZ}wqp*Z4K$@E$=l}^dXWtevDsSNocaVnN_Ic<+@}A`EyyhAf zDHWk`wPf^Ba(rEdo!YVfdw;m39#8(w=s}6*UyQszL%k>F_u3Lk<^;#Cw>IxP$T5; zq>cNtiQNKxYwvf``xfD(sl1mZtcL!-J?*?DE?-}~qXU~aC{E(T6fhi@s2HxQ7|uN@ zs@zNP;v%p8WZqofI=6dDmH?*d%AKRIqS862&bO_xKPm{TL}(kTe0zZKRed0@o_GB9 zT;ig4H*v{bbj|T{rmh3=wdF78%OPL&=Alkb(r$@Onpz9Eq$9GXBZZ-O^Z;XPYF6>) zftJ;}#a}#LYlqU(Z>gx*Ig@GSudil<6wjEuM(2Itc1*2_UUBzd@(G$IIbaZq!*8ew2JC?u!!(uTSieVpn)6VRjJ~xEp#u^1`F%qjQiU z)9cTA>LN9SMoK$?LHasvMR=7iq^uVy2B@ps$HnOx-vW-M1pNS~Vk#d^?)rAS*p1)c zSHD%xjx3Cm{7oNgr4$q2IOaIyc5XsecUu`iSB~L7tPbCmcBU2(hV%BmPeTn3VQ)rX z+;ka{)0OaR+%~xV!8u7o(%O-h$|+3A3BRmziu9OF4%cr7?v>vUgAOQ#riL5q1Afpl)NjC^+|sq`G(J$rffZwTIUU3uyE`lepat? zJJRu)e{hEEXiLW8%F8QTk0ZhPp4XD3-?>*{@(pSh@x-gifZC{cex_XsR+0X+p;vQA znz7>f@tZ4lt~J8}KU_6|&L{@1=E2ao`S>7KuX#_6!0gwG2i;Ly#ajHL=m4R#2}O8uUG3dkbi>D6kWVZt zdRT~YQ*19USisXG8 zh8gLs@D%xdNrBtv!IQ*J^GQfHBV(du5Za-v;@*v~%TDB&1B#c$&t5G!m}XShD+>DE zeS1Yk%UCZh!6)fPT@l~6IzSLbzD$tzMU1*>CE|r}1!IaiyCdj-{q!2K9bpOkcBLc2 zOO-nElMhY4Zb&db;n7fShhBcM=ny4_9T85s%73HRd;ov-G3(|tS$Yti`@Mqt@h$Va z-peZwXuWvTI+fE1Jd_+{@fJTP1*I)Nnwc!2R#$kCMBMWqqx0*9MGnZtEOPMC$|pTwCydov}0GPB4V;IfWO zZj}2=x3ay4$9yNtEZ-w170)n0POj2hv1}1ENklUSr4jM8_4S@Hy#@d|!uDK(p~F7n zpq+xyp^5skZBz0vevPNX$yiajUq5L2p9@d3J`TM|thjw6;opb_X3mGI3%;As2wmX% zXlSW~-q%|=?KoS}2@~x>H1m*=s{T(XbLMm44d2sqIJpqU4oY){>Ew3s65HtVvkT zHYSEE(z330$2a+|9t~&AgXgc!J~`M<&RiSH!wsBp%K4222uv@R(mVVeaX&rh&eT`L z`j85Y5;f)Oz-nN9(>c!`elR_4WT^jRBSnwRvq8QG%M5Zp5@9jn-q+gr{R5Q)ko992 znlxVWkWb$FCW3!ba{7Xm{mt+_#^_M6PQZM}75l;I|E$UVa-vXAvmDNm=>R>v7a5oDDjL z)e6jxsz5PKzEJCafil>W@>%WYmV2V`B*80oUZVB!e$M;(nc0?W0VA7EtBl{bvj(*o z{#wq^+zj&2N4xAiox0|oOs#lt_k~Y3Q5T>CoUxLGZXAYj|jrPR~46T>rh%HEH96u#+N z8R<6tlA3AsI&0F$!B;Ikp2c@>RbMBdtkTbx$?wInI5BM8h|3Yk==<00)ce_{-_F;2 zR{mGXr^MB2tn zGSz%%z^{yn_}tA*m3@P{e=LEQPtQFt>DYBC0i8yg=}%E1Oqi)UupIgvWt86t+xPUj z%)uH;`|g2XoEPhqWX8FfqK!e+?gl=gx!38wdrJmYF@Q9rFWG8CIexv*%S{8?gG(+t zxVC5(+`Y@I2QTodysC1wWMw@UCbPjq`P)Rzp-Xa`#N;--fKo@WUyJ|yfwXn15A|H! zuF+TxbhI4?1lI+beBW)l!P5vgcP_?;yzD!(psu)7EisgSQCG{Eay~gIRxN}t!;v@D ze-c47+-00YF+8n?sb6##EgR~AGL(y2a5jU7!`oDr)91W?U?70i?;YMYpJ6zk(aZAU zJV_YHrg?YQO2N`D<7rj%%SOCpE>s7qn801D;~yKR(7ArpqW{`RE(29R+-`4Qk}%^W zEUZTtb1lDV0%EV;YC}WMPJTc}Lw@skc6!d_2A&E*(196}yNB+^+}c_Rd*KTS*%Hc#OQ$3fwWfcPz%&S0Wfu)GJf7 z`bYBy)GT9Qe62A``-*PwhFLvBzVFanVs0)m_r#O3SQvd|MEQA0wJu8@=J!QlLY^!c zlRjdn;Dl`16_1r~OBg2SN!+d8*m66Xotf{j7RzRIleU-G;J1#^B{m^vn5|*4pk%+S zj{0Ckx&%dy_n_+DQc@uVzPOxPpoM4(;z8_EhXa>Qv;6QVuIj|1$jF>x*A~hqwPQM_ zZ<7cmEsf?InN}h~g1Lli^UB)klgt?oq9fWY2>TL`2h{#>=@o5*Z%ts~SS%*&+=KJ4 zbGGV7qts&DjApRP6*8*ne~i)}hNZvwjWmF#ihB}*nO&+|uIqIC+sM(6El zx$Ns36d&~CqF?KI1X5qc$r2h_U2d5nLjm*lL9rGp)NELzq0L#~OgQk5$!g{=I(gvQ z1pm#}g*1{BjM#DJK1=+3<@fg!6`3j1^7S^(%l*(%uLmOLSIC?Q*8q|ee@_<^2oet< z?+9{z_#W*ruGsa1vny%WKMzi&=cg3^%5T)@kXyqsBDU3YBrZ+m=L_mo;xpn0{$^x~UZw?bCEu7!2X^X9@RNL>P_!PqNa! zXQ){%*CEY^xuu%R1swR-LF-m|KC~Xs)Y%lAEOJP^&t`{LytQ!EJWIq}TCV|T+V`)5 zBzGDq`KS=X+E%X)1i6=68rNGoZ?#zEiVbDpA}mPA*>~>wA*Q46o(5bOx^tqm-VG>`j) z<|2hi`nGoZW+wkY+Mggx?`L0)r8z*1v06ubGNzEmsHu=15T&z2{7t;Frp7CXk?%b< zc1@gG`!YvDnuZkX`zVQ4w8bHn>0yA`AMz4Hl}|eXi<>jqOnR+WnmK`fv2- z?IFDvAB+5nu3y{vbq=(8BoKE za^~0<&%iY}Oi)O*x(r|J((v%l=Cd(zI{n`_gt#0`@n-t>Id(PDlltOCI(0d{201{E zG=WswPI57W;|m`tRzVHZYLc~&`z5SiRbscH3dAP=o|xQ8g@-( z5QUq9u?2MHwVLyN?E_{IbWVPG*t2+y{DJ7i!=6U@s?Qw|l1Ba~bnz_iuH)z=fa6A? z;Pr`CIeXmSbkUuR-&caTK`gaBdcr>4zvcz3!TrcyC-+@TmDsj{Y?)YG?=hWLAL8gw7vU*wdlFWv!3%z`R9Zk7}@kQsnG z0tGw+=&}Yo(Gg{RiuVwo3Fj`ukKSf?D?=2D2xa!2aqOVi3G6qm({_BQ!{}>0P<&W;800lKyEN-%-v56P` zpW+f0TCGYE?9{}W8E8s0ceaUF)&_8Zu`GNxnSlbo;Sx)wAvo5q|9ttsnj;>s!J6^9 zOiNh?><^bEM+z;&hEoIS(PpW(0}gf>%MI#exdc1rfo1!ovcaB=)FR@H@v9>p4oyXT zlK7}VX^#*{K###&3FYd6hUZZj6cK&XO!V55p6e!a5y7+$MR!x%0&w94*YZ8J&1oLM zw*xi?bz9riyUppw$nRR;XDbNtKXL#`m0@WJSYw@ClsMfx#bjU0t&o2%3_hp>dJhce zT$-Km^5;*6Mrd{U!mWSbJO62t$Ih--`-d@v<5+(GsX)C$;~Hn`b|l1+hIXfPE&QJg zaPjZ|fAw2xU(D5qcZc3wO%S2$zwGCY(X%GaZknwe1)wc7QZrxKD1)x9%#_L%4qv^; zY?dJ~m`}*LALHQVKp)~7A*Dh0ia|T;_>p^p`{$R7j9dny!q&+p3PwLD@9FpJIrw=+ zkzcylPw6i`)G*#tR^Mofddui6&MF?I)fJCbzZcUlcYO?u5Dz~LEz0W`|1MEMWuI^o z*E?#b>8X!yYFXWCeO(U8vv}hDE4DYc+?N=FtFQLs8|Y(0R~YG9oBJD#Egd@ z$MV1$g~SzfzKh+LE8vLD?bWcQ5>6ZYe%BqiH7rlC{XymKcA|%a-6gM_-1gWG=bk|^ z7LwP=#HGTO$jAEo?M~K~Z{g0L0&a_J1URbiI-0oWM$vn4E>IqZqFqHN!GrtG8s8Bb z*FWGGT#ghY64%ZybiBoRk)7v!%J`3 { - if (document.getElementById("optSound").checked === true) { - global.music2.play() - global.music2.addEventListener('ended', function() {this.currentTime = 0; global.music2.src = pmusic[~~(Math.random() * pmusic.length)]; this.play();}, false); - } else if (document.getElementById("optSound").checked === false) { - global.music2.pause() - global.music2.songname = "Not Playing"; - } - return; };*/ - - var checkbox = document.getElementById("optSound"); - var audio = document.getElementById("audio"); - -checkbox.onclick = function() { - audio.src = randmusic; - audio.load(); - audio.play(); - var context = new AudioContext(); - var src = context.createMediaElementSource(audio); - var analyser = context.createAnalyser(); - - var canvas = document.getElementById("canvas"); - canvas.width = window.innerWidth; - canvas.height = window.innerHeight; - var ctx = canvas.getContext("2d"); - - src.connect(analyser); - analyser.connect(context.destination); - - analyser.fftSize = 256; - - var bufferLength = analyser.frequencyBinCount; - console.log(bufferLength); - - var dataArray = new Uint8Array(bufferLength); - - var WIDTH = canvas.width; - var HEIGHT = canvas.height; - - var barWidth = (WIDTH / bufferLength) * 2.5; - var barHeight; - var x = 0; - - function renderFrame() { - requestAnimationFrame(renderFrame); - - x = 0; - - analyser.getByteFrequencyData(dataArray); - - ctx.fillStyle = "#000"; - ctx.fillRect(0, 0, WIDTH, HEIGHT); - - for (var i = 0; i < bufferLength; i++) { - barHeight = dataArray[i]; - - var r = barHeight + (25 * (i/bufferLength)); - var g = 250 * (i/bufferLength); - var b = 50; - - ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; - ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight); - - x += barWidth + 1; - } - } - - audio.play(); - renderFrame(); - }; -}; \ No newline at end of file diff --git a/neroplayer/stylesheet.css b/neroplayer/stylesheet.css deleted file mode 100644 index c6218fa18..000000000 --- a/neroplayer/stylesheet.css +++ /dev/null @@ -1,14 +0,0 @@ -#canvas { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; -} - -audio { - position: fixed; - left: 10px; - bottom: 10px; - width: calc(100% - 20px); -} \ No newline at end of file diff --git a/neroplayer/visual.html b/neroplayer/visual.html deleted file mode 100644 index 658530558..000000000 --- a/neroplayer/visual.html +++ /dev/null @@ -1,15 +0,0 @@ - - - - - Audio Visualizer - - -

    - - - \ No newline at end of file diff --git a/package.json b/package.json index 2987dcd79..68119883e 100644 --- a/package.json +++ b/package.json @@ -6,16 +6,15 @@ "startOptimized": "node --optimize-for-size --no-lazy --gc_interval=120 server/index", "restartOnSaveOptimized": "node --optimize-for-size --no-lazy --gc_interval=120 --watch server/index", "start": "node server/index", - "startClient": "node public/index", "restartOnSave": "node --watch server/index", "host": "node standaloneClient/index", "build": "node standaloneClient/build minify" }, "dependencies": { - "ws": "^8.16.0" + "ws": "^8.13.0" }, "engines": { - "node": "16.x" + "node": "18.x" }, "license": "GPL-3.0" -} \ No newline at end of file +} diff --git a/public/app.js b/public/app.js index b44b2aad4..af49506b8 100644 --- a/public/app.js +++ b/public/app.js @@ -6,7 +6,6 @@ import { settings } from "./lib/settings.js"; import { Canvas } from "./lib/canvas.js"; import { color } from "./lib/color.js"; import { gameDraw } from "./lib/gameDraw.js"; -import { tankdescs } from "./lib/tankdesc.js"; import * as socketStuff from "./lib/socketInit.js"; (async function (util, global, settings, Canvas, color, gameDraw, socketStuff) { @@ -20,732 +19,7 @@ let { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow } = s // document.getElementById("patchNotes").innerHTML += `
    ${changelog[0][0].slice(1).trim()}: ${changelog[0].slice(1).join(":") || "Update lol"}
      ${changelog.slice(1).map((line) => `
    • ${line.slice(1).trim()}
    • `).join("")}

    `; // } // }); - var playbuttonsound = new Audio(); - playbuttonsound.src = - "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/op1.wav?v=1675463613542"; - function PlaySound69() { - playbuttonsound.play(); - } - var clicked = false; - - var slap = new Audio(); - slap.src = - "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/(Audio)%20videoplayback.m4a?v=1675999054321"; - function PlaySound68() { - slap.play(); - } - - var vsau = new Audio(); - vsau.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jake-chudnow-edited_y1t8j5q.mp3?v=1706018057534" - function PlaySound99() { - vsau.play(); - } - - var clicksound = new Audio(); - clicksound.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/sysse_ok.ogg"; - function PlaySound210() { - clicksound.play(); - } - - var trapperclosely = new Audio(); - trapperclosely.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/look_closely.mp3?v=1705291786778"); - function PlaySoundtrap() { - trapperclosely.play(); - } - - var waterflush = new Audio(); - waterflush.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/toilet_flush.mp3?v=1705296502578"); - function PlaySoundwater() { - waterflush.play(); - } - - var undadewatuh = new Audio(); - undadewatuh.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/y2mate_HOnnyD0.mp3?v=1705296505126"); - function PlaySoundwatuh() { - undadewatuh.play(); - } - - var piss = new Audio(); - piss.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/flowing-water-sound-effect.mp3?v=1705299861150"); - function PlaySoundpiss() { - piss.play(); - } - - var pew = new Audio(); - pew.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/pew_pew-dknight556-1379997159.mp3?v=1705299975747"); - function PlaySoundpew() { - pew.play(); - } - var chipi = new Audio(); - chipi.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chipi-chipi-chapa-chapa.mp3?v=1705302832837"); - function PlaySoundchipi() { - chipi.play(); - } - var neko = new Audio(); - neko.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/neko-arc.mp3?v=1705302835953"); - function PlaySoundneko() { - neko.play(); - } - var bwomp = new Audio(); - bwomp.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bwomp.mp3?v=1705302839344"); - function PlaySoundbwomp() { - bwomp.play(); - } - var nfl = new Audio(); - nfl.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nfl.mp3?v=1705302843389"); - function PlaySoundnfl() { - nfl.play(); - } - - function doSomething() { - if (clicked) { - var optionclicksound = new Audio(); - optionclicksound.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/cancel.wav"; - optionclicksound.load(); - optionclicksound.play(); - } else { - clicksound.load(); - clicksound.play(); - } - clicked = !clicked; - } - - var smallaudio2 = new Audio(); - smallaudio2.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/error.ogg"; - function PlaySound211() { - smallaudio2.play(); - } - - var smallaudio3 = new Audio( - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/socket.wav" - ); - smallaudio3.loop = false; - function PlaySound212() { - smallaudio3.loop = false; - smallaudio3.play(); - } -var killvariablenamething = true; -let metalpipe = new Audio(); -metalpipe.loop = false; -var randomdeathsound = ["https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/metal-pipe-clang.mp3?v=1710271073637", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/undertakers-bell_2UwFCIe.mp3?v=1710268959839", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/aaaaaaaa-online-audio-converter_r9waVUO.mp3?v=1710271069219", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/vine-boom.mp3?v=1710280969499", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tmp_7901-951678082.mp3?v=1710280974624", - "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/emotional-damage-meme.mp3?v=1710280979660", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/discord-notification.mp3?v=1710280983356", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/wrong-answer-sound-effect.mp3?v=1710280995813", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/clash-royale-hog-rider.mp3?v=1710280999656", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/goofy-ahh-car-horn-sound-effect.mp3?v=1710281004188", - "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tf_nemesis.mp3?v=1710281009502", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chinese-rap-song.mp3?v=1710281015151", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fire-in-the-hole-geometry-dash.mp3?v=1710281020367", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/water-on-the-hill.mp3?v=1710281027326", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/taco-bell-bong-sfx.mp3?v=1710281032201", - "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/download.mp3?v=1699142486910", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/spongebob-fail.mp3?v=1699146799125", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/62640b13-df2b-47d8-a06e-fb63b7fbb06e.mp3?v=1699272890577", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/f93f6d33-9dab-4e9d-aebb-917fe2d22982.mp3?v=1700153956047", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/c647ea60-edf9-4bde-a0af-c49353593c7f.mp3?v=1700153959194", - "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/feet-gd.mp3?v=1710431699794", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bad-to-the-bone-meme.mp3?v=1710431694343", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spongebob-boowomp.mp3?v=1710431689245", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/holy-moly-emoji.mp3?v=1710431682780", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/dun_dun_1.mp3?v=1710431679063"]; -function PlaySound420() { - if (global.killsoundready) { - killvariablenamething = true; - getksound(); - } -} -function getksound() { - if (global.killsoundready) { - if (killvariablenamething) { - metalpipe.src = randomdeathsound[Math.floor(Math.random() * randomdeathsound.length)]; - metalpipe.play(); - global.killsoundready = false; - } - } -} - var grubhub = new Audio(); -grubhub.src = ("https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/d318bd1e-5162-4fae-a757-5c350b16ccc9.mp3?v=1700153738394"); -function PlaySound169() { - grubhub.play(); -} - var smallaudio5 = new Audio(); - smallaudio5.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/poka.wav"; - function PlaySound214() { - smallaudio5.play(); - } - var smallaudio6 = new Audio(); - smallaudio6.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/finish.wav"; - function PlaySound215() { - smallaudio6.play(); - } - var camerasound = new Audio(); - camerasound.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/camera.wav"; - function PlaySound213() { - camerasound.play(); - } -//Music functions: - //decide the music - global.music2 = document.getElementById("audio"); - const pmusic = ["https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3?v=1705287022417", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav?v=1705286889038", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3?v=1705807057028", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3?v=1708218475743", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3?v=1708218464295", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.wav?v=1713352428783", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"]; - var randmusic = pmusic[~~(Math.random() * pmusic.length)]; - global.music2.src = (randmusic); - //load the play functions for itasdasf meow - function PlayMusic() { - global.music2.load(); - global.music2.play(); -} - let musicvolume = 0; - -//actually play the audio when the checkbox is clicked on (checked) and stop it when unchecked - $("#optSound").on("click", function() { - if (document.getElementById("optSound").checked === true) { - songrecog() - global.music2.play() - //if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { - document.getElementById("content").style.opacity = 0.5 - //audio.src = randmusic; - //audio.load(); - //audio.play(); - var musiccontext = new AudioContext(); - var musicsrc = musiccontext.createMediaElementSource(global.music2); - var analyser = musiccontext.createAnalyser(); - - let musiccanvas = document.getElementById("canvas"); - musiccanvas.width = window.innerWidth; - musiccanvas.height = window.innerHeight; - var ctx3 = musiccanvas.getContext("2d"); - - musicsrc.connect(analyser); - analyser.connect(musiccontext.destination); - - analyser.fftSize = 2048; - - var bufferLength = analyser.frequencyBinCount; - console.log(bufferLength); - - var WIDTHOFBAR = musiccanvas.width; - var HEIGHTOFBAR = musiccanvas.height; - - var dataArray = new Uint8Array(bufferLength); - - var musicbarWidth = (WIDTHOFBAR / bufferLength) * 2.5; - var musicbarHeight; - var barstuffx = 0; - - function renderFrame() { - - let deviscale = window.devicePixelRatio - - requestAnimationFrame(renderFrame); - - barstuffx = 0; - - analyser.getByteFrequencyData(dataArray); - - ctx3.fillStyle = "rgba(0,0,0,0.12)"; - ctx3.fillRect(0, 0, WIDTHOFBAR, global.screenHeight); - - for (var i = 0; i < bufferLength; i++) { - musicbarHeight = dataArray[i]; - musicvolume = musicbarHeight; - - var b = musicbarHeight + (18 * (i/bufferLength)); - var r = 250 * (i/bufferLength); - var g = 50; - - ctx3.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; - ctx3.fillRect(barstuffx, global.screenHeight - musicbarHeight * deviscale, musicbarWidth, musicbarHeight); - barstuffx += musicbarWidth + 1; - } - } - //audio.play(); - renderFrame(); - //} - global.music2.addEventListener('ended', function() {this.currentTime = 0; global.music2.src = pmusic[~~(Math.random() * pmusic.length)]; this.play(); songrecog();}, false); - } else if (document.getElementById("optSound").checked === false) { - document.getElementById("content").style.opacity = 0 - global.music2.pause() - global.music2.songname = "Not Playing"; - } - return; }); - - let counterthing = document.querySelector(".displaytest"); - let skinnamedisplay = document.querySelector(".displayskinname"); - let myImg = document.querySelector("#skinpreview"); - let lock = document.querySelector("#lockedskin"); - let selectimage = document.querySelector("#selectskin"); - - $("#rightarrowbutton").on("click", function() { - if (global.skinpage === 16) { - global.skinpage = 0; - } else { - global.skinpage += 1; - }; - changeskinpreview(); - }); - $("#leftarrowbutton").on("click", function() { - if (global.skinpage === 0) { - global.skinpage = 16; - } else { - global.skinpage -= 1; - }; - changeskinpreview(); - }); - - $("#selectskin").on("click", function() { - if (global.lockedornot === 0) { - global.skin = global.selectedskin; - selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; - } else { - selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; - } - }) - - - function checkifachieve(ach, lockcolor) { - if (global.selectedskin !== "") { - if (localStorage.getItem(ach) === "YOUDIDIT:D!!!") { - global.lockedornot = 0; - lock.style.display = 'none'; - myImg.style.filter = 'brightness(1)'; - updateskinselectbutton(); - } else { - global.lockedornot = 1; - selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; - lock.style.display = 'inline-block'; - myImg.style.filter = 'brightness(0.5)'; - if (lockcolor === "white") { - lock.style.filter = 'invert(1)'; - } else if (lockcolor === "grey") { - lock.style.filter = 'invert(0.7)'; - } else if (lockcolor === "dgrey") { - lock.style.filter = 'invert(0.3)'; - } else { - lock.style.filter = 'invert(0)'; - } - } - } else { - lock.style.display = 'none'; - if (global.skin === global.selectedskin) { - selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; - } else { - global.skin === global.selectedskin - selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png?v=1708718071992"; - }; - } -} - - function updateskinselectbutton() { - if (global.lockedornot === 0) { - if (global.skin === global.selectedskin) { - selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; - } else { - selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png?v=1708718071992"; - } - } else { - selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; - } - } - - function changeskinpreview() { - if (global.skinpage === 0) { - counterthing.textContent = "◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = ""; - skinnamedisplay.textContent = "Default"; - checkifachieve("", ""); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png?v=1708568179353"; - } - if (global.skinpage === 1) { - counterthing.textContent = "○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "bsignalskin"; - skinnamedisplay.textContent = "Broken Signal"; - checkifachieve("disconnectachievement", "black"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png?v=1708615075011" - } - if (global.skinpage === 2) { - counterthing.textContent = "○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "tankcharmskin"; - skinnamedisplay.textContent = "Tank Charm"; - checkifachieve("25killsachievement", "dgrey"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png?v=1708536680813"; - } - if (global.skinpage === 3) { - counterthing.textContent = "○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "dfxskin"; - skinnamedisplay.textContent = "Deltafyrex"; - checkifachieve("50killsachievement", "grey"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif?v=1708618924966"; - } - if (global.skinpage === 4) { - counterthing.textContent = "○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "primalskin"; - skinnamedisplay.textContent = "Ultimate Primal"; - checkifachieve("100killsachievement", "white"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp?v=1708602763032"; - } - if (global.skinpage === 5) { - counterthing.textContent = "○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "kangarooskin"; - skinnamedisplay.textContent = "Kangaroo"; - checkifachieve("killachievement", "black"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp?v=1708623596560"; - } - if (global.skinpage === 6) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "cswmskin"; - skinnamedisplay.textContent = "ChickenSandwhichMan"; - checkifachieve("killachievement2", "grey"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg?v=1708356424097" - } - if (global.skinpage === 7) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "cogskin"; - skinnamedisplay.textContent = "Cogwheel"; - checkifachieve("lagachievement", "black"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381"; - } - if (global.skinpage === 8) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "eggskin"; - skinnamedisplay.textContent = "Eggbert"; - checkifachieve("100shapesachievement", "black"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp?v=1714156807621"; - } - if (global.skinpage === 9) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "squareskin"; - skinnamedisplay.textContent = "Squarey"; - checkifachieve("250shapesachievement", "dgrey"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp?v=1714156773284"; - } - if (global.skinpage === 10) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○"; - global.selectedskin = "triangleskin"; - skinnamedisplay.textContent = "Triangleton"; - checkifachieve("500shapesachievement", "dgrey"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp?v=1714156768932"; - } - if (global.skinpage === 11) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○"; - global.selectedskin = "pentagonskin"; - skinnamedisplay.textContent = "Pentogan"; - checkifachieve("750shapesachievement", "white"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp?v=1714156764280"; - } - if (global.skinpage === 12) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○"; - global.selectedskin = "gemskin"; - skinnamedisplay.textContent = "Gemy"; - checkifachieve("1000shapesachievement", "grey"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp?v=1714156778841"; - } - if (global.skinpage === 13) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○"; - global.selectedskin = "coinskin"; - skinnamedisplay.textContent = "Coined"; - checkifachieve("tokenachievement", "black"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png?v=1708619146196"; - } - if (global.skinpage === 14) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○"; - global.selectedskin = "discordskin"; - skinnamedisplay.textContent = "Sex Update"; - checkifachieve("Getbacktowoooak", "dgrey"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png?v=1701908710293"; - } - if (global.skinpage === 15) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○"; - global.selectedskin = "deltaDecoskin"; - skinnamedisplay.textContent = "Cat-Code"; - checkifachieve("creditsachievement", "grey"); - myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png?v=1705301828958"; - } - if (global.skinpage === 16) { - counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉"; - global.selectedskin = "incomskin"; - skinnamedisplay.textContent = "Very Much Incommodiousness"; - checkifachieve("pissio", "grey"); - myImg.style.filter = 'blur(10px)'; - myImg.src = "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/1200px-Icon-round-Question_mark.svg.png?v=1699273933044"; - } - }; - let tanktype = "unfinished", - tankdesc = "unfinished", - tanktier = "???", - tankweap = "???", - tankabil = "???", - tankweak = "unfinished", - tankupto = ["Tier 2: ???", "Tier 3: ???", "Tier 4: ???", "Misc: ???"], - tankupfr = "unfinished", - tankorgn = "???", - tankupad = "???"; - let tabappearance = document.querySelector(".tabappearance"); - let taboptions = document.querySelector(".taboptions"); - let tabcontrols = document.querySelector(".tabcontrols"); - let tablinks = document.querySelector(".tablinks"); - let tabappearancebutton = document.querySelector(".tabappearancebutton"); - let taboptionsbutton = document.querySelector(".taboptionsbutton"); - let tabcontrolsbutton = document.querySelector(".tabcontrolsbutton"); - let tablinksbutton = document.querySelector(".tablinksbutton"); - - function changetab(vroomvroomimaracecarreeeroweaweerrrm) { - switch(vroomvroomimaracecarreeeroweaweerrrm) { - case 0: - tabappearance.style.display = 'block'; - taboptions.style.display = 'none'; - tabcontrols.style.display = 'none'; - tablinks.style.display = 'none'; - tabappearancebutton.classList.add("active"); - taboptionsbutton.classList.remove("active"); - tabcontrolsbutton.classList.remove("active"); - tablinksbutton.classList.remove("active"); - break; - case 1: - tabappearance.style.display = 'none'; - taboptions.style.display = 'block'; - tabcontrols.style.display = 'none'; - tablinks.style.display = 'none'; - tabappearancebutton.classList.remove("active"); - taboptionsbutton.classList.add("active"); - tabcontrolsbutton.classList.remove("active"); - tablinksbutton.classList.remove("active"); - break; - case 2: - tabappearance.style.display = 'none'; - taboptions.style.display = 'none'; - tabcontrols.style.display = 'block'; - tablinks.style.display = 'none'; - tabappearancebutton.classList.remove("active"); - taboptionsbutton.classList.remove("active"); - tabcontrolsbutton.classList.add("active"); - tablinksbutton.classList.remove("active"); - break; - case 3: - tabappearance.style.display = 'none'; - taboptions.style.display = 'none'; - tabcontrols.style.display = 'none'; - tablinks.style.display = 'block'; - tabappearancebutton.classList.remove("active"); - taboptionsbutton.classList.remove("active"); - tabcontrolsbutton.classList.remove("active"); - tablinksbutton.classList.add("active"); - break; - } - } - - if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { - - $(".tabappearancebutton").on("click", function() { - changetab(0); - }); - $(".taboptionsbutton").on("click", function() { - changetab(1); - }); - $(".tabcontrolsbutton").on("click", function() { - changetab(2); - }); - $(".tablinksbutton").on("click", function() { - changetab(3); - }); - -} - -let trollface = null; - -function songrecog() { -//song names for display in the debug menu (may move it to a different place later) -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033") { - global.music2.songname = "OI OI OI --- Action Agenda"; -} -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3?v=1705287022417") { - global.music2.songname = "Dejected --- Deltafyrex"; -} -if (global.music2.src === "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav?v=1705286889038") { - global.music2.songname = "World's End --- Deltafyrex"; -} -if (global.music2.src === "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/Meloncholy.mp3?v=1675465750213") { - global.music2.songname = "Melancholy --- Deltafyrex"; -} -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474") { - global.music2.songname = "Depredation Remastered V2--- Deltafyrex"; -} -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3?v=1705807057028") { - global.music2.songname = "Anybody can find Love (except You.) --- hkmori" -} -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3?v=1708218475743") { - global.music2.songname = "Resurgam --- Amaryllis" -} -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3?v=1708218464295") { - global.music2.songname = "Longing --- Amaryllis" -} -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240") { - global.music2.songname = "Killa --- Action Agenda (DFX EDIT)" -} -if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis%20(1).mp3?v=1713525419376") { - global.music2.songname = "Apotheosis V2 --- Deltafyrex" -} -} -function lagachloop() { - if (global.metrics.rendertime <= 45 && global.metrics.rendertime >= 15) { - util.submitAchievementToLocalStorage("lagachievement"); - } - if (global.savedkillcount >= 100) { - util.submitAchievementToLocalStorage("100killsachievement"); - } - if (global.savedkillcount >= 50) { - util.submitAchievementToLocalStorage("50killsachievement"); - } - if (global.savedkillcount >= 25) { - util.submitAchievementToLocalStorage("25killsachievement"); - } - if (global.savedshapecount >= 100) { - util.submitAchievementToLocalStorage("100shapesachievement"); - } - if (global.savedshapecount >= 250) { - util.submitAchievementToLocalStorage("250shapesachievement"); - } - if (global.savedshapecount >= 500) { - util.submitAchievementToLocalStorage("500shapesachievement"); - } - if (global.savedshapecount >= 750) { - util.submitAchievementToLocalStorage("750shapesachievement"); - } - if (global.savedshapecount >= 1000) { - util.submitAchievementToLocalStorage("1000shapesachievement"); - } -} -/*if (localStorage.getItem("killachievement") !== "YOUDIDIT:D!!!") { - if (global.achievements.kills >= 4) { - util.submitAchievementToLocalStorage("killachievement"); - } -}*/ -if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { -if (localStorage.getItem("startachievement") !== "YOUDIDIT:D!!!") { -localStorage.setItem("savedkills", 0); -} -} -function resetAllAchievements() { - var zeroyeah = 0; - util.resetAchievementFromLocalStorage("killachievement"); -} - let nIntervId; - if (!nIntervId) { - nIntervId = setInterval(gettimesince, 1000); - } - function gettimesince() { - const date = new Date() - var sec = 0; - var min = 0; - var hour = 0; - var day = 0; - var month = 0; - var year = 0; - var nerosec = ''; - var neromin = ''; - var nerohour = ''; - var neroday = ''; - var neromonth = ''; - var daysinm = 0; - if (date.getMonth() == 8 || 10 || 3 || 5) { - daysinm = 30 - } else { - if (date.getMonth() == 1) { - if (date.getFullYear() == 2024 || 2028 || 2032 || 2036 || 2040 || 2044 || 2048 || 2042) { - daysinm = 29 - } else { - daysinm = 28 - } - } else { - daysinm = 31 - } - } - if (date.getSeconds() + 28 > 59) { - sec = (date.getSeconds() + 60) - 92 - } else { - sec = (date.getSeconds() + 60) - 32 - }; - if (date.getMinutes() < 45) { - if (date.getSeconds() > 31) { - min = (date.getMinutes() + 60) - 44 - } else { - min = (date.getMinutes() + 60) - 45 - } - } else { - if (date.getSeconds() > 31) { - min = (date.getMinutes() + 60) - 104 - } else { - min = (date.getMinutes() + 60) - 105 - } - } - if (date.getHours() < 11) { - if (date.getMinutes() > 44) { - hour = ((date.getHours() + 24) - 10) - } else { - hour = ((date.getHours() + 24) - 11) - } - } else { - if (date.getMinutes() > 44) { - hour = ((date.getHours() + 24) - 34) - } else { - hour = ((date.getHours() + 24) - 35) - } - } - if (date.getDate() < 24) { - if (date.getHours() > 10) { - day = (date.getDate() + daysinm) - 23 - } else { - day = (date.getDate() + daysinm) - 24 - } - } else { - if (date.getHours() > 10) { - day = (date.getDate() + daysinm) - (23 + daysinm) - } else { - day = (date.getDate() + daysinm) - (24 + daysinm) - } - }; - if (date.getMonth() < 4) { - if (date.getDate() > 23) { - if (date.getMonth() == 3) { - month = (date.getMonth() + 11) - 14 - } else { - month = (date.getMonth() + 11) - 2 - } - } else { - month = (date.getMonth() + 11) - 3 - } - } else { - if (date.getDate() > 23) { - month = (date.getMonth() + 11) - 14 - } else { - month = (date.getMonth() + 11) - 15 - } - }; - if (date.getMonth() > 2) { - year = ' | Years: ' + (date.getFullYear() - 2019) - } else { - year = ' | Years: ' + (date.getFullYear() - 2020) - } - if (sec !== 0) { - nerosec = ', Seconds: ' + sec - } else { - nerosec = '' - } - if (min !== 0) { - neromin = ', Minutes: ' + min - } else { - neromin = '' - } - if (hour !== 0) { - nerohour = ', Hours: ' + hour - } else { - nerohour = '' - } - if (day !== 0) { - neroday = ', Days: ' + day - } else { - neroday = '' - } - if (month !== 0) { - neromonth = ', Months: ' + month - } else { - neromonth = '' - } - //const currentdate = ' / Current Year: ' + date.getFullYear() + ' / Current Month: ' + date.getMonth() + ' / Current Day: ' + date.getDate() + ' / Current Hour: ' + date.getHours() + ' / Current Minute: ' + date.getMinutes() + ' / Current Second: ' + date.getSeconds() + ' /' - const nerodate = year + ' ' + neromonth + ' ' + neroday + ' ' + nerohour + ' ' + neromin + ' ' + nerosec + ' |' - $(document.getElementById("updatetime")).html("

    " + nerodate + "

    "); - //$(document.getElementById("updatetime2")).html("

    " + currentdate + "

    "); - } fetch("changelog.html", { cache: "no-cache" }) .then(async ChangelogsHTMLFile => { let patchNotes = document.querySelector("#patchNotes"); @@ -765,25 +39,6 @@ fetch("changelog.html", { cache: "no-cache" }) } }); -fetch("credits.html", { cache: "no-cache" }) -.then(async CreditsHTMLFile => { - let patchNotes = document.querySelector("#credits"); - try { - let parser = new DOMParser(), - RawHTMLString = await CreditsHTMLFile.text(), - ParsedHTML = parser.parseFromString(RawHTMLString, "text/html"), - titles = ParsedHTML.documentElement.getElementsByTagName('h1'); - for (const title of titles) { - title.classList.add('title'); - } - - patchNotes.innerHTML += ParsedHTML.documentElement.innerHTML; - } catch (error) { - patchNotes.innerHTML = `

    An error occured while trying to fetch 'credits.html'

    ${error}

    `; - console.error(error); - } -}); - class Animation { constructor(start, to, smoothness = 0.05) { this.start = start; @@ -866,7 +121,6 @@ function getMockups() { util.pullJSON("mockups").then(data => { global.mockups = data; console.log('Mockups loading complete.'); - console.log("%cWhy are you here Lmfao", "color: #FFFFFF; font-size: 45px; background: #333333; text-shadow: #FFF 0px 0px 5px, #FFF 0px 0px 10px, #FFF 0px 0px 15px, #FF2D95 0px 0px 20px, #FF2D95 0px 0px 30px, #FF2D95 0px 0px 40px, #FF2D95 0px 0px 50px, #FF2D95 0px 0px 75px;"); Resolve(); }); }); @@ -930,24 +184,15 @@ window.onload = async () => { util.retrieveFromLocalStorage("optCustom"); util.retrieveFromLocalStorage("optNoPointy"); util.retrieveFromLocalStorage("optBorders"); - util.retrieveFromLocalStorage("optResolution"); util.retrieveFromLocalStorage("seperatedHealthbars"); - util.retrieveFromLocalStorage("optOgIcon"); - util.retrieveFromLocalStorage("disableDeathSounds"); - util.retrieveFromLocalStorage("optNoEmojis"); util.retrieveFromLocalStorage("autoLevelUp"); // Set default theme if (document.getElementById("optColors").value === "") { - document.getElementById("optColors").value = "nero"; + document.getElementById("optColors").value = "normal"; } if (document.getElementById("optBorders").value === "") { - document.getElementById("optBorders").value = "nero"; + document.getElementById("optBorders").value = "normal"; } - if (document.getElementById("optResolution").value === "") { - document.getElementById("optResolution").value = "normal"; - } - // Achievement Shit - document.getElementById("resetachievementsbutton").onclick = () => resetAllAchievements(); // Game start stuff document.getElementById("startButton").onclick = () => startGame(); document.onkeydown = (e) => { @@ -959,36 +204,13 @@ window.onload = async () => { window.addEventListener("resize", resizeEvent); resizeEvent(); }; -var callofduty = ""; function resizeEvent() { - if (settings.graphical.quality === undefined) { - settings.graphical.quality = 1; - }; let scale = window.devicePixelRatio; if (!settings.graphical.fancyAnimations) { scale *= 0.5; } - if (typeof settings.graphical.quality === 'string' || settings.graphical.quality instanceof String) { - callofduty = new Image(); // Create new img element - if (settings.graphical.quality == "cod") { - callofduty.src = "https://image.api.playstation.com/cdn/EP0002/CUSA12443_00/VgKYOxWoNSp4mNJ2KvzEFVBWN0idCM5I.png?w=440" - } - } else { - scale *= settings.graphical.quality - } - if (settings.graphical.quality == "1dim") { global.screenWidth = window.innerWidth * scale; - global.screenHeight = 1 * scale; - } else if (settings.graphical.quality == "d1dim") { - global.screenWidth = 1 * scale; global.screenHeight = window.innerHeight * scale; - } else if (settings.graphical.quality == "1pix") { - global.screenWidth = 1 * scale; - global.screenHeight = 1 * scale; - } else { - global.screenWidth = window.innerWidth * scale; - global.screenHeight = window.innerHeight * scale; - } c.resize(global.screenWidth, global.screenHeight); global.ratio = scale; global.screenSize = Math.min(1920, Math.max(window.innerWidth, 1280)); @@ -1017,7 +239,7 @@ function Smoothbar(value, speed, sharpness = 3, lerpValue = 0.025) { display = util.lerp(display, value, lerpValue); if (Math.abs(value - display) < 0.1 && round) display = value; return display; - }, + }, force: (val) => { display = value = val; }, @@ -1062,7 +284,7 @@ function parseTheme(string){ stripped += '='; let data = atob(stripped); - let name = 'Unknown Theme', + let name = 'Unknown Theme', author = ''; let index = data.indexOf('\x00'); if (index === -1) return null; @@ -1112,6 +334,7 @@ function parseTheme(string){ } return { name, author, content }; } catch (e) {} + // Decode from JSON try { let output = JSON.parse(string); @@ -1156,36 +379,22 @@ function parseTheme(string){ } // This starts the game and sets up the websocket function startGame() { - PlaySound69(); - clearInterval(nIntervId); - // release our intervalID from the variable - nIntervId = null; // Set flag global.gameLoading = true; console.log('Started connecting.') - //set start achievement - util.submitAchievementToLocalStorage("startachievement"); // Get options util.submitToLocalStorage("optFancy"); util.submitToLocalStorage("centerTank"); util.submitToLocalStorage("optBorders"); - util.submitToLocalStorage("optResolution"); util.submitToLocalStorage("optNoPointy"); - util.submitToLocalStorage("optOgIcon"); - util.submitToLocalStorage("disableDeathSounds"); - util.submitToLocalStorage("optNoEmojis"); util.submitToLocalStorage("autoLevelUp"); util.submitToLocalStorage("optPredictive"); util.submitToLocalStorage("optScreenshotMode"); util.submitToLocalStorage("coloredHealthbars"); - util.submitToLocalStorage("seperatedHealthbars"); - global.ISTHEGODAMNFUCKINGGAMEON = "yeah"; + util.submitToLocalStorage("seperatedHealthbars"); settings.graphical.fancyAnimations = !document.getElementById("optFancy").checked; settings.graphical.centerTank = document.getElementById("centerTank").checked; settings.graphical.pointy = !document.getElementById("optNoPointy").checked; - settings.game.optOgIcon = !document.getElementById("optOgIcon").checked; - settings.game.disableDeathSounds = !document.getElementById("disableDeathSounds").checked; - settings.game.optNoEmojis = !document.getElementById("optNoEmojis").checked; settings.game.autoLevelUp = document.getElementById("autoLevelUp").checked; settings.lag.unresponsive = document.getElementById("optPredictive").checked; settings.graphical.screenshotMode = document.getElementById("optScreenshotMode").checked; @@ -1207,50 +416,9 @@ function startGame() { settings.graphical.darkBorders = settings.graphical.neon = true; break; } - switch (document.getElementById("optResolution").value) { - case "normal": - settings.graphical.quality = 1; - break; - case "low": - settings.graphical.quality = 0.75; - break; - case "high": - settings.graphical.quality = 1.5; - break; - case "higher": - settings.graphical.quality = 2; - break; - case "rtx": - settings.graphical.quality = 4; - break; - case "really low": - settings.graphical.quality = 0.5; - break; - case "really really low": - settings.graphical.quality = 0.25; - break; - case "unplayable": - settings.graphical.quality = 0.1; - break; - case "1d": - settings.graphical.quality = "1dim"; - break; - case "d1": - settings.graphical.quality = "d1dim"; - break; - case "onepixel": - settings.graphical.quality = "1pix"; - break; - case "codbo4": - settings.graphical.quality = "cod"; - break; - case "drugs": - settings.graphical.quality = "trippy"; - break; - } util.submitToLocalStorage("optColors"); let a = document.getElementById("optColors").value; - color = color[a === "" ? "nero" : a]; + color = color[a === "" ? "normal" : a]; if (a == "custom") { let customTheme = document.getElementById("optCustom").value; color = parseTheme(customTheme).content; @@ -1270,8 +438,6 @@ function startGame() { global.screenHeight = window.innerHeight; document.getElementById("startMenuWrapper").style.maxHeight = "0px"; document.getElementById("gameAreaWrapper").style.opacity = 1; - - document.getElementById("hideongamestart").style.zIndex = "-3"; // Set up the socket if (!global.socket) { global.socket = socketInit(26301); @@ -1283,9 +449,6 @@ function startGame() { setInterval(() => moveCompensation.iterate(global.socket.cmd.getMotion()), 1000 / 30); document.getElementById("gameCanvas").focus(); window.onbeforeunload = () => true; - if (settings.game.optNoEmojis) { - trollface = new Image(); // Create new img element - } } // Background clearing function clearScreen(clearColor, alpha) { @@ -1300,7 +463,7 @@ function arrayifyText(rawText) { // string with double § txt col txt txt // "...§text§§text§..." => [..., "text", "", "text", ...] => [..., "text§text", ...] // this code is balanced on tight threads, holy shit - let textArrayRaw = rawText.split(/§|;;/), + let textArrayRaw = rawText.split('§'), textArray = []; if (!(textArrayRaw.length & 1)) { textArrayRaw.unshift(''); @@ -1398,162 +561,6 @@ function drawText(rawText, x, y, size, defaultFillStyle, align = "left", center } context.restore(); } - -// Library: mltext.js -// Desciption: Extends the CanvasRenderingContext2D that adds two functions: mlFillText and mlStrokeText. -// -// The prototypes are: -// -// function mlFillText(text,x,y,w,h,vAlign,hAlign,lineheight); -// function mlStrokeText(text,x,y,w,h,vAlign,hAlign,lineheight); -// -// Where vAlign can be: "top", "center" or "button" -// And hAlign can be: "left", "center", "right" or "justify" -// Author: Jordi Baylina. (baylina at uniclau.com) -// License: GPL -// Date: 2013-02-21 - -function mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, defaultFillStyle = color.guiwhite, fn = "strokeText") { - textsize += settings.graphical.fontSizeBoost; - // Get text dimensions and resize/reset the canvas - let offset = textsize / 5, - ratio = 1; - if (ctx.getTransform) { - ratio = ctx.getTransform().d; - offset *= ratio; - } - if (ratio !== 1) { - textsize *= ratio; - } - ctx.font = "bold " + textsize + "px Ubuntu"; - text = text.replace(/[\n]/g, " \n "); - text = text.replace(/\r/g, ""); - lineheight += settings.graphical.fontSizeBoost; - var words = text.split(/[ ]+/); - var sp = ctx.measureText(' ').width; - var lines = []; - var actualline = 0; - var actualsize = 0; - var wo; - lines[actualline] = {}; - lines[actualline].Words = []; - let i = 0; - while (i < words.length) { - var word = words[i]; - if (word == "\n") { - lines[actualline].EndParagraph = true; - actualline++; - actualsize = 0; - lines[actualline] = {}; - lines[actualline].Words = []; - i++; - } else { - wo = {}; - wo.l = ctx.measureText(word).width; - if (actualsize === 0) { - while (wo.l > w) { - word = word.slice(0, word.length - 1); - wo.l = ctx.measureText(word).width; - } - if (word === "") return; // I can't fill a single character - wo.word = word; - lines[actualline].Words.push(wo); - actualsize = wo.l; - if (word != words[i]) { - words[i] = words[i].slice(word.length, words[i].length); - } else { - i++; - } - } else { - if (actualsize + sp + wo.l > w) { - lines[actualline].EndParagraph = false; - actualline++; - actualsize = 0; - lines[actualline] = {}; - lines[actualline].Words = []; - } else { - wo.word = word; - lines[actualline].Words.push(wo); - actualsize += sp + wo.l; - i++; - } - } - } - } - if (actualsize === 0) lines[actualline].pop(); - lines[actualline].EndParagraph = true; - - var totalH = lineheight * lines.length; - while (totalH > h) { - lines.pop(); - totalH = lineheight * lines.length; - } - - var yy; - if (vAlign == "bottom") { - yy = y + h - totalH + lineheight; - } else if (vAlign == "center") { - yy = y + h / 2 - totalH / 2 + lineheight; - } else { - yy = y + lineheight; - } - - var oldTextAlign = ctx.textAlign; - ctx.textAlign = "left"; - ctx.strokeStyle = color.black; - ctx.fillStyle = defaultFillStyle; - ctx.lineWidth = (textsize + 1) / settings.graphical.fontStrokeRatio; - - for (var li in lines) { - var totallen = 0; - var xx, usp; - for (wo in lines[li].Words) totallen += lines[li].Words[wo].l; - if (hAlign == "center") { - usp = sp; - xx = x + w / 2 - (totallen + sp * (lines[li].Words.length - 1)) / 2; - } else if ((hAlign == "justify") && (!lines[li].EndParagraph)) { - xx = x; - usp = (w - totallen) / (lines[li].Words.length - 1); - } else if (hAlign == "right") { - xx = x + w - (totallen + sp * (lines[li].Words.length - 1)); - usp = sp; - } else { // left - xx = x; - usp = sp; - } - for (wo in lines[li].Words) { - if (fn == "fillText") { - ctx.fillText(lines[li].Words[wo].word, xx, yy); - } else if (fn == "strokeText") { - ctx.strokeText(lines[li].Words[wo].word, xx, yy); - let textArray = lines[li].Words[wo].word; - var Xoffset = 0; - for (let i = 0; i < textArray.length; i++) { - let str = textArray[i]; - if (i) { - Xoffset += ctx.measureText(textArray[i - 1] + str).width - ctx.measureText(str).width; - } - ctx.fillText(str, xx + Xoffset, yy); - } - } - xx += lines[li].Words[wo].l + usp; - } - yy += lineheight; - } - ctx.textAlign = oldTextAlign; -} - -(function mlInit() { - CanvasRenderingContext2D.prototype.mlFunction = mlFunction; - - CanvasRenderingContext2D.prototype.mlFillText = function (text, x, y, w, h, vAlign, hAlign, lineheight, textsize, defaultFillStyle) { - ctx.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, "fillText"); - }; - - CanvasRenderingContext2D.prototype.mlStrokeText = function (text, x, y, w, h, vAlign, hAlign, lineheight, textsize, defaultFillStyle) { - ctx.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, "strokeText"); - } - })(); // Gui drawing functions function drawGuiRect(x, y, length, height, stroke = false) { switch (stroke) { @@ -1563,43 +570,6 @@ function drawGuiRect(x, y, length, height, stroke = false) { case false: ctx.fillRect(x, y, length, height); break; - case 0: - ctx.beginPath(); - ctx.lineTo(x, y); - ctx.lineTo(x + length, y); - ctx.lineTo(x, y + height); - ctx.lineTo(x + length, y + height); - ctx.closePath(); - ctx.stroke(); - break; - case 1: - ctx.beginPath(); - ctx.roundRect(x, y, length, height, 5); - ctx.stroke(); - break; - case 2: - ctx.beginPath(); - ctx.roundRect(x, y, length, height, 5); - ctx.stroke(); - ctx.fill(); - break; - case 3: - ctx.beginPath(); - ctx.roundRect(x, y, length, height, [5,5,0,0]); - ctx.stroke(); - ctx.fill(); - break; - case 4: - ctx.beginPath(); - ctx.lineTo(x, y); - ctx.lineTo(x + length, y); - ctx.lineTo(x + length, y + height); - ctx.lineTo(x, y + height); - //ctx.lineWidth = strokeWidth; - //ctx.strokeStyle = color; - ctx.closePath(); - ctx.stroke(); - break; } } @@ -1630,21 +600,6 @@ function drawBar(x1, x2, y, width, color) { ctx.closePath(); ctx.stroke(); } -//checking for images in the shape so we can draw them -function isImageURL(url) { - try { - const parsedUrl = new URL(url); - const path = parsedUrl.pathname; - const ext = path.split('.').pop().toLowerCase(); // Get the lowercase file extension - - // List of common image file extensions - const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']; - - return imageExtensions.includes(ext) || parsedUrl.protocol == 'data:'; - } catch (error) { - return false; // URL parsing failed, or it's not an image URL. - } -} // Sub-drawing functions const drawPolyImgs = []; function drawPoly(context, centerX, centerY, radius, sides, angle = 0, borderless, fill, imageInterpolation) { @@ -1660,57 +615,17 @@ function drawPoly(context, centerX, centerY, radius, sides, angle = 0, borderles ); } else { if ("string" === typeof sides) { - if (isImageURL(sides)) { - //ideally we'd preload images when mockups are loaded but im too lazy for that atm - if (!drawPolyImgs[sides]) { - drawPolyImgs[sides] = new Image(); - drawPolyImgs[sides].src = sides; - drawPolyImgs[sides].isBroken = false; - drawPolyImgs[sides].onerror = function() { - console.log('Failed to load image!\nURL:', sides); - this.isBroken = true; - }; - } - let img = drawPolyImgs[sides]; - if (img.isBroken || !img.complete) { // check if img is broken and draw placeholder if so - //this is probably the worst way to draw a missing texture checkerboard but im too lazy to do a better one - context.translate(centerX, centerY); - context.rotate(angle); - context.beginPath(); - context.fillStyle = '#ff00ff'; - context.lineTo(-radius,-radius); - context.lineTo(radius,-radius); - context.lineTo(radius,radius); - context.lineTo(-radius,radius); - context.lineTo(-radius,-radius); - context.fill(); - context.closePath(); - context.beginPath(); - context.fillStyle = '#000000'; - context.lineTo(-radius,-radius); - context.lineTo(0,-radius); - context.lineTo(0,0); - context.lineTo(0, radius); - context.lineTo(radius, radius); - context.lineTo(radius, 0); - context.lineTo(0, 0); - context.lineTo(-radius, 0); - context.lineTo(-radius,-radius); - context.fill(); - context.closePath(); - context.rotate(-angle); - context.translate(-centerX, -centerY); - return; - } - context.translate(centerX, centerY); - context.rotate(angle); - context.imageSmoothingEnabled = imageInterpolation; - context.drawImage(img, -radius, -radius, radius*2, radius*2); - context.imageSmoothingEnabled = true; - context.rotate(-angle); - context.translate(-centerX, -centerY); - return; - } else { + //ideally we'd preload images when mockups are loaded but im too lazy for that atm + if (!drawPolyImgs[sides]) { + drawPolyImgs[sides] = new Image(); + drawPolyImgs[sides].src = sides; + drawPolyImgs[sides].isBroken = false; + drawPolyImgs[sides].onerror = function() { + this.isBroken = true; + }; + } + let img = drawPolyImgs[sides]; + if (img.isBroken || !img.complete) { // check if img is broken and draw as path2d if so let path = new Path2D(sides); context.save(); context.translate(centerX, centerY); @@ -1723,6 +638,14 @@ function drawPoly(context, centerX, centerY, radius, sides, angle = 0, borderles context.restore(); return; } + context.translate(centerX, centerY); + context.rotate(angle); + context.imageSmoothingEnabled = imageInterpolation; + context.drawImage(img, -radius, -radius, radius*2, radius*2); + context.imageSmoothingEnabled = true; + context.rotate(-angle); + context.translate(-centerX, -centerY); + return; } angle += sides % 2 ? 0 : Math.PI / sides; } @@ -1959,7 +882,7 @@ function drawHealth(x, y, instance, ratio, alpha) { let health = instance.render.health.get(), shield = instance.render.shield.get(); if (health < 0.99 || shield < 0.99) { - let col = settings.graphical.coloredHealthbars ? gameDraw.mixColors(gameDraw.modifyColor(instance.color), color.guiwhite, 0.5) : color.blue; + let col = settings.graphical.coloredHealthbars ? gameDraw.mixColors(gameDraw.modifyColor(instance.color), color.guiwhite, 0.5) : color.lgreen; let yy = y + realSize + 15 * ratio; let barWidth = 3 * ratio; ctx.globalAlpha = fade * (alpha ** 2); @@ -1989,7 +912,7 @@ function drawHealth(x, y, instance, ratio, alpha) { ctx.globalAlpha = 1; } } - + const iconColorOrder = [10, 11, 12, 15, 13, 2, 14, 4, 5, 1, 0, 3]; function getIconColor(colorIndex) { return iconColorOrder[colorIndex % 12].toString(); @@ -2002,55 +925,13 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c entityX = x + 0.5 * len, entityY = y + 0.5 * height, baseColor = picture.color; - // Find x and y shift for the entity image - let xShift = position.middle.x * Math.cos(angle) - position.middle.y * Math.sin(angle), + + // Find x and y shift for the entity image + let xShift = position.middle.x * Math.cos(angle) - position.middle.y * Math.sin(angle), yShift = position.middle.x * Math.sin(angle) + position.middle.y * Math.cos(angle); - entityX -= scale * xShift; - entityY -= scale * yShift; - - if (settings.game.optOgIcon) { - // Draw box - ctx.strokeStyle = color.black; - ctx.fillStyle = color.black; - ctx.lineWidth = 3 * lineWidthMult; - ctx.globalAlpha = 0.4 - drawGuiRect(x + 8, y + 8, len, height, 2); - ctx.globalAlpha = alpha; - ctx.fillStyle = picture.upgradeColor != null - ? gameDraw.modifyColor(picture.upgradeColor) - : gameDraw.getColor(getIconColor(colorIndex)); - //drawGuiRect(x + 25, y + 25, len - 50, height - 50, 2); - drawGuiRect(x, y, len, height, 2); - ctx.globalAlpha = 0.1; - drawGuiRect(x, y, len, height * 0.6, 3); - ctx.globalAlpha = 0.25 * alpha; - ctx.fillStyle = color.black; - drawGuiRect(x, y + height * 0.6, len, height * 0.4); - // Shading for hover - if (hover) { - ctx.globalAlpha = 0.15 * alpha; - ctx.fillStyle = color.guiwhite; - drawGuiRect(x, y, len, height, 3); - } - ctx.globalAlpha = 1; - if (settings.graphical.quality == "cod") { - ctx.drawImage(callofduty, x, y, len, height); - } + entityX -= scale * xShift; + entityY -= scale * yShift; - // Draw Tank - drawEntity(baseColor, entityX, entityY, picture, 1, 1, scale / picture.size, lineWidthMult, angle, true); - - // Tank name - drawText(picture.upgradeName ?? picture.name, x + (upgradeKey ? 0.9 * len : len) / 2, y + height * 0.94, height / 10, color.guiwhite, "center"); - - // Upgrade key - if (upgradeKey) { - drawText("[" + upgradeKey + "]", x + len - 4, y + height - 6, height / 8 - 5, color.guiwhite, "right"); - } - ctx.strokeStyle = color.black; - ctx.lineWidth = 3 * lineWidthMult; - drawGuiRect(x, y, len, height, 1); // Border - } else { // Draw box ctx.globalAlpha = alpha; ctx.fillStyle = picture.upgradeColor != null @@ -2067,9 +948,6 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c drawGuiRect(x, y, len, height); } ctx.globalAlpha = 1; - if (settings.graphical.quality == "cod") { - ctx.drawImage(callofduty, x, y, len, height); - } // Draw Tank drawEntity(baseColor, entityX, entityY, picture, 1, 1, scale / picture.size, lineWidthMult, angle, true); @@ -2084,7 +962,6 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c ctx.strokeStyle = color.black; ctx.lineWidth = 3 * lineWidthMult; drawGuiRect(x, y, len, height, true); // Border - } } // Start animation @@ -2305,15 +1182,8 @@ function drawFloor(px, py, ratio) { ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : color.white; ctx.fillRect(left, top, right - left, bottom - top); ctx.globalAlpha = 0.3; - if (settings.graphical.quality === "trippy") { - ctx.fillStyle = gameDraw.getColor("animatedepilepsy") - } else { - ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : gameDraw.modifyColor(tile); - } + ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : gameDraw.modifyColor(tile); ctx.fillRect(left, top, right - left, bottom - top); - if (settings.graphical.quality == "cod") { - ctx.drawImage(callofduty, left, top, right - left, bottom - top); - } } } ctx.lineWidth = 1.25; @@ -2395,26 +1265,11 @@ function drawEntities(px, py, ratio) { text = chat.text, msgLengthHalf = measureText(text, 15 * ratioForChat) / 2, alpha = Math.max(0, Math.min(1000, chat.expires - now) / 1000); + ctx.globalAlpha = 0.5 * alpha; - if (settings.game.optNoEmojis) { - if (text.includes("--troll")) { - trollface.addEventListener("load", () => { - global.emojiloaded = true; - }); - trollface.src = "https://upload.wikimedia.org/wikipedia/en/thumb/9/9a/Trollface_non-free.png/220px-Trollface_non-free.png"; // Set source path - msgLengthHalf = (measureText(text, 15 * ratioForChat) / 2) - 23; - } - }; drawBar(x - msgLengthHalf, x + msgLengthHalf, y, 30 * ratioForChat, gameDraw.modifyColor(instance.color)); ctx.globalAlpha = alpha; settings.graphical.fontStrokeRatio *= 1.2; - if (settings.game.optNoEmojis) { - if (global.emojiloaded && text.includes("--troll")) { - let wheretrollfaceis = (ratioForChat) - msgLengthHalf; - text = text.replace("--troll", ""); - ctx.drawImage(trollface, x - wheretrollfaceis, y + -1 * ratioForChat, 18 * ratioForChat, 18 * ratioForChat); - } - } drawText(text, x, y + 7 * ratioForChat, 15 * ratioForChat, color.guiwhite, "center"); settings.graphical.fontStrokeRatio /= 1.2; y -= 35 * ratioForChat; @@ -2646,67 +1501,19 @@ function drawSelfInfo(spacing, alcoveSize, max) { ctx.lineWidth = 1; // Draw the exp bar - //ctx.fillStyle = color.black; - //drawGuiRect(x - 13, y - 3, len + 26, (height + 1) + settings.graphical.barChunk); - //ctx.fillStyle = color.grey; - //drawGuiRect(x - 10, y, len + 20, height - settings.graphical.barChunk / 4); - //ctx.fillStyle = color.blue; - //drawGuiRect(x - 10, y, (len + 20) * gui.__s.getProgress(), height - settings.graphical.barChunk / 4); drawBar(x, x + len, y + height / 2, height + settings.graphical.barChunk, color.black); drawBar(x, x + len, y + height / 2, height - settings.graphical.barChunk / 4, color.grey); - drawBar(x, x + len * gui.__s.getProgress(), y + height / 2, height - 2, color.blue); + drawBar(x, x + len * gui.__s.getProgress(), y + height / 2, height - 2, color.gold); // Draw the class type drawText("Level " + gui.__s.getLevel() + " " + gui.class, x + len / 2, y + height / 2 + 1, height - 2.5, color.guiwhite, "center", true); height = 16; y -= height + vspacing; - - if (gui.class === "Winsor") { - PlaySound169(); - } - document.onkeydown = (e) => { - var key = e.which || e.keyCode; - if (gui.class === "Trapper_guy" & key === global.KEY_SHIFT) { - PlaySoundtrap(); - } else { - if (gui.class === "Waduh" & key === global.KEY_SHIFT) { - PlaySoundwater(); - } else { - if (gui.class === "Waduh" & key === global.KEY_CHOOSE_5) { - PlaySoundwatuh(); - } else { - if (gui.class === "Pissliner" & key === global.KEY_SHIFT) { - PlaySoundpiss(); - } else { - if (gui.class === "Pissliner" & key === global.KEY_SPLIT) { - PlaySoundpew(); - } else { - if (gui.class === "Delta Congregation" & key === global.KEY_SPLIT) { - PlaySoundchipi(); - } else { - if (gui.class === "Delta" & key === global.KEY_CHOOSE_5) { - PlaySoundneko(); - } else { - if (gui.class === "Delta" & key === global.KEY_CHOOSE_4) { - PlaySoundbwomp(); - } else { - if (gui.class === "Delta" & key === global.KEY_CHOOSE_3) { - PlaySoundnfl(); - } - } - } - } - } - } - } - } - } - } // Draw the %-of-leader bar drawBar(x + len * 0.1, x + len * 0.9, y + height / 2, height - 3 + settings.graphical.barChunk, color.black); drawBar(x + len * 0.1, x + len * 0.9, y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.grey); - drawBar(x + len * 0.1, x + len * (0.1 + 0.8 * (max ? Math.min(1, gui.__s.getScore() / max) : 1)), y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.teal); + drawBar(x + len * 0.1, x + len * (0.1 + 0.8 * (max ? Math.min(1, gui.__s.getScore() / max) : 1)), y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.green); //write the score and name drawText("Score: " + util.formatLargeNumber(Math.floor(gui.__s.getScore())), x + len / 2, y + height / 2 + 1, height - 3.5, color.guiwhite, "center", true); @@ -2760,6 +1567,7 @@ function drawMinimapAndDebug(spacing, alcoveSize) { ctx.globalAlpha = 1; ctx.lineWidth = 3; ctx.fillStyle = color.black; + drawGuiRect(x, y, len, height, true); // Border for (let entity of minimap.get()) { ctx.fillStyle = gameDraw.mixColors(gameDraw.modifyColor(entity.color), color.black, 0.3); ctx.globalAlpha = entity.alpha; @@ -2776,38 +1584,29 @@ function drawMinimapAndDebug(spacing, alcoveSize) { } } ctx.globalAlpha = 1; - ctx.lineWidth = 3; - ctx.fillStyle = color.black; - if (settings.game.optOgIcon) { - drawGuiRect(x, y, len, height, 1); // Border ctx.lineWidth = 1; - } else { - drawGuiRect(x, y, len, height, true); // Border ctx.lineWidth = 1; - } - ctx.strokeStyle = color.black; - ctx.fillStyle = color.black; + ctx.lineWidth = 1; + ctx.strokeStyle = color.guiblack; + ctx.fillStyle = color.guiblack; drawGuiCircle(x + (global.player.cx / global.gameWidth) * len - 1, y + (global.player.cy / global.gameHeight) * height - 1, 2, false); if (global.showDebug) { drawGuiRect(x, y - 40, len, 30); lagGraph(lag.get(), x, y - 40, len, 30, color.teal); gapGraph(global.metrics.rendergap, x, y - 40, len, 30, color.pink); - //timingGraph(GRAPHDATA, x, y - 40, len, 30, color.yellow); + timingGraph(GRAPHDATA, x, y - 40, len, 30, color.yellow); } //minimap stuff ends here //debug stuff if (!global.showDebug) y += 14 * 3; // Text if (global.showDebug) { - drawText("Nero Engine v3.1", x + len, y - 50 - 7 * 14 - 2, 15, "#6a36e3", "right"); - //drawText("Prediction: " + Math.round(GRAPHDATA) + "ms", x + len, y - 50 - 4 * 14, 10, color.guiwhite, "right"); - drawText("Update Version: " + "v3.112", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); - drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 5 * 14, 10, color.guiwhite, "right"); - drawText("Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 4 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); - drawText("Server Speed: " + ((global.metrics.updatetime * global.metrics.rendergap-global.metrics.lag) / 10).toFixed(2) + "%", x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); - drawText("Kills: " + global.metrics.killcount + " Shapes: " + global.metrics.shapecount, x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); - drawText("Song: " + global.music2.songname, x + len, y - 50 - 1 * 14, 10, color.guiwhite, "right"); - drawText(global.metrics.latency + " ms - neroio2 :FFA:", x + len, y - 50, 10, color.guiwhite, "right"); + drawText("Open Source Arras", x + len, y - 50 - 5 * 14 - 2, 15, "#B6E57C", "right"); + drawText("Prediction: " + Math.round(GRAPHDATA) + "ms", x + len, y - 50 - 4 * 14, 10, color.guiwhite, "right"); + drawText(`Bandwidth: ${gui.bandwidth.in} in, ${gui.bandwidth.out} out`, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); + drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); + drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); + drawText(global.metrics.latency + " ms - " + global.serverName, x + len, y - 50, 10, color.guiwhite, "right"); } else { - drawText("Nero.io v3.1", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); + drawText("Open Source Arras", x + len, y - 50 - 2 * 14 - 2, 15, "#B6E57C", "right"); drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); drawText(global.metrics.latency + " ms : " + global.metrics.updatetime + "Hz", x + len, y - 50, 10, color.guiwhite, "right"); } @@ -2843,16 +1642,16 @@ function drawLeaderboard(spacing, alcoveSize, max) { y += vspacing + height; } } + function drawAvailableUpgrades(spacing, alcoveSize) { // Draw upgrade menu if (gui.upgrades.length > 0) { let internalSpacing = 15; let len = alcoveSize / 2; let height = len; - + // Animation processing -// let columnCount = Math.max(Math.ceil(gui.upgrades.length / 5), 3); - let columnCount = Math.max(3, Math.ceil(gui.upgrades.length / 3)); + let columnCount = Math.max(3, Math.floor(gui.upgrades.length ** 0.55)); upgradeMenu.set(0); if (!global.canUpgrade) { upgradeMenu.force(-columnCount * 3) @@ -2873,7 +1672,7 @@ function drawAvailableUpgrades(spacing, alcoveSize) { let lastBranch = -1; let upgradeHoverIndex = global.clickables.upgrade.check({x: global.mouse.x, y: global.mouse.y}); upgradeSpin += 0.01; - + for (let i = 0; i < gui.upgrades.length; i++) { let upgrade = gui.upgrades[i]; let upgradeBranch = upgrade[0]; @@ -2900,12 +1699,10 @@ function drawAvailableUpgrades(spacing, alcoveSize) { if (y > initialY) initialY = y; rowWidth = x; - -// global.clickables.upgrade.place(i, y * clickableRatio, x * clickableRatio, len * clickableRatio, height * clickableRatio); - global.clickables.upgrade.place(i, x * clickableRatio, y * clickableRatio, len * clickableRatio, height * clickableRatio); - let upgradeKey = getClassUpgradeKey(upgradeNum); - -// drawEntityIcon(model, y, x, len, height, 1, upgradeSpin, 0.5, colorIndex++, upgradeKey); + + global.clickables.upgrade.place(i, x * clickableRatio, y * clickableRatio, len * clickableRatio, height * clickableRatio); + let upgradeKey = getClassUpgradeKey(upgradeNum); + drawEntityIcon(model, x, y, len, height, 1, upgradeSpin, 0.6, colorIndex++, upgradeKey, upgradeNum == upgradeHoverIndex); ticker++; @@ -3068,80 +1865,17 @@ const gameDrawDead = () => { drawText("(press enter to respawn)", x, y + 125, 16, color.guiwhite, "center"); ctx.translate(0, shift * global.screenHeight); }; -const gameDrawWiki = () => { - clearScreen(color.black, 0.5); - let ratio = util.getScreenRatio(); - scaleScreenRatio(ratio, true); - let shift = animations.deathScreen.get(); - ctx.translate(0, -shift * global.screenHeight); - let x = global.screenWidth / 2 - 215, - y = global.screenHeight / 2 - 50; - let len = 140, - position = global.mockups[parseInt(gui.type.split("-")[0])].position, - scale = len / position.axis, - xx = global.screenWidth / 2 - scale * position.middle.x * 0.707 - 215, - yy = global.screenHeight / 2 - 35 + scale * position.middle.y * 0.707, - picture = util.getEntityImageFromMockup(global.wikidisplaytank.toString(), color.blue), - baseColor = picture.color; - if (eval(`tankdescs.${picture.className}`) !== undefined) { - tanktype = eval(`tankdescs.${picture.className}.type`); - tankdesc = eval(`tankdescs.${picture.className}.desc`); - tanktier = eval(`tankdescs.${picture.className}.tier`); - tankweap = eval(`tankdescs.${picture.className}.weapons`); - tankabil = eval(`tankdescs.${picture.className}.abilities`); - tankweak = eval(`tankdescs.${picture.className}.weak`); - tankupto = eval(`tankdescs.${picture.className}.upgradesto`); - tankupfr = eval(`tankdescs.${picture.className}.upgradesfrom`); - tankorgn = eval(`tankdescs.${picture.className}.origin`); - tankupad = eval(`tankdescs.${picture.className}.updateadded`); - } else { - tanktype = "???"; - tankdesc = "???"; - tanktier = "???"; - tankweap = "???"; - tankabil = "???"; - tankweak = "???"; - tankupto = ["Tier 2: ???", "Tier 3: ???", "Tier 4: ???", "Misc: ???"]; - tankupad = "???"; - tankupfr = "???"; - tankorgn = "???"; - }; - drawEntity(baseColor, (xx - 190 - len / 2 + 0.5) | 0, (yy - 10 + 0.5) | 0, picture, 1.5, 1, (0.6 * scale) / picture.realSize, 1, -Math.PI / 4, true); - drawText(picture.name, (xx - 190 - len / 2 + 0.5) | 0, (yy + 78.5 + 0.5) | 0, 18, color.guiwhite, "center"); - drawText("Class." + picture.className, (xx - 190 - len / 2 + 0.5) | 0, (yy - 80 + 0.5) | 0, 14, color.guiwhite, "center"); - drawText(global.wikidisplaytank.toString(), (xx - 190 - len / 2 + 0.5) | 0, (yy - 100 + 0.5) | 0, 16, color.guiwhite, "center"); - drawText("Description:", x - 185, y - 70, 17, color.guiwhite, "left"); - ctx.mlStrokeText(tankdesc, x - 185, y - 70, 215, 200, 'top', 'left', 20, 14); - drawText("Do yall think this will work?", x + 100, y + 130, 16, color.guiwhite, "center"); - drawText("[Esc] Exit Entity Debugger", 10, global.screenHeight - 56, 12, color.guiwhite, "left"); - drawText("[Enter] Search Entity ID", 10, global.screenHeight - 33, 12, color.guiwhite, "left"); - drawText("[A] Cycle Left || [D] Cycle Right", 10, global.screenHeight - 10, 12, color.guiwhite, "left"); - drawGuiLine(x + 40, y - 90, x + 40, (yy + 58 + 0.5)); - drawText("Tier: " + tanktier, x + 60, y - 75, 14, color.guiwhite, "left"); - drawText("Weapons: " + tankweap, x + 60, y - 52, 14, color.guiwhite, "left"); - drawText("Abilities: " + tankabil, x + 60, y - 29, 14, color.guiwhite, "left"); - drawText("Upgrades From: " + tankupfr, x + 60, y - 6, 14, color.guiwhite, "left"); - drawText("Weak To: " + tankweak, x + 60, y + 17, 14, color.guiwhite, "left"); - drawText("Type: " + tanktype, x + 60, y + 40, 14, color.guiwhite, "left"); - drawText("Update: " + tankupad, x + 60, y + 63, 14, color.guiwhite, "left"); - drawText("Origin: " + tankorgn, x + 60, y + 86, 14, color.guiwhite, "left"); - drawGuiLine(x + 300, y - 90, x + 300, (yy + 58 + 0.5)); - drawText("Upgrades To: ", x + 320, y - 75, 14, color.guiwhite, "left"); - ctx.mlStrokeText(tankupto[0] + " \n " + tankupto[1] + " \n " + tankupto[2] + " \n " + tankupto[3], x + 320, y - 75, 350, 200, 'top', 'left', 16, 11); - ctx.translate(0, shift * global.screenHeight); -}; const gameDrawBeforeStart = () => { let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); - clearScreen(color.white, 1); + clearScreen(color.white, 0.5); let shift = animations.connecting.get(); ctx.translate(0, -shift * global.screenHeight); drawText("Connecting...", global.screenWidth / 2, global.screenHeight / 2, 30, color.guiwhite, "center"); - drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.blue, "center"); + drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.lgreen, "center"); ctx.translate(0, shift * global.screenHeight); }; const gameDrawDisconnected = () => { - util.submitAchievementToLocalStorage("disconnectachievement"); let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(gameDraw.mixColors(color.red, color.guiblack, 0.3), 0.25); @@ -3152,14 +1886,13 @@ const gameDrawDisconnected = () => { ctx.translate(0, shift * global.screenHeight); }; const gameDrawError = () => { - util.submitAchievementToLocalStorage("disconnectachievement"); let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(gameDraw.mixColors(color.red, color.guiblack, 0.2), 0.35); let shift = animations.error.get(); ctx.translate(0, -shift * global.screenHeight); drawText("There has been an error!", global.screenWidth / 2, global.screenHeight / 2 - 50, 50, color.guiwhite, "center"); - drawText("(This Either Means The Dev's Working On The Game Or Its Bugged)", global.screenWidth / 2, global.screenHeight / 1.8, 20, color.blue, "center"); + drawText("Check the browser console for details.", global.screenWidth / 2, global.screenHeight / 2, 30, color.guiwhite, "center"); drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.orange, "center"); ctx.translate(0, shift * global.screenHeight); }; @@ -3174,7 +1907,6 @@ function animloop() { ctx.lineJoin = "round"; // Draw the game if (global.gameStart && !global.disconnected) { - lagachloop(); global.time = getNow(); if (global.time - lastPing > 1000) { // Latency @@ -3199,35 +1931,22 @@ function animloop() { } if (global.died) { gameDrawDead(); - if (settings.game.disableDeathSounds) { - PlaySound420(); - } - global.metrics.killcount = 0; - } else { - if (global.stopthefuckingkillsoundyouprick) { - metalpipe.pause(); - metalpipe.currentTime = 0; - global.stopthefuckingkillsoundyouprick = false; - } } if (global.disconnected) { gameDrawDisconnected(); } - if (global.wiki) { - gameDrawWiki(); - } ctx.translate(-0.5, -0.5); + //oh no we need to throw an error! } catch (e) { - + //hold on.... gameDrawError(); ctx.translate(-0.5, -0.5); - + //okay, NOW throw the error! throw e; - } } -})(util, global, settings, Canvas, color, gameDraw, socketStuff); \ No newline at end of file +})(util, global, settings, Canvas, color, gameDraw, socketStuff); diff --git a/public/changelog.html b/public/changelog.html index c31a69522..0d2f173ba 100644 --- a/public/changelog.html +++ b/public/changelog.html @@ -1,506 +1,18 @@ -
    -

    Update 3.1

    - [2024] -
      -
    • fixed date since counter
    • -
    • Added BackShield & Mirror Shield
    • -
    • Fixed Tag Gamemode
    • -
    • Removed Stats Temporarily
    • -
    • Changed Bot Leveling
    • -
    • Nerfs & Buffs
    • -
    • Reorganized Entities
    • -
    • Added New Color System
    • -
    • Fixed Color System
    • -
    • New DFX Maze Map
    • -
    • Added Apotheosis V2 & Depredation Remastered V2 By Deltafyrex and Killa By Action Agenda (DFX Edit) To OST
    • -
    • Fixed Siege
    • -
    • Fixed Movement System
    • -
    • Fixed Death Sounds
    • -
    • Revamped Menu Popups
    • -
    • Added TwinSniper Branch And More to Acid And Chiller Branch
    • -
    • Fixed Music Bug, And Added Aura Basic, Jump Smasher And Whirlwind To The Main game
    • -
    • Fixed Shields
    • -
    • Moved Aura From Tier 3 To Tier 2 And Added Aura Branch
    • -
    • Added Flail & Buffed Auras
    • -
    • Added Firecracker, Douverie & Auto-2 Branch
    • -
    • Added Brella (upgrades from backshield) And Lancer Branch
    • -
    • Added More Options For Quality Of Life Features
    • -
    • Added New Achievements & Skins
    • -
    • Fixed Player Skin Bug
    • -
    • Fixed Color System Again And Added Glow + Nerfs/Buffs And other Bug Fixes
    • -

      Holay Molay

      -
    -
    -
    -

    Update 3.0

    - [2024] -
      -
    • Added Clubbin
    • -
    • Testing Achievements
    • -
    • Added Reset Achievements Button
    • -
    • Added Start Achievement
    • -
    • Added and Fixed Achievement Details
    • -
    • Added Disconnect, Lag, And Killstreak Achievement
    • -
    • Removed Kill Achievement cuz it dont work
    • -
    • Added New Special Achievement Type
    • -
    • Added Special Piss.io Achievement And Funny Skype Achievement
    • -
    • Re-Added And Fixed 5 Killstreak Achievement Again
    • -
    • Added Server to Client Functions
    • -
    • Added 10 Killstreak Achievement
    • -
    • Changed Debug Menu
    • -
    • Added Kill Amount In Debug
    • -
    • Added Audio Visualizer in the title screen
    • -
    • Fixed Embed Not Working Properly
    • -
    • Fixed Bug Where Audio Visualizer Appears In Game
    • -
    • Added Token And Discord Achievement
    • -
    • Added Achievements Tab
    • -
    • Removed Ach Testing
    • -
    • Added Credits Button
    • -
    • fixed credits interfering with changelog
    • -
    • added credits-changelog animation transition
    • -
    • moved credits button (its 1:08 am im soooooo tired)
    • -
    • Fixed Game Breaking Bug
    • -
    • Added Contagion Branch To Subduer & Trapper
    • -
    • Added Longing And Resurgam By Amaryllis To The OST
    • -
    • added credits ach
    • -
    • Added 2 New Branches For Desmos
    • -
    • Testing Skins
    • -
    • Added Beta Skin Menu
    • -
    • Fixed Skin Bug
    • -
    • Fixed Crashing On Respawn
    • -
    • Added More Detail To Skin Menu
    • -
    • Added Cat Code and Chickensandwhichman Skin
    • -
    • Added Daily Tanks
    • -
    • Added Plenty New Skins, New Achievements And Made Achievements Unlockable
    • -
    • Added Skater & Hitman
    • -
    • Added New "Duality" Map
    • -

      Update 2.93 [2024]

      -
    • David Goggins Event
    • -
    • Updated Menu
    • -
    • Added Marksman Branch To Sniper And Car Branch To
    • -
    • Added Trollface Emote (add --troll to the end of a chat message)
    • -
    • Added Waterfall, Acid, Cooler, Rainmaker And New Options Layout
    • -
    • Added Notes Tab + Live Counter
    • -
    • Added More Customization, Graphics, Helecopter And Fixed Music Bug
    • -
    • Added Reverie Branch And Injector
    • -
    • Added Debugger Menu
    • -
    • You Can Now Color Messages With §
    • -

      Niners fucking lost Again Bruh...Fuck Taylor Swift

      -
    -
    -
    -

    Update 2.9

    - [2024] -
      -
    • Added Motor
    • -
    • Added Kivaaharatedas (i did not spell that right)
    • -
    • Added Equilibrium, Revobrid, Subverter
    • -
    • shrapnel testing
    • -
    • removed unfinished aimbot/boosting testing
    • -
    • Added Basic Hybrid Tier 3 branch
    • -
    • Bug Fixed Colors
    • -
    • Added Tanks of my friends and tank soundboard support
    • -
    • Added the rest of the Basic Hybrid branch (tier 4)
    • -
    • Fixed changelog not appearing
    • -
    • Added beta music support including 5 songs
    • -
    • changed start button look to not shade out and actually work like a button
    • -
    • fixed debug key (again)
    • -
    • fixed screen tearing
    • -
    • worked bullet spawn position
    • -
    • Better organized dev menu and changed the way utilities looks
    • -
    • Added music recognition in the debug key to see the song name & artist
    • -
    • Added new song (Anybody can find Love (except You) by hkmori
    • -
    • fixed debug not recognizing a song and not updating after a song is finished
    • -
    • Testing wall colors/effects
    • -
    • Added Shield Turrets
    • -
    • Added new tiles (dance floor+black)
    • -
    • added new "banquet" map
    • -
    • Finished Revolutionist Branch
    • -
    • Added Inception & Albuquerque
    • -
    • im a fucking moron
    • -
    • Added Machceptioner & Tailgator
    • -
    • Added Interceptor, Twinceptioner, Inceptionist branch, hybrid/auto ver of inception branch
    • -
    • Added Desmos/Inception/Bascrid Ception
    • -
    • fixed the ceptionist turrets/autobullet turrets
    • -
    • nerfed shit
    • -
    • fixed some upgrades not appearing
    • -
    • no players (dead game and nobody plays is sadly)
    • -
    • so it turns out i forgot to give twinceptionist the right bullets so i fixed that :/
    • -
    • fixed flankcept branch turrets
    • -

      Update 2.91 [2024]

      -
    • Added the subduer branch
    • -
    • Fixed The Rest of the menu buttons and fixed sound effects
    • -
    • Added flankduer
    • -
    • Added Binary branch, Pathogen branch, mitochondrion branch, Subduer-Hybrid branch and Auto-Subduer Branch
    • -
    • fixed missing upgrades
    • -

      Hey! vsauce, Michael here. the game is stable and non buggy...or is it?

      -
    -
    -
    -

    Update 2.8

    - [2023] -
      -
    • Tank Adding Wave Two (ex. hadron, dictator, railgun + more)
    • -
    • Debug Key Bug Fix (how ironic)
    • -
    • Fixed Rng Images Bugging Out
    • -
    • Testing Whirlwind Branch
    • -
    • Fixed Maze Gamemode
    • -
    • Added Tooltips (beta)
    • -
    • Added Status Effects (beta+devevent)
    • -
    • Added Addon Support
    • -
    • Fixed button Shadows
    • -
    • Upgraded APS++ Updating Speed
    • -
    • New Mouse Controller
    • -
    • Keybind Fix
    • -
    • Enter can cancel a chat message being sent
    • -
    • CoNgReGaTiOn JuMpScArEs
    • -
    • Images on Tanks/Sound Effects For Tanks (dev)
    • -
    • Blackhole (dont ask just roll with it)
    • -
    • P A P Y R U S
    • -
    • Fixed Some Lag Holding Down Server Speed
    • -
    • 109.43.21.5.14
    • -
    • Added Desmos Branch
    • -
    • Theres Prob More But I Forgor
    • -

      wahhh... (i forgor why im crying)

      -
    -
    -
    -

    Update 2.7

    - [2023] -
      -
    • Debuffed Many Tanks
    • -
    • Migrated to new host
    • -
    • Removed all Nero Exclusive Tanks From The Game (for now anyway, dont worry)
    • -
    • Added "revolutionist" to testbed"
    • -
    • Massive Testbed overhaul
    • -
    • Added a funny randomly generated image on the start screen
    • -
    • Readded Sounds, design and other previous widgets
    • -
    • Hired new devs
    • -
    • did some tweaks to bots
    • -
    • got rid of the "nero" theme and the server list
    • -
    • added easter eggs
    • -
    • added random funny image
    • -

      Update 2.71 [2023]

      -
    • Tank Adding Wave One (ex. auto branch, revolutionist, cloner + more)
    • -
    • plenty of new dev features
    • -
    • added gamemode polls (once theres enough people)
    • -

      There are Easter Eggs All Over The Main Menu, You Might Find Something...

      -
    -
    -
    -

    Update 2.6

    - [2023] -
      -
    • replaced smashers origional upgrade path with the "armoury" tree -added lancer and smasher upgrades to armoury tree
    • -
    • added "Sword", "Injector" and "Fencer" to lancer upgrades
    • -
    • buffed drone tanks, twin tanks & tank health
    • -
    • added "Dictator" -added "Tripwire"
    • -
    • added "Barricade", "Twister", "Cyclone" and "Architect" -added "Tri-Trapper" tree -added "auto tritrapper", "auto armour" and "autolancer"
    • -
    • added "eagle" and "bulwark"
    • -
    • updated debug menu
    • -
    • removed hivemind from basic
    • -
    • added cloner upgrade
    • -
    • added hivemind and "splitter" to cloner upgrade
    • -
    • added "auto cloner", "auto flamethrower", "flamethrower hybrid" and "lancer hybrid"
    • -
    • updated colorscheme and other color related things
    • -
    • updated teams on 2tdm after 3 team bug -added all new Rock Maze gamemode
    • -

      Ryerson Loves Burger King

      -
    -
    -
    -

    Update 2.5

    - [2023] -
      -
    • added new tanks into beta for further testing
    • -
    • hired new devs
    • -
    • neroio discord is up
    • -
    • added new mascallenus tank and section
    • -
    • hired new beta testers
    • -
    • added new easter eggs
    • -
    • tested 2nd server opening
    • -
    • added "Scanner" and "hadoken"
    • -
    • nerfed Hahaugobrr
    • -
    • promoted lucas medieros to co-owner of the game
    • -
    • demoted a few staff
    • -
    • added 2TDM game mode
    • -
    • woomy event is back! now with free access to testbed
    • -
    • added "flankdrive", "twindrive" and "machinedrive"
    • -
    • fixed trapper look
    • -
    • added "infantry", "musket", "Traprid", "Auto Traprid", "Snigrav", "AsWdragafora", "Assasolak", "Builifacate", "Rifagiulus", "Auto Snigrav"
    • -
    • added "flamethrower", "Baker", "Wildfire" and "Equinox"
    • -
    • new nero.io default theme instead of using arras's
    • -
    • added insane af tanks to testbed
    • -
    • added "lancer"
    • -

      Open Na Noor

      -
    -
    -
    -

    Update 2.4

    - [2023] -
      -
    • added 2 new admin commands
    • -
    • added homing auto Basic
    • -
    • added bosses tab to AIT
    • -
    • bwomp AA $$ €€
    • -
    • added easter egg name colors
    • -
    • added the tanks "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", and "neptune"
    • -
    • added a new boss
    • -
    • added more natural spawning bosses
    • -
    • added "SpawnTrap"
    • -
    • updated bot names
    • -
    • ended woomy event
    • -

      Oh great red Text of the Changelog, What is your Wisdom?

      -
    -
    -
    -

    Update 2.3

    - [2023] -
      -
    • added "maleficator", "stalker", "landmine", "jumpsmash", "speedbent", "heavy3", and re-added "twindrive", "interceptioner", the "drive" subtree to autobasic, plus increased map size
    • -
    • fixed and debuffed jumpsmash
    • -
    • debuffed speedbent
    • -
    • added a public changelog (the one your looking at now)
    • -
    • added the red text
    • -
    • updated sounds and styles
    • -
    • added the "corrupted" button
    • -

      So Hows Ur Day?

      - -
    -
    -
    -

    Update 2.2

    - [2023] -
      -
    • added more tanks into beta
    • -
    • added sounds and updated client backround
    • -
    • Decoration finished
    • -
    • started decoration on migration host
    • -
    • added chat feature
    • -
    • migration big fixes
    • -
    • WE DID IT! MIGRATION COMPLETE!
    • -
    • during migration found multiple small bugs that was fixed
    • -
    • 2nd failed migrating attempt, starting yet another
    • -
    • fixed crashing bug
    • -
    • 2nd attempt at migrating
    • -
    • added random bot and skill classes
    • -
    • made bots more op
    • -
    • fixed a bot bug
    • -
    • downgraded bots
    • -
    • added tank visualizers
    • -
    • buffed bots a tiny bit more
    • -
    • fixed visualizer bug
    • -
    • added "rifle"
    • -
    • fixed "lilfact" upgrade path
    • -
    • added auto "lilfact"
    • -
    • renamed "lilfact" to "spawner"
    • -
    • added secret tanks for update 2.3
    • -
    • minor crash bug fixes
    • -
    • removed "rifle" and "autospawner" from beta
    • -
    • fixed smasher bug
    • -
    • failed "lancer" class attempt
    • -
    • secret tank updates
    • -
    • major bug fixes
    • -
    • rainbow color old client fix
    • -
    • last patches before big update
    • -
    • fixed tiny bug
    • -

      I Know Where You Live

      -
    -
    -
    -

    Update 2.1

    - [2022] -
      -
    • fixed the 2 game crashing bugs
    • -
    • tried to migrate to another server host but yet failed due to unknown reasons
    • -
    • added "speedbent" to beta
    • -
    • updated messages
    • -

      tbh im sad the 49ers missed the super bowl :/

      -
    -
    -
    -

    Update 2.0

    - [2021] -
      -
    • brought the ception tree into beta tanks
    • -
    • figured out that the "ceptions" arent really ceptions
    • -
    • forgot to add the actual way to access it LOL, also added a REAL machine ceptionist as a test
    • -
    • removed ceptionist and drive tanks as they are too overpowered
    • -
    • added lazer guns
    • -
    • stole code from someone elses server
    • -
    • added beta shock and burn
    • -
    • added some secret really stupid tanks
    • -
    • fixed a tank
    • -
    • removed revolutionist for being too buggy
    • -
    • added new auto class branch
    • -
    • added hivemind
    • -
    • bug fixes
    • -
    • major bug that caused no tanks to be added or bugs fixed causing confusion
    • -
    • crashing bug made game unplayable for large amount of time (like a whole 9 months)
    • -

      Whats Up Guys Quandale Dingle Here

      -
    -
    -
    -

    Update 1.9

    - [2021] -
      -
    • testing in progress
    • -
    • approved multiple tanks into the game
    • -
    • did some stupidity and added random stuff and figured out that there is indeed, 12882 lines of code in this project
    • -
    • added some dumb tanks like "mInIfLyInGfAsTeRtHiNgY"
    • -
    • added some cool colored objects on the "AsWdWsA" branch
    • -
    • added a secret tank
    • -
    • messed with some things like homing bullets
    • -
    • removed the homing stuff due to bugs
    • -
    • tried to recreate the "revolutionist" tank from woomy arras
    • -
    • more tests
    • -
    • added auto bullets
    • -
    • added drive tanks into beta testing phase
    • -
    • moved where the secret tank is
    • -
    • debuffed "single"
    • -
    • added "Cascal", "Gunto", "Catalyst", And "Cescav" to beta tanks
    • -
    • added a beta version of the drive tree into the game after some testing
    • -

      What A Dumb Fucking Game!

      -
    -
    -
    -

    Update 1.8

    - [2021] -
      -
    • completed and put the poison function into the game
    • -
    • completed and put the freeze function into the game
    • -
    • created a seprate freeze and poison bullets
    • -
    • added a stun function
    • -
    • added a healing and speed function
    • -
    • added a stun, healing and speed bullet shooting tanks
    • -
    • added the "AsWdWsA" branch
    • -
    • fixed poison cannon
    • -
    • renamed the bullets to respected name
    • -
    • renamed the cannons to a respected name
    • -
    • created a page 2 for the mascallenus
    • -
    • put multitanks into testbed
    • -
    • put multitanks into testbed
    • -
    • organized the tanks
    • -
    • removed public testbed
    • -

      :skull:

      -
    -
    -
    -

    Update 1.7

    - [2020] -
      -
    • added an admin logger
    • -
    • changed the AI color to pink
    • -
    • changed AI to have twin upgrade instead of basic
    • -
    • expanded the map
    • -
    • changed the colors of the spawning player to be random instead of always red or blue
    • -
    • added the tanks "oof" and "oof2" to mascallenus
    • -
    • added the tank "minibee" to testbed
    • -
    • added the tank "hexa trapper" into the game
    • -
    • added the tank "Paint Brush" into the crayon tree
    • -
    • added the tank "brutalizer"
    • -
    • added "sidewinder"
    • -

      Share with your friends!

      -
    -
    -
    -

    Update 1.6

    - [2020] -
      -
    • added the tank "tower mech"
    • -
    • added the "AIT" category into testbed
    • -
    • added a way to get back to a basic tank after becoming testbed
    • -
    • added the tank "crayon"
    • -
    • added the two tanks "marker" and "pastel"
    • -
    • added the tank "pen"
    • -
    • added a kill button to testbed
    • -
    • added the tank "highlighter"
    • -
    • added a way to immediatly upgrade into a basic trapper
    • -
    • invited some friends to help code my game
    • -

      Yo shout out to Lucas Medeiros

      -
    -
    -
    -

    Update 1.5

    - [2020] -
      -
    • removed jesus donut
    • -
    • removed DeltaCannon
    • -
    • fixed some bugs with AI's
    • -
    • fixed some bugs with crashers and bosses
    • -
    • added a bunch of testbed tanks into the real thing
    • -
    • removed fairsquare
    • -
    • added flame killa to testbed
    • -
    • removed access to the recently added tanks from testbed to save space
    • -
    • added Boxer to testbed
    • -
    • removed every testbed tank
    • -
    • added categories to test bed like "beta" and "mascallenus"
    • -

      come down today and try some corn, or we will sacrifice your newborn

      -
    -
    -
    -

    Update 1.4

    - [2020] -
      -
    • added Lottery to testbed
    • -
    • added hellblazer and Rocketer to testbed
    • -
    • added Nautilus to testbed
    • -
    • added jesus donut to testbed
    • -
    • experimented with bullet effects
    • -
    • added SleamShot
    • -
    • added TrapHard into testbed
    • -

      LMFAO WHAT A BOZO

      -
    -
    -
    -

    Update 1.3

    - [2020] -
      -
    • added master
    • -
    • added lilfact
    • -
    • fixed bug with bots
    • -
    • fixed bug with lilfact
    • -
    • ADDED PUBLIC TESTBED
    • -
    • fixed some bugs
    • -
    • fixed testbed problems
    • -
    • fixed testbed key errors regarding platform
    • -
    • added helltank to testbed
    • -
    • added DeltaCannon to testbed
    • -

      DrUgS aRe BaD fOr YoU1!1!

      -
    -
    -
    -

    Update 1.2

    - [2020] -
      -
    • server shutdown due to server problems
    • -
    • fixed problem
    • -
    • fixed some more bugs
    • -
    • fixed bug with the upgrades
    • -
    • added 3 pre-made extra tanks (hive shooter, auto assassin, auto cruiser)
    • -
    • added Unlocked
    • -
    • added more ways to get hive shooter
    • -
    • added more ways to get unlocked
    • -
    • added bots
    • -
    • fixed bad bug with Unlocked
    • -

      tbh play a better game than this

      -
    -
    -
    -

    Update 1.1

    - [2019] -
      -
    • added revix
    • -
    • added DeltaGunner
    • -

      OH BABY A TRIPLE

      -
    -
    -
    -

    Update 1.0

    - [2019] -
      -
    • just opened server
    • -
    • testing new tanks
    • -

      Bwomp

      -
    -
    -You've Reached The End
    ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file +
    +

    Title 1: optional description

    + optional date +
      +
    • Change 1
    • +
    • Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, excepturi.
    • +
    • Change 3
    • +
    +
    +
    +

    Title 2: optional description

    + optional date +
      +
    • Change 1
    • +
    • Change 2
    • +
    • Change 3
    • +
    +
    \ No newline at end of file diff --git a/public/credits.html b/public/credits.html deleted file mode 100644 index ecb93e106..000000000 --- a/public/credits.html +++ /dev/null @@ -1,104 +0,0 @@ -
    -

    Deltafyrex

    - [Lead Dev, Game Owner and Discord Owner] -
      -
    • certified moron
    • -
    • pissass
    • -
    • favorite colors are cyan, white and black
    • -
    • does everything in this game
    • -
    • the reason you get disconnected often while in game lol
    • -
    • game founder
    • -
    • working on nero since 2019
    • -
    -
    -
    -

    Can Karaman

    - [Site Manager, Co-Lead Dev] -
      -
    • second most helpful person here
    • -
    • sets up the whole domain and security section of the site
    • -
    • absolutely just an all around amazing person
    • -
    • nero would be nowhere without him
    • -
    • bill nye the server guy
    • -
    • pulling nero out of the glitch rabbit hole
    • -
    • Scares the fuck out of me when he takes such an authoritarian position
    • -
    -
    -
    -

    Eguy

    - [Lead Beta Tester] -
      -
    • third most helpful person here
    • -
    • helps deltafyrex all the time
    • -
    • cool guy 😎
    • -
    • nero would fr be not as cool as it is without eguy
    • -
    • helps test and balance tanks
    • -
    -
    -
    -

    Ultimate primal

    - [Beta Tester and Discord Server Admin] -
      -
    • actually cares about nero.io
    • -
    • Pretty fun to have around
    • -
    • quite a chill fellow
    • -
    • will definitely destroy you
    • -
    -
    -
    -

    "Wait What!?"

    - [Helper] -
      -
    • quite wise
    • -
    • owner of phoearras
    • -
    • gives Deltafyrex wisdom and pieces of code sometimes (very nice)
    • -
    -
    -
    -

    MGLIFEYT

    - [Fucking Dipshit (only still on the team because he made the damn discord bot)] -
      -
    • SeX uPdAtE wHeN!/!?11/
    • -
    • RoBlOx NeRo BeTtEr!!!!! (spoiler alert: it doesn't even fucking exist)
    • -
    • useless asshole who has bad taste in imagery
    • -
    • Discord Bot maker
    • -
    • owner of vehicle wars on roblox
    • -
    -
    -
    -

    "C"

    - [Dev In Training (i have a good feeling about him)] -
      -
    • Deltafyrex's Best Friend irl
    • -
    • bro looks like a fucking mexican border crosser in yearbook photos ☠☠☠
    • -
    • Hair that could mop a floor lol
    • -
    • O U R P l E
    • -
    • severe alastor enthusiast
    • -
    • ChickenSandwhichMan
    • -
    -
    -
    -

    Special Thanks:

    - [Other Special Thank-you's] -
      -
    • Meta (sip!)
    • -
    • Maeka09 (Also Deltafyrex's best friend)
    • -
    • Darkfrost (No need to Specify >:3)
    • -
    • "D" (I AM THE GREENMAN I SPEAK FOR THE TREES)
    • -
    • O_S (YIPPEE)
    • -
    • SafariSE (helped delta start out on creating nero all those years ago)
    • -
    • Lucas Medeiros (Fellow Faithful Member)
    • -
    • Fruitmelon (gave delta some tips awhile back)
    • -
    • The Piss Cult (yeah you know who you are)
    • -
    • Maaxxi3114 Yesus' Pet Roblox Nero Endorser
    • -
    • Galaxy Dash (David Goggins, "I cant even count that high")
    • -
    • NoahPlays (Funny Nero Hater Lol)
    • -
    • Tokay Dragon (Furry)
    • -
    • Deltas Youtube Subscribers (Thanks!)
    • -
    • Deltas Body (worked on nero through countless hours of sleep deprivation HOLY SHIT ITS 12:00 AM)
    • -
    • APS++ Developers (very nice)
    • -
    • Arras Mayhem (this is here cuz some dude got mad at me for not crediting mayhem bc i used 2 of their sounds like boohoo)
    • -
    • im not putting any other license than the "do whatever the fuck you want" license
    • -
    -
    -You've Reached The End OwO ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ diff --git a/public/favicon.ico b/public/favicon.ico index 23a67e49d6cba160f4370dbeb97260b1bcfa0641..263db474e5caa9ef7a67202982a0bbf6d98f2ac4 100644 GIT binary patch literal 21654 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 z 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¥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 diff --git a/public/icon32x32.png b/public/icon32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..df137ff100a823f62fc60607d2233bf88087ba5b GIT binary patch literal 1898 zcmV-w2bK7VP)=yltj6!_e)T&!-r=&jy-S-KOj1c3ZiSF)3oAdTe$-NhX7lwi`!892Kue*Dgz3l45B0j2&kZTv_r2V7<=1P zy|^cj2t9yX44+YH=&D6meTbxotQ4epkP}RyXMJub#Qpc+!Qb(lkL}j_q7r~H-a(n<^ zfFzR~0^f6}4AyM<4AO=VhWthIqLPT01e3Grud^Wn?0Qiwh5sN@TmoN{2lR(y2eyX5 z=|gh1`j1{n2$`v4rXIC7UboABWu|S=CAqo^xwzn!Y)BvfBq|(?)gXbx)efVEJpt)s zM@N7MWn=Ldd?gYjo3-y*s+nbo2)S<#PM4C zxG_wCgyMen`Yq`2`t?v~h~&B7uR+e->6{Y}T3Vt0PLn@@1!1E3DeFO*+N&Tjqi*#) z3N8HsV>@d25U9CQ#}?9+0nifJln9v_6X3PnIh^^q*)yPE^>%1NAWBpM+OTpl6TNZ! z9-RBFHl!O%+bnn?Pco00hHVzCTuNaC$nujVI~crZ_t&s_=ON&}g@0@%J}Y4&Ha0(k zbLVTp>1>BZFJz*ZX29{YHQ@EB489&e1pfNkkD=A+#7KKV$Nr-GIzW(RyJQ}1EkdQk zm{p*jNj9%tfo{uS@WbC#FrjZh-wMT>RzgZr5}dESgP*K0dHT4~Q1Mj}gHy?o+<)*7s5ppZ(|}MYL`-H%QU`{ju0iP)+|R(^VbpC*CMWgh z0vHGa%<4SVDFzaHm#FDpqyKs?R^0!7)8_#?OOOv&C?F|9yGJ1;V~uxIm_SYxcX!3 zCsBrN_{HZkI!R!cOT*HQ>3-mfwuzeCRTW|_2+vesj!6J7OS&HM$CnXVe#5xSa;+#3~ z>PuNYlAw-9U9zg?8Vnth3LmXo&ZYY9hx@_f@kB)>14TIwRG)7N?Tna!3+FPnOL<%Na@_vo&w!|Z93*&~$YB=?(I;07jRS;eo= z=26+TF+>5MF;BTzqJ%=y^$E+fg;tP+6KaPWJrRAA5_Buoy#FKiib{tX{HKUQ+!EzN zi7i4`v=_(|n%i5cs~wggpnoSE0F)$%Dd;`b>qcM=u?Nnzht1DQ^s256uG-$^%^7*RE^J9@@&Aqha;&a0*5E=$jFM2A-Hy z)qipd3?v%qa=!s=13qvRRL@@JVyV)b{+I;9i16`T>+ob_Os9fwSnzHCY1u$Pfrpw+ kOz2-N#Y^SEERQAs0wHl$MK9tqX8-^I07*qoM6N<$g2vH(TL1t6 literal 0 HcmV?d00001 diff --git a/public/index.html b/public/index.html index 253455d22..602027ceb 100644 --- a/public/index.html +++ b/public/index.html @@ -3,277 +3,59 @@ - + - - - - + - - Nero.io 3.1 + Open Source Arras - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - - - - - - -
    - - -
    - +
    diff --git a/public/index.js b/public/index.js deleted file mode 100644 index 1508924f2..000000000 --- a/public/index.js +++ /dev/null @@ -1,49 +0,0 @@ -let fs = require('fs'), - path = require('path'), - servers = require('./servers.json'), - publicRoot = path.join(__dirname, "../public"), - sharedRoot = path.join(__dirname, "../shared"), - mimeSet = { - "js": "application/javascript", - "json": "application/json", - "css": "text/css", - "html": "text/html", - "md": "text/markdown", - "png": "image/png", - "ico": "image/x-icon" - }, - server, - port = 3000, - host = "https://neroio2.glitch.me", - // If someone tries to get a file that does not exist, send them this instead. - DEFAULT_FILE = "index.html", - modify_file = (file, root) => { - if (!fs.existsSync(file)) { - file = path.join(root, DEFAULT_FILE); - } else if (!fs.lstatSync(file).isFile()) { - file = path.join(root, DEFAULT_FILE); - } - return file; - }; - -server = require('http').createServer((req, res) => { - let shared = req.url.startsWith('/shared/'), - root = shared ? sharedRoot : publicRoot, - fileToGet = path.join(root, req.url.slice(shared ? 7 : 0)); - - if (req.url == './servers.json') { - res.writeHead(200); - res.end(servers); - } else { - //if this file does not exist, return the default; - fileToGet = modify_file(fileToGet, root); - - //return the file - res.writeHead(200, { 'Content-Type': mimeSet[ fileToGet.split('.').pop() ] || 'text/html' }); - return fs.createReadStream(fileToGet).pipe(res); - } -}); - -server.listen(port, host, () => console.log("Client server listening on port", port)); - -module.exports = { server }; \ No newline at end of file diff --git a/public/lib/socketInit.js b/public/lib/socketInit.js index 798506757..bf25e408a 100644 --- a/public/lib/socketInit.js +++ b/public/lib/socketInit.js @@ -758,7 +758,7 @@ const protocols = { }; const socketInit = port => { window.resizeEvent(); - let socket = new WebSocket(protocols[location.protocol] + window.serverAdd); + let socket = new WebSocket(protocols[window.connectionAdd] + window.serverAdd); // Set up our socket socket.binaryType = 'arraybuffer'; socket.open = false; @@ -862,7 +862,7 @@ const socketInit = port => { global.player.name = m[0]; break; case "achieve": - const achievementTable = ['killachievement', 'killachievement2', 'tokenachievement'] // lookup table of achievements and their ids + const achievementTable = ['killachievement', 'killachievement2', 'tokenachievement', 'bossachivement'] // lookup table of achievements and their ids util.submitAchievementToLocalStorage(achievementTable[m[0]]) // whatever code to actually give the player the achievement break; case "menu": diff --git a/public/lib/util.js b/public/lib/util.js index b9e9f542c..4a8c2197e 100644 --- a/public/lib/util.js +++ b/public/lib/util.js @@ -87,7 +87,7 @@ const util = { }, pullJSON: fileName => { return new Promise((resolve, reject) => { - const url = `${location.protocol}//${window.serverAdd}/lib/json/${fileName}.json`; + const url = `${window.connectionAdd}//${window.serverAdd}/lib/json/${fileName}.json`; console.log("Loading JSON from " + url); fetch(url).then(response => response.json()).then(json => { console.log("JSON load from " + url + " complete"); diff --git a/public/main.css b/public/main.css index c65d60fca..f0d1d0103 100644 --- a/public/main.css +++ b/public/main.css @@ -178,8 +178,8 @@ input { border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; - margin-top: 5px; - margin-bottom: 5px; + margin-top: 10px; + margin-bottom: -10px; outline: none; } @@ -252,11 +252,11 @@ div.optionsHeader { } .serverSelector { - height: 65px; + height: 75px; text-align: center; font-size: 14px; font-weight: bold; - line-height: 13px; + line-height: 14px; padding-left: 10px; overflow-y: scroll; scroll-behavior: smooth; @@ -275,6 +275,15 @@ div.optionsHeader { cursor: default; } +.serverSelector tr:hover { + color: #8ABC3F; +} +.serverSelector tr.selected:hover { + color: #1B3353; + cursor: default; +} + + #startMenu { position: relative; margin: auto; @@ -1472,14 +1481,15 @@ body.mobile #skinpdiv { #eventtitle { position: absolute; float: center; - top: 10%; - left: 50%; + top: 600px; + width: 70%; + left: 15%; color: white; outline: #000000 solid; z-index: 0; cursor: pointer; text-shadow: -1px -1px 0 #000000, 1px -1px 0 #000000, -1px 1px 0 #000000, 1px 1px 0 #000000; - background: #202020 url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/channels4_profile.jpg?v=1709324207088") 0px 0px/100px repeat; + background: #202020 url("https://yt3.googleusercontent.com/yDCc9Bsxd-JFacxEfYiO_Nz_B3ZbqJBYazWi8ltyHMOHA_k2t-1zSPSC58u9ZxG9ByurM2cZag=s900-c-k-c0x00ffffff-no-rj") 0px 0px/100px repeat; } #controls { height: 200px; @@ -1969,6 +1979,13 @@ td b { vertical-align: bottom; } +.tdLeft { + width: 25%; +} +.tdCenter { + width: 350px; +} + *:focus { outline: 1px solid transparent; border-style: none; diff --git a/public/run.bat b/public/run.bat deleted file mode 100644 index d43f21b4d..000000000 --- a/public/run.bat +++ /dev/null @@ -1,2 +0,0 @@ -"C:\Program Files\nodejs\node.exe" ".\server\index.js" -pause \ No newline at end of file diff --git a/public/servers.json b/public/servers.json deleted file mode 100644 index eac27490d..000000000 --- a/public/servers.json +++ /dev/null @@ -1,5 +0,0 @@ -[ - "neroio.xyz", - "old.neroio.xyz", - "https://neroio2.glitch.me" -] \ No newline at end of file diff --git a/run.bat b/run.bat new file mode 100644 index 000000000..bf09668f0 --- /dev/null +++ b/run.bat @@ -0,0 +1,2 @@ +"C:\Program Files\nodejs\node.exe" --trace-warnings ".\server\index.js" +pause \ No newline at end of file diff --git a/runLoop.bat b/runLoop.bat new file mode 100644 index 000000000..42689d54c --- /dev/null +++ b/runLoop.bat @@ -0,0 +1,4 @@ +:loop +"C:\Program Files\nodejs\node.exe" --trace-warnings ".\server\index.js" +timeout /T 5 +goto loop \ No newline at end of file diff --git a/server/config.js b/server/config.js index 89a68661e..492445fa7 100644 --- a/server/config.js +++ b/server/config.js @@ -5,13 +5,16 @@ module.exports = { // If 'localhost:NUMBER', the port must equal the port setting. host: "neroio2.glitch.me", + // Behind https proxy + https: true, + + // World-wide location + // Leave empty to show host name instead + location: "USA", + // Which port to run the web server on. port: 3000, - // Region/Location the server is in - // For glitch its US West - region: "US West", - // name of the server ex. main server, beta server, etc serverName: "Beta", @@ -28,7 +31,7 @@ module.exports = { // Log speed loop warnings LOGS: false, - // If there's only one server + // If there's only one server COMBINED: true, // The \modules\setup\gamemodeconfigs\ files to load. @@ -55,6 +58,9 @@ module.exports = { // They get sanitized after addons interpret them, but before they're added to the chat message dictionary. SANITIZE_CHAT_MESSAGE_COLORS: false, + // If someone tries to get a file that does not exist, send them this instead. + DEFAULT_FILE: 'index.html', + // Window name of the server terminal. WINDOW_NAME: 'Nero Game Server Instance', @@ -105,6 +111,8 @@ module.exports = { if (level <= 45 && level & 1 == 1) return 1; return 0; }, + // Show the health bar text or not. + SHOW_HEALTHBAR_TEXT: false, // Default skill caps. MAX_SKILL: 9, @@ -137,7 +145,7 @@ module.exports = { BOT_CLASS_UPGRADE_CHANCES: [ 1, 5, 20, 37, 37], // The prefix of the bot's name. - BOT_NAME_PREFIX: "[AI] ", + BOT_NAME_PREFIX: '§#888§[AI]§reset§ ', // The class that players and player-bots spawn as. SPAWN_CLASS: "basic", @@ -152,6 +160,12 @@ module.exports = { // Natural Spawns + // Allow foods to be spawned or not. + FOOD_SPAWN_CHANCE: 0.05, // Likeliness of normal food spawn attempts succeedingg. 0.875 + // NOTE: Disabling it decreases lagness, also very useful if you don't need foods to be spawned. + FOOD_SPAWN_COOLDOWN: 100, // Cooldown (in game ticks) of food spawn attempts being made. 30 + ENABLE_FOOD: true, + FOOD_CAP: 1, // Max normal food per normal tile. 3 FOOD_SPAWN_CHANCE: 0.05, // Likeliness of normal food spawn attempts succeedingg. 0.875 FOOD_SPAWN_COOLDOWN: 100, // Cooldown (in game ticks) of food spawn attempts being made. 30 diff --git a/server/index.js b/server/index.js index 90e7b78f8..299d7451f 100644 --- a/server/index.js +++ b/server/index.js @@ -30,6 +30,9 @@ function collide(collision) { // Pull the two objects from the collision grid let instance = collision[0], other = collision[1]; + if (instance.noclip || other.noclip) { + return 0; + } instance.emit('collide', { body: instance, instance, other }); other.emit('collide', { body: other, instance: other, other: instance }); // Check for ghosts... @@ -77,12 +80,8 @@ function collide(collision) { case 4: mazewallcollide(wall, entity); break; - case 0: - mooncollide(wall, entity); - break; default: - let a = entity.type === "bullet" ? 1 + 10 / (entity.velocity.length + 10) : 1; - advancedcollide(wall, entity, false, false, a); + mooncollide(wall, entity); break; } break; @@ -222,7 +221,7 @@ function collide(collision) { } // The most important loop. Lots of looping. -let time, ticks = 0; +let ticks = 0; const gameloop = () => { logs.loops.tally(); logs.master.startTracking(); @@ -290,7 +289,7 @@ const gameloop = () => { } }; -setTimeout(closeArena, 2 * 60 * 60 * 1000); // Restart every 2 hours +setTimeout(closeArena, 24 * 60 * 60 * 1000); // Restart every 2 hours global.naturallySpawnedBosses = []; global.bots = []; @@ -317,10 +316,10 @@ const maintainloop = () => { } sockets.broadcast(amount > 1 ? "Visitors are coming." : "A visitor is coming."); setSyncedTimeout(() => { - let names = []; + let names = ran.chooseBossName(selection.nameType, amount); for (let i = 0; i < amount; i++) { - let spot, attempts = 30, name = ran.chooseBossName(selection.nameType); + let spot, attempts = 30, name = names[i]; do { spot = getSpawnableArea(TEAM_ENEMIES); } while (attempts-- && dirtyCheck(spot, 500)); let boss = new Entity(spot); @@ -330,7 +329,6 @@ const maintainloop = () => { boss.name = name; } - names.push(boss.name); naturallySpawnedBosses.push(boss); boss.on('dead', () => util.remove(naturallySpawnedBosses, naturallySpawnedBosses.indexOf(boss))); } @@ -377,7 +375,10 @@ const maintainloop = () => { bots.push(o); setTimeout(() => { // allow them to move - o.define([o.defs, 'bot']); + // Save index so it isn't overwritten by the bot Class's index + let index = o.index; + o.define('bot'); + o.index = index; o.refreshBodyAttributes(); o.invuln = false; }, 3000 + Math.floor(Math.random() * 7000)); diff --git a/server/lib/random.js b/server/lib/random.js index f8f61c765..f0556a927 100644 --- a/server/lib/random.js +++ b/server/lib/random.js @@ -100,4 +100,4 @@ exports.nameLists = { exports.chooseBotName = () => exports.choose(exports.nameLists.bots); -exports.chooseBossName = code => code in exports.nameLists ? exports.choose(exports.nameLists[code]) : undefined; \ No newline at end of file +exports.chooseBossName = (code, amount) => code in exports.nameLists ? exports.chooseN(exports.nameLists[code], amount) : []; \ No newline at end of file diff --git a/server/modules/definitions/addons/defsReloadCommand.js b/server/modules/definitions/addons/defsReloadCommand.js index 21bbd0495..4ae7f60a2 100644 --- a/server/modules/definitions/addons/defsReloadCommand.js +++ b/server/modules/definitions/addons/defsReloadCommand.js @@ -1,5 +1,6 @@ let lastReloadTime = 1; const validCommands = ['**reload definitions', '**reload defs', '**redefs']; + Events.on('chatMessage', ({ message, socket, preventDefault }) => { let perms = socket.permissions; // No perms restriction @@ -47,15 +48,22 @@ Events.on('chatMessage', ({ message, socket, preventDefault }) => { // Redefine all tanks and bosses for (let entity of entities) { - if (entity.type != 'tank' && entity.type != 'miniboss') continue; + // If it's a valid type and it's not a turret + if (!['tank', 'miniboss', 'food'].includes(entity.type)) continue; + if (entity.bond) continue; let entityDefs = JSON.parse(JSON.stringify(entity.defs)); + // Save color to put it back later + let entityColor = entity.color.compiled; + + // Redefine all properties and update values to match entity.upgrades = []; entity.define(entityDefs); entity.destroyAllChildren(); entity.skill.update(); entity.syncTurrets(); entity.refreshBodyAttributes(); + entity.color.interpret(entityColor); } // Tell the command sender diff --git a/server/modules/definitions/addons/dreadv1.js b/server/modules/definitions/addons/dreadv1.js index adfc7d78e..b3caf31bc 100644 --- a/server/modules/definitions/addons/dreadv1.js +++ b/server/modules/definitions/addons/dreadv1.js @@ -19,23 +19,26 @@ g.dreadv1Generic = { g.dreadv1Sniper = { speed: 1.07, maxSpeed: 1.07, - health: 1.1, + health: 1.2, + damage: 1.1, reload: 1.13, - density: 1.6, + density: 1.8, pen: 1.05, - resist: 1.1, + resist: 1.2, range: 0.8, } g.dreadv1Slow = { health: 1.3, + damage: 1.25, + resist: 1.1, speed: 0.65, maxSpeed: 0.65, -}; +} g.dreadv1Drone = { - health: 1.25, + health: 1.1, speed: 0.68, maxSpeed: 0.68, - reload: 0.8, + reload: 1.2, size: 1.2, recoil: 0, } @@ -44,7 +47,7 @@ g.dreadv1Trap = { shudder: 0.2, speed: 1.05, reload: 2.8, - damage: 1.8, + damage: 1.45, health: 1.35, resist: 1.1, size: 1.25, @@ -535,7 +538,7 @@ Class.inquisitorOfficialV1 = { GUNS: weaponArray({ POSITION: [7, 7.5, 1.3, 7.5, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.dreadv1Drone, {speed: 0.95, maxSpeed: 0.95, damage: 0.9, health: 0.92}]), + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.dreadv1Drone, {speed: 0.95, maxSpeed: 0.95, damage: 0.93, health: 0.92}]), TYPE: "drone", AUTOFIRE: true, SYNCS_SKILLS: true, @@ -555,12 +558,13 @@ Class.assailantOfficialV1 = { }, { POSITION: [1.5, 10, 1, 14.25, 0, 0, 0], PROPERTIES: { - MAX_CHILDREN: 4, - SHOOT_SETTINGS: combineStats([g.factory, g.overseer, g.dreadv1Drone, {damage: 0.6}]), - TYPE: ["minion", {GUN_STAT_SCALE: {reload: 1.333, health: 0.7, speed: 0.8, maxSpeed: 0.8}}], + SHOOT_SETTINGS: combineStats([g.factory, g.overseer, g.dreadv1Drone, {damage: 0.45}]), + TYPE: ["minion", {GUN_STAT_SCALE: {reload: 1.5, health: 0.75, speed: 0.8, maxSpeed: 0.8}}], STAT_CALCULATOR: "drone", AUTOFIRE: true, - SYNCS_SKILLS: true + SYNCS_SKILLS: true, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 4, } }, { POSITION: [11.5, 10, 1, 0, 0, 0, 0] @@ -642,7 +646,7 @@ Class.minotaurOfficialV1 = { }, { POSITION: [3, 9.5, 1.6, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { reload: 1.55, range: 0.93, health: 1.55 }]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { damage: 0.9, reload: 1.55, range: 0.93, health: 1.55 }]), TYPE: ["unsetTrap", {HITS_OWN_TYPE: "never"} ], STAT_CALCULATOR: "block" } @@ -731,100 +735,74 @@ if (!enableHealers) { t1Bodies.splice(4, 1); // Remove Medicare if healers are disabled } -// Build both tiers of dreads -for (let primary of Class.dreadOfficialV1[`UPGRADES_TIER_${tier1}`]) { - let primaryName = primary; - primary = ensureIsClass(primary); - primary[`UPGRADES_TIER_${tier1}`] = []; - - for (let secondary of t1Bodies) { - let secondaryName = secondary; - secondary = ensureIsClass(secondary); - - let GUNS = [], - TURRETS = [], - LABEL = primary.LABEL + "-" + secondary.LABEL, - BODY = JSON.parse(JSON.stringify(dreadnoughtBody)), - UPGRADE_TOOLTIP = (primary.UPGRADE_TOOLTIP ?? "") + " + " + (secondary.UPGRADE_TOOLTIP ?? ""); - - // Label it - if (primary.LABEL == secondary.LABEL) LABEL = primary.LABEL; - if (primary.UPGRADE_TOOLTIP == secondary.UPGRADE_TOOLTIP) UPGRADE_TOOLTIP = primary.UPGRADE_TOOLTIP; - - // Guns - if (primary.GUNS) GUNS.push(...primary.GUNS); - for (let g in secondary.GUNS) { - let POSITION = JSON.parse(JSON.stringify(secondary.GUNS[g].POSITION)), - PROPERTIES = secondary.GUNS[g].PROPERTIES; - POSITION[5] += 60; - GUNS.push({ POSITION, PROPERTIES }); +function mergeDreads(dread1, dread2, sourceDread, tier) { + let dread1Name = dread1; + let dread2Name = dread2; + + dread1 = ensureIsClass(dread1); + dread2 = ensureIsClass(dread2); + + let GUNS = [], + TURRETS = [], + LABEL = `${dread1.LABEL}-${dread2.LABEL}`, + BODY = JSON.parse(JSON.stringify(dreadnoughtBody)), + UPGRADE_TOOLTIP = `${dread1.UPGRADE_TOOLTIP ?? ""}+${dread2.UPGRADE_TOOLTIP ?? ""}`; + + // Label it + if (dread1.LABEL == dread2.LABEL) LABEL = dread1.LABEL; + if (dread1.UPGRADE_TOOLTIP == dread2.UPGRADE_TOOLTIP) UPGRADE_TOOLTIP = dread1.UPGRADE_TOOLTIP; + + // Guns + if (dread1.GUNS) GUNS.push(...dread1.GUNS); + for (let g in dread2.GUNS) { + let POSITION = JSON.parse(JSON.stringify(dread2.GUNS[g].POSITION)), + PROPERTIES = dread2.GUNS[g].PROPERTIES; + POSITION[5] += 60; + GUNS.push({ POSITION, PROPERTIES }); + } + + // Turrets + if (dread1.TURRETS) TURRETS.push(...dread1.TURRETS); + if (dread2.TURRETS) TURRETS.push(...dread2.TURRETS); + + // Body + if (dread1.BODY) { + for (let m in dread1.BODY) { + BODY[m] += (dread1.BODY[m] - dreadnoughtBody[m]) / 2; + } + } + if (dread2.BODY) { + for (let m in dread2.BODY) { + BODY[m] += (dread2.BODY[m] - dreadnoughtBody[m]) / 2; } + } - // Turrets - if (primary.TURRETS) TURRETS.push(...primary.TURRETS); - if (secondary.TURRETS) TURRETS.push(...secondary.TURRETS); - - // Body - if (primary.BODY) for (let m in primary.BODY) BODY[m] *= primary.BODY[m]; - if (secondary.BODY) for (let m in secondary.BODY) BODY[m] *= secondary.BODY[m]; - - // Definition name - let definitionName = primaryName + secondaryName; - - // Actually make that guy - Class[definitionName] = { - PARENT: "genericDreadnought1", - BODY, LABEL, UPGRADE_TOOLTIP, GUNS, TURRETS, - }; - Class[primaryName][`UPGRADES_TIER_${tier1}`].push(definitionName); - Class[definitionName][`UPGRADES_TIER_${tier2}`] = []; - - // Compile T2 - for (let primary2 of primary.UPGRADES_TIER_M1) { - let primaryName2 = primary2; - primary2 = ensureIsClass(primary2); - - for (let secondary2 of secondary.UPGRADES_TIER_M1) { - let secondaryName = secondary2; - secondary2 = ensureIsClass(secondary2); - - let GUNS = [], - TURRETS = [], - LABEL = primary2.LABEL + "-" + secondary2.LABEL, - BODY = JSON.parse(JSON.stringify(dreadnoughtBody)), - UPGRADE_TOOLTIP = (primary2.UPGRADE_TOOLTIP ?? "") + " + " + (secondary2.UPGRADE_TOOLTIP ?? ""); - - // Label it - if (primary2.LABEL == secondary2.LABEL) LABEL = primary2.LABEL; - if (primary2.UPGRADE_TOOLTIP == secondary2.UPGRADE_TOOLTIP) UPGRADE_TOOLTIP = primary2.UPGRADE_TOOLTIP; - - // Guns - if (primary2.GUNS) GUNS.push(...primary2.GUNS); - for (let g in secondary2.GUNS) { - let POSITION = JSON.parse(JSON.stringify(secondary2.GUNS[g].POSITION)), - PROPERTIES = secondary2.GUNS[g].PROPERTIES; - POSITION[5] += 60; - GUNS.push({ POSITION, PROPERTIES }); - } - - // Turrets - if (primary2.TURRETS) TURRETS.push(...primary2.TURRETS); - if (secondary2.TURRETS) TURRETS.push(...secondary2.TURRETS); - - // Body - if (primary2.BODY) for (let m in primary2.BODY) BODY[m] *= primary2.BODY[m]; - if (secondary2.BODY) for (let m in secondary2.BODY) BODY[m] *= secondary2.BODY[m]; - - // Definition name - let definitionName2 = primaryName2 + secondaryName; - - // Actually make that guy - Class[definitionName2] = { - PARENT: "genericDreadnought1", - BODY, LABEL, UPGRADE_TOOLTIP, GUNS, TURRETS - }; - Class[definitionName][`UPGRADES_TIER_${tier2}`].push(definitionName2); - } + // Definition name + let definitionName = dread1Name + dread2Name; + + // Save definition to Class + Class[definitionName] = { + PARENT: "genericDreadnought1", + BODY, LABEL, UPGRADE_TOOLTIP, GUNS, TURRETS, + } + + // Save upgrade to previous dread + let upgradeLevel = `UPGRADES_TIER_${eval(`tier${tier}`)}`; + util.forcePush(Class[sourceDread], upgradeLevel, definitionName); + + // Generate new dreads recursively + if (!dread1.UPGRADES_TIER_M1 || !dread2.UPGRADES_TIER_M1) return; + + for (let upgrade1 of dread1.UPGRADES_TIER_M1) { + for (let upgrade2 of dread2.UPGRADES_TIER_M1) { + mergeDreads(upgrade1, upgrade2, definitionName, tier + 1); } } +} + +// Initiate dread merge +for (let branch1 of Class.dreadOfficialV1[`UPGRADES_TIER_${tier1}`]) { + for (let branch2 of t1Bodies) { + mergeDreads(branch1, branch2, branch1, 1); + } } \ No newline at end of file diff --git a/server/modules/definitions/addons/dreadv2.js b/server/modules/definitions/addons/dreadv2.js index 5231d08f9..b1446dd9d 100644 --- a/server/modules/definitions/addons/dreadv2.js +++ b/server/modules/definitions/addons/dreadv2.js @@ -260,10 +260,6 @@ Class.swordOfficialV2 = { }, }, 2), } -Class.sword2OfficialV2 = { - PARENT: "swordOfficialV2", - BATCH_UPGRADES: true, -} Class.pacifierOfficialV2 = { PARENT: "genericEggnought", LABEL: "Pacifier", @@ -275,10 +271,6 @@ Class.pacifierOfficialV2 = { }, }, 2), } -Class.pacifier2OfficialV2 = { - PARENT: "pacifierOfficialV2", - BATCH_UPGRADES: true, -} Class.peacekeeperOfficialV2 = { PARENT: "genericEggnought", LABEL: "Peacekeeper", @@ -290,10 +282,6 @@ Class.peacekeeperOfficialV2 = { }, }, 2), } -Class.peacekeeper2OfficialV2 = { - PARENT: "peacekeeperOfficialV2", - BATCH_UPGRADES: true, -} Class.invaderOfficialV2 = { PARENT: "genericEggnought", LABEL: "Invader", @@ -314,10 +302,6 @@ Class.invaderOfficialV2 = { }, }, 2), } -Class.invader2OfficialV2 = { - PARENT: "invaderOfficialV2", - BATCH_UPGRADES: true, -} Class.centaurOfficialV2 = { PARENT: "genericEggnought", LABEL: "Centaur", @@ -334,10 +318,6 @@ Class.centaurOfficialV2 = { }, ], 2), } -Class.centaur2OfficialV2 = { - PARENT: "centaurOfficialV2", - BATCH_UPGRADES: true, -} // T1 Bodies Class.byteTurretOfficialV2 = { @@ -1912,14 +1892,34 @@ Class.pegasusOfficialV2 = { ], } +// Generate split upgrades buffer upgrades +const firstTier = ['sword', 'pacifier', 'peacekeeper', 'invader', 'centaur']; +for (let def of firstTier) { + let newDef = `${def}2OfficialV2`; + let originalDef = `${def}OfficialV2`; + Class[newDef] = dereference(originalDef); + Class[newDef].BATCH_UPGRADES = true; + + // Save to upgrades + util.forcePush(Class.dreadOfficialV2, 'UPGRADES_TIER_0', [newDef, "dreadBodyOfficialV2"]); + util.forcePush(Class.dreadWeaponOfficialV2, 'UPGRADES_TIER_0', originalDef); +} + +/* +The above does the following: + +Class.dreadOfficialV2.UPGRADES_TIER_0 = [ + ["sword2OfficialV2", "dreadBodyOfficialV2",], + ["pacifier2OfficialV2", "dreadBodyOfficialV2"], + ["peacekeeper2OfficialV2", "dreadBodyOfficialV2"], + ["invader2OfficialV2", "dreadBodyOfficialV2"], + ["centaur2OfficialV2", "dreadBodyOfficialV2"], +]; + +Class.dreadWeaponOfficialV2.UPGRADES_TIER_0 = ["swordOfficialV2", "pacifierOfficialV2", "peacekeeperOfficialV2", "invaderOfficialV2", "centaurOfficialV2"]; +*/ + Class.addons.UPGRADES_TIER_0.push("dreadOfficialV2"); - Class.dreadOfficialV2.UPGRADES_TIER_0 = [ - ["sword2OfficialV2", "dreadBodyOfficialV2",], - ["pacifier2OfficialV2", "dreadBodyOfficialV2"], - ["peacekeeper2OfficialV2", "dreadBodyOfficialV2"], - ["invader2OfficialV2", "dreadBodyOfficialV2"], - ["centaur2OfficialV2", "dreadBodyOfficialV2"], - ]; Class.sword2OfficialV2.UPGRADES_TIER_0 = ["swordOfficialV2"]; Class.pacifier2OfficialV2.UPGRADES_TIER_0 = ["pacifierOfficialV2"]; @@ -1927,8 +1927,6 @@ Class.addons.UPGRADES_TIER_0.push("dreadOfficialV2"); Class.invader2OfficialV2.UPGRADES_TIER_0 = ["invaderOfficialV2"]; Class.centaur2OfficialV2.UPGRADES_TIER_0 = ["centaurOfficialV2"]; - Class.dreadWeaponOfficialV2.UPGRADES_TIER_0 = ["swordOfficialV2", "pacifierOfficialV2", "peacekeeperOfficialV2", "invaderOfficialV2", "centaurOfficialV2"]; - Class.swordOfficialV2.UPGRADES_TIER_0 = ["gladiusOfficialV2", "sabreOfficialV2"]; Class.gladiusOfficialV2.UPGRADES_TIER_0 = ["bladeOfficialV2"]; Class.bladeOfficialV2.UPGRADES_TIER_0 = ["rapierOfficialV2"]; diff --git a/server/modules/definitions/addons/playerskins.js b/server/modules/definitions/addons/playerskins.js index 293271c68..4895f3232 100644 --- a/server/modules/definitions/addons/playerskins.js +++ b/server/modules/definitions/addons/playerskins.js @@ -19,6 +19,7 @@ Class.squarecharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e- Class.trianglecharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp?v=1714156768932", "orange") Class.pentagoncharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp?v=1714156764280", "purple") Class.gemcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp?v=1714156778841", "aqua") +Class.tokaycharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spider_2.png?v=1722633319003") Class.bsignalskin = { MAX_CHILDREN: 0, @@ -172,4 +173,13 @@ Class.gemskin = { POSITION: [15, -5, 5.5, 0, 360, 3], TYPE: "gemcharm" }] +}; +Class.tokayskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -6, 5.5, 0, 360, 3], + TYPE: "tokaycharm" + }] }; \ No newline at end of file diff --git a/server/modules/definitions/facilitators.js b/server/modules/definitions/facilitators.js index a69ee4af5..ad774addd 100644 --- a/server/modules/definitions/facilitators.js +++ b/server/modules/definitions/facilitators.js @@ -81,6 +81,8 @@ exports.skillSet = (args) => { // functions exports.dereference = type => { + type = ensureIsClass(type); + let output = JSON.parse(JSON.stringify(type)); if (type.GUNS) { for (let i = 0; i < type.GUNS.length; i++) { @@ -421,7 +423,7 @@ exports.makeRadialAuto = (type, options = {}) => { let turretIdentifier = type; if (!isTurret) { - type = exports.dereference(ensureIsClass(type)); + type = exports.dereference(type); let extraStats = options.extraStats ?? []; if (!Array.isArray(extraStats)) { @@ -484,7 +486,7 @@ exports.makeTurret = (type, options = {}) => { - independent: turret independence */ - type = exports.dereference(ensureIsClass(type)); + type = exports.dereference(type); let CONTROLLERS = []; if (options.canRepel) { // default false @@ -551,6 +553,35 @@ exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor, s ] }; } +exports.setTurretProjectileRecoil = (type, recoilFactor) => { + type = exports.dereference(type); + + if (!type.GUNS) return; + + // Sets the recoil of each of the turret's guns to the desired value. + for (let gun of type.GUNS) { + if (!gun.PROPERTIES) continue; + + // Set gun type to account for recoil factor + let finalType = gun.PROPERTIES.TYPE; + if (!Array.isArray(finalType)) { + finalType = [finalType, {}]; + } + if (typeof finalType[1] != "object") { + finalType[1] = {}; + } + // Set via BODY.RECOIL_FACTOR + if (!finalType[1].BODY) { + finalType[1].BODY = {}; + } + finalType[1].BODY.RECOIL_MULTIPLIER = recoilFactor; + + // Save changes + gun.PROPERTIES.TYPE = finalType; + } + + return type; +} exports.makeAura = (type, name = -1, options = {}) => { let turret = { type: "auraBasicGen", @@ -668,7 +699,7 @@ class LayeredBoss { SHAPE: this.shape, COLOR: -1, INDEPENDENT: true, - CONTROLLERS: [["spin", { independent: true, speed: 0.02 / Config.runSpeed * (this.layerID % 2 ? -1 : 1) }]], + FACING_TYPE: ["spin", { speed: 0.02 / Config.runSpeed * (this.layerID % 2 ? -1 : 1) }], MAX_CHILDREN, GUNS: [], TURRETS: [], @@ -818,7 +849,7 @@ exports.makeRare = (type, level) => { LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Trans"][level] + " " + type.LABEL, VALUE: [100, 500, 2000, 4000, 5000][level] * type.VALUE, SHAPE: type.SHAPE, - SIZE: type.SIZE + level, + SIZE: type.SIZE, COLOR: ["lightGreen", "teal", "darkGrey", "rainbow", "trans"][level], ALPHA: level == 2 ? 0.25 : 1, BODY: { diff --git a/server/modules/definitions/groups/bosses.js b/server/modules/definitions/groups/bosses.js index a2f126bcc..70ba3ba50 100644 --- a/server/modules/definitions/groups/bosses.js +++ b/server/modules/definitions/groups/bosses.js @@ -1,7 +1,9 @@ -const { combineStats, skillSet, makeAuto, addAura, LayeredBoss, makeDeco, weaponArray } = require('../facilitators.js'); +const { combineStats, skillSet, makeAuto, addAura, LayeredBoss, makeDeco, weaponArray, setTurretProjectileRecoil } = require('../facilitators.js'); const { base, smshskl } = require('../constants.js'); const g = require('../gunvals.js'); require('./generics.js'); +require('./tanks.js'); +require('./turrets.js'); Class.miniboss = { PARENT: "genericBoss", @@ -23,9 +25,10 @@ Class.elite = { VALUE: 15e4, BODY: { FOV: 1.25, - SPEED: 0.1 * base.SPEED, + SPEED: 0.15 * base.SPEED, HEALTH: 7 * base.HEALTH, DAMAGE: 2.5 * base.DAMAGE, + REGEN: 0.5 * base.REGEN, }, } Class.eliteDestroyer = { @@ -56,6 +59,7 @@ Class.eliteGunner = { UPGRADE_LABEL: "Elite Gunner", UPGRADE_COLOR: "pink", FACING_TYPE: "toTarget", + AI: { NO_LEAD: false }, GUNS: [ { POSITION: [14, 16, 1, 0, 0, 180, 0], @@ -72,7 +76,6 @@ Class.eliteGunner = { POSITION: [6, 14, -2, 2, 0, 300, 0], }, ], - AI: { NO_LEAD: false }, TURRETS: [ { POSITION: [14, 8, 0, 60, 180, 0], @@ -98,10 +101,10 @@ Class.eliteSprayer = { ...weaponArray([ { POSITION: [9, 6, -5, 60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], + TYPE: ["sprayer", { COLOR: "grey", GUN_STAT_SCALE: {damage: 0.9, resist: 0.95} }], }, { POSITION: [9, 6, 5, 60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], + TYPE: ["sprayer", { COLOR: "grey", GUN_STAT_SCALE: {damage: 0.9, resist: 0.95} }], }, ], 3) ], @@ -114,21 +117,21 @@ Class.eliteBattleship = { { POSITION: [4, 6, 0.6, 7, -8, 60, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {speed: 0.95, maxSpeed: 0.95, health: 1.1, resist: 1.05}]), TYPE: "autoswarm", STAT_CALCULATOR: "swarm", }, }, { POSITION: [4, 6, 0.6, 7, 0, 60, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {speed: 0.95, maxSpeed: 0.95, health: 1.1, resist: 1.05}]), TYPE: "autoswarm", STAT_CALCULATOR: "swarm", }, }, { POSITION: [4, 6, 0.6, 7, 8, 60, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {speed: 0.95, maxSpeed: 0.95, health: 1.1, resist: 1.05}]), TYPE: "autoswarm", STAT_CALCULATOR: "swarm", }, @@ -199,7 +202,7 @@ Class.eliteTrapGuard = { }, { POSITION: [3, 6, 1.7, 10.5, 0, 60, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), + SHOOT_SETTINGS: combineStats([g.trap, {speed: 1.1, maxSpeed: 1.1, reload: 1.5, damage: 1.6}]), TYPE: "trap", STAT_CALCULATOR: "trap", }, @@ -213,10 +216,10 @@ Class.eliteTrapGuard = { ...weaponArray([ { POSITION: [5, 8, -7, 60, 160, 0], - TYPE: ["autoTurret", { INDEPENDENT: false }], + TYPE: ["autoTurret", { INDEPENDENT: false, GUN_STAT_SCALE: {health: 1.1} }], }, { POSITION: [5, 8, 7, 60, 160, 0], - TYPE: ["autoTurret", { INDEPENDENT: false }], + TYPE: ["autoTurret", { INDEPENDENT: false, GUN_STAT_SCALE: {health: 1.1} }], }, ], 3) ], @@ -226,24 +229,24 @@ Class.eliteSpinner = { UPGRADE_LABEL: "Elite Spinner", UPGRADE_COLOR: "pink", AI: { STRAFE: false }, - FACING_TYPE: ["spin", {speed: 0.1}], + FACING_TYPE: ["spin", {speed: 0.08}], GUNS: weaponArray([ { - POSITION: [9.5, 2, 1, -1.5, 11.5, 10, 0], + POSITION: [9.5, 2, 1, -1.5, 11.5, 10, 2/3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.5, maxSpeed: 1.25 }]), TYPE: "bullet", }, }, { POSITION: [9.5, 2, 1, 3.5, 6.5, 10, 1/3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.5, maxSpeed: 1.25 }]), TYPE: "bullet", }, }, { - POSITION: [9.5, 2, 1, 8.5, 1.5, 10, 2/3], + POSITION: [9.5, 2, 1, 8.5, 1.5, 10, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.5, maxSpeed: 1.25 }]), TYPE: "bullet", }, }, { @@ -315,7 +318,7 @@ Class.gunnerLegion = { }, { POSITION: [4, 16, 1.5, 14, 0, 180, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, {health: 1.1,speed: 1.5, range: 0.3}]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, {health: 1.1, speed: 1.5, range: 0.3}]), TYPE: "unsetPillbox", STAT_CALCULATOR: "trap", }, @@ -328,10 +331,10 @@ Class.gunnerLegion = { TURRETS: [ { POSITION: [14, 8, 0, 60, 180, 0], - TYPE: ["auto4gun", {GUN_STAT_SCALE: {health: 1.1}}], + TYPE: ["auto4gun", {GUN_STAT_SCALE: {health: 1.15}}], }, { POSITION: [14, 8, 0, 300, 180, 0], - TYPE: ["auto4gun", {GUN_STAT_SCALE: {health: 1.1}}], + TYPE: ["auto4gun", {GUN_STAT_SCALE: {health: 1.15}}], }, ], } @@ -348,7 +351,7 @@ Class.sprayerLegion = { }, TURRETS: weaponArray({ POSITION: [14, 6, 0, 60, 190, 0], - TYPE: ["machineGun", {GUN_STAT_SCALE: {health: 1.1, damage: 1.2, speed: 1.1, maxSpeed: 1.1}, COLOR: -1}], + TYPE: ["machineGun", {GUN_STAT_SCALE: {health: 1.1, damage: 1.2, speed: 1.2, resist: 1.05}, COLOR: -1}], }, 3) } Class.battleshipLegion = { @@ -364,21 +367,21 @@ Class.battleshipLegion = { { POSITION: [4, 6, 0.6, 7, -8, 60, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {damage: 1, speed: 1.1, maxSpeed: 1.1}]), + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {speed: 1.05, maxSpeed: 1.05, health: 1.2, resist: 1.1}]), TYPE: "autoswarm", STAT_CALCULATOR: "swarm", }, }, { POSITION: [4, 6, 0.6, 7, 0, 60, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {damage: 1, speed: 1.1, maxSpeed: 1.1}]), + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {speed: 1.05, maxSpeed: 1.05, health: 1.2, resist: 1.1}]), TYPE: "autoswarm", STAT_CALCULATOR: "swarm", }, }, { POSITION: [4, 6, 0.6, 7, 8, 60, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {damage: 1, speed: 1.1, maxSpeed: 1.1}]), + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {speed: 1.05, maxSpeed: 1.05, health: 1.2, resist: 1.1}]), TYPE: "autoswarm", STAT_CALCULATOR: "swarm", }, @@ -408,7 +411,7 @@ Class.spawnerLegion = { }, { POSITION: [2, 18, 1, 11, 0, 60, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, {size: 0.5, speed: 0.6, maxSpeed: 0.6, heath: 1.5}]), + SHOOT_SETTINGS: combineStats([g.drone, {reload: 2, size: 0.5, speed: 0.65, maxSpeed: 0.65, heath: 1.5}]), TYPE: "sentrySwarmMinion", SYNCS_SKILLS: true, AUTOFIRE: true, @@ -417,7 +420,7 @@ Class.spawnerLegion = { }, { POSITION: [2, 18, 1, 11, 0, 180, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, {size: 0.5, speed: 0.6, maxSpeed: 0.6, heath: 1.5}]), + SHOOT_SETTINGS: combineStats([g.drone, {reload: 2, size: 0.5, speed: 0.65, maxSpeed: 0.65, heath: 1.5}]), TYPE: "sentryTrapMinion", SYNCS_SKILLS: true, AUTOFIRE: true, @@ -426,7 +429,7 @@ Class.spawnerLegion = { }, { POSITION: [2, 18, 1, 11, 0, 300, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, {size: 0.5, speed: 0.6, maxSpeed: 0.6, heath: 1.5}]), + SHOOT_SETTINGS: combineStats([g.drone, {reload: 2, size: 0.5, speed: 0.65, maxSpeed: 0.65, heath: 1.5}]), TYPE: "sentryGunMinion", SYNCS_SKILLS: true, AUTOFIRE: true, @@ -437,7 +440,7 @@ Class.spawnerLegion = { TURRETS: [ { POSITION: [11, 0, 0, 0, 360, 1], - TYPE: ["auto4gun", { GUN_STAT_SCALE: {health: 1.1}, INDEPENDENT: false, COLOR: -1 }], + TYPE: ["auto4gun", { GUN_STAT_SCALE: {health: 1.15}, INDEPENDENT: false, COLOR: -1 }], }, ], } @@ -452,7 +455,7 @@ Class.legionaryCrasherTop = { { POSITION: [4, 9.5, 0.7, 7, 5, 60, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 2, maxSpeed: 1.7, size: 0.6, range: 2.8}]), TYPE: [ "swarm", { INDEPENDENT: true } ], STAT_CALCULATOR: "swarm", AUTOFIRE: true, @@ -461,7 +464,7 @@ Class.legionaryCrasherTop = { }, { POSITION: [4, 9.5, 0.7, 7, -5, 60, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 2, maxSpeed: 1.7, size: 0.6, range: 2.8}]), TYPE: [ "swarm", { INDEPENDENT: true } ], STAT_CALCULATOR: "swarm", AUTOFIRE: true, @@ -470,7 +473,7 @@ Class.legionaryCrasherTop = { ], 3), TURRETS: weaponArray({ POSITION: [9.5, 10, 0, 0, 190, 0], - TYPE: ["auto4gun", {GUN_STAT_SCALE: {speed: 1.2, maxSpeed: 1.2, range: 1.3}}], + TYPE: ["auto4gun", {GUN_STAT_SCALE: {damage: 1.4, health: 1.1, speed: 1.2, maxSpeed: 1.2, resist: 1.1, range: 1.3}}], }, 3), } Class.legionaryCrasherSpawner = { @@ -478,14 +481,14 @@ Class.legionaryCrasherSpawner = { SHAPE: "", INDEPENDENT: true, GUNS: [{ - POSITION: [0, 10, 0, 0, 0, 0, 0], + POSITION: [0, 10, 0, 0, 0, 0, 10], PROPERTIES: { TYPE: 'destroyerLegion', - SHOOT_SETTINGS: combineStats([{reload: 0.01}]), + SHOOT_SETTINGS: combineStats([{reload: 0.1}]), INDEPENDENT_CHILDREN: true, MAX_CHILDREN: 3, IDENTIFIER: 1, - AUTOFIRE: true + AUTOFIRE: true, } }], ON: [{ @@ -533,7 +536,7 @@ Class.legionaryCrasher = { }, ...weaponArray({ POSITION: [14, 8, 0, 60, 180, 0], - TYPE: [ "sprayer", { GUN_STAT_SCALE: {speed: 1.1, maxSpeed: 1.1, health: 1.5}, COLOR: -1 } ], + TYPE: [ "sprayer", { GUN_STAT_SCALE: {speed: 1.3, health: 1.5, damage: 1.4, resist: 1.2}, COLOR: -1 } ], }, 3), { POSITION: [12, 0, 0, 0, 0, 0], @@ -562,7 +565,7 @@ Class.sorcerer = { GUNS: weaponArray({ POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.machineGun, g.machineGunner, { damage: 2, size: 0.4, spray: 150, speed: 2, shudder: 1.75 }]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.machineGun, g.machineGunner, { damage: 1.8, size: 0.4, spray: 150, speed: 2, shudder: 1.75 }]), TYPE: "minichip", AUTOFIRE: true, SYNCS_SKILLS: true, @@ -618,7 +621,7 @@ Class.enchantress = { GUNS: weaponArray({ POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.9 }]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.9, damage: 1.1 }]), TYPE: "dorito", AUTOFIRE: true, SYNCS_SKILLS: true, @@ -646,7 +649,7 @@ Class.exorcistor = { GUNS: weaponArray({ POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, {maxSpeed: 1.2}]), TYPE: "demonchip", AUTOFIRE: true, SYNCS_SKILLS: true, @@ -674,7 +677,7 @@ Class.shaman = { GUNS: weaponArray({ POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { size: 1.1 }]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { size: 1.1, maxSpeed: 1.2, damage: 1.1 }]), TYPE: "realchip", AUTOFIRE: true, SYNCS_SKILLS: true, @@ -828,7 +831,7 @@ Class.roguePalisade = { GUNS: weaponArray({ POSITION: [4, 6, -1.6, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2, damage: 0.7, density: 0.6 }]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: "drone", AUTOFIRE: true, @@ -839,7 +842,7 @@ Class.roguePalisade = { }, 6), TURRETS: weaponArray({ POSITION: [5, 10, 0, 30, 110, 0], - TYPE: "baseTrapTurret" + TYPE: ["baseTrapTurret", {GUN_STAT_SCALE: {health: 0.7, damage: 0.8}}] }, 6) }; Class.rogueArmada = { @@ -862,55 +865,55 @@ Class.rogueArmada = { { POSITION: [8, 2, 1, 0, -2, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2, damage: 1.5, health: 1.5, resist: 1.25}]), TYPE: "casing" } }, { POSITION: [8, 2, 1, 0, -1.5, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2, damage: 1.5, health: 1.5, resist: 1.25}]), TYPE: "casing" } }, { POSITION: [8, 2, 1, 0, -1, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2, damage: 1.5, health: 1.5, resist: 1.25}]), TYPE: "bullet" } }, { POSITION: [8, 3, 1, 0, 0.5, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2, damage: 1.5, health: 1.5, resist: 1.25}]), TYPE: "bullet" } }, { POSITION: [8, 3, 1, 0, 0, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2, damage: 1.5, health: 1.5, resist: 1.25}]), TYPE: "bullet" } }, { POSITION: [8, 3, 1, 0, 0.5, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2, damage: 1.5, health: 1.5, resist: 1.25}]), TYPE: "bullet" } }, { POSITION: [8, 4, 1, 0, 1, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2, damage: 1.5, health: 1.5, resist: 1.25}]), TYPE: "bullet" } }, { POSITION: [8, 4, 1, 0, 1.5, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2, damage: 1.5, health: 1.5, resist: 1.25}]), TYPE: "casing" } }, { POSITION: [8.5, 6, 1, 4, 0, 360 / 14, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.pounder, {reload: 2}, g.fake]), TYPE: "casing" } }, { @@ -918,7 +921,7 @@ Class.rogueArmada = { } ], 7), TURRETS: weaponArray({ - POSITION: [5, 10, 0, 0, 160, 0], + POSITION: [5, 10, 0, 0, 110, 0], TYPE: "shottrapTurret" }, 7), } @@ -1031,12 +1034,13 @@ Class.terrestrial = { VALUE: 5e5, SHAPE: 7, SIZE: 35, + CONTROLLERS: [["minion", {orbit: 170}]], BODY: { FOV: 1, HEALTH: 1000, - SHIELD: 2, + SHIELD: 50, REGEN: base.REGEN * 0.1, - SPEED: 0.75, + SPEED: base.SPEED * 0.3, DAMAGE: 9, }, }; @@ -1047,12 +1051,13 @@ Class.celestial = { VALUE: 1e6, SHAPE: 9, SIZE: 45, + CONTROLLERS: [["minion", {orbit: 200}]], BODY: { FOV: 1, - HEALTH: 1000, - SHIELD: 2, + HEALTH: 1500, + SHIELD: 75, REGEN: base.REGEN * 0.1, - SPEED: 0.75, + SPEED: base.SPEED * 0.2, DAMAGE: 12, }, }; @@ -1068,12 +1073,13 @@ Class.eternal = { VALUE: 4e6, SHAPE: 11, SIZE: 90, + CONTROLLERS: [["minion", {orbit: 240}]], BODY: { FOV: 1, HEALTH: 3000, - SHIELD: 2, + SHIELD: 150, REGEN: base.REGEN * 0.1, - SPEED: 0.75, + SPEED: base.SPEED * 0.15, DAMAGE: 18, }, }; @@ -1083,7 +1089,7 @@ let ares = new LayeredBoss(null, "Ares", "terrestrial", 7, "purple", "terrestria ares.addLayer({gun: { POSITION: [3.75, 7, 1.2, 8, 0, null, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.8, maxSpeed: 0.8 }]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, {health: 1.2, damage: 1.1, resist: 1.1, density: 1.5, maxSpeed: 1.25}]), TYPE: ["demonchip", { INDEPENDENT: true }], AUTOFIRE: true, SYNCS_SKILLS: true, @@ -1099,18 +1105,18 @@ ares.addLayer({turret: { let gersemi = new LayeredBoss(null, "Gersemi", "terrestrial", 7, "lightGreen", "terrestrialTrapTurret", 7, 5.5); gersemi.addLayer({turret: { POSITION: [9, 8, 0, null, 160, 0], - TYPE: ["swarmTurret", { INDEPENDENT: true }], + TYPE: ["swarmTurret", { INDEPENDENT: true, GUN_STAT_SCALE: {health: 1.7, damage: 1.2} }], }}); gersemi.addLayer({turret: { POSITION: [9.5, 7.5, 0, null, 160, 0], - TYPE: ["basicTurret", { INDEPENDENT: true }], + TYPE: ["basicTurret", { INDEPENDENT: true, GUN_STAT_SCALE: {health: 1.8, damage: 1.3} }], }}, true, 6.5); let ezekiel = new LayeredBoss(null, "Ezekiel", "terrestrial", 7, "orange", "terrestrialTrapTurret", 7, 5.5); ezekiel.addLayer({gun: { POSITION: [3.75, 7, 1.2, 8, 0, null, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.8, maxSpeed: 0.8 }]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, {health: 1.2, damage: 1.1, resist: 1.1, density: 1.5, maxSpeed: 1.25}]), TYPE: ["dorito", { COLOR: "orange", INDEPENDENT: true }], AUTOFIRE: true, SYNCS_SKILLS: true, @@ -1120,14 +1126,14 @@ ezekiel.addLayer({gun: { }}, true, null, 18); ezekiel.addLayer({turret: { POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["skimmerTurret", { COLOR: "grey", INDEPENDENT: true }], + TYPE: [setTurretProjectileRecoil("skimmerTurret", 0.5), { COLOR: "grey", INDEPENDENT: true, GUN_STAT_SCALE: {maxSpeed: 0.5} }], }}, true, 6.5) let eris = new LayeredBoss(null, "Eris", "terrestrial", 7, "pink", "terrestrialTrapTurret", 7, 5.5); eris.addLayer({gun: { POSITION: [3.75, 7, 1.2, 8, 0, null, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.7, maxSpeed: 0.85, damage: 0.8 }]), TYPE: ["minion", { INDEPENDENT: true, COLOR: "pink" }], AUTOFIRE: true, SYNCS_SKILLS: true, @@ -1137,14 +1143,14 @@ eris.addLayer({gun: { }}, false, null, 14); eris.addLayer({turret: { POSITION: [10, 8.5, 0, null, 160, 0], - TYPE: ["rocketeerTurret", { INDEPENDENT: true }], + TYPE: [setTurretProjectileRecoil("rocketeerTurret", 0.43), { INDEPENDENT: true, GUN_STAT_SCALE: {maxSpeed: 0.43} }], }}, true, 6.5); let selene = new LayeredBoss(null, "Selene", "terrestrial", 7, "gold", "terrestrialTrapTurret", 7, 5.5); selene.addLayer({gun: { POSITION: [3.75, 7, 1.2, 8, 0, null, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.8, maxSpeed: 0.8 }]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, {health: 1.2, damage: 1.1, resist: 1.1, density: 1.5, maxSpeed: 1.25}]), TYPE: ["summonerDrone", { COLOR: "gold", INDEPENDENT: true }], AUTOFIRE: true, SYNCS_SKILLS: true, @@ -1162,7 +1168,7 @@ let paladin = new LayeredBoss(null, "Paladin", "celestial", 9, "purple", "baseTr paladin.addLayer({gun: { POSITION: [3.8, 6, 1.4, 8, 0, null, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, {health: 1.4, damage: 1.4, resist: 1.2, density: 1.8, maxSpeed: 1.325}]), TYPE: ["demonchip", {INDEPENDENT: true}], AUTOFIRE: true, SYNCS_SKILLS: true, @@ -1172,18 +1178,18 @@ paladin.addLayer({gun: { }}, true, null, 16); paladin.addLayer({turret: { POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: "swarmerTurret", + TYPE: ["swarmerTurret", {GUN_STAT_SCALE: {speed: 1.45, maxSpeed: 0.5, health: 1.3, range: 1.3}}], }}, true, 6); // FREYJA let freyja = new LayeredBoss(null, "Freyja", "celestial", 9, "lightGreen", "baseTrapTurret", 6.5, 5.5); freyja.addLayer({turret: { POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "cruiserTurret", + TYPE: ["cruiserTurret", {GUN_STAT_SCALE: {health: 1.2, damage: 1.3, speed: 1.1, maxSpeed: 1.1, resist: 1.05}}], }}); freyja.addLayer({turret: { POSITION: [10.6, 7.5, 0, null, 160, 0], - TYPE: "auto4gun", + TYPE: ["auto4gun", {GUN_STAT_SCALE: {health: 1.2, damage: 1.2, speed: 1.15, maxSpeed: 0.9, resist: 1.2}}], }}, true, 6); // ZAPHKIEL @@ -1191,7 +1197,7 @@ let zaphkiel = new LayeredBoss(null, "Zaphkiel", "celestial", 9, "orange", "base zaphkiel.addLayer({gun: { POSITION: [3.8, 6, 1.4, 8, 0, null, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, {health: 1.4, damage: 1.4, resist: 1.2, density: 1.8, maxSpeed: 1.325}]), TYPE: ["dorito", {INDEPENDENT: true}], AUTOFIRE: true, SYNCS_SKILLS: true, @@ -1199,7 +1205,7 @@ zaphkiel.addLayer({gun: { }}, true, null, 16); zaphkiel.addLayer({turret: { POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["skimmerTurret", {COLOR: "grey", INDEPENDENT: true}], + TYPE: [setTurretProjectileRecoil("skimmerTurret", 0.65), {COLOR: "grey", INDEPENDENT: true, GUN_STAT_SCALE: {maxSpeed: 0.65}}], }}, true, 6); // NYX @@ -1207,7 +1213,7 @@ let nyx = new LayeredBoss(null, "Nyx", "celestial", 9, "pink", "baseTrapTurret", nyx.addLayer({gun: { POSITION: [3.8, 7, -1.4, 8, 0, null, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.7, maxSpeed: 0.85, damage: 0.8 }]), TYPE: ["minion", {INDEPENDENT: true,}], AUTOFIRE: true, SYNCS_SKILLS: true, @@ -1215,7 +1221,7 @@ nyx.addLayer({gun: { }}, true, null, 16); nyx.addLayer({turret: { POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: "rocketeerTurret", + TYPE: [setTurretProjectileRecoil("rocketeerTurret", 0.5), { INDEPENDENT: true, GUN_STAT_SCALE: {maxSpeed: 0.5} }], }}, true, 6); // THEIA @@ -1223,7 +1229,7 @@ let theia = new LayeredBoss(null, "Theia", "celestial", 9, "gold", "baseTrapTurr theia.addLayer({gun: { POSITION: [3.8, 6, 1.4, 8, 0, null, 1], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, {health: 1.4, damage: 1.4, resist: 1.2, density: 1.8, maxSpeed: 1.325}]), TYPE: ["summonerDrone", {INDEPENDENT: true}], AUTOFIRE: true, WAIT_TO_CYCLE: true, @@ -1232,7 +1238,7 @@ theia.addLayer({gun: { }}, true, null, 35); theia.addLayer({turret: { POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["twisterTurret", {INDEPENDENT: true, COLOR: "grey"}], + TYPE: ["twisterTurret", {INDEPENDENT: true, COLOR: "grey", GUN_STAT_SCALE: {health: 1.3, damage: 1.1, resist: 1.2, speed: 1.1, maxSpeed: 0.8}}], }}, true, 6); // ATLAS @@ -1243,7 +1249,7 @@ atlas.addLayer({turret: { }}); atlas.addLayer({turret: { POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "nailgunTurret", + TYPE: ["nailgunTurret", {GUN_STAT_SCALE: {speed: 1.1, maxSpeed: 1.1, resist: 1.3}}], }}, true, 6); // RHEA @@ -1265,7 +1271,7 @@ julius.addLayer({turret: { }}); julius.addLayer({turret: { POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "launcherTurret", + TYPE: [setTurretProjectileRecoil("launcherTurret", 0.82), {GUN_STAT_SCALE: {health: 1.3, damage: 1.3, maxSpeed: 0.82}}], }}, true, 6); // GENGHIS @@ -1276,7 +1282,7 @@ genghis.addLayer({turret: { }}); genghis.addLayer({turret: { POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "auto4gun", + TYPE: ["auto4gun", {GUN_STAT_SCALE: {speed: 1.2, maxSpeed: 0.85, health: 1.15, damage: 1.2, resist: 1.2}}], }}, true, 6); // NAPOLEON @@ -1298,18 +1304,18 @@ kronos.addLayer({turret: { }}); kronos.addLayer({turret: { POSITION: [6.5, 9, 0, null, 160, 0], - TYPE: "carrierTurret", + TYPE: ["carrierTurret", {GUN_STAT_SCALE: g.battleship}], }}, true, 4); kronos.addLayer({turret: { POSITION: [8.5, 9, 0, null, 160, 0], - TYPE: "tripletTurret", + TYPE: ["tripletTurret", {GUN_STAT_SCALE: {health: 1.15, damage: 1.1, resist: 1.3, speed: 1.1, maxSpeed: 0.9}}], }}, true, 4); let odin = new LayeredBoss(null, "Odin", "eternal", 11, "aqua", "baseTrapTurret", 4.5, 3.5); odin.addLayer({gun: { POSITION: [2.25, 3.25, -1.6, 9, 0, null, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, g.destroyer]), + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, g.destroyer, {speed: 1.25, maxSpeed: 1.25}]), TYPE: ["realchip", {INDEPENDENT: true, DRAW_HEALTH: true, COLOR: 'hexagon'}], AUTOFIRE: true, SYNCS_SKILLS: true, diff --git a/server/modules/definitions/groups/dev.js b/server/modules/definitions/groups/dev.js index 816f34597..e7eb4196f 100644 --- a/server/modules/definitions/groups/dev.js +++ b/server/modules/definitions/groups/dev.js @@ -28,6 +28,7 @@ Class.developer = { INVISIBLE: [0, 0], ALPHA: [0, 1], HITS_OWN_TYPE: "hardOnlyTanks", + NECRO: false, SHAPE: [ [-1, -0.8], [-0.8, -1], @@ -707,7 +708,7 @@ Class.turretStatScaleTest = { })) } -Class.auraBasicGen = addAura(5, 1.3); +Class.auraBasicGen = addAura(4.3, 1.3); Class.auraHealerGen = addAura(-1); Class.auraHealer = { PARENT: "genericTank", @@ -1206,43 +1207,6 @@ Class.sidewinderOld = { ], } -Class.whirlwindDeco = makeDeco(6) -Class.whirlwindDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]] -Class.whirlwind = { - PARENT: "genericTank", - LABEL: "Whirlwind", - ANGLE: 60, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "whirlwindDeco" - } - ], - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 6; i++) { - output.push({ - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: i * 60}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} - // Whirlwind Class.whirlwindDeco = makeDeco(6) Class.whirlwindDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]] @@ -4360,6 +4324,16 @@ Class.utilities = { LABEL: "Utilities", SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381' }; +Class.stupidpony = { + PARENT: "developer", + LABEL: "Big long pink thing", + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_1942.png?v=1723341388613" +} +Class.billcipher = { + PARENT: "developer", + LABEL: "Bill", + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/52459e59-5ff9-4646-9949-a2a1461c7202.image.png?v=1724373801016" +} Class.AIT = menu("AIT") Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons"] @@ -4395,7 +4369,7 @@ Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons Class.features.UPGRADES_TIER_0 = ["tanks", "diamondShape", "rotatedTrap", "colorMan", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "radialAutoTest", "makeAutoTest", "imageShapeTest", "turretStatScaleTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "gunBenchmark", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight", "rayofdeath", "biggerCheese", "kivaship"] - Class.goofytanks.UPGRADES_TIER_0 = ["overpowered", "pisseroo", "papyrus", "Trapper_guy", "watertank", "piszerbeam", "baseThrowerDelta", "pouner", "adsfoipuasdfiopu", "goofywhirlwind", "gettingoverit", "alchem"] + Class.goofytanks.UPGRADES_TIER_0 = ["overpowered", "pisseroo", "papyrus", "Trapper_guy", "watertank", "piszerbeam", "baseThrowerDelta", "pouner", "adsfoipuasdfiopu", "goofywhirlwind", "gettingoverit", "alchem", "stupidpony", "billcipher"] //the "winsor" tank needs this to function, it worked before the "ON" thing was added Class.winsor0.UPGRADES_TIER_0 = ["winsor1", "winsor2", "winsor3", "winsor4"] diff --git a/server/modules/definitions/groups/misc.js b/server/modules/definitions/groups/misc.js index 018bce308..b43a59aed 100644 --- a/server/modules/definitions/groups/misc.js +++ b/server/modules/definitions/groups/misc.js @@ -62,38 +62,6 @@ Class.fovwall = { other.addStatusEffect(biggerfov) }}] } -let biggersize = new StatusEffect(1, {size: 2}); -Class.bigsizewall = { - PARENT: "wall", - GLOW: { - RADIUS: 30, - COLOR: 30, - ALPHA: 1, - RECURSION: 5 - }, - COLOR: 30, - ON: [{ - event: "collide", - handler: ({ body, other }) => { - if (other.type != "wall") other.addStatusEffect(biggersize) - }}] -} -let smallersize = new StatusEffect(1, {size: 0.5}); -Class.smallsizewall = { - PARENT: "wall", - GLOW: { - RADIUS: 30, - COLOR: 31, - ALPHA: 1, - RECURSION: 5 - }, - COLOR: 31, - ON: [{ - event: "collide", - handler: ({ body, other }) => { - if (other.type != "wall") other.addStatusEffect(smallersize) - }}] -} Class.dfxwall = { PARENT: "wall", TURRETS: [{ @@ -356,37 +324,6 @@ Class.crasher = { HAS_NO_MASTER: true, DRAW_HEALTH: true, }; -Class.crasherSpawner = { - PARENT: "genericTank", - LABEL: "Spawned", - STAT_NAMES: statnames.drone, - CONTROLLERS: ["nearestDifferentMaster"], - COLOR: "pink", - INDEPENDENT: true, - AI: { - chase: true, - }, - MAX_CHILDREN: 4, - GUNS: [ - { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak]), - TYPE: [ - "drone", - { - LABEL: "Crasher", - VARIES_IN_SIZE: true, - DRAW_HEALTH: true, - }, - ], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: "drone", - }, - }, - ], -}; // SENTRIES Class.sentry = { diff --git a/server/modules/definitions/groups/projectiles.js b/server/modules/definitions/groups/projectiles.js index 857559b91..c6c4aa1d6 100644 --- a/server/modules/definitions/groups/projectiles.js +++ b/server/modules/definitions/groups/projectiles.js @@ -47,7 +47,7 @@ Class.superSplitterBullet = { }, ] } -Class.turretedBullet = makeAuto('bullet', "Auto-Bullet", {size: 14, color: "veryLightGrey", angle: 0}); +Class.turretedBullet = makeAuto('bullet', "Auto-Bullet", {type: "bulletAutoTurret", size: 14, color: "veryLightGrey", angle: 0}); Class.speedBullet = { PARENT: "bullet", MOTION_TYPE: "accel", @@ -222,7 +222,7 @@ Class.protoHive = { STAT_CALCULATOR: "swarm", AUTOFIRE: true }, - }, 5, 1/3) + }, 3, 1/3) } Class.snake = { PARENT: "bullet", @@ -284,7 +284,7 @@ Class.kronosMissile = { POSITION: [4, 6, 1.6, 13, 0, 90, 0.5], PROPERTIES: { AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, {reload: 3}]), + SHOOT_SETTINGS: combineStats([g.trap, g.lowPower, {reload: 2, speed: 1.3, maxSpeed: 1.3, range: 0.5}]), TYPE: [ "trap", { PERSISTS_AFTER_DEATH: true } ], STAT_CALCULATOR: "trap", }, @@ -292,7 +292,7 @@ Class.kronosMissile = { POSITION: [4, 6, 1.6, 13, 0, -90, 0.5], PROPERTIES: { AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, {reload: 3}]), + SHOOT_SETTINGS: combineStats([g.trap, g.lowPower, {reload: 2, speed: 1.3, maxSpeed: 1.3, range: 0.5}]), TYPE: [ "trap", { PERSISTS_AFTER_DEATH: true } ], STAT_CALCULATOR: "trap", }, @@ -300,7 +300,7 @@ Class.kronosMissile = { POSITION: [14, 6, 1, 0, -2, 150, 0], PROPERTIES: { AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.weak, {reload: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower, {speed: 1.3, maxSpeed: 1.3}]), TYPE: [ "bullet", { PERSISTS_AFTER_DEATH: true } ], STAT_CALCULATOR: "thruster", }, @@ -308,7 +308,7 @@ Class.kronosMissile = { POSITION: [14, 6, 1, 0, 2, 210, 0], PROPERTIES: { AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.weak, {reload: 3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower, {speed: 1.3, maxSpeed: 1.3}]), TYPE: [ "bullet", { PERSISTS_AFTER_DEATH: true } ], STAT_CALCULATOR: "thruster", }, @@ -437,12 +437,12 @@ Class.minion = { LABEL: "Minion", TYPE: "minion", DAMAGE_CLASS: 0, - HITS_OWN_TYPE: "hardWithBuffer", + HITS_OWN_TYPE: "hard", FACING_TYPE: "smoothToTarget", BODY: { FOV: 0.5, SPEED: 3, - ACCELERATION: 0.4, + ACCELERATION: 1, HEALTH: 5, SHIELD: 0, DAMAGE: 1.2, diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index bd1f21426..608e90963 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -3097,7 +3097,7 @@ Class.sidewinder = { { POSITION: [20, 8, -4/3, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sidewinder]), + SHOOT_SETTINGS: combineStats([g.basic, g.sidewinder2]), TYPE: ["bullet", {CONTROLLERS: ['snake']}] }, }, @@ -3271,14 +3271,14 @@ Class.coil = { { POSITION: [20, 8, 0.75, 0, -5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sidewinder]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sidewinder2]), TYPE: ["bullet", {CONTROLLERS: ['snake']}] }, }, { POSITION: [20, 8, 0.75, 0, 5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sidewinder]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sidewinder2]), TYPE: ["bullet", {CONTROLLERS: [['snake', {invert: true}]]}] }, }, @@ -3321,7 +3321,7 @@ Class.ranch = { POSITION: [1, 12, 1, 15, 0, 0, 0], PROPERTIES: { MAX_CHILDREN: 3, - SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory, g.sidewinder]), + SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory, g.sidewinder2]), TYPE: ["minion", {CONTROLLERS: ['snake']}], STAT_CALCULATOR: "drone", AUTOFIRE: true, @@ -3352,7 +3352,7 @@ Class.oroboros = { { POSITION: [20, 10, 0.8, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sidewinder, { speed: 3 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.sidewinder2, { speed: 3 }]), TYPE: ["bullet", {CONTROLLERS: ['snake']}] }, }, @@ -3369,6 +3369,7 @@ Class.cocciPart1 = { LABEL: "", BODY: { REGEN: 999999, + HEALTH: 99999, PENETRATION: 999 }, TURRETS: [ @@ -3388,6 +3389,7 @@ Class.cocciPart2 = { LABEL: "", BODY: { REGEN: 999999, + HEALTH: 99999, PENETRATION: 999 }, TURRETS: [ @@ -3407,6 +3409,7 @@ Class.cocciPart3 = { LABEL: "", BODY: { REGEN: 999999, + HEALTH: 99999, PENETRATION: 999, }, TURRETS: [ @@ -4335,7 +4338,7 @@ Class.hivemind = { { POSITION: [0, 20, 1, 0, 0, 90, 3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 5 }]), TYPE: "hiveprobe", MAX_CHILDREN: 1, WAIT_TO_CYCLE: true @@ -4344,7 +4347,7 @@ Class.hivemind = { { POSITION: [0, 20, 1, 0, 0, 270, 3.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 5 }]), TYPE: "hiveprobe", MAX_CHILDREN: 1, WAIT_TO_CYCLE: true @@ -4375,7 +4378,7 @@ Class.cloner = { { POSITION: [0, 20, 1, 0, 0, 180, 3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.slow, { reload: 5 }]), TYPE: "clonerprobe", MAX_CHILDREN: 1, WAIT_TO_CYCLE: true @@ -5985,6 +5988,27 @@ Class.knight = { }, ] } +Class.saturn = { + PARENT: "genericSmasher", + LABEL: "Saturn", + BODY: { + DENSITY: 2 * base.DENSITY + }, + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, + { + POSITION: [3, 0, 0, 0, 360, 1], + TYPE: "saturnDeco" + }, + { + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "saturnturretBase" + } + ], +} // Auto tanks Class.autoBasic = makeAuto("basic", "Auto-Basic"); @@ -6404,7 +6428,7 @@ Class.auraJouster = makeAura(Class.jouster); // TANK UPGRADE PATHS Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "autoBasic", "desmos", "bascrid", "littleHunter", "inception", "propel", "lancer", "auto2", "auraBasic", "whirlwind"] Class.basic.UPGRADES_TIER_2 = ["smasher", "cloner"] - Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "landmine", "cocci", "pion", "trackerSmasher", "skater", "acidsmasher", "flail", "autoSmasher", "auraSmasher", "jumpSmasher"] + Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "landmine", "cocci", "pion", "trackerSmasher", "saturn", "skater", "acidsmasher", "flail", "autoSmasher", "auraSmasher", "jumpSmasher"] Class.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] Class.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner"] diff --git a/server/modules/definitions/groups/turrets.js b/server/modules/definitions/groups/turrets.js index 97e3f02c8..87ac6371a 100644 --- a/server/modules/definitions/groups/turrets.js +++ b/server/modules/definitions/groups/turrets.js @@ -87,7 +87,7 @@ Class.architectGun = makeTurret({ { POSITION: [2, 16, 1.1, 20, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.flankGuard]), TYPE: "setTrap", STAT_CALCULATOR: "block" }, @@ -118,7 +118,7 @@ Class.baseTrapTurret = makeTurret({ }, { POSITION: [4, 14, 1.8, 16, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.pounder, g.hexaTrapper, {size: 1.2, speed: 0.9, shudder: 0.1}]), + SHOOT_SETTINGS: combineStats([g.trap, g.pounder, g.hexaTrapper, {reload: 1.3, size: 1.2, health: 1.35, damage: 1.4, speed: 0.9, shudder: 0.1}]), TYPE: "trap", STAT_CALCULATOR: "trap", AUTOFIRE: true, @@ -133,7 +133,7 @@ Class.terrestrialTrapTurret = makeTurret({ }, { POSITION: [4, 14, 1.8, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.pounder, g.hexaTrapper, {size: 1.2, speed: 0.9, shudder: 0.1}]), + SHOOT_SETTINGS: combineStats([g.trap, g.pounder, g.hexaTrapper, {reload: 1.3, size: 1.2, health: 1.35, damage: 1.4, speed: 0.9, shudder: 0.1}]), TYPE: "trap", STAT_CALCULATOR: "trap", AUTOFIRE: true, @@ -142,7 +142,7 @@ Class.terrestrialTrapTurret = makeTurret({ ], }, {independent: true, hasAI: false, extraStats: []}) const shottrapTurretProperties = { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.shotgun, g.machineGun, { speed: 0.7, maxSpeed: 0.2, damage: 1.5, range: 0.6 }]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.shotgun, g.machineGun, { reload: 0.65, speed: 0.7, maxSpeed: 0.1, damage: 0.7, range: 0.5 }]), AUTOFIRE: true, TYPE: "shotTrapBox", STAT_CALCULATOR: "block", @@ -178,7 +178,7 @@ Class.shottrapTurret = makeTurret({ POSITION: [ 16, 14, -1.4, 0, 0, 0, 0 ], }, { POSITION: [ 6, 14, 1.6, 16, 0, 0, 0 ], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.shotgun, g.machineGun, g.fake]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.shotgun, g.machineGun, {reload: 0.65}, g.fake]), AUTOFIRE: true, TYPE: "bullet" } @@ -207,7 +207,7 @@ Class.kronosSkimmerTurret = makeTurret({ }, { POSITION: [15, 18, -0.8, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, { reload: 2, health: 1.7, damage: 1.4, resist: 1.2 }]), TYPE: "kronosMissile", }, }, @@ -220,7 +220,7 @@ Class.autoSmasherLauncherTurret = makeTurret({ }, { POSITION: [18, 20, -0.7, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, { reload: 2, speed: 1.5, maxSpeed: 1.5, range: 2.5 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, { reload: 2, health: 1.9, damage: 1.2, resist: 1.2, speed: 1.3, maxSpeed: 1.3, range: 2.5 }]), TYPE: "autoSmasherMissile", }, }, @@ -269,7 +269,7 @@ Class.triTrapGuardTurret = { Class.eliteSpinnerCyclone = { PARENT: "genericTank", COLOR: -1, - FACING_TYPE: ["spin", { speed: 0.1, independent: true }], + FACING_TYPE: ["spin", { speed: -0.1, independent: true }], GUNS: weaponArray([ { POSITION: [15, 3.5, 1, 0, 0, 0, 0], @@ -315,13 +315,13 @@ Class.crowbarTurret = makeTurret({ TURRETS: [ { POSITION: [6, 38, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { GUN_STAT_SCALE: [g.flankGuard], INDEPENDENT: true, HAS_NO_RECOIL: true } ], + TYPE: [ "autoTankGun", { GUN_STAT_SCALE: g.flankGuard, INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, { POSITION: [6, 28, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { GUN_STAT_SCALE: [g.flankGuard], INDEPENDENT: true, HAS_NO_RECOIL: true } ], + TYPE: [ "autoTankGun", { GUN_STAT_SCALE: g.flankGuard, INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, { POSITION: [6, 18, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { GUN_STAT_SCALE: [g.flankGuard], INDEPENDENT: true, HAS_NO_RECOIL: true } ], + TYPE: [ "autoTankGun", { GUN_STAT_SCALE: g.flankGuard, INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, ], }, {canRepel: true, limitFov: true, extraStats: []}) @@ -336,13 +336,13 @@ Class.wrenchTurret = makeTurret({ TURRETS: [ { POSITION: [6, 68, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { GUN_STAT_SCALE: [g.flankGuard], INDEPENDENT: true, HAS_NO_RECOIL: true } ], + TYPE: [ "autoTankGun", { GUN_STAT_SCALE: g.flankGuard, INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, { POSITION: [6, 58, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { GUN_STAT_SCALE: [g.flankGuard], INDEPENDENT: true, HAS_NO_RECOIL: true } ], + TYPE: [ "autoTankGun", { GUN_STAT_SCALE: g.flankGuard, INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, { POSITION: [6, 48, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { GUN_STAT_SCALE: [g.flankGuard], INDEPENDENT: true, HAS_NO_RECOIL: true } ], + TYPE: [ "autoTankGun", { GUN_STAT_SCALE: g.flankGuard, INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, ], }, {canRepel: true, limitFov: true, extraStats: []}) @@ -351,7 +351,7 @@ Class.protoSwarmerTurret = makeTurret({ { POSITION: [10, 14, -1.2, 5, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.hive]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.hive, {speed: 1.3, maxSpeed: 0.5, health: 1.3, range: 1.3}]), TYPE: "protoHive", }, }, { @@ -371,6 +371,27 @@ Class.swarmTurret = makeTurret({ }, ], }, {canRepel: true, limitFov: true, extraStats: []}) +Class.crasherSpawner = makeTurret({ + MAX_CHILDREN: 4, + GUNS: [ + { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, {health: 1.1}]), + TYPE: [ + "drone", + { + LABEL: "Crasher", + DRAW_HEALTH: true, + }, + ], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: "drone", + }, + }, + ], +}, {independent: true, aiSettings: {chase: true}, label: 'Spawned', color: 'pink'}) Class.genghisLowerTurret = makeTurret({ MAX_CHILDREN: 4, GUNS: [ @@ -379,7 +400,7 @@ Class.genghisLowerTurret = makeTurret({ }, { POSITION: [2, 12, 1, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.babyfactory, { reload: 1.5 }]), + SHOOT_SETTINGS: combineStats([g.swarm, g.babyfactory, { reload: 1.5, health: 2, damage: 2, range: 2 }]), TYPE: ["tinyMinion", {INDEPENDENT: true}], AUTOFIRE: true, SYNCS_SKILLS: true, @@ -394,14 +415,14 @@ Class.napoleonLowerTurret = makeTurret({ { POSITION: [8, 8, 0.6, 6, 0, 30, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.bee, g.pounder, { speed: 1.3, maxSpeed: 1.3 }]), + SHOOT_SETTINGS: combineStats([g.swarm, g.bee, g.pounder]), TYPE: ["bee", { INDEPENDENT: true }], STAT_CALCULATOR: "swarm", }, }, { POSITION: [8, 8, 0.6, 6, 0, -30, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.bee, g.pounder, { speed: 1.3, maxSpeed: 1.3 }]), + SHOOT_SETTINGS: combineStats([g.swarm, g.bee, g.pounder]), TYPE: ["bee", { INDEPENDENT: true }], STAT_CALCULATOR: "swarm", }, @@ -413,27 +434,27 @@ Class.gunnerCruiserTurret = makeTurret({ { POSITION: [4, 7.5, 0.6, 6, 4.5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {maxSpeed: 1.1}]), TYPE: "swarm", STAT_CALCULATOR: "swarm", }, }, { POSITION: [4, 7.5, 0.6, 6, -4.5, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship, {maxSpeed: 1.1}]), TYPE: "swarm", STAT_CALCULATOR: "swarm", }, }, { POSITION: [16, 3, 1, 0, -3, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, {health: 1.2, damage: 1.2, speed: 1.2, maxSpeed: 0.9}]), TYPE: "bullet", }, }, { POSITION: [16, 3, 1, 0, 3, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, {health: 1.2, damage: 1.2, speed: 1.2, maxSpeed: 0.9}]), TYPE: "bullet", }, }, @@ -445,7 +466,7 @@ Class.juliusLowerTurret = makeTurret({ { POSITION: [8.5, 11, 0.6, 6, 0, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.sunchip]), + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, {size: 0.8, health: 1.5, damage: 1.5, density: 1.2, maxSpeed: 0.8}]), TYPE: "minichip", STAT_CALCULATOR: "drone", }, @@ -494,7 +515,7 @@ Class.napoleonUpperTurret = makeTurret({ }, { POSITION: [16, 12, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { speed: 0.93, maxSpeed: 0.93 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { reload: 1.2, health: 1.2, damage: 1.2, speed: 0.93, maxSpeed: 0.93, range: 1.5 }]), TYPE: ["turretedBullet", {COLOR: "veryLightGrey"}], }, }, @@ -524,6 +545,17 @@ Class.droneAutoTurret = makeTurret({ }, ], }, {label: "Turret", fov: 0.8, extraStats: []}) +Class.bulletAutoTurret = makeTurret({ + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.turret, {speed: 0.8, maxSpeed: 0.8, reload: 1.2, health: 1.4}]), + TYPE: "bullet", + }, + }, + ] +}, {label: "Turret", fov: 0.8, extraStats: []}) Class.autoSmasherTurret = makeTurret({ GUNS: [ { @@ -959,6 +991,92 @@ Class.pionturretBase = { VULNERABLE: true, }] }; +Class.saturnturretBase = { + LABEL: "Base", + COLOR: 'mirror', + BORDERLESS: true, + OPACITY: 0.5, + SHAPE: 'M -1.75 1 L -1.75 -1 L -0 -2 L 1.75 -1 L 1.75 1 L 0 2 L -1.75 1 L -1.6625 0.95 L 0 1.9 L 1.6625 0.95 L 1.6625 -0.95 L -0 -1.9 L -1.6625 -0.95 L -1.6625 0.95', + FACING_TYPE: ["spin", { speed: 0.1 }], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [2, 17, 0, 60, 0, 1], + TYPE: "saturnbullet", + }, { + POSITION: [2, 17, 0, 120, 0, 1], + TYPE: "saturnbullet", + }, { + POSITION: [2, 17, 0, 180, 0, 1], + TYPE: "saturnbullet", + }, { + POSITION: [2, 17, 0, 240, 0, 1], + TYPE: "saturnbullet", + }, { + POSITION: [2, 17, 0, 300, 0, 1], + TYPE: "saturnbullet", + }, { + POSITION: [2, 17, 0, 0, 0, 1], + TYPE: "saturnbullet", + }] +} +Class.saturnDeco = { + LABEL: "", + FACING_TYPE: ["spin", { speed: 0.1 }], + COLOR: "black", + SHAPE: "M -1.75 1 L -1.75 -1 L -0 -2 L 1.75 -1 L 1.75 1 L 0 2 L -1.75 1 L -1.6625 0.95 L 0 1.9 L 1.6625 0.95 L 1.6625 -0.95 L -0 -1.9 L -1.6625 -0.95 L -1.6625 0.95", + INDEPENDENT: true +} +Class.saturnbullet = { + PARENT: "genericTank", + COLOR: "mirror", + SHAPE: 0, + INDEPENDENT: true, + BODY: { + HEALTH: 10000, + SHIELD: 10000, + REGEN: 10000, + }, + GUNS: [ + { + POSITION: {WIDTH: 8, LENGTH: 10}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { + range: 0.1, + speed: 0, + maxSpeed: 0, + recoil: 0, + reload: 0.1, + damage: 4, + size: 2, + health: 1, + }]), + TYPE: ["bullet", { + BODY: { + PENETRATION: 1, + SPEED: 3.75, + RANGE: 90, + DENSITY: 1.25, + HEALTH: 0.165, + DAMAGE: 150, + PUSHABILITY: 0.3, + }, + ALPHA: 0, + ON: [{ + event: 'tick', + handler: ({body}) => { + body.DAMAGE -= 1; + body.SIZE -= 0.6; + if (body.SIZE < 1) body.kill(); + } + }], + }], + AUTOFIRE: true, + BORDERLESS: true, + DRAW_FILL: false, + } + } + ] +} Class.revogun = { LABEL: 'Auto Turret', SYNC_TURRET_SKILLS: true, @@ -1135,10 +1253,10 @@ Class.switcherDeco = makeDeco('M 0 0 M 2 -1 L -2 -1 L -2 8 L -1 8 L 1 8 L 2 8') Class.effectBulletDeco = makeDeco(0) Class.firecrackerDeco = makeDeco(-6) Class.auraDamageGen = addAura(7.5, 1.3, 0.3, "red"); -Class.auraRangeGen = addAura(5, 1.8, 0.3, "teal", "rangeAuraSymbol"); -Class.auraDamageRangeGen = addAura(7.5, 1.8, 0.3, "red", "rangeAuraSymbol"); -Class.auraMoreDamageGen = addAura(11, 1.3, 0.3, "orange"); -Class.auraMoreRangeGen = addAura(5, 2.3, 0.3, "aqua", "rangeAuraSymbol"); +Class.auraRangeGen = addAura(4.3, 1.8, 0.3, "teal", "rangeAuraSymbol"); +Class.auraDamageRangeGen = addAura(7, 1.8, 0.3, "red", "rangeAuraSymbol"); +Class.auraMoreDamageGen = addAura(9, 1.3, 0.3, "orange"); +Class.auraMoreRangeGen = addAura(4.3, 2.3, 0.3, "aqua", "rangeAuraSymbol"); Class.auraSmasherGen = addAura(11, 1.3); Class.surgeDeco = makeDeco(-1, "spaceGem"); Class.katanaDeco = makeDeco('M 0 2 L 0 -1 L 1 0 L 0 -1 L -1 0 L 0 -1', "#add6f7"); \ No newline at end of file diff --git a/server/modules/definitions/gunvals.js b/server/modules/definitions/gunvals.js index 6697af6cb..41f6c2ed1 100644 --- a/server/modules/definitions/gunvals.js +++ b/server/modules/definitions/gunvals.js @@ -16,7 +16,7 @@ module.exports = { tripleShot: { reload: 1.1, shudder: 0.8, health: 0.9, pen: 0.8, density: 0.8, spray: 0.5 }, spreadshotMain: { reload: 0.781, recoil: 0.25, shudder: 0.5, health: 0.5, speed: 1.923, maxSpeed: 2.436 }, spreadshot: { reload: 1.5, shudder: 0.25, speed: 0.7, maxSpeed: 0.7, spray: 0.25 }, - triplet: { reload: 1.2, recoil: 0.667, shudder: 0.9, health: 0.85, damage: 0.85, pen: 0.9, density: 1.1, spray: 0.9, resist: 0.95 }, + triplet: { reload: 1.2, recoil: 2/3, shudder: 0.9, health: 0.85, damage: 0.85, pen: 0.9, density: 1.1, spray: 0.9, resist: 0.95 }, turret: { reload: 2, health: 0.8, damage: 0.6, pen: 0.7, density: 0.1 }, autoTurret: { reload: 0.9, recoil: 0.75, shudder: 0.5, size: 0.8, health: 0.9, damage: 0.6, pen: 1.2, speed: 1.1, range: 0.8, density: 1.3, resist: 1.25 }, littleHunter: { recoil: 0.9, shudder: 0.9, health: 0.9, damage: 0.7, pen: 0.9 }, @@ -63,9 +63,9 @@ module.exports = { bee: { reload: 1.3, size: 1.4, damage: 1.5, pen: 0.5, speed: 1.5, maxSpeed: 1.5, density: 0.25 }, sunchip: { reload: 4, size: 1.4, health: 0.5, damage: 0.4, pen: 0.6, density: 0.8 }, maleficitor: { reload: 0.25, size: 1.05, health: 1.15, damage: 1.15, pen: 1.15, speed: 0.8, maxSpeed: 0.8, density: 1.15 }, - summoner: { reload: 0.3, size: 1.125, health: 0.4, damage: 0.345, pen: 0.4, density: 0.8 }, + summoner: { reload: 0.3, size: 1.125, health: 0.5, damage: 0.345, pen: 0.4, density: 0.8 }, minionGun: { recoil: 0, shudder: 2, health: 0.4, damage: 0.4, pen: 1.2, range: 0.75, spray: 2 }, - babyfactory: { reload: 1.5, maxSpeed: 1.35 }, + babyfactory: { reload: 1.5, maxSpeed: 1.25 }, bigCheese: { reload: 1.5, size: 1.8, health: 2.5, speed: 1.25 }, mothership: { reload: 1.25, pen: 1.1, speed: 0.775, maxSpeed: 0.8, range: 15, resist: 1.15 }, satellite: { size: 0.8, reload: 3, damage: 1.875 }, @@ -94,7 +94,7 @@ module.exports = { // Traps and blocks setTrap: { reload: 1.1, recoil: 2, shudder: 0.1, size: 1.5, health: 2, pen: 1.25, speed: 1.5, maxSpeed: 2.5, range: 1.25, resist: 1.25 }, construct: { reload: 1.3, size: 0.9, maxSpeed: 1.1 }, - boomerang: { reload: 0.8, health: 0.5, damage: 0.5, speed: 0.75, maxSpeed: 0.75, range: 1.333 }, + boomerang: { reload: 0.8, health: 0.5, damage: 0.5, speed: 0.75, maxSpeed: 0.75, range: 4/3 }, nestKeeper: { reload: 3, size: 0.75, health: 1.05, damage: 1.05, pen: 1.1, speed: 0.5, maxSpeed: 0.5, range: 0.5, density: 1.1 }, hexaTrapper: { reload: 1.3, shudder: 1.25, speed: 0.8, range: 0.5 }, trapperDominator: { reload: 1.26, recoil: 0, shudder: 0.25, health: 1.25, damage: 1.45, pen: 1.6, speed: 0.5, maxSpeed: 2, range: 0.7, spray: 0.5 }, @@ -162,6 +162,6 @@ module.exports = { solarioblast: { reload: 0.05, health: 5, pen: 100, speed: 14, maxSpeed: 14, spread: 4, size: 2, range: 0.12 }, emplaser: { reload: 1.25, recoil: 0, size: 1.7 }, empbullet: { reload: 1.25, recoil: 0, size: 2.5, speed: 1.1, maxSpeed: 1.1, spray: 0.2 }, - cloner: { damage: 0.9, pen: 0.85 }, - sidewinder: { shudder: 0, spray: 0, size: 0.8, speed: 0.001, damage: 2 }, + cloner: { damage: 0.78, pen: 0.85 }, + sidewinder2: { shudder: 0, spray: 0, size: 0.8, speed: 0.001, damage: 5 }, } \ No newline at end of file diff --git a/server/modules/gamemodes/groups.js b/server/modules/gamemodes/groups.js index 7365fa62b..1c8f26670 100644 --- a/server/modules/gamemodes/groups.js +++ b/server/modules/gamemodes/groups.js @@ -13,7 +13,6 @@ class Group { this.private = false; this.teamID = getID(); activeGroups.push(this); - console.log("New group created."); } setPrivate() { if (this.private) this.private = false; @@ -33,7 +32,6 @@ class Group { delete() { for (let i = 0; i < this.members.length; i++) removeMember(this.members[i]); activeGroups = activeGroups.filter(entry => entry !== this); - console.log("Group deleted."); } getSpawn() { let validMembers = this.members.map(entry => entry).filter(a => !!a.player).filter(b => !!b.player.body); diff --git a/server/modules/gamemodes/oldDreadnoughts.js b/server/modules/gamemodes/oldDreadnoughts.js index 37dd33716..d3db773f4 100644 --- a/server/modules/gamemodes/oldDreadnoughts.js +++ b/server/modules/gamemodes/oldDreadnoughts.js @@ -98,7 +98,7 @@ let generateLabyrinth = (size) => { for (let x = padding; x < size + padding; x++) { for (let y = padding; y < size + padding; y++) { // Find spawn location and size - if (!maze[x - 1][y - 1]) continue; + if (!maze[y - 1][x - 1]) continue; let d = { x: x * mazeWallScale + mazeWallScale / 2, @@ -118,7 +118,7 @@ let generateLabyrinth = (size) => { o.life(); makeHitbox(o); walls.push(o); - validPositions[x][y] = false; + validPositions[y][x] = false; } } @@ -133,17 +133,17 @@ let generateLabyrinth = (size) => { } } validPositions = truePositions; -} -// Big food -// Class.sphere.SIZE = 17; -// Class.cube.SIZE = 22; -// Class.tetrahedron.SIZE = 27; -// Class.octahedron.SIZE = 28; -// Class.dodecahedron.SIZE = 30; -// Class.icosahedron.SIZE = 32; -// Class.tesseract.SIZE = 39; -delete Class.food.LEVEL_CAP; + // Big food + // Class.sphere.SIZE = 17; + // Class.cube.SIZE = 22; + // Class.tetrahedron.SIZE = 27; + // Class.octahedron.SIZE = 28; + // Class.dodecahedron.SIZE = 30; + // Class.icosahedron.SIZE = 32; + // Class.tesseract.SIZE = 39; + delete Class.food.LEVEL_CAP; +} // Portal loop class PortalLoop { @@ -178,7 +178,14 @@ class PortalLoop { type: "spikyPortalOfficialV1", destination: this.openBounds, buffer: 1500, - spawnArray: validPositions + spawnArray: validPositions, + handler: (entity) => { + // Spawn in default spawnable area if on a tank team + if (entity.team == TEAM_DREADNOUGHTS) return; + let {x, y} = getSpawnableArea(entity.team); + entity.x = x; + entity.y = y; + } }, { type: "bluePortalOfficialV1", @@ -196,7 +203,7 @@ class PortalLoop { entity.destroyAllChildren(); entity.upgrades = []; entity.define('dreadOfficialV1'); - entity.team = 10; + entity.team = TEAM_DREADNOUGHTS; }, entryBarrier: (entity) => { return entity.skill.level >= 150; @@ -255,7 +262,7 @@ class PortalLoop { // Validity checking if (other.type != 'tank') { if ( - other.type != "miniboss" && other.type != "food" && other.type != "aura" && other.type != "wall" && other.type != "unknown" && + other.type != "miniboss" && other.type != "food" && other.type != "crasher" && other.type != "aura" && other.type != "wall" && other.type != "unknown" && (other.x - entity.x) ** 2 + (other.y - entity.y) ** 2 <= 625 ) { other.kill(); diff --git a/server/modules/global.js b/server/modules/global.js index 419c30635..430c5a3ab 100644 --- a/server/modules/global.js +++ b/server/modules/global.js @@ -11,7 +11,6 @@ global.protocol = require(".././lib/fasttalk.js"); // Global Variables (These must come before we import from the modules folder.) global.fps = "Unknown"; -global.playerskin = ""; global.minimap = []; global.entities = []; global.walls = []; @@ -21,9 +20,6 @@ global.entitiesToAvoid = []; global.grid = new hshg.HSHG(); global.arenaClosed = false; global.mockupsLoaded = false; -const d = new Date(); -global.dayofweek = d.getUTCDay(); -global.cangrappleonceagain = "yes" global.loadedAddons = []; global.TEAM_BLUE = -1; @@ -34,6 +30,7 @@ global.TEAM_YELLOW = -5; global.TEAM_ORANGE = -6; global.TEAM_BROWN = -7; global.TEAM_CYAN = -8; +global.TEAM_DREADNOUGHTS = -10; global.TEAM_ROOM = -100; global.TEAM_ENEMIES = -101; global.getSpawnableArea = team => ran.choose((team in room.spawnable && room.spawnable[team].length) ? room.spawnable[team] : room.spawnableDefault).randomInside(); @@ -56,7 +53,7 @@ global.getWeakestTeam = () => { teamcounts = Object.entries(teamcounts).map(([teamId, amount]) => { let weight = teamId in Config.TEAM_WEIGHTS ? Config.TEAM_WEIGHTS[teamId] : 1; return [teamId, amount / weight]; - }); + }); let lowestTeamCount = Math.min(...teamcounts.map(x => x[1])), entries = teamcounts.filter(a => a[1] == lowestTeamCount); return parseInt(!entries.length ? -Math.ceil(Math.random() * Config.TEAMS) : ran.choose(entries)[0]); @@ -90,12 +87,13 @@ global.tickEvents = new EventEmitter(); global.syncedDelaysLoop = () => tickEvents.emit(tickIndex++); global.setSyncedTimeout = (callback, ticks = 0, ...args) => tickEvents.once(tickIndex + Math.round(ticks), () => callback(...args)); +const lowercaseRegex = /[a-z]/, + uppercaseRegexG = /[A-Z]/g; function TO_SCREAMING_SNAKE_CASE(TEXT) { - if (/^[A-Z_]*[A-Z]$/.test(TEXT)) { - return TEXT; - } else if (/[a-zA-Z]+/.test(TEXT)) { - return TEXT.replace(/[A-Z]/g, _ => '_' + _).toUpperCase(); + if (lowercaseRegex.test(TEXT)) { + return TEXT.replace(uppercaseRegexG, _ => '_' + _).toUpperCase(); } + return TEXT; } global.Config = new Proxy(new EventEmitter(), { @@ -150,6 +148,7 @@ global.makeHitbox = wall => { Math.atan2( _size, 0 - _size) + wall.angle ], distance = Math.sqrt(_size ** 2 + _size ** 2); + //convert 4 corners into 4 lines for (let i = 0; i < 4; i++) { relativeCorners[i] = { @@ -157,6 +156,7 @@ global.makeHitbox = wall => { y: distance * Math.cos(relativeCorners[i]) }; } + wall.hitbox = [ [relativeCorners[0], relativeCorners[1]], [relativeCorners[1], relativeCorners[2]], @@ -188,7 +188,6 @@ const requires = [ "./gamemodes/manhunt.js", // The Manhunt mode "./gamemodes/trainwars.js", // The Train Wars mode "./gamemodes/moon.js", // The Space mode - "./gamemodes/risk.js", // Risk "./gamemodes/gamemodeLoop.js", // The gamemode loop. "./gamemodes/groups.js", // Duos/Trios/Squads "./gamemodes/tag.js", // Tag @@ -202,4 +201,4 @@ for (let file of requires) { } } -module.exports = { creationDate: new Date() }; \ No newline at end of file +module.exports = { creationDate: new Date() }; diff --git a/server/modules/live/controllers.js b/server/modules/live/controllers.js index 8127881c2..dc9b464f7 100644 --- a/server/modules/live/controllers.js +++ b/server/modules/live/controllers.js @@ -392,31 +392,30 @@ class io_onlyAcceptInArc extends IO { class io_stackGuns extends IO { constructor(body, opts = {}) { super(body); - this.timeUntilFire = opts.timeUntilFire || 0; + this.stackAtTime = opts.stackAtTime || 0.2; } think ({ target }) { - //why even bother? if (!target) { return; } //find gun that is about to shoot - let lowestReadiness = Infinity, + let lowestTimeToFire = Infinity, readiestGun; for (let i = 0; i < this.body.guns.length; i++) { let gun = this.body.guns[i]; if (!gun.canShoot || !gun.stack) continue; - let reloadStat = (gun.calculator == "necro" || gun.calculator == "fixed reload") ? 1 : gun.bulletSkills.rld, - readiness = (1 - gun.cycle) / (gun.shootSettings.reload * reloadStat); - if (lowestReadiness > readiness) { - lowestReadiness = readiness; + + let timeToFire = (1 - gun.cycleTimer) / (gun.shootSettings.reload * gun.reloadRateFactor * Config.runSpeed); + if (lowestTimeToFire > timeToFire) { + lowestTimeToFire = timeToFire; readiestGun = gun; } } //if we aren't ready, don't spin yet - if (!readiestGun || (this.timeUntilFire && this.timeUntilFire > lowestReadiness)) { + if (!readiestGun || (this.stackAtTime && lowestTimeToFire > this.stackAtTime)) { return; } @@ -682,7 +681,7 @@ class io_hangOutNearMaster extends IO { } think(input) { if (this.body.invisible[1]) return {} - if (this.body.source !== this.body) { + if (this.body.source.id !== this.body.id) { let bound1 = this.orbit * 0.8 + this.body.source.size + this.body.size let bound2 = this.orbit * 1.5 + this.body.source.size + this.body.size let dist = util.getDistance(this.body, this.body.source) + Math.PI / 8; diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index fc7119f25..c3f4eff6e 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -268,6 +268,9 @@ class Gun extends EventEmitter { bullet.team = this.body.team; } defineBullet(bullet) { + // Set bullet source + bullet.source = this.body; + // Define bullet based on natural properties and skills this.bulletType.SIZE = (this.body.size * this.width * this.shootSettings.size) / 2; bullet.define(this.bulletType); @@ -287,7 +290,6 @@ class Gun extends EventEmitter { this.body.children.push(bullet); this.children.push(bullet); } - bullet.source = this.body; bullet.facing = bullet.velocity.direction; if (!bullet.settings.necroTypes) { @@ -323,7 +325,8 @@ class Gun extends EventEmitter { setBulletType(type, clearChildren = false) { // Pre-flatten bullet types to save on doing the same define() sequence a million times this.bulletType = Array.isArray(type) ? type : [type]; - let flattenedType = {}; + // Preset BODY because not all definitions have BODY defined when flattened + let flattenedType = {BODY: {}}; for (let type of this.bulletType) { type = ensureIsClass(type); util.flattenDefinition(flattenedType, type); @@ -375,7 +378,7 @@ class Gun extends EventEmitter { RANGE: shoot.range / Math.sqrt(this.bulletSkills.spd), DENSITY: (shoot.density * this.bulletSkills.pen * this.bulletSkills.pen) / sizeFactor, PUSHABILITY: 1 / this.bulletSkills.pen, - HETERO: 3 - 2.8 * this.bulletSkills.ghost, + HETERO: Math.max(0, 3 - 1.2 * this.bulletSkills.ghost), }; this.reloadRateFactor = this.bulletSkills.rld; // Special cases @@ -408,8 +411,7 @@ class Gun extends EventEmitter { out.PUSHABILITY = 1; out.PENETRATION = Math.max(1, shoot.pen * (0.5 * (this.bulletSkills.pen - 1) + 1)); out.HEALTH = (shoot.health * this.bulletSkills.str + sizeFactor) / Math.pow(this.bulletSkills.pen, 0.8); - out.DAMAGE = shoot.damage * this.bulletSkills.dam * Math.sqrt(sizeFactor) * shoot.pen * this.bulletSkills.pen; - out.RANGE = shoot.range * Math.sqrt(sizeFactor); + out.DAMAGE = shoot.damage * this.bulletSkills.dam * Math.sqrt(sizeFactor) * Math.sqrt(shoot.pen * this.bulletSkills.pen); break; } if (this.independentChildren) return; @@ -1204,27 +1206,26 @@ class Entity extends EventEmitter { this.settings.necroDefineGuns = {}; for (let shape of this.settings.necroTypes) { // Pick the first gun with the right necroType to use for stats and use its defineBullet function - this.settings.necroDefineGuns[shape] = this.guns.filter((gun) => gun.bulletType.NECRO === shape || (gun.bulletType.NECRO === true && gun.bulletType.SHAPE === this.shape) || gun.bulletType.NECRO.includes(shape))[0]; + this.settings.necroDefineGuns[shape] = this.guns.filter((gun) => gun.bulletType.NECRO && (gun.bulletType.NECRO === shape || (gun.bulletType.NECRO === true && gun.bulletType.SHAPE === this.shape) || gun.bulletType.NECRO.includes(shape)))[0]; } this.necro = (host) => { let gun = this.settings.necroDefineGuns[host.shape]; - if (gun.checkShootPermission()) { - let save = { - facing: host.facing, - size: host.SIZE, - }; - host.define("genericEntity"); - gun.defineBullet(host); - host.team = this.master.master.team; - host.master = this.master; - host.color.base = this.color.base; - host.facing = save.facing; - host.SIZE = save.size; - host.health.amount = host.health.max; - return true; - } - return false; + if (!gun || !gun.checkShootPermission()) return false; + + let savedFacing = host.facing; + let savedSize = host.SIZE; + + host.controllers = []; + host.define("genericEntity"); + gun.defineBullet(host); + host.team = this.master.master.team; + host.master = this.master; + host.color.base = this.color.base; + host.facing = savedFacing; + host.SIZE = savedSize; + host.health.amount = host.health.max; + return true; } } if (set.MAX_CHILDREN != null) this.maxChildren = set.MAX_CHILDREN; @@ -1608,7 +1609,7 @@ class Entity extends EventEmitter { return (this.velocity.y + this.accel.y) / Config.runSpeed; } set gunStatScale(gunStatScale) { - if (typeof gunStatScale == "object") { + if (!Array.isArray(gunStatScale)) { gunStatScale = [gunStatScale]; } for (let gun of this.guns) { @@ -2226,6 +2227,7 @@ class Entity extends EventEmitter { case "miniboss": instance.killCount.bosses++; + if (instance.socket) instance.socket.talk("achieve", 3); break; } diff --git a/server/modules/network/discoverability.js b/server/modules/network/discoverability.js index 9212bfd9b..ae2cf3a17 100644 --- a/server/modules/network/discoverability.js +++ b/server/modules/network/discoverability.js @@ -1 +1,6 @@ -// TODO: Add stuff that submits this server to server browsers \ No newline at end of file +// IP and if has https proxy +// NOTE: Server auto adds itself to the list +module.exports = [ + ["us.neroio.xyz", "USA", true], + [] +]; \ No newline at end of file diff --git a/server/modules/network/webServer.js b/server/modules/network/webServer.js index 956b06b02..1e6153abb 100644 --- a/server/modules/network/webServer.js +++ b/server/modules/network/webServer.js @@ -1,5 +1,6 @@ let fs = require('fs'), path = require('path'), + ips = require("./discoverability.js"), publicRoot = path.join(__dirname, "../../../public"), sharedRoot = path.join(__dirname, "../../../shared"), normalRoot = path.join(__dirname, "../../.."), @@ -12,8 +13,8 @@ let fs = require('fs'), "png": "image/png", "ico": "image/x-icon" }, - DEFAULT_FILE = "index.html", wsServer; + try { wsServer = new (require('../../lib/ws/index.js').WebSocketServer)({ noServer: true }); } catch (err) { @@ -27,6 +28,7 @@ if (Config.host === 'localhost') { if (Config.host.match(/localhost:(\d)/) && Config.host !== 'localhost:' + Config.port) { util.warn('[WEB SERVER] config.host is a localhost domain but its port is different to config.port!'); } +ips.push([ Config.host, Config.location, Config.https ]); server = require('http').createServer((req, res) => { let resStr = ""; @@ -35,9 +37,9 @@ server = require('http').createServer((req, res) => { //if this file does not exist, return the default; if (!fs.existsSync(fileToGet)) { - fileToGet = path.join(sharedRoot, DEFAULT_FILE); + fileToGet = path.join(sharedRoot, Config.DEFAULT_FILE); } else if (!fs.lstatSync(fileToGet).isFile()) { - fileToGet = path.join(sharedRoot, DEFAULT_FILE); + fileToGet = path.join(sharedRoot, Config.DEFAULT_FILE); } //return the file @@ -47,35 +49,32 @@ server = require('http').createServer((req, res) => { case "/lib/json/mockups.json": resStr = mockupJsonData; break; - case "/lib/json/gamemodeData.json": + case "/serverData.json": resStr = JSON.stringify({ gameMode: Config.gameModeName, players: views.length }); break; - case "/serverData.json": - resStr = JSON.stringify({ ip: Config.host, gameMode: Config.gameModeName, players: views.length, region: Config.region, name: Config.serverName }); + case "/browserData.json": + resStr = JSON.stringify(ips); break; default: - if (Config.COMBINED) { - let fileToGet = path.join(publicRoot, req.url); + let fileToGet = path.join(publicRoot, req.url); - //if this file does not exist, return the default; - if (!fs.existsSync(fileToGet)) { - if (req.url.includes("/file/")) { - fileToGet = path.join(normalRoot, req.url.replace("/file", "")); - } else { - fileToGet = path.join(publicRoot, DEFAULT_FILE); - } - } else if (!fs.lstatSync(fileToGet).isFile()) { - fileToGet = path.join(publicRoot, DEFAULT_FILE); - } - - //return the file - res.writeHead(200, { 'Content-Type': mimeSet[ fileToGet.split('.').pop() ] || 'text/html' }); - return fs.createReadStream(fileToGet).pipe(res); + //if this file does not exist, return the default; + if (!fs.existsSync(fileToGet)) { + if (req.url.includes("/file/")) { + fileToGet = path.join(normalRoot, req.url.replace("/file", "")); + } else { + fileToGet = path.join(publicRoot, Config.DEFAULT_FILE); + } + } else if (!fs.lstatSync(fileToGet).isFile()) { + fileToGet = path.join(publicRoot, Config.DEFAULT_FILE); } - } + //return the file + res.writeHead(200, { 'Content-Type': mimeSet[ fileToGet.split('.').pop() ] || 'text/html' }); + return fs.createReadStream(fileToGet).pipe(res); + } // CORS? - res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Origin', '*'); res.writeHead(200); res.end(resStr); diff --git a/server/modules/setup/rooms/map_neroio_mazearena.js b/server/modules/setup/rooms/map_neroio_mazearena.js index 447092ab7..3e55ed953 100644 --- a/server/modules/setup/rooms/map_neroio_mazearena.js +++ b/server/modules/setup/rooms/map_neroio_mazearena.js @@ -1,25 +1,25 @@ let { rock, roid } = require('../tiles/decoration.js'), - { wall: WALL, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf, dfxwall: DWAL, fovwall: FWAL, bigsizewall: BWAL, smallsizewall: SWAL } = require('../tiles/misc.js'), + { wall: WALL, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf, dfxwall: DWAL, fovwall: FWAL } = require('../tiles/misc.js'), { portal: port } = require('../tiles/portal.js'), room = [ - [rock,rock,____,WALL,WALL,WALL,____,WALL,WALL,roid,____,F___,____,F___,____,F___,roid,rock,rock], + [rock,rock,____,FWAL,WALL,WALL,____,WALL,WALL,roid,____,F___,____,F___,____,F___,roid,rock,rock], [rock,rock,roid,WALL,F___,WALL,F___,roid,WALL,____,F___,WALL,WALL,____,WALL,WALL,WALL,rock,rock], - [WALL,F___,____,F___,roid,F___,WALL,F___,____,F___,SWAL,F___,____,F___,____,F___,____,F___,____], + [WALL,F___,____,F___,roid,F___,WALL,F___,____,F___,FWAL,F___,____,F___,____,F___,____,F___,____], [WALL,____,WALL,____,WALL,____,roid,____,WALL,WALL,WALL,____,WALL,roid,port,____,WALL,rock,WALL], - [WALL,F___,____,F___,WALL,WALL,WALL,F___,____,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,F___,WALL], + [WALL,F___,____,F___,WALL,WALL,WALL,F___,____,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,F___,FWAL], [WALL,WALL,WALL,roid,F___,____,F___,____,WALL,____,roid,____,F___,____,F___,____,F___,____,roid], [____,F___,roid,rock,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], [F___,WALL,roid,roid,WALL,roid,WALL,nest,nesf,nest,nesf,nest,WALL,roid,F___,____,F___,roid,WALL], - [____,WALL,BWAL,F___,WALL,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [____,WALL,FWAL,F___,WALL,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], [F___,____,F___,____,WALL,____,F___,nest,nesf,nest,nesf,nest,F___,____,F___,____,F___,____,WALL], [____,WALL,____,F___,roid,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], [rock,WALL,WALL,WALL,F___,roid,WALL,nest,nesf,nest,nesf,nest,WALL,roid,F___,____,F___,roid,WALL], [____,F___,____,F___,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], [F___,WALL,F___,WALL,F___,roid,F___,____,F___,roid,F___,____,F___,roid,F___,____,F___,____,F___], [roid,WALL,____,WALL,port,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,____,WALL,WALL,F___,____], - [F___,WALL,F___,WALL,WALL,____,WALL,____,F___,roid,WALL,roid,F___,____,F___,roid,F___,WALL,F___], - [____,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,F___,DWAL,WALL,____,F___,____,WALL,roid], + [F___,WALL,F___,WALL,FWAL,____,WALL,____,F___,roid,WALL,roid,F___,____,F___,roid,F___,WALL,F___], + [____,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,F___,DWAL,WALL,____,F___,____,FWAL,roid], [rock,rock,roid,WALL,WALL,WALL,WALL,____,WALL,____,WALL,FWAL,F___,____,F___,WALL,WALL,rock,rock], [rock,rock,____,F___,____,F___,____,F___,WALL,F___,roid,F___,____,WALL,____,roid,____,rock,rock] ]; diff --git a/server/modules/setup/tiles/misc.js b/server/modules/setup/tiles/misc.js index 1064244d3..ca4b17337 100644 --- a/server/modules/setup/tiles/misc.js +++ b/server/modules/setup/tiles/misc.js @@ -181,34 +181,6 @@ fovwall = new Tile({ } }), -bigsizewall = new Tile({ - color: 30, - init: tile => { - let o = new Entity(tile.loc); - o.define("bigsizewall"); - o.team = TEAM_ROOM; - o.SIZE = room.tileWidth / 1.82; - o.protect(); - o.life(); - makeHitbox(o); - walls.push(o); - } -}), - -smallsizewall = new Tile({ - color: 31, - init: tile => { - let o = new Entity(tile.loc); - o.define("smallsizewall"); - o.team = TEAM_ROOM; - o.SIZE = room.tileWidth / 1.82; - o.protect(); - o.life(); - makeHitbox(o); - walls.push(o); - } -}), - hookpoint = new Tile({ color: "cyan", init: tile => { @@ -221,4 +193,4 @@ hookpoint = new Tile({ } }); -module.exports = { normal, normalNoFood, nest, nestNoFood, wall, nestNoBoss, blacktile, dancefloor, dancefloor1, dancefloor2, dancefloor3, dancefloor4, dancefloor5, dfxwall, hookpoint, fovwall, bigsizewall, smallsizewall }; \ No newline at end of file +module.exports = { normal, normalNoFood, nest, nestNoFood, wall, nestNoBoss, blacktile, dancefloor, dancefloor1, dancefloor2, dancefloor3, dancefloor4, dancefloor5, dfxwall, hookpoint, fovwall }; \ No newline at end of file From 92c85e52b96613398ecad1b1d8d7e4b0e074414f Mon Sep 17 00:00:00 2001 From: "Glitch (neroio2)" Date: Fri, 8 Nov 2024 15:36:25 +0000 Subject: [PATCH 13/15] dasdiojasdas --- .glitch-assets | 20 + changelog preview | 54 +- public/app.js | 120 +- public/changelog.html | 65 +- public/credits.html | 57 +- public/index.html | 34 +- public/lib/canvas.js | 13 +- public/lib/global.js | 4 +- public/lib/socketInit.js | 5 +- public/lib/tankdesc.js | 242 +++- public/lib/util.js | 1 + server/lib/util.js | 1 - server/modules/definitions/addons/dreadv1.js | 19 +- .../modules/definitions/addons/playerskins.js | 16 +- server/modules/definitions/addons/solario.js | 87 +- server/modules/definitions/groups/bosses.js | 221 ++++ server/modules/definitions/groups/dev.js | 134 +- server/modules/definitions/groups/food.js | 22 +- server/modules/definitions/groups/generics.js | 9 +- .../modules/definitions/groups/projectiles.js | 110 +- server/modules/definitions/groups/tanks.js | 1097 +++++++++++++---- server/modules/definitions/groups/turrets.js | 27 +- server/modules/definitions/gunvals.js | 9 +- server/modules/gamemodes/oldDreadnoughts.js | 12 +- server/modules/global.js | 6 +- server/modules/live/entity.js | 13 +- server/modules/network/discoverability.js | 1 - server/modules/setup/mockups.js | 1 + 28 files changed, 1871 insertions(+), 529 deletions(-) diff --git a/.glitch-assets b/.glitch-assets index 252339975..565d2ec8d 100644 --- a/.glitch-assets +++ b/.glitch-assets @@ -224,3 +224,23 @@ {"name":"spider_2.png","date":"2024-08-02T21:15:19.003Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spider_2.png","type":"image/png","size":14419,"imageWidth":158,"imageHeight":127,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spider_2.png","thumbnailWidth":158,"thumbnailHeight":127,"uuid":"dr215LMSNrjEayVI"} {"name":"IMG_1942.png","date":"2024-08-11T01:56:28.613Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_1942.png","type":"image/png","size":349865,"imageWidth":903,"imageHeight":869,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_1942.png","thumbnailWidth":330,"thumbnailHeight":318,"uuid":"IE8b2wO2CuoFPxKz"} {"name":"52459e59-5ff9-4646-9949-a2a1461c7202.image.png","date":"2024-08-23T00:43:21.016Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/52459e59-5ff9-4646-9949-a2a1461c7202.image.png","type":"image/png","size":32907,"imageWidth":602,"imageHeight":598,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F52459e59-5ff9-4646-9949-a2a1461c7202.image.png","thumbnailWidth":330,"thumbnailHeight":328,"uuid":"7n3Mf5ySFZaYGt9y"} +{"name":"eb38cb57-74b4-4965-b9b5-f4b83bd80de3.image.png","date":"2024-09-15T03:32:23.116Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/eb38cb57-74b4-4965-b9b5-f4b83bd80de3.image.png","type":"image/png","size":343944,"imageWidth":634,"imageHeight":616,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Feb38cb57-74b4-4965-b9b5-f4b83bd80de3.image.png","thumbnailWidth":330,"thumbnailHeight":321,"uuid":"5gMgdFgGHHpnYjJs"} +{"name":"SuperSaw.wav","date":"2024-09-29T21:04:14.959Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/SuperSaw.wav","type":"audio/wav","size":4214828,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FSuperSaw.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"PKzCxQwewiAF7Gs0"} +{"uuid":"PKzCxQwewiAF7Gs0","deleted":true} +{"name":"Nero.wav","date":"2024-09-29T21:07:08.814Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Nero.wav","type":"audio/wav","size":29626412,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FNero.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"F2PbIeRc9lFIJmeh"} +{"name":"Atomic.wav","date":"2024-09-29T21:07:28.951Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Atomic.wav","type":"audio/wav","size":49156140,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FAtomic.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"6bY9oHn78ci4iecI"} +{"uuid":"YFI91wH7W4ImAspG","deleted":true} +{"name":"routine2.mp3","date":"2024-09-29T21:23:28.378Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3","type":"audio/mpeg","size":3457701,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Froutine2.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"Zsc0tzfZ9WbJruiV"} +{"uuid":"Zsc0tzfZ9WbJruiV","deleted":true} +{"uuid":"TFRBBNfrVJUyspgF","deleted":true} +{"uuid":"lVqeyaHXOOHA3aZa","deleted":true} +{"uuid":"zW0KIBTt4lgumW6g","deleted":true} +{"uuid":"1XBSkO00yeI1Yi2Y","deleted":true} +{"uuid":"Be3hu6iiO23cqEY0","deleted":true} +{"uuid":"gT7k6nINNGIZi3N3","deleted":true} +{"uuid":"J2BTiSehE6If7Hxe","deleted":true} +{"name":"Failed Connection.mp3","date":"2024-09-29T21:28:24.666Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Failed%20Connection.mp3","type":"audio/mpeg","size":8843969,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FFailed%20Connection.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"LAtmB7m49HCAls6f"} +{"name":"Acension (Apotheosis 2).wav","date":"2024-10-21T12:52:46.145Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Acension%20(Apotheosis%202).wav","type":"audio/wav","size":30978092,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FAcension%20(Apotheosis%202).wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"9slDjUspOoEUXAlt"} +{"name":"Nadir (Apotheosis 3).wav","date":"2024-10-21T12:52:50.342Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Nadir%20(Apotheosis%203).wav","type":"audio/wav","size":33538092,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FNadir%20(Apotheosis%203).wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"K21MpQlwwaIrOtvb"} +{"name":"Methemphetaphacktomine.wav","date":"2024-10-21T12:52:53.719Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Methemphetaphacktomine.wav","type":"audio/wav","size":35811372,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMethemphetaphacktomine.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"m3VznFUfVCNRCqkm"} +{"name":"Polychromatism.wav","date":"2024-10-21T12:52:57.274Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Polychromatism.wav","type":"audio/wav","size":35762220,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FPolychromatism.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"TMDLz8dUptnSYX70"} diff --git a/changelog preview b/changelog preview index 119d2ed06..5d7aae1e9 100644 --- a/changelog preview +++ b/changelog preview @@ -8,7 +8,57 @@
  • small fixes im too lazy to write
  • changed server box
  • small minion bugfixes
  • -

    RANDOM BULLSHIT, GO!

    +
  • forgot to remove mace
  • +
  • dreads update
  • +
  • got rid of trilancer branch
  • +
  • dreadv1 changes
  • +
  • undertow update
  • +
  • removed a bunch of songs from ost
  • +
  • removed european server
  • +
  • updated credits
  • +
  • buffed albequerqe
  • +
  • fixed a bug where cloner hybrid did not show up when upgrading from cloner (dunno how i missed that)
  • +
  • removed ranch, marksman and cocci
  • +
  • fixed a bug where autocloner and cloner hybrid having instant clone respawn time
  • +
  • added visualizer to Nero brella
  • +
  • removed sidewinder
  • +
  • removed ceptions
  • +
  • nerfed auras (-100 aura points)
  • +
  • buffed surges emp attack
  • +
  • added choker
  • +
  • added X-Pathogen
  • +
  • added wyrm
  • +
  • added noble branch
  • +
  • added more descriptions
  • +
  • added gatling gun
  • +
  • removed more ceptions
  • +
  • removed aura branch from tier 1
  • +
  • removed auto branch from tier 1
  • +
  • removed hybrid branch from tier 1
  • +
  • removed flankinception branch
  • +
  • added more machceptioner upgrades
  • +
  • added 4 new ost tracks
  • +
  • fixed debug menu
  • +
  • makes shapes killed on run in debug menu reset on death
  • +
  • fixed solario bossfight
  • +
  • fixed bug where recoil doesnt work when upgrading from lancer tree
  • +
  • added charger
  • +
  • revolutionist now upgrades from whirlwind
  • +
  • saturn now upgrades from revolutionist
  • +
  • added formal dehyde and frostbite
  • +
  • buffed smashers
  • +
  • buffed skaters movement speed
  • +
  • gave pion the hadron ability and changed ring color to red
  • +
  • changed bayonet to tier 3
  • +
  • added icegun, fencer arisaka, wakazashi and fireblanket
  • +
  • removed mirror backshield
  • +
  • fixed death sounds
  • +
  • added wark branch
  • +
  • fixed auto2brid not having its main autocannon
  • +
  • fixed bug where scowerer and swivel2brid did not upgrade from its intended branches
  • +
  • fixed grazerbrid not having its autocannon
  • +
  • fixed the skype achievement
  • +

    Big ass update :blehh:

    -
    - - -
    -

    view notes ▸

    -
    -
    - -
    -
    Nero.io runs on Open Source Arras. For more info,
    visit the APS++ GitHub Repository by Taureon And Join The Nero.io Discord With The Widget In The Top Right
    -
    -

    Date Since Creation

    -
    -
    +
    This Arras.io Private Server runs on Open Source Arras.
    For more info, visit the GitHub Repository.

    Not an official Arras.io project. We are not associated with Arras.io or Momentum Studios.
    - +
    +

    Open Source Arras

    +
    +

    Connecting...

    +
    - +

    -

    view options ▸ ≡

    +

    view options ▸


    -
    AppearanceOptionsControlsLinks
    -
    -
    All Controls
    - - - + Advanced Controls:
    +
    W - move up A - move left
    S - move down D - move right
    - + - - - - + + +
    E - auto-fire C - auto-spin
    R - disable AI N - level up
    V - reverse tank G - auto-alt
    V - reverse tank F - auto-alt
    B - reverse mouse O - self-destruct
    T - show tank treeL - stats for nerds
    X - spin lock H - take control
    - - placeholder - - placeholder
    - - placeholder - - placeholder
    T - show tank treeM - maximize stat
    X - spin lock P - developer tank*
    * = requires valid token
    -
    -
    -
    Themes
    + Options: - - - - - -
    -
    -
    UI Stuff
    - + -
    -
    -
    -
    Performance & Optimization
    - - - - - - - + + -
    -
    Miscellaneous
    - - +
    -
    -
    -
    - +
    +
    -
    -
    -
    -
    -
    -
    - - -
    -
    -
    -

    Achievements

    -
    -
    - -
    - -
    - -
    -
    -
    -

    Skins

    -
    -
    -

    Default

    -
    - - -
    - -
    ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○
    -
    - - - -
    @@ -557,10 +139,9 @@

    Default

    - - \ No newline at end of file + diff --git a/public/lib/canvas.js b/public/lib/canvas.js index 10e5c5ca9..d12f84314 100644 --- a/public/lib/canvas.js +++ b/public/lib/canvas.js @@ -7,7 +7,7 @@ class Canvas { this.target = global.target; this.socket = global.socket; this.directions = []; - this.wikiInput = document.getElementById("wikiTankThing"); + this.chatInput = document.getElementById('chatInput'); this.chatInput.addEventListener('keydown', event => { if (![global.KEY_ENTER, global.KEY_ESC].includes(event.keyCode)) return; @@ -18,17 +18,6 @@ class Canvas { if (event.keyCode === global.KEY_ENTER) this.socket.talk('M', this.chatInput.value); this.chatInput.value = ""; }); - this.wikiInput.addEventListener('keydown', event => { - if (global.wiki && global.gameStart) { - if (event.keyCode === global.KEY_ENTER) { - if (this.wikiInput.value != "") { - global.wikidisplaytank = this.wikiInput.value; - this.wikiInput.value = ""; - } - this.cv.focus(); - } - } - }); this.cv = document.getElementById('gameCanvas'); this.cv.addEventListener('mousemove', event => this.mouseMove(event), false); @@ -75,21 +64,13 @@ class Canvas { if (global.showTree) this.treeScrollSpeedMultiplier = 5; else this.socket.cmd.set(6, true); break; - case global.KEY_PING: - global.showDebug = !0; - break; + case global.KEY_ENTER: - global.killsoundready = true // Enter to respawn if (global.died) { - this.socket.talk('s', global.playerName, 0, 1 * settings.game.autoLevelUp, global.skin); + this.socket.talk('s', global.playerName, 0, 1 * settings.game.autoLevelUp); global.died = false; - break; - } - - if (global.wiki && global.gameStart) { - this.wikiInput.focus(); - break; + break; } // or to talk instead @@ -113,19 +94,11 @@ class Canvas { case global.KEY_LEFT_ARROW: if (!global.died && global.showTree) return global.scrollVelocityX = -this.treeScrollSpeed * this.treeScrollSpeedMultiplier; case global.KEY_LEFT: - if (global.wiki && global.gameStart) { - global.wikidisplaytank = parseInt(global.wikidisplaytank) - 1; - break; - } this.socket.cmd.set(2, true); break; case global.KEY_RIGHT_ARROW: if (!global.died && global.showTree) return global.scrollVelocityX = +this.treeScrollSpeed * this.treeScrollSpeedMultiplier; case global.KEY_RIGHT: - if (global.wiki && global.gameStart) { - global.wikidisplaytank = parseInt(global.wikidisplaytank) + 1; - break; - } this.socket.cmd.set(3, true); break; case global.KEY_MOUSE_0: @@ -152,61 +125,6 @@ class Canvas { case global.KEY_SUICIDE: this.socket.talk('1'); break; - case global.KEY_TELEPORT: - this.socket.talk('testTeleport'); - break; - case global.KEY_SMALLER_TANK: - this.socket.talk('smallerTank'); - break; - case global.KEY_BIGGER_TANK: - this.socket.talk('biggerTank'); - break; - case global.KEY_SMALLER_FOV: - this.socket.talk('smallerFOV'); - break; - case global.KEY_BIGGER_FOV: - this.socket.talk('biggerFOV'); - break; - case global.KEY_GOD_MODE: - this.socket.talk('godmodeButton'); - break; - case global.KEY_INVISIBLE: - this.socket.talk('invisibility'); - break; - case global.KEY_CAN_BE_ON_LEADERBOARD: - this.socket.talk('canBeOnLeaderboard'); - break; - case global.KEY_STRONG: - this.socket.talk('keyStrong'); - break; - case global.KEY_WATCH_THIS: - this.socket.talk('watchThis'); - break; - case global.KEY_DRAG: - this.socket.talk('drag'); - break; - case global.KEY_SPAWN_WALL: - this.socket.talk('spawnWall'); - break; - case global.KEY_RANDOM_TEST: - this.socket.talk('randomTestKey'); - break; - case global.KEY_HEAL: - this.socket.talk('heal'); - break; - case global.KEY_WIKI: - global.wiki = true; - document.querySelector("#wikiTankThing").style.display = 'block'; - break; - case global.KEY_ESC: - global.wiki = false; - document.querySelector("#wikiTankThing").style.display = 'none'; - case global.KEY_CHANGE_SONG: - const pmusic = ["https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3?v=1705287022417", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav?v=1705286889038", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3?v=1705807057028", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3?v=1708218475743", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3?v=1708218464295", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.wav?v=1713352428783", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"]; - var randmusic = pmusic[~~(Math.random() * pmusic.length)]; - global.music2.src = (randmusic); - global.music2.load(); - global.music2.play(); } if (!event.repeat) { switch (event.keyCode) { @@ -284,9 +202,6 @@ class Canvas { case global.KEY_UP: this.socket.cmd.set(0, false); break; - case global.KEY_PING: - global.showDebug = !1; - break; case global.KEY_DOWN_ARROW: global.scrollVelocityY = 0; case global.KEY_DOWN: diff --git a/public/lib/color.js b/public/lib/color.js index 8447c71e7..9293836ab 100644 --- a/public/lib/color.js +++ b/public/lib/color.js @@ -1,32 +1,32 @@ var color = { - "nero": { - "teal": "#9EFFE0", - "lgreen": "#87FF8D", - "orange": "#FFB675", - "yellow": "#FDF380", - "lavender": "#b58efd", - "aqua": "#7adbba", - "pink": "#FFBDDD", - "vlgrey": "#E8EBF7", - "lgrey": "#b6b7ba", - "guiwhite": "#F0F0F0", - "black": "#484848", - "blue": "#52A8EB", - "green": "#8ABC3F", - "red": "#FC4E51", - "gold": "#EFC74B", - "purple": "#8D6ADF", - "magenta": "#ED2891", - "grey": "#A7A7AF", - "dgrey": "#726F6F", - "white": "#F0F8FA", - "guiblack": "#000000", - "mustard": "#c49608", - "tangerine": "#ec7b0f", - "brown": "#895918", - "cyan": "#13808e", - "paletteSize": 10, - "border": 0.65 + "normal": { + "teal": "#7ad3db", + "lgreen": "#b9e87e", + "orange": "#e7896d", + "yellow": "#fdf380", + "lavender": "#b58efd", + "aqua": "#7adbba", + "pink": "#ef99c3", + "vlgrey": "#e8ebf7", + "lgrey": "#a4a4ad", //"#aa9f9e", + "guiwhite": "#ffffff", + "black": "#484848", + "blue": "#3ca4cb", + "green": "#8abc3f", + "red": "#e03e41", + "gold": "#efc74b", + "purple": "#8d6adf", + "magenta": "#cc669c", + "grey": "#a7a7af", + "dgrey": "#726f6f", + "white": "#dbdbdb", + "guiblack": "#000000", + "mustard": "#c49608", + "tangerine": "#ec7b0f", + "brown": "#895918", + "cyan": "#13808e", + "paletteSize": 20, + "border": 0.6509803921568628 }, "dark": { "teal": "#6ecedc", @@ -609,4 +609,4 @@ var color = { "border": 0 } }; -export { color } \ No newline at end of file +export { color } diff --git a/public/lib/gameDraw.js b/public/lib/gameDraw.js index b2000f1a2..776c88d91 100644 --- a/public/lib/gameDraw.js +++ b/public/lib/gameDraw.js @@ -94,10 +94,10 @@ var gameDraw = { //TODO: somehow move the calculation to these in reanimateColors to improve performance colorCache: {}, modifyColor: (color, base = "16 0 1 0 false") => { - // Split into array + // Split into array let colorDetails = color.split(" "), baseDetails = base.split(" "); - + // Color mirroring if (colorDetails[0] == "-1" || colorDetails[0] == "mirror") { colorDetails[0] = baseDetails[0]; @@ -156,26 +156,21 @@ var gameDraw = { lesbian: "", gay: "", bi: "", - nero: "", trans: "", magenta: "", blue_red: "", blue_grey: "", grey_blue: "", red_grey: "", - grey_red: "", - sans: "", - epilepsy: "" + grey_red: "" }, reanimateColors: () => { let now = Date.now(), - six_gradient = Math.floor((now / 200) % 6), + //six_gradient = Math.floor((now / 200) % 6), five_bars = Math.floor((now % 2000) / 400), three_bars = Math.floor((now % 2000) * 3 / 2000), - fourtyfive_bars = Math.floor((now % 4000) * 45 / 4000), blinker = 150 > now % 300, - seizure = 5 > now % 10, lesbian_magenta = "#a50062", lesbian_oredange = "#d62900", @@ -183,7 +178,7 @@ var gameDraw = { lesbian_useSecondSet = five_bars < 2, gay_transition = (now / 2000) % 1, - + ratio = (Math.sin(now / 2000 * Math.PI)) / 2 + 0.5, light_purple = { h: 258/360, s: 1, l: 0.84 }, purple = { h: 265/360, s: 0.69, l: 0.47 }, @@ -191,16 +186,6 @@ var gameDraw = { bi_pink = "#D70071", bi_purple = "#9C4E97", bi_blue = "#0035AA", - - nero_blue1 = "#4287F5", - nero_blue2 = "#3CA2F0", - nero_blue3 = "#70B5FF", - nero_blue4 = "#4B90DB", - nero_blue5 = "#355BBD", - nero_blue6 = "#1F4199", - nero_blue7 = "#242bbd", - nero_blue8 = "#1814E0", - nero_blue9 = "#2668d1", trans_pink = "#f7a8b8", trans_blue = "#55cdfc", @@ -221,9 +206,6 @@ var gameDraw = { gameDraw.animatedColor.grey_blue = blinker ? gameDraw.color.grey : gameDraw.color.blue; gameDraw.animatedColor.red_grey = blinker ? gameDraw.color.red : gameDraw.color.grey; gameDraw.animatedColor.grey_red = blinker ? gameDraw.color.grey : gameDraw.color.red; - gameDraw.animatedColor.epilepsy = seizure ? gameDraw.color.guiblack : gameDraw.color.guiwhite; - - gameDraw.animatedColor.nero = [nero_blue1, "#418CF4", "#4092F3", "#3E97F2", "#3D9DF1", nero_blue2, "#46A6F3", "#51AAF6", "#5BADF9", "#66B1FC", nero_blue3, "#69AEF8", "#61A6F1", "#5A9FE9", "#5297E2", nero_blue4, "#4785D5", "#427BCF", "#3E70C9", "#3966C3", nero_blue5, "#3156B6", "#2C51AF", "#284BA7", "#2346A0", nero_blue6, "#203DA0", "#2138A7", "#2234AF", "#232FB6", nero_blue7, "#2226C4", "#1F22CB", "#1D1DD2", "#1A19D9", nero_blue8, "#1B25DD", "#1E36DA", "#2046D7", "#2357D4", nero_blue9, "#2C6ED8", "#3174DF", "#377BE7", "#3C81EE", "#4287F5"][fourtyfive_bars]; }, animatedColors: { // police @@ -261,18 +243,10 @@ var gameDraw = { // bi 38: true, bi: true, - + // magenta 42: true, animatedMagenta: true, - - // nero - 43: true, - animatednero: true, - - // epil - 44: true, - animatedepilepsy: true }, getColor: (colorNumber) => { if (colorNumber[0] == '#') return colorNumber; @@ -439,16 +413,6 @@ var gameDraw = { case "42": case "animatedMagenta": return gameDraw.animatedColor.magenta; - - // nero shit - case "43": - case "animatednero": - case "nero": - return gameDraw.animatedColor.nero; - case "44": - case "animatedepilepsy": - case "epilepsy": - return gameDraw.animatedColor.epilepsy; } }, getColorDark: (givenColor) => { diff --git a/public/lib/global.js b/public/lib/global.js index 083df3af6..36d861af3 100644 --- a/public/lib/global.js +++ b/public/lib/global.js @@ -48,79 +48,61 @@ let Region = (size) => { }; const global = { - // Keys and other mathematical constants - KEY_ESC: 27, - KEY_ENTER: 13, - KEY_SHIFT: 16, - KEY_BECOME: 70, - KEY_CHAT: 13, - KEY_FIREFOOD: 119, - KEY_SPLIT: 32, + // Keys and other mathematical constants. You can find the list here: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode + KEY_ESC: 27,// Escape + KEY_ENTER: 13,// Enter + KEY_SHIFT: 16,// Shift + KEY_BECOME: 70,// F + KEY_CHAT: 13,// Enter + KEY_FIREFOOD: 119,// F8 + KEY_SPLIT: 32,// Space - KEY_LEFT: 65, - KEY_UP: 87, - KEY_RIGHT: 68, - KEY_DOWN: 83, - KEY_LEFT_ARROW: 37, - KEY_UP_ARROW: 38, - KEY_RIGHT_ARROW: 39, - KEY_DOWN_ARROW: 40, + KEY_LEFT: 65,// A + KEY_UP: 87,// W + KEY_RIGHT: 68,// D + KEY_DOWN: 83,// S + KEY_LEFT_ARROW: 37,// ArrowLeft + KEY_UP_ARROW: 38,// ArrowUp + KEY_RIGHT_ARROW: 39,// ArrowRight + KEY_DOWN_ARROW: 40,// ArrowDown - KEY_AUTO_SPIN: 67, - KEY_AUTO_FIRE: 69, - KEY_AUTO_ALT: 71, - KEY_OVER_RIDE: 82, - KEY_REVERSE_TANK: 86, - KEY_REVERSE_MOUSE: 66, - KEY_SPIN_LOCK: 88, + KEY_AUTO_SPIN: 67,// C + KEY_AUTO_FIRE: 69,// E + KEY_AUTO_ALT: 71,// G + KEY_OVER_RIDE: 82,// R + KEY_REVERSE_TANK: 86,// V + KEY_REVERSE_MOUSE: 66,// B + KEY_SPIN_LOCK: 88,// X KEY_LEVEL_UP: 78, - KEY_FUCK_YOU: 192, - KEY_PING: 76, - KEY_CLASS_TREE: 84, - KEY_MAX_STAT: 77, - KEY_SUICIDE: 79, - KEY_ZOOM_OUT: 45, - KEY_ZOOM_IN: 61, - KEY_TELEPORT: 80, - KEY_SMALLER_TANK: 188, - KEY_BIGGER_TANK: 190, - KEY_SMALLER_FOV: 187, - KEY_BIGGER_FOV: 189, - KEY_GOD_MODE: 186, - KEY_INVISIBLE: 222, - KEY_CAN_BE_ON_LEADERBOARD: 113, - KEY_STRONG: 191, - KEY_HEAL: 220, - KEY_WATCH_THIS: 219, - KEY_DRAG: 221, - KEY_SPAWN_WALL: 90, - KEY_RANDOM_TEST: 81, - KEY_CHANGE_SONG: 112, + KEY_FUCK_YOU: 80,// P + KEY_CLASS_TREE: 84,// T + KEY_MAX_STAT: 77,// M + KEY_SUICIDE: 79,// O + KEY_ZOOM_OUT: 45,// ?? + KEY_ZOOM_IN: 61,// ?? - KEY_UPGRADE_ATK: 49, - KEY_UPGRADE_HTL: 50, - KEY_UPGRADE_SPD: 51, - KEY_UPGRADE_STR: 52, - KEY_UPGRADE_PEN: 53, - KEY_UPGRADE_DAM: 54, - KEY_UPGRADE_RLD: 55, - KEY_UPGRADE_MOB: 56, - KEY_UPGRADE_RGN: 57, - KEY_UPGRADE_SHI: 48, - KEY_MOUSE_0: 32, - KEY_MOUSE_1: 86, - KEY_MOUSE_2: 16, - KEY_CHOOSE_1: 89, - KEY_CHOOSE_2: 85, - KEY_CHOOSE_3: 73, - KEY_CHOOSE_4: 72, - KEY_CHOOSE_5: 74, - KEY_CHOOSE_6: 75, - KEY_WIKI: 118, + KEY_UPGRADE_ATK: 49,// 1 + KEY_UPGRADE_HTL: 50,// 2 + KEY_UPGRADE_SPD: 51,// 3 + KEY_UPGRADE_STR: 52,// 4 + KEY_UPGRADE_PEN: 53,// 5 + KEY_UPGRADE_DAM: 54,// 6 + KEY_UPGRADE_RLD: 55,// 7 + KEY_UPGRADE_MOB: 56,// 8 + KEY_UPGRADE_RGN: 57,// 9 + KEY_UPGRADE_SHI: 48,// 0 + KEY_MOUSE_0: 32,// 32 + KEY_MOUSE_1: 86,// V + KEY_MOUSE_2: 16,// ShiftLeft + KEY_CHOOSE_1: 89,// Y + KEY_CHOOSE_2: 85,// U + KEY_CHOOSE_3: 73,// I + KEY_CHOOSE_4: 72,// H + KEY_CHOOSE_5: 74,// J + KEY_CHOOSE_6: 75,// K showTree: false, - showDebug: !1, scrollX: 0, realScrollX: 0, // Canvas @@ -137,7 +119,6 @@ const global = { died: false, kicked: false, continuity: false, - wiki: false, startPingTime: 0, toggleMassState: 0, backgroundColor: '#f2fbff', @@ -167,18 +148,7 @@ const global = { lastrender: 0, rendergap: 0, lastuplink: 0, - killcount: 0, - shapecount: 0, }, - emojiloaded: false, - wikidisplaytank: 999, - ISTHEGODAMNFUCKINGGAMEON: "no", - killsoundready: true, - skin: "", - skinpage: 0, - savedkillcount: 0, - savedshapecount: 0, - lockedornot: 0, mouse: { x: 0, y: 0}, target: { x: 0, y: 0 }, reverseTank: 1, @@ -187,12 +157,6 @@ const global = { ratio: window.devicePixelRatio, mockupLoading: { then: cb => cb() }, treeScale: 1, - chats: {}, - music2: { - src: "", - songname: "", - }, - stopthefuckingkillsoundyouprick: false, - + chats: {} }; export { global } diff --git a/public/lib/json/color.json b/public/lib/json/color.json index d201cdd04..6c64942c4 100644 --- a/public/lib/json/color.json +++ b/public/lib/json/color.json @@ -1,33 +1,4 @@ { - "nero": { - "teal": "#9EFFE0", - "lgreen": "#87FF8D", - "orange": "#FFB675", - "yellow": "#FDF380", - "lavender": "#b58efd", - "aqua": "#7adbba", - "pink": "#FFBDDD", - "vlgrey": "#E8EBF7", - "lgrey": "#b6b7ba", - "guiwhite": "#F0F0F0", - "black": "#484848", - "blue": "#52A8EB", - "green": "#8ABC3F", - "red": "#FC4E51", - "gold": "#EFC74B", - "purple": "#8D6ADF", - "magenta": "#ED2891", - "grey": "#A7A7AF", - "dgrey": "#726F6F", - "white": "#F0F8FA", - "guiblack": "#000000", - "mustard": "#c49608", - "tangerine": "#ec7b0f", - "brown": "#895918", - "cyan": "#13808e", - "paletteSize": 10, - "border": 0.65 - }, "normal": { "teal": "#7ad3db", "lgreen": "#b9e87e", diff --git a/public/lib/json/manifest.json b/public/lib/json/manifest.json index 8d9cdc749..edb615004 100644 --- a/public/lib/json/manifest.json +++ b/public/lib/json/manifest.json @@ -1,15 +1,15 @@ { - "name": "Nero.io 2", - "theme_color": "#000000", + "name": "Open Source Arras", + "theme_color": "#454b7f", "background_color": "#484948", - "description": "Nero.io 2 runs on Open Source Arras.", + "description": "This server runs on Open Source Arras.", "orientation": "landscape", "start_url": "/", "scope": "/", "display": "fullscreen", "icons": [{ - "src": "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png?v=1701910145704", + "src": "round.png", "sizes": "96x96", "type": "image/png" }] -} \ No newline at end of file +} diff --git a/public/lib/settings.js b/public/lib/settings.js index ac519ff62..5991c0fe4 100644 --- a/public/lib/settings.js +++ b/public/lib/settings.js @@ -7,7 +7,7 @@ const settings = { deathBlurAmount: 3, darkBorders: false, fancyAnimations: true, - colors: 'nero', + colors: 'normal', pointy: true, fontSizeBoost: 1.4, fontStrokeRatio: 4.5, diff --git a/public/lib/socketInit.js b/public/lib/socketInit.js index 1b12c3ec2..8d841f31f 100644 --- a/public/lib/socketInit.js +++ b/public/lib/socketInit.js @@ -809,11 +809,6 @@ const socketInit = port => { if (socket.cmd.check()) socket.cmd.talk(); }); }; - var KillSound = new Audio(); - function PlaySoundKS() { - KillSound.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Voicy_Slap%20Battles%20Killstreak%20Kill.mp3?v=1714045643190"); - KillSound.play(); - } // Handle incoming messages socket.onmessage = async function socketMessage(message) { await new Promise(Resolve => setTimeout(Resolve, window.fakeLagMS)); @@ -827,7 +822,7 @@ const socketInit = port => { case 'w': // welcome to the game if (m[0]) { // Ask to spawn console.log('The server has welcomed us to the game room. Sending spawn request.'); - socket.talk('s', global.playerName, 1, 1 * settings.game.autoLevelUp, global.skin); + socket.talk('s', global.playerName, 1, 1 * settings.game.autoLevelUp); global.message = ''; } break; @@ -850,24 +845,6 @@ const socketInit = port => { global.message = m[0]; console.log(m[0]); break; - case "achieve": - const achievementTable = ['killachievement', 'killachievement2', 'tokenachievement'] // lookup table of achievements and their ids - util.submitAchievementToLocalStorage(achievementTable[m[0]]) // whatever code to actually give the player the achievement - break; - case "killgained": - PlaySoundKS() - global.metrics.killcount += 1; - global.savedkillcount = (Number(localStorage.getItem("savedkills")) + 1); - localStorage.setItem("savedkills", global.savedkillcount.toString()); - break; - case "shapegained": - global.metrics.shapecount += 1; - global.savedshapecount = (Number(localStorage.getItem("savedshapes")) + 1); - localStorage.setItem("savedshapes", global.savedshapecount.toString()); - break; - case "killstreakreset": - global.metrics.killcount = 0; - break; case 'c': // force camera move global.player.renderx = global.player.cx = m[0]; global.player.rendery = global.player.cy = m[1]; @@ -914,7 +891,6 @@ const socketInit = port => { global.gameStart = true; global.entities = []; global.message = ''; - global.stopthefuckingkillsoundyouprick = true; }); } break; @@ -1057,4 +1033,4 @@ const socketInit = port => { return socket; }; -export { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow }; \ No newline at end of file +export { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow }; diff --git a/public/lib/tankdesc.js b/public/lib/tankdesc.js deleted file mode 100644 index d6926f36b..000000000 --- a/public/lib/tankdesc.js +++ /dev/null @@ -1,545 +0,0 @@ -const tankdescs = { -/* - template: { - type: "", - desc: "", - tier: "", - weapons: "", - abilities: "", - weak: "", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "", - origin: "", - updateadded: "", - } -*/ - basic: { - type: "Catalyst", - desc: "The Starting Tank Of Nero.io, The Beginning Of Nero.io, The Catalyst Of Nero.io, It Starts It All.", - tier: "1", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: Twin, Sniper, Machine Gun, Flank Guard, Director, Pounder, Trapper, Auto-Basic, Desmos, Basic-Hybrid, Subduer, Inception.", - "Tier 3: Smasher, Cloner.", - "Misc: Daily Tank", - "---"], - upgradesfrom: "N/A", - origin: "diep.io", - updateadded: "1.0", - }, - twin: { - type: "Assaulter", - desc: "Basic With An Extra Front Barrel. Good If You Like More Barrels Without Losing Too Much Penetration. Excels In Mid To Long-ish Range Combat.", - tier: "2", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 3: Double Twin, Triple Shot, Gunner, Hexa Tank, Auto Twin, Helix, Twin Hybrid, Binary", - "Tier 4: Bulwark, Musket", - "---", - "---"], - upgradesfrom: "Basic", - origin: "diep.io", - updateadded: "1.0", - }, - sniper: { - type: "Ranger", - desc: "Longer and more Powerful Basic. Good for Long Range, Dont Get Too Close To Your Enemy Though As Snipers Are Meant For Long Range Combat Afterall...", - tier: "2", - weapons: "Bullets", - abilities: "N/A", - weak: "Drones, Close Range", - upgradesto: ["Tier 2: Assassin, Hunter", - "Tier 3: ", - "Tier 4: ", - "Misc: N/A"], - upgradesfrom: "Basic", - origin: "diep.io", - updateadded: "1.0", - }, - machineGun: { - type: "Spammer", - desc: "Easy To Play As, Fun To Use. Good For Spamming, Not The Best Idea To Go Up Against High Penetration Tanks Though!", - tier: "2", - weapons: "Bullets", - abilities: "N/A", - weak: "Drones, Snipers", - upgradesto: ["Tier 2: Gunner", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Basic", - origin: "diep.io", - updateadded: "1.0", - }, - flankGuard: { - type: "Assaulter", - desc: "Guards Your Back From Sneaky People. Great At Getting More Bullet Coverage. Well Balanced And Serves Its Perpose", - tier: "2", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: Hexa Tank, Tri-Angle", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Basic", - origin: "diep.io", - updateadded: "1.0", - }, - director: { - type: "Controller", - desc: "Instead Of Bullets, Try Drones! Control Them With The Cursor. Beware Though, The Drones May Not Go As Fast As You Want Them To.", - tier: "2", - weapons: "Drones", - abilities: "N/A", - weak: "Assaulters, Fast Tanks", - upgradesto: ["Tier 2: Overseer", - "Tier 3: ", - "Tier 4: ", - "Misc: N/A"], - upgradesfrom: "Basic", - origin: "arras.io", - updateadded: "1.0", - }, - pounder: { - type: "Lobber", - desc: "Heavier Bullets With More Of A Kick To Them. Great For Close Combat, Just Dont Let The Slower Fire Rate And Bullet Speed Kill You!", - tier: "2", - weapons: "Bullet", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: Destroyer", - "Tier 3: ", - "Tier 4: ", - "Misc: N/A"], - upgradesfrom: "Basic", - origin: "arras.io", - updateadded: "1.0", - }, - trapper: { - type: "Defender", - desc: "Deploys Traps Instead Of Bullets, These Act Like Shields To Protect You From Things. They Arent Invincible Though!", - tier: "2", - weapons: "Traps", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Basic", - origin: "diep.io", - updateadded: "1.6", - }, - desmos: { - type: "Siner", - desc: "Gives Bullets The Ability To Act Like Waves, Helpful For Getting Around High Bullet Health Coming Straight At You", - tier: "2", - weapons: "Sine-Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Basic", - origin: "arras.io", - updateadded: "2.8", - }, - smasher: { - type: "Banger", - desc: "No Guns, Only Melee Damage. For People Who Like Agressive Playstyles Or Just Want Something More In Your Control", - tier: "3", - weapons: "Armour", - abilities: "N/A", - weak: "Anything Faster", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Basic", - origin: "diep.io", - updateadded: "1.0", - }, - healer: { - type: "Supporter", - desc: "", - tier: "3", - weapons: "Healer-Bullets", - abilities: "Healing", - weak: "", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Basic?Siege", - origin: "arras.io", - updateadded: "2.8", - }, - doubleTwin: { - type: "Assaulter", - desc: "", - tier: "3", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Twin, Flank Guard", - origin: "diep.io", - updateadded: "1.0", - }, - tripleShot: { - type: "Assaulter", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "", - origin: "diep.io", - updateadded: "1.0", - }, - tripleTwin: { - type: "Assaulter", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "", - origin: "diep.io", - updateadded: "1.0", - }, - hewnDouble: { - type: "Assaulter", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Double Twin", - origin: "arras.io", - updateadded: "1.0", - }, - pentaShot: { - type: "Assaulter", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Triple Shot", - origin: "diep.io", - updateadded: "1.0", - }, - spreadshot: { - type: "Assaulter", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Triple Shot", - origin: "diep.io", - updateadded: "1.0", - }, - bentDouble: { - type: "Assaulter", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Penta Shot, Double Twin", - origin: "arras.io", - updateadded: "1.0", - }, - triplet: { - type: "Assaulter", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Triple Shot", - origin: "diep.io", - updateadded: "1.0", - }, - assassin: { - type: "Ranger", - desc: "", - tier: "3", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Sniper", - origin: "diep.io", - updateadded: "1.0", - }, - hunter: { - type: "Ranger-Stacker", - desc: "", - tier: "3", - weapons: "Bullets", - abilities: "Scope", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Sniper", - origin: "diep.io", - updateadded: "1.0", - }, - rifle: { - type: "Ranger", - desc: "", - tier: "3", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Sniper", - origin: "arras.io", - updateadded: "2.2", - }, - ranger: { - type: "Ranger", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Assassin", - origin: "diep.io", - updateadded: "1.0", - }, - stalker: { - type: "Ranger-Ghoster", - desc: "", - tier: "3", - weapons: "Bullets", - abilities: "Invisibility", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Assassin", - origin: "diep.io", - updateadded: "2.3", - }, - single: { - type: "Assaulter", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Assassin", - origin: "arras.io", - updateadded: "1.0", - }, - predator: { - type: "Ranger-Stacker", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "Scope", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Hunter", - origin: "diep.io", - updateadded: "1.0", - }, - xHunter: { - type: "Ranger-Stacker", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "Heavy Scope", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Hunter", - origin: "arras.io", - updateadded: "2.7", - }, - dual: { - type: "Ranger-Stacker", - desc: "Hunter With Dual Barrels Similar To Twin", - tier: "4", - weapons: "Bullets", - abilities: "Scope", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Hunter", - origin: "arras.io", - updateadded: "1.2", - }, - musket: { - type: "Ranger-Assaulter", - desc: "Rifle With Dual Barrels Similar To Twin", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Rifle, Twiper", - origin: "arras.io", - updateadded: "2.2", - }, - crossbow: { - type: "Ranger-Assaulter", - desc: "Rifle With Added Mini Barrels", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Rifle", - origin: "arras.io", - updateadded: "2.2", - }, - minigun: { - type: "Spammer", - desc: "3 Stacked Barrels Firing Very Fast", - tier: "3", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Sniper, Machine Gun, Subduer", - origin: "arras.io", - updateadded: "1.0", - }, - gunner: { - type: "Spammer", - desc: "", - tier: "3", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Twin, Machine Gun", - origin: "diep.io", - updateadded: "1.0", - }, - sprayer: { - type: "Spammer", - desc: "", - tier: "3", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Machine Gun, Subduer", - origin: "diep.io", - updateadded: "1.0", - }, - streamliner: { - type: "Spammer", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Minigun", - origin: "diep.io", - updateadded: "1.0", - }, - barricade: { - type: "Defense-Spammer", - desc: "", - tier: "4", - weapons: "Bullets", - abilities: "N/A", - weak: "N/A", - upgradesto: ["Tier 2: ", - "Tier 3: ", - "Tier 4: ", - "Misc: "], - upgradesfrom: "Trapper, Minigun", - origin: "arras.io", - updateadded: "2.6", - } -}; -export { tankdescs } \ No newline at end of file diff --git a/public/lib/util.js b/public/lib/util.js index 2e26ececb..d0b93dad3 100644 --- a/public/lib/util.js +++ b/public/lib/util.js @@ -11,17 +11,6 @@ const util = { document.getElementById(name).checked = localStorage.getItem(name + 'Checked') === 'true'; return false; }, - submitAchievementToLocalStorage: achive => { - localStorage.setItem(achive, "YOUDIDIT:D!!!"); - return false; - }, - resetAchievementFromLocalStorage: achive => { - localStorage.setItem(achive, "noachievement"); - return false; - }, - getTankWikiStats: name => { - return name; - }, handleLargeNumber: (a, cullZeroes = false) => { if (cullZeroes && a == 0) { return ''; @@ -210,7 +199,6 @@ const util = { facing: mainMockup.facing, shape: mainMockup.shape, name: name.substring(1), - className: mainMockup.className, upgradeTooltip: upgradeTooltip.substring(1), upgradeName: mainMockup.upgradeName, score: 0, @@ -258,8 +246,9 @@ const util = { }), }; }, - sizeMultipleMockups: (positionData) => { + sizeMultipleMockups: (positionData) => { let endPoints = []; + function rounder(val) { if (Math.abs(val) < 0.00001) val = 0; return +val.toPrecision(6); @@ -301,6 +290,7 @@ const util = { // Check point is on the line with a small margin return Math.abs(checkPoint[1] - predictedY) <= 1e-5; } + // Find circumcircle and circumcenter function constructCircumcirle(point1, point2, point3) { // Rounder to avoid floating point nonsense @@ -310,6 +300,7 @@ const util = { let y2 = rounder(point2[1]); let x3 = rounder(point3[0]); let y3 = rounder(point3[1]); + // Invalid math protection if (x3 == x1 || x3 == x2) { x3 += 1e-5; @@ -324,6 +315,7 @@ const util = { let y = (numer1 * factorX1 - numer2 * factorX2) / (factorY1 * factorX2 - factorY2 * factorX1); let x = ((y - y3) ** 2 - (y - y1) ** 2 - x1 ** 2 + x3 ** 2) / factorX2; let r = Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2)); + return {x, y, r}; } @@ -335,6 +327,7 @@ const util = { endPoints.push([middle.x + Math.cos(theta) * axis / 2, middle.y + Math.sin(theta) * axis / 2]); } } + // Convert to useful info endPoints.sort((a, b) => (b[0] ** 2 + b[1] ** 2 - a[0] ** 2 - a[1] ** 2)); let point1 = getFurthestFrom(0, 0), @@ -344,6 +337,7 @@ const util = { while (point1[0] == 0 && point2[0] == 0 || point1[1] == 0 && point2[1] == 0) { point2 = getFurthestFrom(...point1); } + let avgX = (point1[0] + point2[0]) / 2, avgY = (point1[1] + point2[1]) / 2, point3 = getFurthestFrom(avgX, avgY); @@ -354,6 +348,7 @@ const util = { } let {x, y, r} = constructCircumcirle(point1, point2, point3); + return { axis: r * 2, middle: {x, y}, diff --git a/public/main.css b/public/main.css index 18ecb7be6..43bd90677 100644 --- a/public/main.css +++ b/public/main.css @@ -1,8 +1,6 @@ :root { font-family: Ubuntu; font-size: 14px; - --backgroundColor: #DDE6EB; - --menuTextColor: #000000; } .conceal { @@ -10,7 +8,7 @@ } #mainBody { - background-color: #484848; + background-color: #dbdbdb; } ::-webkit-scrollbar { @@ -38,51 +36,29 @@ body { -moz-user-select: none; user-select: none; } + body { font-family: Ubuntu; font-size: 14px; - background-image: url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png?v=1713356636170"); - background-color: #484848; + background-image: url('./osa_background_tile.png'); + background-repeat: repeat; + background-color: gray; } html, body, -canvas[id=gameCanvas] { +canvas { width: 100%; height: 100%; margin: 0; padding: 0; } -canvas[id=gameCanvas] { +canvas { image-rendering: optimizeSpeed; image-rendering: pixelated; } -#content { - position: absolute; - top: 0; - left: 0; - background: #000000; - width: 100%; - height: 100%; -} - -canvas[id=musiccanvas] { - position: fixed; - left: 0; - top: 0; - width: 100%; - height: 100%; -} - -audio { - position: fixed; - left: 10px; - bottom: 10px; - width: calc(100% - 20px); -} - #gameName { padding: 0; margin-top: 5px; @@ -91,15 +67,7 @@ audio { font-size: xx-large; font-weight: bolder; } -#gameName:active { - padding: 0; - margin-top: 5px; - margin-bottom: 10px; - text-align: center; - font-size: xx-large; - font-weight: bolder; - animation:pfpDefault 800ms linear both; -} + h2 { font-size: small; color: #000000; @@ -117,24 +85,10 @@ options_header { text-align: center; } -miniupdate { - font-size: medium; - color: #000000; - font-weight: bold; - text-align: center; - font-size: 16px; - animation:pfpDefault 800ms linear both; -} - h3 { font-size: small; color: #484848; text-align: center; - animation:pfpDefault 800ms linear both; -} - -h3:hover { - animation:pfpDefault 800ms linear both; } h4 { @@ -185,20 +139,14 @@ input { } input.checkbox { - width: 15px; - height: 15px; + width: 13px; + height: 13px; padding: 0; margin: 0; vertical-align: bottom; position: relative; - top: -1px; + top: -2px; overflow: hidden; - font-family: Ubuntu; -} -input.checkbox:focus, -input.checkbox.focus { - border: none; - box-shadow: 0 0 0px 0px #DDDDDD; } #playerNameInput { @@ -209,7 +157,6 @@ input.checkbox.focus { #playerKeyInput { padding: 3px; color: gray; - } input:focus, @@ -258,7 +205,7 @@ div { margin: auto; width: 1150px; padding: 10px; - margin-top: 74px; + margin-top: 100px; margin-bottom: 100px; border-radius: 5px; -moz-border-radius: 5px; @@ -276,121 +223,14 @@ div { .startMenuHolder { width: 350px; - height: 365px; + height: 380px; padding: 10px; overflow: hidden; display: inline-block; vertical-align: text-top; } -.replace1 { -right: 0; -} -.replace2 { -right: -50; -} -a.menuTab { - float: right; - height: 13px; - font: 13px Ubuntu; - border-radius: 0px 0px 5px 5px; - padding: 6px 10px 7px 10px; - color: #FFFFFF !important; - text-decoration: none; - margin-right: 10px; -} -a.menuTab.discordbutton { - padding: 6px 10px 7px 28px; - border-bottom: 2px solid #6175ba; - box-shadow: inset 0 -2px #6175ba; - -webkit-box-shadow: inset 0 -2px #6175ba; - animation:pfpDefault 800ms linear both; - background: #7289DA url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/svg0.svg") 4px 3px/21px no-repeat; -} -a.menuTab.discordbutton:active, -a.menuTab.discordbutton:hover { - outline: none; - -webkit-box-shadow: none; - box-shadow: none; -} -a.menuTab.catto { - background: #FF0000 url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/coder.png") 8px 6px no-repeat; - padding: 6px 10px 7px 28px; - border-bottom: 2px solid #c91a1a; - box-shadow: inset 0 -2px #c91a1a; - -webkit-box-shadow: inset 0 -2px #c91a1a; - animation:pfpDefault 800ms linear both; -} -a.menuTab.catto:active, -a.menuTab.catto:hover { - outline: none; - -webkit-box-shadow: none; - box-shadow: none; -} -a.menuTab.ach { - background: #2bab2f url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png?v=1708025693434") 3px 2px/23px no-repeat; - padding: 6px 10px 7px 28px; - border-bottom: 2px solid #2a802d; - box-shadow: inset 0 -2px #2a802d; - -webkit-box-shadow: inset 0 -2px #2a802d; - animation:pfpDefault 800ms linear both; -} -a.menuTab.ach:active, -a.menuTab.ach:hover { - top: 1px; - outline: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -a.menuTab.skin { - background: #9900FF url("https://cdn.glitch.global/9b9522e6-a4f4-4511-8978-4c190b6759bd/stick.png?v=1708440293253") 3px 2px/23px no-repeat; - padding: 6px 10px 7px 28px; - border-bottom: 2px solid #7b11c2; - box-shadow: inset 0 -2px #7b11c2; - -webkit-box-shadow: inset 0 -2px #7b11c2; - animation:pfpDefault 800ms linear both; -} -a.menuTab.skin:active, -a.menuTab.skin:hover { - top: 1px; - outline: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -a.menuTab.stat { - background: #1E8449 url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/play.png") 3px 2px/23px no-repeat; - padding: 6px 10px 7px 28px; - border-bottom: 2px solid #156637; - box-shadow: inset 0 -2px #156637; - -webkit-box-shadow: inset 0 -2px #156637; - animation:pfpDefault 800ms linear both; -} -a.menuTab.stat:active, -a.menuTab.stat:hover { - top: 1px; - outline: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -a.menuTab.??? { - background: #FFFFFF url("https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/2022_06_23_11e_Kleki.png?v=1675997243695") 3px 2px/23px no-repeat; - padding: 6px 10px 7px 28px; - animation:pfpDefault 800ms linear both; -} -a.menuTab:link:hover, a.menuTab:visited:hover { - text-decoration: underline; - animation:pfpHoverOn 800ms linear both; -} .sliderHolder { - width: 350px; - height: 323px; - overflow: hidden; -} - -.sliderHolder2 { width: 350px; height: 325px; overflow: hidden; @@ -408,7 +248,6 @@ td { table { width: 100%; - color: black; } .slider { @@ -419,97 +258,23 @@ table { -moz-transition: top 500ms; -o-transition: top 500ms; transition: top 500ms; - animation:pfpDefault 800ms linear both; - transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1.2) -} - -.slider2 { - position: relative; - right: 0px; - width: 100%; - z-index: 0; - display: inline-block; - -webkit-transition: right 1000ms; - -moz-transition: right 1000ms; - -o-transition: right 1000ms; - transition: right 1000ms; - animation:pfpDefault 800ms linear both; - transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1) -} -.slider3 { - position: absolute; - z-index: -6; - right: 400px; - width: 100%; - display: inline-block; - -webkit-transition: right 1000ms; - -moz-transition: right 1000ms; - -o-transition: right 1000ms; - transition: right 1000ms; - animation:pfpDefault 800ms linear both; - transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1) -} - -.slidingtrigger3 { - position: relative; - top: 0px; - width: 100%; - -webkit-transition: top 500ms; - -moz-transition: top 500ms; - -o-transition: top 500ms; - transition: top 500ms; } #startMenuSlidingContent { - height: 300px; + height: 305px; } #startMenuSlidingTrigger { cursor: pointer; height: 15px; } -#startMenuSlidingTrigger:hover { - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); -} -#startMenuSlidingTrigger:active > h3 { - color: #323232; - animation:pfpDefault 800ms linear both; -} - -#startMenuSlidingTrigger:hover > h3 > i.arrow { - border-color: #323232; -} - -#startMenuSlidingTrigger2 { - cursor: pointer; -} -#startMenuSlidingTrigger2:hover { - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); -} -#startMenuSlidingTrigger2:active > h3 { - color: #323232; - animation:pfpDefault 800ms linear both; -} -#startMenuSlidingTrigger2:hover > h3 > i.arrow { - border-color: #323232; -} -#startMenuSlidingTrigger3 { - cursor: pointer; - height: 15px; -} -#startMenuSlidingTrigger3:hover { +#startMenuSlidingTrigger:hover { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); } -.menuTabs { - height: 26px; - margin: 0 8px; -} update { color: #D83848; - animation:pfpDefault 800ms linear both; - font-weight: bold; } @@ -517,56 +282,16 @@ update { padding-left: 10px; font-size: x-large; font-weight: bold; - text-align: justify; + text-align: center; } .shrinkable { padding-left: 0px; width: 360px; } -#credits { - max-width: 330px; - /*animation:pfpDefault 800ms linear both;*/ - height: calc(100% - 100px); - padding: 5px 20px 10px; - overflow: hidden auto; - scrollbar-width: thin; - scrollbar-color: rgba(0, 0, 0, 0.3) rgba(0, 0, 0, 0.15); -} - -#credits div { - > .title { - margin: 0; - font-size: 1.5em; - font-weight: bold; - } - - > date { - color: rgba(0, 0, 0, 0.45); - font-style: italic; - } - - > ul li { - margin-left: 1em; - margin-bottom: .5em; - } - - position: relative; - /*animation:pfpDefault 800ms linear both;*/ - - &::before { - content: ''; - position: absolute; - bottom: 0; - width: 100%; - height: .1em; - background-color: gray; - } -} #patchNotes { max-width: 330px; - /*animation:pfpDefault 800ms linear both;*/ height: calc(100% - 100px); padding: 5px 20px 10px; overflow: hidden auto; @@ -579,8 +304,8 @@ update { margin: 0; font-size: 1.5em; font-weight: bold; - } - + } + > date { color: rgba(0, 0, 0, 0.45); font-style: italic; @@ -592,7 +317,6 @@ update { } position: relative; - /*animation:pfpDefault 800ms linear both;*/ &::before { content: ''; @@ -627,12 +351,10 @@ update { height: 40px; box-sizing: border-box; font-size: larger; - line-height: 0; color: white; - animation:pfpDefault 800ms linear both; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); - background: #335099; + background: #336699; /*background: #A9D86D;*/ border: 0; border-bottom: 2px solid #1B3353; @@ -647,79 +369,14 @@ update { -webkit-border-radius: 5px; } -#hideongamestart { - position: relative; - z-index: 3; - } - -#resetachievementsbutton { - font-family: Ubuntu; - line-height: 0; - top: 30px; - width: 100%; - height: 40px; - max-height: 100px; - top: 443px; - z-index: 3; - color: white; - animation:pfpDefault 800ms linear both; - text-align: center; - text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); - background: #70b5ff; - font-family: Ubuntu; - position: relative; - border: 0; - border-bottom: 2px solid #1B3353; - cursor: pointer; - -webkit-box-shadow: inset 0 -2px #1B3353; - box-shadow: inset 0 -2px #1B3353; - border-radius: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; - float: left; -} - -.icon { - animation:pfpDefault 800ms linear both; -} - -.icon:hover { - animation:pfpHoverOn 800ms linear both; -} - -.icon:active { - animation:pfpDefault 400ms linear both; -} - #startButton:active, #startButton:hover { top: 1px; - background: #335099; - /*background: #A9D86D;*/ - border: 0; - border-bottom: 3px solid #1B3353; - /*background: #1B3353;*/ + background: #1B3353; /*background: #8ABC3F;*/ - line-height: 25px; - text-align: center; outline: none; -webkit-box-shadow: none; box-shadow: none; - height: 39px; -} - -#resetachievementsbutton:active, -#resetachievementsbutton:hover { - line-height: 25px; - text-align: center; - outline: none; - -webkit-box-shadow: none; - box-shadow: none; - height: 39px; - border: 0; - border-bottom: 3px solid #1B3353; - top: 444px; - } #bottomHolder { @@ -747,132 +404,108 @@ a.link { } .discord { - top: 2px; - animation:pfpDefault 800ms linear both; background: #7289da; - line-height: 15px; border-bottom: 2px solid #6175ba; box-shadow: inset 0 -2px #6175ba; -webkit-box-shadow: inset 0 -2px #6175ba; } .discord:active, .discord:hover { - top: 3px; - background: #7289da; + top: 1px; + background: #6175ba; outline: none; - height: 85%; - line-height: 15px; - border-bottom: 1px solid #6175ba; - box-shadow: inset 0 -2px #6175ba; - -webkit-box-shadow: inset 0 -2px #6175ba; + -webkit-box-shadow: none; + box-shadow: none; +} + +.revolt { + background: #fd6671; + border-bottom: 2px solid #ed4245; + box-shadow: inset 0 -2px #ed4245; + -webkit-box-shadow: inset 0 -2px #ed4245; +} +.revolt:active, +.revolt:hover { + top: 1px; + background: #ed4245; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; } .reddit { - top: 2px; - animation:pfpDefault 800ms linear both; background: #f75401; - line-height: 15px; border-bottom: 2px solid #d24a01; box-shadow: inset 0 -2px #d24a01; -webkit-box-shadow: inset 0 -2px #d24a01; } - .reddit:active, .reddit:hover { - top: 3px; - background: #f75401; + top: 1px; + background: #d24a01; outline: none; - height: 85%; - line-height: 15px; - border-bottom: 1px solid #d24a01; - box-shadow: inset 0 -2px #d24a01; - -webkit-box-shadow: inset 0 -2px #d24a01; + -webkit-box-shadow: none; + box-shadow: none; } .original { - top: 2px; - animation:pfpDefault 800ms linear both; background: #77bf79; - line-height: 15px; border-bottom: 2px solid #679c68; box-shadow: inset 0 -2px #679c68; -webkit-box-shadow: inset 0 -2px #679c68; } - .original:active, .original:hover { - top: 3px; - background: #77bf79; + top: 1px; + background: #679c68; outline: none; - height: 85%; - line-height: 15px; - border-bottom: 1px solid #679c68; - box-shadow: inset 0 -2px #679c68; - -webkit-box-shadow: inset 0 -2px #679c68; + -webkit-box-shadow: none; + box-shadow: none; } .developer { - top: 2px; - animation:pfpDefault 800ms linear both; background: #454b7f; - line-height: 15px; border-bottom: 2px solid #313454; box-shadow: inset 0 -2px #313454; -webkit-box-shadow: inset 0 -2px #313454; } .developer:active, .developer:hover { - top: 3px; - background: #454b7f; + top: 1px; + background: #313454; outline: none; - height: 85%; - line-height: 15px; - border-bottom: 1px solid #313454; - box-shadow: inset 0 -2px #313454; - -webkit-box-shadow: inset 0 -2px #313454; + -webkit-box-shadow: none; + box-shadow: none; } .youtube { - top: 2px; - animation:pfpDefault 800ms linear both; background: #f71701; - line-height: 15px; border-bottom: 2px solid #d21401; box-shadow: inset 0 -2px #d21401; -webkit-box-shadow: inset 0 -2px #d21401; } - .youtube:active, .youtube:hover { - top: 3px; - background: #f71701; + top: 1px; + background: #d21401; outline: none; - height: 85%; - line-height: 15px; - border-bottom: 1px solid #d21401; - box-shadow: inset 0 -2px #d21401; - -webkit-box-shadow: inset 0 -2px #d21401; + -webkit-box-shadow: none; + box-shadow: none; } .github { - top: 2px; - animation:pfpDefault 800ms linear both; background: #666666; - line-height: 15px; border-bottom: 2px solid #333333; - box-shadow: inset 0 -2px #333333; -webkit-box-shadow: inset 0 -2px #333333; + box-shadow: inset 0 -2px #333333; } .github:active, .github:hover { - top: 3px; - background: #666666; + top: 1px; + background: #333333; outline: none; - height: 85%; - line-height: 15px; - border-bottom: 1px solid #333333; - box-shadow: inset 0 -2px #333333; - -webkit-box-shadow: inset 0 -2px #333333; + -webkit-box-shadow: none; + box-shadow: none; } #startMenuWrapper { @@ -932,17 +565,6 @@ a.link { color: black; background-color: #ffffff88; } -p.vsaucereference { - animation:pfpHoverOn 400ms linear both; - font-size: 13px; -} -p.vsaucereference:hover { - animation:pfpHoverOn 400ms linear both; -} - -p.vsaucereference:active { - animation: pfpDefault 800ms linear both; -} input [type="image"]:focus { border: none; @@ -953,700 +575,4 @@ input [type="image"]:focus { *:focus { outline: 1px solid transparent; border-style: none; -} -.popup { - position: absolute; - display: block; - width: auto; - max-width: 42%; - height: auto; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - z-index: 3; - border-radius: 10px; - background: var(--backgroundColor); - padding: 10px; - font-size: larger; - text-align: center; - border-style: solid; - border-color: #c1cfd8; - color: var(--menuTextColor); -} - -.popup button { - margin: 15px; - padding: 10px 50px 10px 50px; - width: auto; - box-sizing: border-box; - color: white; - text-align: center; - text-shadow: 0 0 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.2); - background: #A9D86D; - border: 0; - border-bottom: 2px solid #8ABC3F; - cursor: pointer; - box-shadow: inset 0 -2px #8ABC3F; - border-radius: 5px; - font: 18px Ubuntu; -} - -.popup button:hover { - border-bottom: 1px solid #8ABC3F; -} - -.popup button:active { - background: #FFFFFF; - border-bottom: 0; - outline: none; - box-shadow: none; -} - -.popup span.small { - font-size: xx-large; - font-weight: bold; - color: black; - white-space: pre-line; -} - -.popup span { - font-size: x-large; - white-space: pre-line; - font-weight: light; - color: black; -} -.achievementsHolder { - position: absolute; - display: block; - width: 700px; - height: 550px; - padding-top: 50px; - top: 47.5%; - left: 50%; - transform: translate(-50%, -50%); - z-index: 3; - background: var(--backgroundColor); - padding: 10px; - font-size: larger; - text-align: center; - border-style: solid; - border-color: #c1cfd8; - color: black; - display: none; -} - -.achievementsHolder span.small { - font-size: xx-large; - font-weight: bold; - color: black; - animation:pfpDefault 800ms linear both; -} - -.achievementsHolder span { - font-size: x-large; - font-weight: lighter; - color: black; - animation:pfpDefault 800ms linear both; -} - -#achievementsClose { - height: 45px; - width: 50px; - float: right; - position: relative; - opacity: .8; - background-image: url('data:image/svg+xml,%3Csvg xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" fill%3D"%23DD0000" viewBox%3D"0 0 16 16" width%3D"30" height%3D"30"%3E%3Cpath d%3D"M3 0 0 3 6 8 0 13 3 16 8 10 13 16 16 13 10 8 16 3 13 0 8 6 3 0Z"%3E%3C%2Fpath%3E%3C%2Fsvg%3E'); - background-repeat: no-repeat; - background-position: center; -} - -#achievementsClose:hover { - cursor: pointer; - opacity: 1; -} - -#achievementsDisplay { - height: 450px; - margin-top: -20px; - position: absolute; - animation:pfpDefault 800ms linear both; - width: 96.5%; - border-style: solid; - border-color: #c1cfd8; - background-color: rgba(0, 0, 0, 0.2); - background: url("https://cdn.glitch.global/ded4b664-3b74-4a3b-9282-9796baafc60b/41R6Ok5aeKL.jpg?v=1713446403687") 0px -550px/100% repeat; -} - -.achievementsItem { - margin: 16px 16px 12px 16px; - border-radius: 14px; - animation:pfpDefault 800ms linear both; - padding: 6px; - -} - -.achievementsItem h1 { - font-size: 22px; - animation:pfpDefault 800ms linear both; - font-weight: bold; - color: #22160b; -} - -.achievementsItem span { - font-size: 17px; - font-weight: bold; - animation:pfpDefault 800ms linear both; - color: #22160b; -} - -.greenachievement { - background-color: rgb(138, 187, 68); -} - -.greyachievement { - background-color: rgb(159, 159, 159); -} - -.bleenachievement { - background-color: rgb(125, 195, 235); -} - -.grueachievement { - background-color: rgb(160, 170, 180); -} - -#achievementsStatsTable td { - animation:pfpDefault 800ms linear both; - font-size: 18px; -} - -#achievementsStatsTable tr b { - animation:pfpDefault 800ms linear both; - font-size: 22px; -} -.autoBorder { - display: block; - border: 3.5px solid rgba(0, 0, 0, 0.35); -} -.metasip { - height: 10px; - width: 10px; - background-image: "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/svg0.svg" -} -#wikiTankThing { - display: none; - position: absolute; - top: 58.5vh; - left: 40%; - z-index: 5; - width: 20%; -} -.skinHolder { - position: absolute; - display: block; - width: 650px; - height: 600px; - top: 47.5%; - left: 50%; - transform: translate(-50%, -50%); - z-index: 3; - background: var(--backgroundColor); - padding: 10px; - font-size: larger; - text-align: center; - border-style: solid; - border-color: #c1cfd8; - color: black; - display: none; -} - -.skinHolder span.small { - font-size: xx-large; - font-weight: bold; - color: black; - animation:pfpDefault 800ms linear both; -} - -.skinHolder span { - font-size: x-large; - font-weight: light; - color: black; - animation:pfpDefault 800ms linear both; -} - -#skinClose { - height: 45px; - width: 50px; - float: right; - position: relative; - opacity: .8; - background-image: url('data:image/svg+xml,%3Csvg xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" fill%3D"%23DD0000" viewBox%3D"0 0 16 16" width%3D"30" height%3D"30"%3E%3Cpath d%3D"M3 0 0 3 6 8 0 13 3 16 8 10 13 16 16 13 10 8 16 3 13 0 8 6 3 0Z"%3E%3C%2Fpath%3E%3C%2Fsvg%3E'); - background-repeat: no-repeat; - background-position: center; -} - -#skinClose:hover { - cursor: pointer; - opacity: 1; -} - -#skinDisplay { - height: 448px; - margin-top: -20px; - position: absolute; - animation:pfpDefault 800ms linear both; - width: 96.5%; - border-style: solid; - border-color: #c1cfd8; - background-color: rgba(0, 0, 0, 0.2); -} - -.skinItem { - margin: 16px 16px 12px 16px; - border-radius: 14px; - animation:pfpDefault 800ms linear both; - padding: 6px; - -} - -.skinItem h1 { - font-size: 22px; - animation:pfpDefault 800ms linear both; - font-weight: light; - color: #22160b; -} - -.skinItem span { - font-size: 17px; - font-weight: bold; - animation:pfpDefault 800ms linear both; - color: #22160b; -} - -#leftarrowbutton { - position: relative; - float: left; - height: 20%; - width: 20%; -} -#rightarrowbutton { - position: relative; - float: right; - height: 20%; - width: 20%; -} -#leftarrowbutton:active { - animation:pfpDefault 800ms linear both; -} -#rightarrowbutton:active { - animation:pfpDefault 800ms linear both; -} -.displaytest { - top: 0; - position: relative; - text-align: center; - margin-left: auto; - margin-right: auto; - margin-top: auto; -} -.displayskinname { - top: -2%; - position: relative; -} -#skinpdiv { - top: -3%; - position: relative; - margin-left: auto; - margin-right: auto; - width: 50%; -} -#skinpreview { - vertical-align: bottom; - width: 100%; - height: 100%; - z-index: 3; - -} -#selectskin { - vertical-align: bottom; - float: center; - margin-left: auto; - margin-right: auto; - height: 130px; - width: 260px; - z-index: 3; -} -#lockedskin { - display: none; - width: 100%; - height: 100%; - top: 0; - left: 0; - position: absolute; - z-index: 3; -} -#lockbg { - display: inline-block; - width: 100%; - height: 100%; - top: 0; - left: 0; - position: absolute; - opacity: 0.4; - z-index: -5; -} -#eventtitle { - position: absolute; - float: center; - top: 10%; - left: 50%; - color: white; - outline: #000000 solid; - z-index: 0; - cursor: pointer; - text-shadow: -1px -1px 0 #000000, 1px -1px 0 #000000, -1px 1px 0 #000000, 1px 1px 0 #000000; - background: #202020 url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/channels4_profile.jpg?v=1709324207088") 0px 0px/100px repeat; -} -.horizontalSelector { - padding: 4px 0; - margin-bottom: 4px; - font: bold 12px Ubuntu; - text-align: center; -} -.horizontalSelector span { - padding: 4px 10px; - color: #343434; - cursor: pointer; -} -.horizontalSelector span:hover { - color: #5f5f5f; -} -.horizontalSelector span.active { - background: #335099; - color: #ffffff; - border-radius: 5px; - cursor: default; -} -.tabappearance { - display: block; -} -.taboptions { - display: none; -} -.tabcontrols { - display: none; -} -.tablinks { - display: none; -} -#controls { - height: 200px; -} -.animpop { - animation:pfpDefault 800ms linear both; -} -.animinvert { - animation:invertation 2s linear both; - -webkit-animation-timing-function: linear; - animation-timing-function: linear; -} -.incog:active { - animation:wack2 2s linear 3; - -webkit-animation-timing-function: linear; - animation-timing-function: linear -} -.popuptaskbar { - display: block; - position: relative; - height: 50px; - width: 102.8%; - left: -10px; - top: -32px; - background: #2bab2f url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png?v=1708025693434") 0px 0px/50px no-repeat; -} -#achievementsHeader { - padding: 5px; - text-align: left; - margin-left: 50px; - color: #FFFFFF -} -.popuptaskbar2 { - display: block; - position: relative; - height: 50px; - width: 102.8%; - left: -10px; - top: -32px; - background: #9900FF url("https://cdn.glitch.global/9b9522e6-a4f4-4511-8978-4c190b6759bd/stick.png?v=1708440293253") 0px 0px/50px no-repeat; -} -#skinHeader { - padding: 5px; - text-align: left; - margin-left: 50px; - color: #FFFFFF -} -.atthebottom { - position: relative; - top: 425px; -} - -@keyframes pfpHoverOn { - 0% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 3.4% { transform: matrix3d(1.032, 0, 0, 0, 0, 1.041, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 4.7% { transform: matrix3d(1.045, 0, 0, 0, 0, 1.06, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 6.81% { transform: matrix3d(1.066, 0, 0, 0, 0, 1.089, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 9.41% { transform: matrix3d(1.088, 0, 0, 0, 0, 1.117, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 10.21% { transform: matrix3d(1.094, 0, 0, 0, 0, 1.123, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 13.61% { transform: matrix3d(1.112, 0, 0, 0, 0, 1.133, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 14.11% { transform: matrix3d(1.114, 0, 0, 0, 0, 1.133, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 17.52% { transform: matrix3d(1.121, 0, 0, 0, 0, 1.124, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 18.72% { transform: matrix3d(1.121, 0, 0, 0, 0, 1.119, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 21.32% { transform: matrix3d(1.12, 0, 0, 0, 0, 1.107, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 24.32% { transform: matrix3d(1.115, 0, 0, 0, 0, 1.096, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 25.23% { transform: matrix3d(1.113, 0, 0, 0, 0, 1.094, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 29.03% { transform: matrix3d(1.106, 0, 0, 0, 0, 1.09, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 29.93% { transform: matrix3d(1.105, 0, 0, 0, 0, 1.09, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 35.54% { transform: matrix3d(1.098, 0, 0, 0, 0, 1.096, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 36.74% { transform: matrix3d(1.097, 0, 0, 0, 0, 1.098, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 41.04% { transform: matrix3d(1.096, 0, 0, 0, 0, 1.102, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 44.44% { transform: matrix3d(1.097, 0, 0, 0, 0, 1.103, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 52.15% { transform: matrix3d(1.099, 0, 0, 0, 0, 1.101, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 59.86% { transform: matrix3d(1.101, 0, 0, 0, 0, 1.099, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 63.26% { transform: matrix3d(1.101, 0, 0, 0, 0, 1.099, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 75.28% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 85.49% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 90.69% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 100% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } -} - -@keyframes pfpDefault { - 0% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 3.4% { transform: matrix3d(1.068, 0, 0, 0, 0, 1.059, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 4.7% { transform: matrix3d(1.055, 0, 0, 0, 0, 1.04, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 6.81% { transform: matrix3d(1.034, 0, 0, 0, 0, 1.011, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 9.41% { transform: matrix3d(1.012, 0, 0, 0, 0, 0.983, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 10.21% { transform: matrix3d(1.006, 0, 0, 0, 0, 0.977, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 13.61% { transform: matrix3d(0.988, 0, 0, 0, 0, 0.967, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 14.11% { transform: matrix3d(0.986, 0, 0, 0, 0, 0.967, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 17.52% { transform: matrix3d(0.979, 0, 0, 0, 0, 0.976, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 18.72% { transform: matrix3d(0.979, 0, 0, 0, 0, 0.981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 21.32% { transform: matrix3d(0.98, 0, 0, 0, 0, 0.993, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 24.32% { transform: matrix3d(0.985, 0, 0, 0, 0, 1.004, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 25.23% { transform: matrix3d(0.987, 0, 0, 0, 0, 1.006, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 29.03% { transform: matrix3d(0.994, 0, 0, 0, 0, 1.01, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 29.93% { transform: matrix3d(0.995, 0, 0, 0, 0, 1.01, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 35.54% { transform: matrix3d(1.002, 0, 0, 0, 0, 1.004, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 36.74% { transform: matrix3d(1.003, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 41.04% { transform: matrix3d(1.004, 0, 0, 0, 0, 0.998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 44.44% { transform: matrix3d(1.003, 0, 0, 0, 0, 0.997, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 52.15% { transform: matrix3d(1.001, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 59.86% { transform: matrix3d(0.999, 0, 0, 0, 0, 1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 63.26% { transform: matrix3d(0.999, 0, 0, 0, 0, 1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 75.28% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 85.49% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 90.69% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } - 100% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } -} -@keyframes invertation { - 0% { - background-color: black; - color: white; - } - - 50% { - background-color: white; - -webkit-filter: invert(1); - filter: invert(1); - } -} -@keyframes wack { - 25% { - transform: scale(1, 5); - } - 75% { - transform: scale(5, 1) - } -} -@keyframes wack2 { - 20% { - transform: scale(100, 5); - } - 40% { - transform: scale(2, 10) - } - 60% { - transform: scale(0.2, 15); - } - 80% { - transform: scale(-10, 6) - } - 100% { - transform: scale(-3, -1) - } -} -@keyframes flashing { - 0% { - background-color: black; - color: white; - -webkit-filter: invert(0); - filter: invert(0); - } - 5% { - background-color: black; - -webkit-filter: invert(1); - filter: invert(1); - } - 10% { - background-color: red; - color: white; - -webkit-filter: invert(0); - filter: invert(0); - } - 15% { - background-color: red; - -webkit-filter: invert(1); - filter: invert(1); - } - 20% { - background-color: black; - color: white; - -webkit-filter: invert(0); - filter: invert(0); - } - 25% { - background-color: black; - -webkit-filter: invert(1); - filter: invert(1); - } - 30% { - background-color: white; - color: white; - -webkit-filter: invert(0); - filter: invert(0); - } - 35% { - background-color: white; - -webkit-filter: invert(1); - filter: invert(1); - } - 40% { - background-color: red; - color: white; - -webkit-filter: invert(0); - filter: invert(0); - - } - 45% { - background-color: black; - } - 50% { - background-color: orange; - color: white; - } - 55% { - background-color: white; - } - 60% { - background-color: yellow; - } - 65% { - background-color: black; - } - 70% { - background-color: green; - } - - 75% { - background-color: white; - } - 80% { - background-color: blue; - } - 85% { - background-color: black; - } - 90% { - background-color: purple; - } - 95% { - background-color: white; - } -} -@keyframes pop { - 0% { - transform: scale(1, 1); - } - 5% { - transform: scale(0.9, 0.9); - } - 10% { - transform: scale(0.8, 0.8); - } - 15% { - transform: scale(0.7, 0.7); - } - 20% { - transform: scale(0.6, 0.6); - } - 25% { - transform: scale(0.5, 0.5); - } - 30% { - transform: scale(0.4, 0.4); - } - 35% { - transform: scale(0.3, 0.3); - } - 40% { - transform: scale(0.2, 0.2); - } - 45% { - transform: scale(0.1, 0.1); - } - 50% { - transform: scale(0, 0); - } - 55% { - transform: scale(0.1, 0.1); - } - 60% { - transform: scale(0.2, 0.2); - } - 65% { - transform: scale(0.3, 0.3); - } - 70% { - transform: scale(0.4, 0.4); - } - 75% { - transform: scale(0.5, 0.5); - } - 80% { - transform: scale(0.6, 0.6); - } - 85% { - transform: scale(0.7, 0.7); - } - 90% { - transform: scale(0.8, 0.8); - } - 95% { - transform: scale(0.9, 0.9); - } -} -@keyframes movedown { - 0% { - padding: 6px 10px 7px 28px; - } - 100% { - padding: 6px 10px 70px 28px; - } -} -@keyframes moveup { - 0% { - transform: translatey(100px); - } - 100% { - transform: translatey(0px); - } } \ No newline at end of file diff --git a/public/osa_background_tile.png b/public/osa_background_tile.png new file mode 100644 index 0000000000000000000000000000000000000000..1266bc53d30cd59b94ef59271561b93664c7634d GIT binary patch literal 748 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 LBMqdQGyMMm(j~<0 literal 0 HcmV?d00001 diff --git a/public/run.bat b/run.bat similarity index 100% rename from public/run.bat rename to run.bat diff --git a/server/config.js b/server/config.js index 03c7fe9aa..893ebd919 100644 --- a/server/config.js +++ b/server/config.js @@ -3,10 +3,10 @@ module.exports = { // Game server domain. // If 'localhost:NUMBER', the port must equal the port setting. - host: "neroio2.glitch.me", + host: "localhost:26301", // Which port to run the web server on. - port: 3000, + port: 26301, // How often to update the list of the entities that players can see. // Has effects of when entities are activated. @@ -17,25 +17,25 @@ module.exports = { // Flatten entity definition, which gets rid of PARENT attributes and applies the parents' attributes to the entity definition, if they're not set in the entity already. flattenDefintions: false, - + // Log speed loop warnings LOGS: true, // The \modules\setup\gamemodeconfigs\ files to load. // To change specific things about specific gamemodes (such as team count for tdm), edit their config file in \modules\setup\gamemodeconfigs\. - GAME_MODES: ['ffa'], + GAME_MODES: ['tdm', 'domination'], // The room files to load in the setup/rooms folder. // NOTE: If a /gamemodeconfig/ file "replaces" the value of ROOM_SETUP, it just adds its own ROOM_SETUP's content to this array. // NOTE: Files starting with `map_` are maps. files starting with `overlay_` are overlays that get added on. // NOTE: These prefixes are only for categorisation, a room file would work the same regardless of its prefix. APS++ does nothing based on file name prefixes. - ROOM_SETUP: ['map_neroio_mazearena'], + ROOM_SETUP: ['map_apspp_default'], // The dimensions of a single tile on the map. - TILE_WIDTH: 200, //400 - TILE_HEIGHT: 200, //400 - - + TILE_WIDTH: 400, + TILE_HEIGHT: 400, + + // Miscellaneous @@ -45,43 +45,43 @@ module.exports = { // If you don't want your players to color their messages. // They get sanitized after addons interpret them, but before they're added to the chat message dictionary. - SANITIZE_CHAT_MESSAGE_COLORS: false, + SANITIZE_CHAT_MESSAGE_COLORS: true, // If someone tries to get a file that does not exist, send them this instead. DEFAULT_FILE: 'index.html', // Window name of the server terminal. - WINDOW_NAME: 'Nero Game Server Instance', + WINDOW_NAME: 'OSA Game Server Instance', // Allows you to type and run javascript code in the terminal. REPL_WINDOW: false, // Welcome message once a player spawns. - WELCOME_MESSAGE: "You have spawned! Welcome to the game, Hold N To Level Up.\n" - +"You will be invulnerable until you move or shoot OR ACCIDENTALLY PRESS THE FUCKING SPACE BAR.\n" - +"Please report any bugs you encounter on our discord! :)", - + WELCOME_MESSAGE: "You have spawned! Welcome to the game.\n" + +"You will be invulnerable until you move or shoot.\n" + +"Please report any bugs you encounter!", // How long a popup message lasts before fading out in milliseconds. MESSAGE_DISPLAY_TIME: 10_000, + // Physics // General multiplier for acceleration and max speeds. - runSpeed: 1.5, //1.5 + runSpeed: 1.5, // General damage multiplier everytime damage is dealt. - DAMAGE_CONSTANT: 0.5, // 0.5 + DAMAGE_CONSTANT: 0.5, // General knockback multiplier everytime knockback is applied. - KNOCKBACK_CONSTANT: 1.5, //1.5 + KNOCKBACK_CONSTANT: 1.5, // TODO: Figure out how the math behind this works. GLASS_HEALTH_FACTOR: 2, // How strong the force is that confines entities to the map and portals apply to entities. - ROOM_BOUND_FORCE: 0.01, //0.01 + ROOM_BOUND_FORCE: 0.01, @@ -111,20 +111,20 @@ module.exports = { LEVEL_CHEAT_CAP: 45, // Amount of player-bots to spawn. - BOTS: 6, + BOTS: 0, // How much XP player-bots get per second until they reach LEVEL_CAP. BOT_XP: 125, - + // How much XP player-bots will receive when first created. - BOT_START_XP: 26302, + BOT_START_XP: 0, // The chances of a player-bot upgrading a specific skill when skill upgrades are available. BOT_SKILL_UPGRADE_CHANCES: [ 1, 1, 3, 4, 4, 4, 4, 2, 1, 1], // The chances of a player-bot upgrading a specific amount of times before it stops upgrading. BOT_CLASS_UPGRADE_CHANCES: [ 1, 5, 20, 37, 37], - + // The prefix of the bot's name. BOT_NAME_PREFIX: "[AI] ", @@ -133,22 +133,22 @@ module.exports = { - // Natural Spawns + // Natural Spawns - FOOD_CAP: 1, // Max normal food per normal tile. 3 - FOOD_SPAWN_CHANCE: 0.1, // Likeliness of normal food spawn attempts succeedingg. 0.875 - FOOD_SPAWN_COOLDOWN: 60, // Cooldown (in game ticks) of food spawn attempts being made. 30 + FOOD_CAP: 3, // Max normal food per normal tile. + FOOD_SPAWN_CHANCE: 0.875, // Likeliness of normal food spawn attempts succeeding. + FOOD_SPAWN_COOLDOWN: 30, // Cooldown (in game ticks) of food spawn attempts being made. - FOOD_CAP_NEST: 1, // Max nest food per nest tile. 3 - FOOD_SPAWN_CHANCE_NEST: 0.1, // Likeliness of nest food spawn attempts succeeding. 0.25 - FOOD_SPAWN_COOLDOWN_NEST: 120, // Cooldown (in game ticks) of nest food spawn attempts being made. 45 + FOOD_CAP_NEST: 3, // Max nest food per nest tile. + FOOD_SPAWN_CHANCE_NEST: 0.25, // Likeliness of nest food spawn attempts succeeding. + FOOD_SPAWN_COOLDOWN_NEST: 45, // Cooldown (in game ticks) of nest food spawn attempts being made. - ENEMY_CAP_NEST: 0, // Max nest enemies per nest tile. 1 - ENEMY_SPAWN_CHANCE_NEST: 0.9, // Likeliness of nest enemies spawn attempts succeeding. 0.9 + ENEMY_CAP_NEST: 1, // Max nest enemies per nest tile. + ENEMY_SPAWN_CHANCE_NEST: 0.9, // Likeliness of nest enemies spawn attempts succeeding. ENEMY_SPAWN_COOLDOWN_NEST: 60, // Cooldown (in game ticks) of nest enemies spawn attempts being made. // Cooldown (in seconds) of boss spawns being announced. - BOSS_SPAWN_COOLDOWN: 1800, //120 + BOSS_SPAWN_COOLDOWN: 60, // The delay (in seconds) between the boss spawns being announced and the bosses actually spawning. // NOTE: The spawn message (ex. "A strange trembling...") takes half as long to appear than the boss. BOSS_SPAWN_DURATION: 5, diff --git a/server/index.js b/server/index.js index f565ea784..6358130c4 100644 --- a/server/index.js +++ b/server/index.js @@ -67,7 +67,6 @@ function collide(collision) { if (instance.type === "wall" && other.type === "wall") return; if (instance.type === "aura" || other.type === "aura") return; if (instance.type === "satellite" || other.type === "satellite") return; - if (instance.type === "shield" || other.type === "shield" || instance.type === "brella" || other.type === "brella") return; let wall = instance.type === "wall" ? instance : other; let entity = instance.type === "wall" ? other : instance; if (entity.ac || entity.master.ac) return; @@ -85,29 +84,6 @@ function collide(collision) { break; } break; - case instance.type === "shield" || other.type === "shield": - if (instance.type === "aura" || other.type === "aura" || instance.type === "satellite" || other.type === "satellite" || instance.type === "satellite" || other.type === "satellite" || instance.team === other.team) return; - let shield = instance.type === "shield" ? instance : other; - let nonshield = instance.type === "shield" ? other : instance; - switch (true) { - case (shield.shapeData == "m -0.7020 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099"): - mirrorcollide(shield, nonshield); - break; - default: - reflectcollide(shield, nonshield); - break; - } - break; - case instance.type === "brella" || other.type === "brella": - if (instance.type === "aura" || other.type === "aura" || instance.type === "satellite" || other.type === "satellite" || instance.type === "satellite" || other.type === "satellite" || instance.team === other.team) return; - let brella = instance.type === "brella" ? instance : other; - let nonbrella = instance.type === "brella" ? other : instance; - switch (true) { - default: - reflectcollide(brella, nonbrella); - break; - } - break; case instance.team === other.team && (instance.settings.hitsOwnType === "pushOnlyTeam" || other.settings.hitsOwnType === "pushOnlyTeam"): @@ -360,7 +336,7 @@ let maintainloop = () => { o.isBot = true; o.name = Config.BOT_NAME_PREFIX + ran.chooseBotName(); o.leftoverUpgrades = ran.chooseChance(...c.BOT_CLASS_UPGRADE_CHANCES); - let color = c.RANDOM_COLORS ? Math.floor(Math.random() * 20) : team ? getTeamColor(team) : "red"; + let color = c.RANDOM_COLORS ? Math.floor(Math.random() * 20) : team ? getTeamColor(team) : "darkGrey"; o.color.base = color; if (team) o.team = team; bots.push(o); @@ -391,4 +367,4 @@ setInterval(() => { } syncedDelaysLoop(); -}, room.cycleSpeed); \ No newline at end of file +}, room.cycleSpeed); diff --git a/server/lib/hshg.js b/server/lib/hshg.js index 3d6b7a59c..9374fdf4c 100644 --- a/server/lib/hshg.js +++ b/server/lib/hshg.js @@ -627,4 +627,4 @@ you never will because we fired you lol testAABBOverlap: testAABBOverlap, getLongestAABBEdge: getLongestAABBEdge, }; -})(this); \ No newline at end of file +})(this); diff --git a/server/lib/random.js b/server/lib/random.js index c1dc0672e..f8f61c765 100644 --- a/server/lib/random.js +++ b/server/lib/random.js @@ -91,17 +91,13 @@ exports.chooseChance = (...arg) => { } } -exports.chooseBotName = () => { - return exports.choose([ "Alice", "Bob", "Carmen", "David", "Edith", "Freddy", "Gustav", "Helga", "Janet", "Lorenzo", "Mary", "Nora", "Olivia", "Peter", "Queen", "Roger", "Suzanne", "Tommy", "Ursula", "Vincent", "Wilhelm", "Xerxes", "Yvonne", "Zachary", "Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Hotel", "India", "Juliet", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-Ray", "Yankee", "Zulu" ]) -} +exports.nameLists = { + bots: [ "Alice", "Bob", "Carmen", "David", "Edith", "Freddy", "Gustav", "Helga", "Janet", "Lorenzo", "Mary", "Nora", "Olivia", "Peter", "Queen", "Roger", "Suzanne", "Tommy", "Ursula", "Vincent", "Wilhelm", "Xerxes", "Yvonne", "Zachary", "Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Hotel", "India", "Juliet", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo", "Sierra", "Tango", "Uniform", "Victor", "Whiskey", "X-Ray", "Yankee", "Zulu" ], + a: [ "Archimedes", "Akilina", "Anastasios", "Athena", "Alkaios", "Amyntas", "Aniketos", "Artemis", "Anaxagoras", "Apollon" ], + castle: [ "Berezhany", "Lutsk", "Dobromyl", "Akkerman", "Palanok", "Zolochiv", "Palanok", "Mangup", "Olseko", "Brody", "Isiaslav", "Kaffa", "Bilhorod" ], + legion: [ "Vesta", "Juno", "Orcus", "Janus", "Minerva", "Ceres" ] +}; -exports.chooseBossName = code => { - switch (code) { - case "a": - return exports.choose([ "Archimedes", "Akilina", "Anastasios", "Athena", "Alkaios", "Amyntas", "Aniketos", "Artemis", "Anaxagoras", "Apollon" ]); - case "castle": - return exports.choose([ "Berezhany", "Lutsk", "Dobromyl", "Akkerman", "Palanok", "Zolochiv", "Palanok", "Mangup", "Olseko", "Brody", "Isiaslav", "Kaffa", "Bilhorod" ]); - case "legion": - return exports.choose([ "Vesta", "Juno", "Orcus", "Janus", "Minerva", "Ceres" ]); - } -} \ No newline at end of file +exports.chooseBotName = () => exports.choose(exports.nameLists.bots); + +exports.chooseBossName = code => code in exports.nameLists ? exports.choose(exports.nameLists[code]) : undefined; \ No newline at end of file diff --git a/server/modules/debug/speedLoop.js b/server/modules/debug/speedLoop.js index 6abacf94b..c24120637 100644 --- a/server/modules/debug/speedLoop.js +++ b/server/modules/debug/speedLoop.js @@ -13,9 +13,6 @@ const speedcheckloop = () => { active = logs.entities.count(); global.fps = (1000 / sum).toFixed(2); if (sum > 1000 / c.runSpeed / 30) { - for (let entity of entities) { - util.warn(...entity.defs) - } //fails++; if (c.LOGS) { util.warn('~~ LAST SERVER TICK TOOK TOO LONG TO CALCULATE ~~'); diff --git a/server/modules/definitions/addons/amongus.js b/server/modules/definitions/addons/amongus.js deleted file mode 100644 index 7f675df15..000000000 --- a/server/modules/definitions/addons/amongus.js +++ /dev/null @@ -1,108 +0,0 @@ - //UNCOMMENT LINE 11 TO DISABLE - //return - console.log('[AMONG US CREWMATE] Addon running'); - - Class.OSAmongus_basebody = { - PARENT: ["genericTank"], - LABEL: "", - SHAPE: "M -0.731 1.979 Q -1.279 -2.215 -0.005 -2.244 Q 1.635 -2.31 1.485 0 Q 1.415 1.801 0.992 1.822 Q 0.599 1.847 0.591 1.342 Q 0.888 1.29 1.078 1.056 Q 0.551 1.132 0.03 1.073 L -0.008 1.871 Q -0.304 2.162 -0.727 1.982", - } - Class.OSAmongus_basebodyshadow = { - PARENT: ["genericTank"], - LABEL: "", - BORDERLESS: true, - SHAPE: "M 0.431 0.765 C -0.809 0.861 -0.8 -0.981 -0.573 -1.968 C -0.451 -2.449 1.348 -2.396 1.331 -1.051 C 1.829 0.495 0.85 0.826 0.423 0.774", - } - Class.OSAmongus_backpack= { - PARENT: ["genericTank"], - LABEL: "", - SHAPE: "M-.6.9-1 1Q-1.615 1.258-1.567-.014-1.581-1.214-1.094-1.014L-1.095-1.009-.7-.9", - } - Class.OSAmongus_backpackshadow= { - PARENT: ["genericTank"], - BORDERLESS: true, - LABEL: "", - SHAPE: "M -1.11 -0.781 C -1.125 -0.812 -1.481 -0.806 -1.532 -0.734 C -1.507 -0.874 -1.517 -1.033 -1.316 -1.033 C -1.073 -1.069 -1.053 -1.028 -1.11 -0.791", - } - Class.OSAmongus_visor= { - PARENT: ["genericTank"], - LABEL: "", - SHAPE: "M 0.004 -1.131 C -0.007 -0.231 1.655 -0.524 1.649 -1.097 C 1.741 -1.807 0.027 -1.962 -0.001 -1.131", - } - Class.OSAmongus_visorshadow= { - PARENT: ["genericTank"], - BORDERLESS: true, - LABEL: "", - SHAPE: "M 0.178 -1.402 C 0.05 -0.851 1.667 -0.668 1.642 -1.374 C 1.654 -1.609 0.251 -1.785 0.175 -1.411", - } - Class.OSAmongus_visorhighlight= { - PARENT: ["genericTank"], - BORDERLESS: true, - LABEL: "", - SHAPE: "M 0.178 -1.402 C 0.05 -0.851 1.667 -0.668 1.642 -1.374 C 1.654 -1.609 0.251 -1.785 0.175 -1.411", - } - Class.OSAmongus_crewmatebase= { - PARENT: ["genericTank"], - LABEL: "AMONG US", - SHAPE: "M 0.178", - COLOR: 12, - TURRETS:[ - { - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["OSAmongus_backpack", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15,}}], - }, - { - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["OSAmongus_backpackshadow", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 0,}}], - }, - { - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["OSAmongus_basebody", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15,}}], - }, - { - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["OSAmongus_basebodyshadow", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: -1, BRIGHTNESS_SHIFT: 0,}}], - }, - { - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["OSAmongus_visor", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 10, BRIGHTNESS_SHIFT: -15,}}], - }, - { - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["OSAmongus_visorshadow", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 10, BRIGHTNESS_SHIFT: 0,}}], - }, - { - POSITION: [5, 2.75, -4, 0, 0, 1], - TYPE: ["OSAmongus_visorhighlight", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 8, BRIGHTNESS_SHIFT: 0,}}], - }, - ], - } - Class.addons.UPGRADES_TIER_0.push("OSAmongus_crewmatebase"); - Class.OSAmongus_crewmatebase.UPGRADES_TIER_0 = []; - const colors = [ - "red", - "orange", - "gold", - "brown", - "green", - "blue", - "cyan", - "teal", - "pink", - "purple", - "magenta", - "veryLightGray", - "darkGray", - "animatedLesbian", - "animatedTrans", - "rainbow", - ] - for (let i = 0; i < colors.length; i++) { - Class["OSAmongus_" + colors[i] + "crewmate"] = { - PARENT: ["OSAmongus_crewmatebase"], - COLOR: colors[i] - - }; - - Class.OSAmongus_crewmatebase.UPGRADES_TIER_0.push("OSAmongus_" + colors[i] + "crewmate"); -} \ No newline at end of file diff --git a/server/modules/definitions/addons/basicChatModeration.js b/server/modules/definitions/addons/basicChatModeration.js index 4e1ae4f20..5f2c04fe1 100644 --- a/server/modules/definitions/addons/basicChatModeration.js +++ b/server/modules/definitions/addons/basicChatModeration.js @@ -47,4 +47,5 @@ module.exports = ({ Events }) => { }); console.log('[basicChatModeration] Loaded spam prevention!'); -}; \ No newline at end of file +}; + diff --git a/server/modules/definitions/addons/cooper.js b/server/modules/definitions/addons/cooper.js deleted file mode 100644 index 53af0685a..000000000 --- a/server/modules/definitions/addons/cooper.js +++ /dev/null @@ -1,30 +0,0 @@ -const { combineStats, makeAuto, makeHybrid, makeHybridDrive, makeOver, makeDeco, makeGuard, makeBird, makeMulti, makeCeption, makeCeptionNerf, makeTracker } = require('../facilitators.js'); -const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); -require('../groups/generics.js'); -const g = require('../gunvals.js'); - -Class.sandwichdeco = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg?v=1708356424097"); - -Class.A = { - PARENT: "genericTank", - LABEL: "ChickenSandwichTank", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single, g.op]), - TYPE: "bullet" - } - }, - { - POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] - } - ], - TURRETS: [{ - POSITION: [11, 0, 0, 0, 0, 99], - TYPE: "sandwichdeco" - }] -}; - -Class.addons.UPGRADES_TIER_0.push("A") \ No newline at end of file diff --git a/server/modules/definitions/addons/dailyTanks.js b/server/modules/definitions/addons/dailyTanks.js deleted file mode 100644 index e50edb19a..000000000 --- a/server/modules/definitions/addons/dailyTanks.js +++ /dev/null @@ -1,1687 +0,0 @@ -const { dereference, combineStats, makeMulti, makeDeco, makeAuto, makeHybrid, makeCeptionNerf } = require('../facilitators.js'); -const { base, gunCalcNames, statnames, dfltskl, smshskl } = require('../constants.js'); -const g = require('../gunvals.js'); - -const addToMain = true - -// Bullets -Class.masterBullet = { - PARENT: "missile", - FACING_TYPE: "veryfastspin", - MOTION_TYPE: "motor", - HAS_NO_RECOIL: false, - DIE_AT_RANGE: false, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), - TYPE: "bullet", - LABEL: "Front", - AUTOFIRE: true, - }, - }, - { - POSITION: [13, 8, 1, 0, -1, 140, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: "Thruster", - AUTOFIRE: true, - }, - }, - { - POSITION: [13, 8, 1, 0, 1, 220, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: "Thruster", - AUTOFIRE: true, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: "Thruster", - AUTOFIRE: true, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: "Thruster", - AUTOFIRE: true, - }, - }, - ], -} - -Class.squareSatellite = { - PARENT: "satellite", - SHAPE: 4 -} - -// Turrets -Class.lamgSpinnerTurret = makeMulti({ - PARENT: "genericTank", - LABEL: "Spinner Turret", - GUNS: [ - { - POSITION: [15, 3.5, 1, 0, 0, 0, 0] - } - ] -}, 10) - -// Decorations -Class.tornadoDeco = makeDeco(4); -Class.tornadoDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; -Class.megaTornadoDeco = makeDeco([[0,-1],[0.5,0],[0,1],[-0.5,0]]) -Class.megaTornadoDeco.CONTROLLERS = [["spin", { independent: true }]]; -Class.tempestDeco1 = makeDeco(3); -Class.tempestDeco1.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; -Class.tempestDeco2 = makeDeco(3); -Class.tempestDeco2.CONTROLLERS = [["spin", { independent: true, speed: -0.128 }]]; -Class.thunderboltDeco = makeDeco(4); -Class.thunderboltDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.16 }]]; -Class.hurricaneDeco = makeDeco(8); -Class.hurricaneDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; -Class.typhoonDeco = makeDeco(10); -Class.typhoonDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; -Class.blizzardDeco1 = makeDeco(5); -Class.blizzardDeco1.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; -Class.blizzardDeco2 = makeDeco(5); -Class.blizzardDeco2.CONTROLLERS = [["spin", { independent: true, speed: -0.128 }]]; - -// Whirlwind upgrades -Class.dlywhirlwind = { - PARENT: "genericTank", - LABEL: "Whirlwind", - //UPGRADE_TOOLTIP: "Daily Tank!", - //UPGRADE_COLOR: "rainbow", - ANGLE: 60, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "whirlwindDeco" - } - ], - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 6; i++) { - output.push({ - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: i * 60}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} -Class.tornado = { - PARENT: "genericTank", - LABEL: "Tornado", - DANGER: 6, - TURRETS: [ - { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: "tornadoDeco", - }, - ], - ANGLE: 90, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 4; i++) { - output.push({ - POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), - TYPE: ["satellite", {ANGLE: i * 90}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} -Class.hurricane = { - PARENT: ["genericTank"], - LABEL: "Hurricane", - DANGER: 6, - ANGLE: 45, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "hurricaneDeco", - }, - ], - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 8; i++) { - output.push({ - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: i * 45}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} -Class.hexaWhirl = { - PARENT: ["genericTank"], - LABEL: "Hexa Whirl", - DANGER: 7, - ANGLE: 45, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.mixed, - AI: { - SPEED: 2, - }, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "tornadoDeco", - }, - ], - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet", - }, - }, - { - POSITION: [18, 8, 1, 0, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet", - }, - }, - { - POSITION: [18, 8, 1, 0, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet", - }, - }, - { - POSITION: [18, 8, 1, 0, 0, 60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet", - }, - }, - { - POSITION: [18, 8, 1, 0, 0, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet", - }, - }, - { - POSITION: [18, 8, 1, 0, 0, 300, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet", - }, - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 0}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 90}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 180}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 270}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - } - ], -} -Class.munition = { - PARENT: ["genericTank"], - DANGER: 7, - LABEL: "Munition", - ANGLE: 45, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.mixed, - AI: { - SPEED: 2, - }, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "tornadoDeco", - }, - ], - GUNS: [ - { - POSITION: [17, 3, 1, 0, -6, -7, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [17, 3, 1, 0, 6, 7, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [19, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), - TYPE: "bullet", - LABEL: "Heavy", - }, - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 0}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 90}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 180}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 270}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - } - ], -} -Class.whirl3 = { - PARENT: "genericTank", - LABEL: "Whirl-3", - DANGER: 7, - FACING_TYPE: "autospin", - ANGLE: 90, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.mixed, - AI: { - SPEED: 2, - }, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "tornadoDeco", - }, - { - POSITION: [11, 8, 0, 0, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 120, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 240, 190, 0], - TYPE: "autoTankGun", - }, - ], - GUNS: (() => { - let output = [] - for (let i = 0; i < 4; i++) { - output.push({ - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: i * 90}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }) - } - return output - })() -} -Class.whirlGuard = { - PARENT: ["genericTank"], - LABEL: "Whirl Guard", - ANGLE: 45, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.mixed, - AI: { - SPEED: 2, - }, - DANGER: 7, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "tornadoDeco", - }, - ], - GUNS: [ - { - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet", - }, - }, - { - POSITION: [13, 8, 1, 0, 0, 180, 0], - }, - { - POSITION: [4, 8, 1.7, 13, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 0}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 90}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 180}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 270}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - } - ], -} -Class.prophet = { - PARENT: ["genericTank"], - LABEL: "Prophet", - DANGER: 7, - ANGLE: 45, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.mixed, - BODY: { - SPEED: 0.9 * base.SPEED, - }, - AI: { - SPEED: 2, - }, - SHAPE: 4, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "tornadoDeco", - }, - ], - GUNS: [ - { - POSITION: [5.25, 12, 1.2, 8, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - MAX_CHILDREN: 7, - }, - }, - { - POSITION: [5.25, 12, 1.2, 8, 0, 270, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - MAX_CHILDREN: 7, - }, - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["squareSatellite", {ANGLE: 0}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["squareSatellite", {ANGLE: 90}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["squareSatellite", {ANGLE: 180}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["squareSatellite", {ANGLE: 270}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - } - ], -} -Class.vortex = { - PARENT: ["genericTank"], - LABEL: "Vortex", - BODY: { - FOV: base.FOV * 1.1, - }, - ANGLE: 45, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.mixed, - AI: { - SPEED: 2, - }, - DANGER: 7, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "tornadoDeco", - }, - ], - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [10, 9, 1, 9, 0, 0, 0], - }, - { - POSITION: [17, 13, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery]), - TYPE: "minimissile", - STAT_CALCULATOR: gunCalcNames.sustained, - }, - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 0}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 90}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 180}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - }, - { - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: 270}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true, - HAS_NO_RECOIL: true - } - } - ], -} - -// Tornado upgrades -Class.megaTornado = { - PARENT: "genericTank", - LABEL: "Mega Tornado", - DANGER: 7, - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: "megaTornadoDeco", - }, - ], - ANGLE: 180, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 2; i++) { - output.push({ - POSITION: {WIDTH: 16, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite, g.pounder, g.destroyer]), - TYPE: ["satellite", {ANGLE: i * 180}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} -Class.tempest = { - PARENT: "genericTank", - LABEL: "Tempest", - DANGER: 7, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "tempestDeco1", - }, - { - POSITION: [4, 0, 0, 180, 360, 1], - TYPE: "tempestDeco2", - }, - ], - ANGLE: 120, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 3; i++) { - output.push({ - POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), - TYPE: ["satellite", {ANGLE: i * 120}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - for (let i = 0; i < 3; i++) { - output.push({ - POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), - TYPE: ["satellite", { ANGLE: i * 120, CONTROLLERS: [['orbit', {invert: true}]] }], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} -Class.thunderbolt = { - PARENT: ["genericTank"], - LABEL: "Thunderbolt", - DANGER: 7, - TURRETS: [ - { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: "thunderboltDeco", - }, - ], - ANGLE: 90, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - AI: { - SPEED: 2.5, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 4; i++) { - output.push({ - POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), - TYPE: ["satellite", {ANGLE: i * 90}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} - -// Hurricane upgrades -Class.typhoon = { - PARENT: ["genericTank"], - LABEL: "Typhoon", - DANGER: 7, - ANGLE: 36, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "typhoonDeco", - }, - ], - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 10; i++) { - output.push({ - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: i * 36}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} -Class.blizzard = { - PARENT: "genericTank", - LABEL: "Blizzard", - DANGER: 7, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "blizzardDeco1", - }, - { - POSITION: [6, 0, 0, 180, 360, 1], - TYPE: "blizzardDeco2", - }, - ], - ANGLE: 72, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 5; i++) { - output.push({ - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", {ANGLE: i * 72}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - for (let i = 0; i < 5; i++) { - output.push({ - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["satellite", { ANGLE: i * 72, CONTROLLERS: [['orbit', {invert: true}]] }], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: false, - WAIT_TO_CYCLE: true - } - }) - } - return output - })() -} - -// Whirlwind upgrade paths -Class.dlywhirlwind.UPGRADES_TIER_2 = ["tornado", "hurricane"] - Class.dlywhirlwind.UPGRADES_TIER_3 = ["hexaWhirl", "munition", "whirl3", "whirlGuard", "prophet", "vortex"] - Class.tornado.UPGRADES_TIER_3 = ["megaTornado", "tempest", "thunderbolt"] - Class.hurricane.UPGRADES_TIER_3 = ["typhoon", "blizzard"] - -// December 14th - Master -Class.master = { - PARENT: "genericTank", - LABEL: "Master", - UPGRADE_TOOLTIP: "Daily Tank!", - UPGRADE_COLOR: "rainbow", - BODY: { - HEALTH: base.HEALTH * 0.4, - SHIELD: base.SHIELD * 0.4, - DENSITY: base.DENSITY * 0.3, - }, - DANGER: 8, - GUNS: [ - { - POSITION: [18, 16, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "masterBullet", - MAX_CHILDREN: 4, - DESTROY_OLDEST_CHILD: true, - }, - }, - { - POSITION: [13, 8, 1, 0, -1, 140, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [13, 8, 1, 0, 1, 220, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - ], -} - -// December 16th - Literally a Machine Gun -Class.literallyAMachineGun = { - PARENT: "genericTank", - LABEL: "Literally a Machine Gun", - UPGRADE_TOOLTIP: "Daily Tank!", - UPGRADE_COLOR: "rainbow", - DANGER: 7, - BODY: { - FOV: base.FOV * 1.2 - }, - TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", - TURRETS: [ - { - POSITION: [10, 14, 0, 0, 0, 1], - TYPE: "lamgSpinnerTurret" - } - ], - GUNS: [ - { - POSITION: [22, 8, 1, 0, 0, 0, 0] - }, { - POSITION: [2, 3.5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - } - ] -} - -// Dev shit -Class.dailyTanks = { - PARENT: "genericTank", - LABEL: "Daily Tanks!", - UPGRADE_COLOR: "rainbow", - UPGRADES_TIER_0: [ - "dlywhirlwind", - "master", - "literallyAMachineGun", - "literallyATank", - "crayon", - "jumpSmasher", - "dlylancer", - ] -} - -// December 19th-20th - Jump Smasher -Class.jumpsmasherBody = { - LABEL: "", - CONTROLLERS: [["spin", { independent: true, speed: 0.3 }]], - COLOR: "black", - SHAPE: 8, - INDEPENDENT: true -} -Class.jumpSmasher = { - PARENT: "genericSmasher", - LABEL: "Jump Smasher", - //UPGRADE_TOOLTIP: "Daily Tank!", - //UPGRADE_COLOR: "rainbow", - DANGER: 7, - GUNS: [ - { - POSITION: [2, 10, 1, 0, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.tonsmorerecoil, g.tonsmorerecoil, g.halfreload, g.halfreload, g.halfreload, g.halfreload, g.norange]), - TYPE: "bullet", - ALT_FIRE: true - } - } - ], - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "jumpsmasherBody" - } - ] -} - -// *InsertCorrectDateHereCuzIdk* - Literally A Tank -class io_turretWithMotion extends IO { - constructor(b, opts = {}) { - super(b) - } - think(input) { - return { - target: this.body.master.velocity, - main: true, - }; - } -} -ioTypes.turretWithMotion = io_turretWithMotion -Class.latTop = makeDeco(0) -Class.latDeco1 = { - PARENT: "genericTank", - LABEL: "Tank Deco", - FACING_TYPE: ["turnWithSpeed"], - COLOR: "#5C533F", - SHAPE: "M -1 -2 C -1 -2 -1 -3 0 -3 C 1 -3 1 -2 1 -2 V 2 C 1 2 1 3 0 3 C -1 3 -1 2 -1 2 V -2", - MIRROR_MASTER_ANGLE: true, -} -Class.latDeco2 = { - PARENT: "genericTank", - LABEL: "Tank Deco", - FACING_TYPE: ["turnWithSpeed"], - COLOR: "#5C533F", - SHAPE: "M -2 0 H 2 L 0 1 L -2 0", - MIRROR_MASTER_ANGLE: true, -} -Class.latDeco3 = { - PARENT: "genericTank", - LABEL: "Tank Deco", - FACING_TYPE: ["turnWithSpeed"], - COLOR: "#3F3B2D", - SHAPE: "M -10 -1 L 10 -1 L 10 1 L -10 1 L -10 -1", - MIRROR_MASTER_ANGLE: true, -} -Class.latRight = { - PARENT: "genericTank", - LABEL: "Tank Side", - FACING_TYPE: ["turnWithSpeed"], - COLOR: "#96794E", - SHAPE: "M -6 0 H 5 V 1 C 5 2 4 2 4 2 H -5 C -6 2 -6 1 -6 1 V 0", - MIRROR_MASTER_ANGLE: true, - TURRETS: [ - { - POSITION: [4.8, 31, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, 24, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, 17, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, -42, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, -35, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, -28, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [18, -5, 0, 0, 0, 1], - TYPE: "latDeco2", - }, - ] -} -Class.latLeft = { - PARENT: "genericTank", - LABEL: "Tank Side", - FACING_TYPE: ["turnWithSpeed"], - COLOR: "#96794E", - SHAPE: "M -5 0 H 6 V 1 C 6 2 5 2 5 2 H -4 C -5 2 -5 1 -5 1 V 0", - MIRROR_MASTER_ANGLE: true, - TURRETS: [ - { - POSITION: [4.8, -31, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, -24, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, -17, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, 42, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, 35, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [4.8, 28, 10, 0, 0, 1], - TYPE: "latDeco1", - }, - { - POSITION: [18, 5, 0, 0, 0, 1], - TYPE: "latDeco2", - }, - ] -} -Class.latBase = { - PARENT: "genericTank", - LABEL: "Tank Base", - CONTROLLERS: ["turretWithMotion"], - COLOR: "#96794E", - SHAPE: [ - [1.1, 1], - [1.4, 0], - [1.1, -1], - [-1.1, -1], - [-0.8, 0], - [-1.1, 1] - ], - GUNS: [ - { - POSITION: [16, 5.5, 1, 1, 6.5, 0, 0] - }, - { - POSITION: [14.5, 5.5, 1, 1, 6.5, 0, 0] - }, - { - POSITION: [13, 5.5, 1, 1, 6.5, 0, 0] - }, - { - POSITION: [16, 5.5, 1, 1, -6.5, 0, 0] - }, - { - POSITION: [14.5, 5.5, 1, 1, -6.5, 0, 0] - }, - { - POSITION: [13, 5.5, 1, 1, -6.5, 0, 0] - }, - { - POSITION: [13, 5.5, 1, 1, 6.5, 180, 0] - }, - { - POSITION: [11.5, 5.5, 1, 1, 6.5, 180, 0] - }, - { - POSITION: [10, 5.5, 1, 1, 6.5, 180, 0] - }, - { - POSITION: [8.5, 5.5, 1, 1, 6.5, 180, 0] - }, - { - POSITION: [13, 5.5, 1, 1, -6.5, 180, 0] - }, - { - POSITION: [11.5, 5.5, 1, 1, -6.5, 180, 0] - }, - { - POSITION: [10, 5.5, 1, 1, -6.5, 180, 0] - }, - { - POSITION: [8.5, 5.5, 1, 1, -6.5, 180, 0] - }, - ], - TURRETS: [ - { - POSITION: [5.3, 0, -10, 0, 0, 1], - TYPE: "latLeft", - }, - { - POSITION: [5.3, 0, -10, 180, 0, 1], - TYPE: "latRight", - }, - { - POSITION: [2, 0, -1.4, 90, 0, 1], - TYPE: "latDeco3", - }, - ] -} -Class.literallyATank = { - PARENT: "genericTank", - UPGRADE_TOOLTIP: "Daily Tank!", - UPGRADE_COLOR: "rainbow", - DANGER: 6, - BODY: { - HEALTH: base.HEALTH * 1.2, - }, - LABEL: "Literally a Tank", - SHAPE: "M -1 -1 H 0 C 1 -1 1 0 1 0 C 1 0 1 1 0 1 H -1 V -1", - GUNS: [ - { - POSITION: [30, 8, 1, 0, 0, 0, 0] - }, - { - POSITION: [4, 8, -1.4, 8, 0, 0, 0] - }, - { - POSITION: [12, 8, 1.3, 30, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "developerBullet" - } - }, - { - POSITION: [2, 11, 1, 34, 0, 0, 0] - } - ], - TURRETS: [ - { - POSITION: [15, 0, 0, 0, 360, 1], - TYPE: [ "latTop", { COLOR: "#5C533F" } ], - }, - { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: [ "latTop", { COLOR: "#736245" } ], - }, - { - POSITION: [35, 0, 0, 0, 360, 0], - TYPE: [ "latBase", { COLOR: "#96794E" } ], - }, - ] -} - -Class.dlylancer = { - PARENT: "genericLancer", - LABEL: "Lancer", - //UPGRADE_TOOLTIP: "Daily Tank!", - //UPGRADE_COLOR: "rainbow", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - } - ] -} -Class.dlylancebrid = makeHybrid(Class.dlylancer, "Lancebrid"); -Class.dlyautolancer = makeAuto(Class.dlylancer, "Auto-Lancer"); -Class.dlyautolancebrid = makeAuto(Class.dlylancebrid, "Auto-Lancebrid"); -Class.dlytrilancer = { - PARENT: "genericLancer", - LABEL: "Tri-Lancer", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 120, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 240, 0] - } - ] -} -Class.dlyhexalancer = { - PARENT: "genericLancer", - LABEL: "Hexa Lancer", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 60, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 120, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 180, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 240, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 300, 0] - } - ] -} -Class.dlychasseur = { - PARENT: "genericLancer", - LABEL: "Chasseur", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 1 - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true, - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - } - ] -} -Class.dlyautochasseur = makeAuto(Class.dlychasseur, "Auto-Chasseur"); -Class.dlylancerception = makeAuto(Class.dlylancer, "Lancer-Ception"); -Class.dlyautotrilancer = makeAuto(Class.dlytrilancer, "Auto-Trilancer"); -Class.dlychasseubrid = makeHybrid(Class.dlychasseur, "Chasseubrid"); -Class.dlytrilancebrid = makeHybrid(Class.dlytrilancer, "Trilancebrid"); -Class.dlytrichasseur = { - PARENT: "genericLancer", - LABEL: "Tri-Chasseur", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 1 - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [25, 15, 0.001, 0, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 120, 0] - }, - { - POSITION: [25, 15, 0.001, 0, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 240, 0] - } - ] -} -Class.dlytripleur = { - PARENT: "genericLancer", - LABEL: "Tripleur", - BODY: { - SPEED: base.SPEED * 1.1, - DAMAGE: base.DAMAGE * 1 - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, -30, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, -30, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 30, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 30, 0] - } - ] -} -Class.dlytrailblazer = { - PARENT: "genericLancer", - LABEL: "Trailblazer", - BODY: { - HEALTH: 0.8 * base.HEALTH, - SHIELD: 0.8 * base.SHIELD, - DENSITY: 0.6 * base.DENSITY, - }, - HAS_NO_RECOIL: false, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lance]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - } - ] -} - -Class.dlylancer.UPGRADES_TIER_2 = [ - "dlychasseur", // - "dlylancebrid", // - "dlytrilancer", // - "dlyautolancer", // -]; -Class.dlychasseur.UPGRADES_TIER_3 = [ - "dlytripleur", // - "flail", - "dlyautochasseur", // - "dlytrichasseur", // - "dlychasseubrid", // -]; -Class.dlytrilancer.UPGRADES_TIER_3 = [ - "dlyhexalancer", // - "dlytrailblazer", // - "dlytrichasseur", // - "dlytrilancebrid", // - "dlyautotrilancer", // -]; -Class.dlyautolancer.UPGRADES_TIER_3 = [ - "dlyautochasseur", // - "dlyautolancebrid", // - "dlyautotrilancer", // - "dlylancerception", // -]; -Class.dlylancebrid.UPGRADES_TIER_3 = [ - "dlychasseubrid", // - "dlyautolancebrid", // - "dlytrilancebrid", // -]; -Class.crayon = { - PARENT: "genericTank", - LABEL: "Crayon", - UPGRADE_COLOR: "rainbow", - UPGRADE_TOOLTIP: "Daily Tank!", - SIZE: 12, - SHAPE: 0, - GUNS: [{ - POSITION: [16.615, 6.4, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin]), - TYPE: "bullet" - } - }, { - POSITION: [16.615, 6.4, 1, 0, -5.538, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin]), - TYPE: "bullet" - }, - }, - { - POSITION: [16.615, 6.4, 1, 0, 5.538, 0, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin]), - TYPE: "bullet" - }, - }, - ], -}; -Class.autocrayon = makeAuto(Class.crayon, 'Auto Crayon'); - -Class.crayon.UPGRADES_TIER_3 = ["autocrayon"]; - -let dlytanks = ["master", "dlywhirlwind", "literallyATank", "jumpSmasher", "dlylancer", "literallyAMachineGun", "crayon"]; -dailytank = dlytanks[global.dayofweek]; - -if (addToMain == true) { -Class.basic.UPGRADES_TIER_1.push("dlylancer", "dlywhirlwind") -Class.smasher.UPGRADES_TIER_3.push("jumpSmasher") -Class.hexaTank.UPGRADES_TIER_3.push("hexaWhirl") -Class.artillery.UPGRADES_TIER_3.push("munition") -Class.auto3.UPGRADES_TIER_3.push("whirl3") -Class.trapGuard.UPGRADES_TIER_3.push("whirlGuard") -Class.underseer.UPGRADES_TIER_3.push("prophet") -Class.launcher.UPGRADES_TIER_3.push("vortex") -} else { -//Class.basic.UPGRADES_TIER_3 = [dailytank] -} -Class.addons.UPGRADES_TIER_3 = ["dailyTanks"]; \ No newline at end of file diff --git a/server/modules/definitions/addons/dreadv1.js b/server/modules/definitions/addons/dreadv1.js index 498b50431..1d59d6a96 100644 --- a/server/modules/definitions/addons/dreadv1.js +++ b/server/modules/definitions/addons/dreadv1.js @@ -1,4 +1,4 @@ -const { combineStats, makeAuto } = require('../facilitators.js'); +const { combineStats, makeAuto, weaponArray } = require('../facilitators.js'); const { gunCalcNames, smshskl, base } = require('../constants.js'); const g = require('../gunvals.js'); const dreadnoughtBody = { @@ -45,10 +45,10 @@ Class.genericDreadnought1 = { BODY: dreadnoughtBody, SHAPE: 6, COLOR: 'hexagon', - SIZE: 27.5, + SIZE: 22.5, SKILL_CAP: Array(10).fill(smshskl+3), REROOT_UPGRADE_TREE: "dreadOfficialV1", -}; +} Class.mechanismMainTurret = { PARENT: "genericTank", LABEL: "Turret", @@ -65,7 +65,7 @@ Class.mechanismMainTurret = { TYPE: "bullet" } }] -}; +} Class.automationMainTurret = { PARENT: "genericTank", LABEL: "Turret", @@ -82,7 +82,7 @@ Class.automationMainTurret = { TYPE: "bullet" } }] -}; +} Class.automationSecondaryTurret = { PARENT: "genericTank", LABEL: "Turret", @@ -99,31 +99,29 @@ Class.automationSecondaryTurret = { TYPE: "bullet" } }] -}; +} Class.medicareTurret = { PARENT: "genericTank", LABEL: "Turret", CONTROLLERS: [ ["spin", {speed: 0.04}] ], INDEPENDENT: true, COLOR: 16, - GUNS: [], + GUNS: weaponArray([ + { + POSITION: [8, 9, -0.5, 12.5, 0, 0, 0], + }, { + POSITION: [18, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.flankGuard, g.healer]), + TYPE: "healerBullet", + AUTOFIRE: true, + }, + } + ], 3), TURRETS: [{ POSITION: [13, 0, 0, 0, 360, 1], TYPE: "healerSymbol", - }], -}; -for(let i = 0; i < 3; i++) { - Class.medicareTurret.GUNS.push({ - POSITION: [8, 9, -0.5, 12.5, 0, 120*i, 0], - }, - { - POSITION: [18, 10, 1, 0, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.pounder, g.healer]), - TYPE: "healerBullet", - AUTOFIRE: true, - }, - }) + }] } Class.medicaidTurret = { PARENT: "genericTank", @@ -131,24 +129,22 @@ Class.medicaidTurret = { CONTROLLERS: [ ["spin", {speed: 0.04}] ], INDEPENDENT: true, COLOR: 16, - GUNS: [], + GUNS: weaponArray([ + { + POSITION: [8, 9, -0.5, 12.5, 0, 0, 0], + }, { + POSITION: [18, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.flankGuard, g.flankGuard, g.healer]), + TYPE: "healerBullet", + AUTOFIRE: true, + }, + } + ], 5), TURRETS: [{ POSITION: [13, 0, 0, 0, 360, 1], TYPE: "healerSymbol", - }], -}; -for(let i = 0; i < 5; i++) { - Class.medicaidTurret.GUNS.push({ - POSITION: [8, 9, -0.5, 12.5, 0, 72*i, 0], - }, - { - POSITION: [18, 10, 1, 0, 0, 72*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.flankGuard, g.pounder, g.healer]), - TYPE: "healerBullet", - AUTOFIRE: true, - }, - }) + }] } Class.turretedTrap = makeAuto("trap", "Auto-Trap", {size: 7.5, type: 'droneAutoTurret'}); Class.turretedTrap.BODY.RECOIL_MULTIPLIER = 0; @@ -163,7 +159,7 @@ Class.weakMinion = { TYPE: "bullet", }, }, - ], + ] } // T0 @@ -180,43 +176,34 @@ Class.swordOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Sword", UPGRADE_TOOLTIP: "Snipers", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.swordOfficialV1.GUNS.push({ - POSITION: [19, 7, 1, 0, 0, 120*i, 0], + GUNS: weaponArray({ + POSITION: [19, 7, 1, 0, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.dreadv1Generic]), TYPE: "bullet" } - }); + }, 3) } Class.pacifierOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Pacifier", UPGRADE_TOOLTIP: "Bullet Spam", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.pacifierOfficialV1.GUNS.push({ - POSITION: [15, 7, 1, 0, 0, 120*i, 0], + GUNS: weaponArray({ + POSITION: [15, 7, 1, 0, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.dreadv1Generic, g.dreadv1Slow]), TYPE: "bullet" } - }); + }, 3) } Class.invaderOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Invader", UPGRADE_TOOLTIP: "Drones", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.invaderOfficialV1.GUNS.push({ - POSITION: [5.5, 7.5, 1.3, 7.5, 0, 120*i, 0], + GUNS: weaponArray({ + POSITION: [5.5, 7.5, 1.3, 7.5, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.dreadv1Drone]), TYPE: "drone", @@ -226,44 +213,42 @@ for (let i = 0; i < 3; i++) { WAIT_TO_CYCLE: true, MAX_CHILDREN: 4, } - }); + }, 3) } Class.centaurOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Centaur", UPGRADE_TOOLTIP: "Traps", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.centaurOfficialV1.GUNS.push({ - POSITION: [12.5, 7, 1, 0, 0, 120*i, 0], - }, { - POSITION: [2.5, 7, 1.6, 12.5, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, {reload: 0.55}]), - TYPE: ["trap", {HITS_OWN_TYPE: "never"} ], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }); + GUNS: weaponArray([ + { + POSITION: [12.5, 7, 1, 0, 0, 0, 0], + }, { + POSITION: [2.5, 7, 1.6, 12.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, {reload: 0.55}]), + TYPE: ["trap", {HITS_OWN_TYPE: "never"} ], + STAT_CALCULATOR: gunCalcNames.trap, + }, + } + ], 3) } Class.automationOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Automation", UPGRADE_TOOLTIP: "Auto Turrets", - TURRETS: [], -} -for (let i = 0; i < 6; i++) { - Class.automationOfficialV1.TURRETS.push({ - POSITION: [3.5, 8.25, 0, 60*i+30, 180, 1], - TYPE: "automationSecondaryTurret", - }); + TURRETS: [ + ...weaponArray({ + POSITION: [3.5, 8.25, 0, 30, 180, 1], + TYPE: "automationSecondaryTurret", + }, 6), + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "automationMainTurret", + } + ] } -Class.automationOfficialV1.TURRETS.push({ - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: "automationMainTurret", -}); Class.juggernautOfficialV1 = { PARENT: "genericDreadnought1", @@ -287,7 +272,7 @@ Class.medicareOfficialV1 = { TURRETS: [{ POSITION: [8, 0, 0, 0, 360, 1], TYPE: "medicareTurret", - }], + }] } // T2 @@ -295,263 +280,247 @@ Class.sabreOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Sabre", UPGRADE_TOOLTIP: "Assassins", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.sabreOfficialV1.GUNS.push({ - POSITION: [26, 7, 1, 0, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.dreadv1Generic]), - TYPE: "bullet" + GUNS: weaponArray([ + { + POSITION: [26, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.dreadv1Generic]), + TYPE: "bullet" + } + }, { + POSITION: [4, 7, -1.4, 9, 0, 0, 0] } - }, { - POSITION: [4, 7, -1.4, 9, 0, 120*i, 0] - }); + ], 3) } Class.gladiusOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Gladius", UPGRADE_TOOLTIP: "Rifles", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.gladiusOfficialV1.GUNS.push({ - POSITION: [17, 9, 1, 0, 0, 120*i, 0] - }, { - POSITION: [20, 6, 1, 0, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.dreadv1Generic]), - TYPE: "bullet" + GUNS: weaponArray([ + { + POSITION: [20, 9, 1, 0, 0, 0, 0] + }, { + POSITION: [23, 6, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.dreadv1Generic]), + TYPE: "bullet" + } } - }); + ], 3) } Class.appeaserOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Appeaser", UPGRADE_TOOLTIP: "Machine Guns", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.appeaserOfficialV1.GUNS.push({ - POSITION: [6, 8, 1.3, 7, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.dreadv1Generic, g.dreadv1Slow, {speed: 0.8, maxSpeed: 0.8, range: 0.75, size: 0.55}]), - TYPE: "bullet" - } - }, { - POSITION: [6, 7.5, 1.2, 9, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.dreadv1Generic, g.dreadv1Slow, {speed: 0.8, maxSpeed: 0.8, range: 0.75, size: 0.55 * 8 / 7.5}]), - TYPE: "bullet" + GUNS: weaponArray([ + { + POSITION: [6, 8, 1.3, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.dreadv1Generic, g.dreadv1Slow, {speed: 0.8, maxSpeed: 0.8, range: 0.75, size: 0.55}]), + TYPE: "bullet" + } + }, { + POSITION: [6, 7.5, 1.2, 9, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.dreadv1Generic, g.dreadv1Slow, {speed: 0.8, maxSpeed: 0.8, range: 0.75, size: 0.55 * 8 / 7.5}]), + TYPE: "bullet" + } } - }); + ], 3) } Class.peacekeeperOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Peacekeeper", UPGRADE_TOOLTIP: "Heavy Bullets", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.peacekeeperOfficialV1.GUNS.push({ - POSITION: [16.5, 10, 1, 0, 0, 120*i, 0], + GUNS: weaponArray({ + POSITION: [16.5, 10, 1, 0, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.dreadv1Generic, g.dreadv1Slow, {reload: 1.3, health: 1.3}]), TYPE: "bullet", } - }); + }, 3) } Class.diplomatOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Diplomat", UPGRADE_TOOLTIP: "Triplets", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.diplomatOfficialV1.GUNS.push({ - POSITION: [14, 5, 1, 0, 2.5, 120*i, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.triplet, g.dreadv1Generic, g.dreadv1Slow]), - TYPE: "bullet" - } - }, { - POSITION: [14, 5, 1, 0, -2.5, 120*i, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.triplet, g.dreadv1Generic, g.dreadv1Slow]), - TYPE: "bullet" - } - }, { - POSITION: [15, 5, 1, 0, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.triplet, g.dreadv1Generic, g.dreadv1Slow]), - TYPE: "bullet" + GUNS: weaponArray([ + { + POSITION: [14, 4.5, 1, 0, 2.75, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.triplet, g.dreadv1Generic, g.dreadv1Slow]), + TYPE: "bullet" + } + }, { + POSITION: [14, 4.5, 1, 0, -2.75, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.triplet, g.dreadv1Generic, g.dreadv1Slow]), + TYPE: "bullet" + } + }, { + POSITION: [15, 4.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.twin, g.triplet, g.dreadv1Generic, g.dreadv1Slow]), + TYPE: "bullet" + } } - }); + ], 3) } Class.inquisitorOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Inquisitor", UPGRADE_TOOLTIP: "Drones", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.inquisitorOfficialV1.GUNS.push({ - POSITION: [7, 7.5, 1.3, 7.5, 0, 120*i, 0], + GUNS: weaponArray({ + POSITION: [7, 7.5, 1.3, 7.5, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.dreadv1Drone, {health: 1.25, reload: 1.1}]), + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.dreadv1Drone, {health: 0.95}]), TYPE: "drone", AUTOFIRE: true, SYNCS_SKILLS: true, STAT_CALCULATOR: gunCalcNames.drone, WAIT_TO_CYCLE: true, - MAX_CHILDREN: 4, + MAX_CHILDREN: 5, } - }); + }, 3) } Class.assailantOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Assailant", UPGRADE_TOOLTIP: "Minions", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.assailantOfficialV1.GUNS.push({ - POSITION: [13.5, 8, 1, 0, 0, 120*i, 0], - }, { - POSITION: [1.5, 10, 1, 13.5, 0, 120*i, 0], - PROPERTIES: { - MAX_CHILDREN: 4, - SHOOT_SETTINGS: combineStats([g.factory, g.overseer, g.dreadv1Drone, {health: 0.65, reload: 0.7}]), - TYPE: "weakMinion", - STAT_CALCULATOR: gunCalcNames.drone, - AUTOFIRE: true, - SYNCS_SKILLS: true + GUNS: weaponArray([ + { + POSITION: [13.5, 8, 1, 0, 0, 0, 0], + }, { + POSITION: [1.5, 10, 1, 13.5, 0, 0, 0], + PROPERTIES: { + MAX_CHILDREN: 4, + SHOOT_SETTINGS: combineStats([g.factory, g.overseer, g.dreadv1Drone, {health: 0.65, reload: 0.7}]), + TYPE: "weakMinion", + STAT_CALCULATOR: gunCalcNames.drone, + AUTOFIRE: true, + SYNCS_SKILLS: true + } + }, { + POSITION: [11.5, 10, 1, 0, 0, 0, 0] } - }, { - POSITION: [11.5, 10, 1, 0, 0, 120*i, 0] - }); + ], 3) } Class.infiltratorOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Infiltrator", UPGRADE_TOOLTIP: "Swarms", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.infiltratorOfficialV1.GUNS.push({ - POSITION: [7, 6, 0.6, 5.5, 2.8, 120*i, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.carrier, { reload: 2, speed: 0.5, range: 0.9, health: 0.85}]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm - } - }, { - POSITION: [7, 6, 0.6, 5.5, -2.8, 120*i, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.carrier, { reload: 2, speed: 0.5, range: 0.9, health: 0.85}]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm - } - }, { - POSITION: [7, 6, 0.6, 8, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.carrier, { reload: 2, speed: 0.5, range: 0.9, health: 0.85}]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm + GUNS: weaponArray([ + { + POSITION: [7, 6, 0.6, 5.5, 2.8, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.carrier, { reload: 2, speed: 0.5, range: 0.9, health: 0.85}]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm + } + }, { + POSITION: [7, 6, 0.6, 5.5, -2.8, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.carrier, { reload: 2, speed: 0.5, range: 0.9, health: 0.85}]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm + } + }, { + POSITION: [7, 6, 0.6, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.carrier, { reload: 2, speed: 0.5, range: 0.9, health: 0.85}]), + TYPE: "swarm", + STAT_CALCULATOR: gunCalcNames.swarm + } } - }); + ], 3) } Class.cerberusOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Cerberus", UPGRADE_TOOLTIP: "Trap Spam", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.cerberusOfficialV1.GUNS.push({ - POSITION: [13.5, 2.25, 1, 0, 4, 120*i, 0] - }, { - POSITION: [1.75, 2.25, 1.7, 13.5, 4, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { size: 1.3 }]), - TYPE: ["trap", {HITS_OWN_TYPE: "never"} ], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [13.5, 2.25, 1, 0, -4, 120*i, 0] - }, { - POSITION: [1.75, 2.25, 1.7, 13.5, -4, 120*i, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { size: 1.3 }]), - TYPE: ["trap", {HITS_OWN_TYPE: "never"} ], - STAT_CALCULATOR: gunCalcNames.trap - } - }, { - POSITION: [15, 3, 1, 0, 0, 120*i, 0] - }, { - POSITION: [2, 3, 1.7, 15, 0, 120*i, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { size: 1.3 }]), - TYPE: ["trap", {HITS_OWN_TYPE: "never"} ], - STAT_CALCULATOR: gunCalcNames.trap + GUNS: weaponArray([ + { + POSITION: [13.5, 2.25, 1, 0, 4, 0, 0] + }, { + POSITION: [1.75, 2.25, 1.7, 13.5, 4, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { size: 1.3 }]), + TYPE: ["trap", {HITS_OWN_TYPE: "never"} ], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, { + POSITION: [13.5, 2.25, 1, 0, -4, 0, 0] + }, { + POSITION: [1.75, 2.25, 1.7, 13.5, -4, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { size: 1.3 }]), + TYPE: ["trap", {HITS_OWN_TYPE: "never"} ], + STAT_CALCULATOR: gunCalcNames.trap + } + }, { + POSITION: [15, 3, 1, 0, 0, 0, 0] + }, { + POSITION: [2, 3, 1.7, 15, 0, 0, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { size: 1.3 }]), + TYPE: ["trap", {HITS_OWN_TYPE: "never"} ], + STAT_CALCULATOR: gunCalcNames.trap + } } - }); + ], 3) } Class.minotaurOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Minotaur", UPGRADE_TOOLTIP: "Blocks", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.minotaurOfficialV1.GUNS.push({ - POSITION: [13, 9, 1, 0, 0, 120*i, 0], - }, { - POSITION: [3, 9, 1.6, 13, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { reload: 1.5, health: 1.4, size: 1.3 }]), - TYPE: ["unsetTrap", {HITS_OWN_TYPE: "never"} ], - STAT_CALCULATOR: gunCalcNames.block + GUNS: weaponArray([ + { + POSITION: [13, 9, 1, 0, 0, 0, 0], + }, { + POSITION: [3, 9, 1.6, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { reload: 1.5, health: 1.4, size: 1.3 }]), + TYPE: ["unsetTrap", {HITS_OWN_TYPE: "never"} ], + STAT_CALCULATOR: gunCalcNames.block + } } - }); + ], 3) } Class.sirenOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Siren", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.sirenOfficialV1.GUNS.push({ - POSITION: [13, 7, -1.5, 0, 0, 120*i, 0], - }, { - POSITION: [2.5, 7, 1.6, 13, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { size: 1.3 }]), - TYPE: ["turretedTrap", {HITS_OWN_TYPE: "never"} ], - STAT_CALCULATOR: gunCalcNames.trap, + GUNS: weaponArray([ + { + POSITION: [13, 7, -1.5, 0, 0, 0, 0], + }, { + POSITION: [2.5, 7, 1.6, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper, g.dreadv1Generic, g.dreadv1Slow, g.dreadv1Trap, { size: 1.3 }]), + TYPE: ["turretedTrap", {HITS_OWN_TYPE: "never"} ], + STAT_CALCULATOR: gunCalcNames.trap, + } } - }); + ], 3) } Class.mechanismOfficialV1 = { PARENT: "genericDreadnought1", LABEL: "Mechanism", UPGRADE_TOOLTIP: "Auto Turrets", - TURRETS: [], -} -for (let i = 0; i < 6; i++) { - Class.mechanismOfficialV1.TURRETS.push({ - POSITION: [4, 8.25, 0, 60*i+30, 180, 1], + TURRETS: [ + ...weaponArray({ + POSITION: [4, 8.25, 0, 30, 180, 1], TYPE: "automationMainTurret", - }) + }, 6), + { + POSITION: [9.5, 0, 0, 0, 360, 1], + TYPE: "mechanismMainTurret", + } + ] } -Class.mechanismOfficialV1.TURRETS.push({ - POSITION: [9.5, 0, 0, 0, 360, 1], - TYPE: "mechanismMainTurret", -}) Class.behemothOfficialV1 = { PARENT: "genericDreadnought1", @@ -566,7 +535,7 @@ Class.behemothOfficialV1 = { TURRETS: [{ POSITION: [23.5, 0, 0, 0, 0, 0], TYPE: 'hexagon' - }], + }] } Class.medicaidOfficialV1 = { PARENT: "genericDreadnought1", @@ -575,7 +544,7 @@ Class.medicaidOfficialV1 = { TURRETS: [{ POSITION: [8, 0, 0, 0, 360, 1], TYPE: "medicaidTurret", - }], + }] } Class.addons.UPGRADES_TIER_0.push("dreadOfficialV1"); @@ -689,4 +658,4 @@ for (let primary of Class.dreadOfficialV1.UPGRADES_TIER_1) { } } } -} \ No newline at end of file +} diff --git a/server/modules/definitions/addons/dreadv2.js b/server/modules/definitions/addons/dreadv2.js index aada00165..3cc2dcda4 100644 --- a/server/modules/definitions/addons/dreadv2.js +++ b/server/modules/definitions/addons/dreadv2.js @@ -2575,4 +2575,4 @@ if(buildHexnoughts) { Class[i].UPGRADES_TIER_0.push(mergeHexnoughtWeaponV2(i, j)); } } -} \ No newline at end of file +} diff --git a/server/modules/definitions/addons/exampleAddon.js b/server/modules/definitions/addons/exampleAddon.js index 8c88557be..3eb655784 100644 --- a/server/modules/definitions/addons/exampleAddon.js +++ b/server/modules/definitions/addons/exampleAddon.js @@ -72,4 +72,4 @@ Class.exampleAddon = { }; Class.addons.UPGRADES_TIER_0.push("exampleAddon"); -console.log('[exampleAddon] The Abomination has been created.'); \ No newline at end of file +console.log('[exampleAddon] The Abomination has been created.'); diff --git a/server/modules/definitions/addons/geometryDashDart.js b/server/modules/definitions/addons/geometryDashDart.js deleted file mode 100644 index 99a98d793..000000000 --- a/server/modules/definitions/addons/geometryDashDart.js +++ /dev/null @@ -1,72 +0,0 @@ -const { combineStats, makeDeco } = require('../facilitators'); -const g = require('../gunvals'); - - Class.geometryDash_square = makeDeco(4, 'blue'); - Class.geometryDash_square.MIRROR_MASTER_ANGLE = true; - - Class.geometryDash_longRect = { - SHAPE: 'M 0 0 L 5 0 L 5 2 L 0 2 L 0 0', - COLOR: 'blue', - MIRROR_MASTER_ANGLE: true - }; - - Class.geometryDash = { - PARENT: 'genericTank', - LABEL: 'Geometry Dash', - SHAPE: 4, - BODY: { - HEALTH: 1e7, - SHIELD: 0, - DAMAGE: 0, - ACCELERATION: 10, - SPEED: 20, - PUSHABILITY: 0 - }, - COLOR: '#FFFF00', - SIZE: 20, - SKILL_CAP: Array(10).fill(10), - EXTRA_SKILL: 10, - FACING_TYPE: 'autospin', - TURRETS: [ - { - POSITION: { SIZE: 5, X: 4, Y: 5, LAYER: 1 }, - TYPE: 'geometryDash_square' - }, - { - POSITION: { SIZE: 5, X: 4, Y: -5, LAYER: 1 }, - TYPE: 'geometryDash_square' - }, - { - POSITION: { SIZE: 5, X: -6.1, Y: 2, ANGLE: 90, LAYER: 1 }, - TYPE: 'geometryDash_longRect' - } - ], - UPGRADES_TIER_0: ['geometryDashWave'] - } - - Class.geometryDashWave = { - PARENT: 'genericTank', - LABEL: 'Dart', - NAME: 'Wave', - SHAPE: 3, - BODY: { - HEALTH: 1e7, - DAMAGE: 1e7, - SHIELD: 0, - ACCELERATION: 0, - SPEED: 0, - PUSHABILITY: 0 - }, - COLOR: '#FFFF00', - SIZE: 20, - GUNS: [{ - POSITION: { LENGTH: 13, WIDTH: 8, ASPECT: 2, ANGLE: 180 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.tonsmorerecoil, g.tonsmorerecoil, g.veryfast, { reload: 0.05, range: 0.2 }]), - TYPE: 'bullet', - COLOR: 'blue' - } - }] - } - - Class.addons.UPGRADES_TIER_0.push('geometryDash'); \ No newline at end of file diff --git a/server/modules/definitions/addons/labyFood.js b/server/modules/definitions/addons/labyFood.js index 17760a9aa..72c1ba124 100644 --- a/server/modules/definitions/addons/labyFood.js +++ b/server/modules/definitions/addons/labyFood.js @@ -1,40 +1,57 @@ module.exports = ({ Config }) => { // To enable this addon, simply comment out the line below. - return console.log('[labyFood.js] Addon disabled by default'); + return console.log('[labyFood.js] Addon disabled by default'); - const disableCrashers = true - if (disableCrashers) Config.ENEMY_CAP_NEST = 0; + const disableCrashers = false; - let shinys = [ "", "Shiny", "Legendary", "Shadow", "Rainbow", "Trans" ], - polys = [ "Egg", "Square", "Triangle", "Pentagon", "Hexagon" ]; + // there is no `ENEMY_CAP`, so we are "reconstructing them" + Config.ENEMY_CAP_NEST = 0; - // Constructs a three-dimensional array of shape types + // Constructs a four-dimensional array of shape types - // 6-wide dimension of the 6 shiny modifiers - Config.FOOD_TYPES = Array(6).fill().map((_, i, a) => [ - // Chance of spawning, set to 200mil for regular polygons and exponents of 10 otherwise - i ? 10 ** (a.length - i - 1) : 200_000_000, + // 3-wide dimension of the 3 base shape types - egg, square, triangle + Config.FOOD_TYPES = Array(3).fill().map((_, i, a) => [ + // Chance of spawning in exponents of 4 + 4 ** (a.length - i), // 4-wide dimension of the 4 shape tiers - regular, beta, alpha, omega Array(4).fill().map((_, j, b) => [ // Chance of spawning in exponents of 5 5 ** (b.length - j), - // 3-wide dimension of the 3 base shape types - egg, square, triangle - Array(3).fill().map((_, k, c) => [ - // Chance of spawning in exponents of 4 - 4 ** (c.length - k), - `laby${j}${shinys[i]}${polys[k]}` + // 6-wide dimension of the 6 shiny modifiers + Array(6).fill().map((_, k, c) => [ + // Chance of spawning, set to 200mil for regular polygons and exponents of 10 otherwise + k ? 10 ** (c.length - k - 1) : 200_000_000, + + + disableCrashers ? // no crashers + `laby_${j}_${i}_${k}_0` + : // 2-wide dimension of the 2 shape "ranks" - normal, crasher + [[24, `laby_${j}_${i}_${k}_0`], [1, `laby_${j}_${i}_${k}_1`]] ]) ]) ]); - - Config.FOOD_TYPES_NEST = Array(6).fill().map((_, i, a) => [ - i ? 10 ** (a.length - i - 1) : 200_000_000, + + + //laby_${poly}_${tier}_${shiny}_${rank} + + // 2-wide dimension of the 2 base shape types - pentagon, hexagon + Config.FOOD_TYPES_NEST = Array(2).fill().map((_, i, a) => [ + // Chance of spawning in exponents of 4 + 4 ** (a.length - i), + // 4-wide dimension of the 4 shape tiers - regular, beta, alpha, omega Array(4).fill().map((_, j, b) => [ + // Chance of spawning in exponents of 5 5 ** (b.length - j), - // 2-wide dimension of the 2 base shape types - pentagon, hexagon - Array(2).fill().map((_, k, c) => [ - 4 ** (c.length - k), - `laby${j}${shinys[i]}${polys[k+3]}` + // 6-wide dimension of the 6 shiny modifiers + Array(6).fill().map((_, k, c) => [ + // Chance of spawning, set to 200mil for regular polygons and exponents of 10 otherwise + k ? 10 ** (c.length - k - 1) : 200_000_000, + + + disableCrashers ? // no crashers + `laby_${i+3}_${j}_${k}_0` + : // 2-wide dimension of the 2 shape "ranks" - normal, crasher + [[24, `laby_${i+3}_${j}_${k}_0`], [1, `laby_${i+3}_${j}_${k}_1`]] ]) ]) ]); diff --git a/server/modules/definitions/addons/lancer.js b/server/modules/definitions/addons/lancer.js deleted file mode 100644 index 0ffcb47c7..000000000 --- a/server/modules/definitions/addons/lancer.js +++ /dev/null @@ -1,663 +0,0 @@ -const { - combineStats, - makeAuto, - makeCeption, - makeBiSwarming, - makeSwarming, - makeHybrid, - makeOver, - makeDeco, - makeGuard, - makeBird, - makeMulti, -} = require("../facilitators.js"); -const { - base, - statnames, - gunCalcNames, - dfltskl, - smshskl, -} = require("../constants.js"); -const generics = require("../groups/generics.js"); -const g = require("../gunvals.js"); - -Class.lancer = { - PARENT: "genericTank", - LABEL: "Lancer", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - } - ] -} -Class.autolancer = makeAuto(Class.lancer, "Auto-Lancer"); -Class.trilancer = { - PARENT: "genericTank", - LABEL: "Tri-Lancer", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 120, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 240, 0] - } - ] -} -Class.hexalancer = { - PARENT: "genericTank", - LABEL: "Hexa Lancer", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 60, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 120, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 180, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 240, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 300, 0] - } - ] -} -Class.hedgehog = { - PARENT: "genericTank", - LABEL: "Hedgehog", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, -50, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, -50, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, -100, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, -100, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, -150, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, -150, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 160, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 160, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 105, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 105, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 50, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 50, 0] - } - ] -} -Class.autohedgehog = makeAuto(Class.hedgehog, "Auto-Hedgehog"); -Class.lancebrid = makeHybrid(Class.lancer, "Lancebrid"); -Class.chasseur = { - PARENT: "genericTank", - LABEL: "Chasseur", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 1 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 1 }], - AUTOFIRE: true, - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - } - ] -} -Class.autochasseur = makeAuto(Class.chasseur, "Auto-Chasseur"); -Class.trichasseur = { - PARENT: "genericTank", - LABEL: "Tri-Chasseur", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 1 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [25, 15, 0.001, 0, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 120, 0] - }, - { - POSITION: [25, 15, 0.001, 0, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 240, 0] - } - ] -} -Class.autotrichasseur = makeAuto(Class.trichasseur, "Auto-Tri-Chasseur"); -Class.spiny = { - PARENT: "genericTank", - LABEL: "Spiny", - BODY: { - SPEED: base.SPEED * 1.2, - DAMAGE: base.DAMAGE * 0.9 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 60, 0] - }, - { - POSITION: [25, 15, 0.001, 0, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 120, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 180, 0] - }, - { - POSITION: [25, 15, 0.001, 0, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 240, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 300, 0] - } - ] -} -Class.tripleur = { - PARENT: "genericTank", - LABEL: "Tripleur", - BODY: { - SPEED: base.SPEED * 1.1, - DAMAGE: base.DAMAGE * 1 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [30, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, -30, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, -30, 0] - }, - { - POSITION: [20, 15, 0.001, 0, 0, 30, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 30, 0] - } - ] -} -Class.trailblazer = { - PARENT: "genericTank", - LABEL: "Trailblazer", - BODY: { - HEALTH: 0.8 * base.HEALTH, - SHIELD: 0.8 * base.SHIELD, - DENSITY: 0.6 * base.DENSITY, - }, - HAS_NO_RECOIL: false, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - } - ] -} -Class.flazer = { - PARENT: "genericTank", - LABEL: "Flazer", - BODY: { - HEALTH: 0.8 * base.HEALTH, - SHIELD: 0.8 * base.SHIELD, - DENSITY: 0.6 * base.DENSITY, - }, - HAS_NO_RECOIL: false, - GUNS: [ - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [25, 15, 0.001, 0, 0, 0, 0] - }, - { - POSITION: [12, 10, 1.4, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.flankGuard]), - TYPE: "bullet", - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - } - ] -} -Class.jouster = { - PARENT: "genericTank", - LABEL: "Jouster", - BODY: { - SPEED: base.SPEED * 1.4, - DAMAGE: base.DAMAGE * 0.8 - }, - HAS_NO_RECOIL: true, - STAT_NAMES: { - BULLET_SPEED: 'Lance Range', - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - }, - GUNS: [ - { - POSITION: [15, 15, 0.001, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }]), - TYPE: ["bullet", { ALPHA: 0 }], - AUTOFIRE: true - } - }, - { - POSITION: [20, 15, 0.001, 0, 0, 0, 0] - } - ] -} -Class.joustebrid = makeHybrid(Class.jouster, "Joustebrid"); -Class.autojoustebrid = makeAuto(Class.joustebrid, "Auto-Joustebrid"); - -Class.jouster.UPGRADES_TIER_2 = [ - "lancer", - "joustebrid", - "smasher", -]; -Class.lancer.UPGRADES_TIER_3 = [ - "chasseur", - "lancebrid", - "trilancer", - "autolancer", -]; -Class.chasseur.UPGRADES_TIER_3 = [ - "tripleur", - "autochasseur", - "trichasseur", -]; -Class.joustebrid.UPGRADES_TIER_3 = [ - "lancebrid", - "autojoustebrid", -]; -Class.trilancer.UPGRADES_TIER_4 = [ - "hexalancer", - "trailblazer", - "trichasseur", -]; -Class.autolancer.UPGRADES_TIER_3 = [ - "autochasseur", -]; -Class.trichasseur.UPGRADES_TIER_5 = [ - "spiny", - "autotrichasseur", -]; -Class.hexalancer.UPGRADES_TIER_5 = [ - "hedgehog", - "spiny", -]; -Class.trailblazer.UPGRADES_TIER_5 = [ - "flazer", -]; -Class.hedgehog.UPGRADES_TIER_6 = [ - "autohedgehog", -]; - -Class.addons.UPGRADES_TIER_0.push("jouster"); \ No newline at end of file diff --git a/server/modules/definitions/addons/playerskins.js b/server/modules/definitions/addons/playerskins.js deleted file mode 100644 index e7a1ad046..000000000 --- a/server/modules/definitions/addons/playerskins.js +++ /dev/null @@ -1,175 +0,0 @@ -const { combineStats, makeAuto, makeHybrid, makeHybridDrive, makeOver, makeDeco, makeGuard, makeBird, makeMulti, makeCeption, makeCeptionNerf, makeTracker } = require('../facilitators.js'); -const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); -require('../groups/generics.js'); -const g = require('../gunvals.js'); - - -Class.bsignalcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png?v=1708615075011") -Class.tcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png?v=1708536680813") -Class.dfxcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif?v=1708618924966") -Class.primalcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp?v=1708602763032") -Class.kangaroocharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp?v=1708602765689") -Class.cogcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381") -Class.skypecharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png?v=1708623594494") -Class.coincharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png?v=1708619146196") -Class.discordcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png?v=1701908710293") -Class.incomcharm = makeDeco("https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/1200px-Icon-round-Question_mark.svg.png?v=1699273933044") -Class.eggcharm = makeDeco(0, "veryLightGrey") -Class.squarecharm = makeDeco(4, "gold") -Class.trianglecharm = makeDeco(3, "orange") -Class.pentagoncharm = makeDeco(5, "purple") -Class.gemcharm = makeDeco(6, "aqua") - -Class.bsignalskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], - TYPE: "bsignalcharm" - }] -}; -Class.tankcharmskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [10, 6, 5.5, 0, 360, 3], - TYPE: "tcharm" - }] -}; -Class.dfxskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], - TYPE: "dfxcharm" - }] -}; -Class.primalskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [20, 0, 0, 0, 360, 3], - TYPE: "primalcharm" - }] -}; -Class.kangarooskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], - TYPE: "kangaroocharm" - }] -}; -Class.cswmskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 0.5], - TYPE: "sandwichdeco" - }] -}; -Class.cogskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], - TYPE: "cogcharm" - }] -}; -Class.skypeskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], - TYPE: "skypecharm" - }] -}; -Class.coinskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], - TYPE: "coincharm" - }] -}; -Class.discordskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], - TYPE: "discordcharm" - }] -}; -Class.deltaDecoskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 3], - TYPE: "deltaDeco" - }] -}; -Class.incomskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [18, 0, 0, 0, 360, 3], - TYPE: "incomcharm" - }] -}; -Class.eggskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [10, -5, 5.5, 0, 360, 3], - TYPE: "eggcharm" - }] -}; -Class.squareskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [10, -5, 5.5, 0, 360, 3], - TYPE: "squarecharm" - }] -}; -Class.triangleskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [10, -5, 5.5, 0, 360, 3], - TYPE: "trianglecharm" - }] -}; -Class.pentagonskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [10, -5, 5.5, 0, 360, 3], - TYPE: "pentagoncharm" - }] -}; -Class.gemskin = { - MAX_CHILDREN: 1, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), - TURRETS: [{ - POSITION: [10, -5, 5.5, 0, 360, 3], - TYPE: "gemcharm" - }] -}; \ No newline at end of file diff --git a/server/modules/definitions/addons/revolutionistPack.js b/server/modules/definitions/addons/revolutionistPack.js deleted file mode 100644 index d421a9d9c..000000000 --- a/server/modules/definitions/addons/revolutionistPack.js +++ /dev/null @@ -1,186 +0,0 @@ -// An addon is guaranteed to run only after all groups are loaded. -// This is helpful, if your group relies on all other definitions already being loaded. -// Addons that are dependant on other addons should be named something like -// "[PARENT ADDON NAME]-[EXTENSION NAME].js", to make sure that it would run after that addon ran. - -const { combineStats, makeDeco, makeAuto, makeCeption } = require('../facilitators'); -const g = require('../gunvals'); - - - // This addon is enabled by default. - // If you want to disable, uncomment the line below. - return console.log('[revolutionistPack.js] Addon disabled by default'); - - Class.revoautoTurret = { - PARENT: "genericTank", - LABEL: "Turret", - BODY: { - FOV: 0.8, - }, - COLOR: "grey", - CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), - TYPE: "bullet", - }, - }, - ], -} - Class.solarioTurret1 = { - PARENT: "genericTank", - LABEL: "Turret", - CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], - COLOR: 13, - SHAPE: 0, - BODY: { - FOV: 0.8, - }, - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), - TYPE: "bullet", - }, - }, - ], -} - Class.solarioTurret2 = { - PARENT: "genericTank", - CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], - LABEL: "Turret", - COLOR: 13, - SHAPE: 3, - BODY: { - FOV: 0.8, - }, - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), - TYPE: "bullet", - }, - }, - ], -} - Class.solarioTurret3 = { - PARENT: "genericTank", - LABEL: "Turret", - CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], - - SHAPE: 4, - COLOR: 13, - BODY: { - FOV: 0.8, - }, - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), - TYPE: "bullet", - }, - }, - ], -} - Class.solarioTurret4 = { - PARENT: "genericTank", - LABEL: "Turret", - CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], - COLOR: 13, - SHAPE: 6, - BODY: { - FOV: 0.8, - }, - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.turret, g.autoTurret, g.power]), - TYPE: "bullet", - }, - }, - ], -} - Class.revoturretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [4.65, 9.85, 0, 90, 220, 1], - TYPE: "revoautoTurret", - }, { - POSITION: [4.65, 9.85, 0, 270, 220, 1], - TYPE: "revoautoTurret", - }] -}; - Class.solarioturretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 13, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [4.65, 9.85, 0, 90, 220, 1], - TYPE: "solarioTurret1", - }, { - POSITION: [4.65, 9.85, 0, 180, 220, 1], - TYPE: "solarioTurret2", - }, { - POSITION: [4.65, 9.85, 0, 270, 220, 1], - TYPE: "solarioTurret3", - }, { - POSITION: [4.65, 9.85, 0, 0, 220, 1], - TYPE: "solarioTurret4", - }] -}; -Class.revolution = { - PARENT: "genericTank", - LABEL: "Revolutionist", - DANGER: 6, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet", - }, - }, - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "revoturretBase", - }, - ], -}; -Class.solario = { - PARENT: "genericTank", - LABEL: "Solario", - COLOR: 13, - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_05_0sn_Kleki.png?v=1701808881532', - SIZE: 15, - DANGER: 6, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet", - }, - }, - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "solarioturretBase", - }, - ], -}; - Class.autorevol = makeAuto(Class.revolution, "Auto-Revolutionist"); - Class.revoceptionist = makeCeption(Class.revolution, "Revo-Ception"); - Class.revolution.UPGRADES_TIER_0 = []; - Class.addons.UPGRADES_TIER_0.push('revolution'); - Class.revolution.UPGRADES_TIER_0.push('revoceptionist', 'autorevol', 'solario'); \ No newline at end of file diff --git a/server/modules/definitions/addons/woomeraddonmeow.js b/server/modules/definitions/addons/woomeraddonmeow.js deleted file mode 100644 index 079863f40..000000000 --- a/server/modules/definitions/addons/woomeraddonmeow.js +++ /dev/null @@ -1,64 +0,0 @@ -// An addon is guaranteed to run only after all groups are loaded. -// This is helpful, if your group relies on all other definitions already being loaded. -// Addons that are dependant on other addons should be named something like -// "[PARENT ADDON NAME]-[EXTENSION NAME].js", to make sure that it would run after that addon ran. -module.Class = ({ Class }) => { - -const { base } = require('../constants.js'); - -// This addon is disabled by default. -// You can also disable addons by not making them end with '.js' -// If you want to enable, simply make the line below just not run. -return console.log('[woomeraddonmeow.js] Addon disabled by default'); - - /* - Class.littleHunter = { - PARENT: "genericTank", - LABEL: "Subduer", - DANGER: 5, - BODY: { - ACCELERATION: base.ACCEL * 0.9, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [23, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, { - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.hunter]), - TYPE: "bullet" - } - }] -}; -Class.flankdue = makeMulti({ - PARENT: "genericTank", - DANGER: 5, - BODY: { - ACCELERATION: base.ACCEL * 0.9, - FOV: 1.1, - SPEED: base.SPEED * 1.1, - }, - GUNS: [{ - POSITION: [23, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, { - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter]), - TYPE: "bullet" - } - }] -}, 3, "Flankduer") -Class.autolittleHunter = makeAuto(Class.littleHunter, "Auto-Subduer") -Class.littleHunterbrid = makeHybrid('littleHunter', "Subduer-Hybrid") -Class.autolittleHunterbrid = makeHybrid('autolittleHunter', "Auto-Subduer-Hybrid") - -*/ -} \ No newline at end of file diff --git a/server/modules/definitions/combined.js b/server/modules/definitions/combined.js index cb2cf3a8d..f8b530de3 100644 --- a/server/modules/definitions/combined.js +++ b/server/modules/definitions/combined.js @@ -80,4 +80,4 @@ let i = 0; for (let key in Class) { if (!Class.hasOwnProperty(key)) continue; Class[key].index = i++; -} \ No newline at end of file +} diff --git a/server/modules/definitions/constants.js b/server/modules/definitions/constants.js index 23182c9e9..25ac48e7f 100644 --- a/server/modules/definitions/constants.js +++ b/server/modules/definitions/constants.js @@ -75,12 +75,6 @@ module.exports = { BULLET_DAMAGE: 'Ball Damage', RELOAD: 'Ball Density', }, - lancer: { - BULLET_HEALTH: 'Lance Longevity', - BULLET_PEN: 'Lance Sharpness', - BULLET_DAMAGE: 'Lance Damage', - RELOAD: 'Lance Density' - } }, gunCalcNames: { default: 0, diff --git a/server/modules/definitions/facilitators.js b/server/modules/definitions/facilitators.js index d90094261..8f0261838 100644 --- a/server/modules/definitions/facilitators.js +++ b/server/modules/definitions/facilitators.js @@ -1,7 +1,6 @@ -const { gunCalcNames } = require('./constants.js'); -const { MAX_SKILL } = require("../../config.js"); -const g = require('./gunvals.js'); - +const { gunCalcNames } = require('./constants.js') +const { MAX_SKILL } = require("../../config.js") +const g = require('./gunvals.js') let skcnv = { atk: 6, spd: 4, @@ -13,9 +12,9 @@ let skcnv = { pen: 1, rgn: 8, hlt: 7, -}; +} -// GUN DEFINITIONS +// gun definitions exports.combineStats = function (stats) { try { // Build a blank array of the appropiate length @@ -65,13 +64,13 @@ exports.combineStats = function (stats) { console.log(err); console.log(JSON.stringify(stats)); } -}; +} exports.setBuild = (build) => { let skills = build.split(build.includes("/") ? "/" : "").map((r) => +r); if (skills.length !== 10) throw new RangeError("Build must be made up of 10 numbers"); return [6, 4, 3, 5, 2, 9, 0, 1, 8, 7].map((r) => skills[r]); -}; +} exports.skillSet = (args) => { let skills = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; for (let s in args) { @@ -79,9 +78,9 @@ exports.skillSet = (args) => { skills[skcnv[s]] = Math.round(MAX_SKILL * args[s]); } return skills; -}; +} -// FUNCTIONS +// functions exports.dereference = type => { let output = JSON.parse(JSON.stringify(type)); if (type.GUNS) { @@ -104,7 +103,28 @@ exports.dereference = type => { return output; } -// CANNON FUNCTIONS +// gun functions +exports.makeMulti = (type, count, name = -1, startRotation = 0) => { + type = ensureIsClass(type); + let greekNumbers = ',Double ,Triple ,Quad ,Penta ,Hexa ,Septa ,Octo ,Nona ,Deca ,Hendeca ,Dodeca ,Trideca ,Tetradeca ,Pentadeca ,Hexadeca ,Septadeca ,Octadeca ,Nonadeca ,Icosa ,Henicosa ,Doicosa ,Triaicosa ,Tetraicosa ,Pentaicosa ,Hexaicosa ,Septaicosa ,Octoicosa ,Nonaicosa ,Triaconta '.split(','), + output = exports.dereference(type), + fraction = 360 / count; + output.GUNS = []; + for (let gun of type.GUNS) { + for (let i = 0; i < count; i++) { + let newgun = exports.dereference(gun); + if (Array.isArray(newgun.POSITION)) { + newgun.POSITION[5] += startRotation + fraction * i; + } else { + newgun.POSITION.ANGLE = (newgun.POSITION.ANGLE ?? 0) + startRotation + fraction * i; + } + if (gun.PROPERTIES) newgun.PROPERTIES = gun.PROPERTIES; + output.GUNS.push(newgun); + }; + } + output.LABEL = name == -1 ? (greekNumbers[count - 1] || (count + ' ')) + type.LABEL : name; + return output; +} exports.makeGuard = (type, name = -1) => { type = ensureIsClass(type); let output = exports.dereference(type), @@ -122,43 +142,6 @@ exports.makeGuard = (type, name = -1) => { output.LABEL = name == -1 ? type.LABEL + " Guard" : name; return output; } -exports.makeConq = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type), - cannons = [{ - POSITION: [18, 14, 1, 0, 0, 180, 0], - }, { - POSITION: [2, 14, 1.1, 18, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.trap, g.setTrap]), - TYPE: "setTrap", - STAT_CALCULATOR: gunCalcNames.block - }, - }]; - output.GUNS = type.GUNS == null ? cannons : type.GUNS.concat(cannons); - output.LABEL = name == -1 ? type.LABEL + " Conqueror" : name; - return output; -} -exports.makeSplit = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let cannons = [{ - POSITION: [18, 8, 1, 0, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.basic, g.flankGuard]), - TYPE: "bullet", - }, - }, { - POSITION: [18, 8, 1, 0, 0, 270, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.basic, g.flankGuard]), - TYPE: "bullet", - }, - }]; - output.GUNS = type.GUNS == null ? cannons : type.GUNS.concat(cannons); - output.LABEL = name == -1 ? "Split " + type.LABEL : name; - return output; -} exports.addBackGunner = (type, name = -1) => { type = ensureIsClass(type); let output = exports.dereference(type); @@ -181,30 +164,14 @@ exports.addBackGunner = (type, name = -1) => { output.LABEL = name == -1 ? type.LABEL : name; return output; } -exports.makeMulti = (type, count, name = -1, startRotation = 0) => { - type = ensureIsClass(type); - let greekNumbers = ',Double ,Triple ,Quad ,Penta ,Hexa ,Septa ,Octo ,Nona ,Deca ,Hendeca ,Dodeca ,Trideca ,Tetradeca ,Pentadeca ,Hexadeca ,Septadeca ,Octadeca ,Nonadeca ,Icosa ,Henicosa ,Doicosa ,Triaicosa ,Tetraicosa ,Pentaicosa ,Hexaicosa ,Septaicosa ,Octoicosa ,Nonaicosa ,Triaconta '.split(','), - output = exports.dereference(type), - fraction = 360 / count; - output.GUNS = []; - for (let gun of type.GUNS) { - for (let i = 0; i < count; i++) { - let newgun = exports.dereference(gun); - if (Array.isArray(newgun.POSITION)) { - newgun.POSITION[5] += startRotation + fraction * i; - } else { - newgun.POSITION.ANGLE = (newgun.POSITION.ANGLE ?? 0) + startRotation + fraction * i; - } - if (gun.PROPERTIES) newgun.PROPERTIES = gun.PROPERTIES; - output.GUNS.push(newgun); - }; - } - output.LABEL = name == -1 ? (greekNumbers[count - 1] || (count + ' ')) + type.LABEL : name; - return output; -} -exports.makeBird = (type, name = -1, frontRecoilFactor = 1, backRecoilFactor = 1, color) => { +exports.makeBird = (type, name = -1, options = {}) => { type = ensureIsClass(type); let output = exports.dereference(type); + let frontRecoilFactor = options.frontRecoil ?? 1; + let backRecoilFactor = options.frontRecoil ?? 1; + let color = options.frontRecoil; + let superBird = options.super ?? false; + // Thrusters let backRecoil = 0.5 * backRecoilFactor; let thrusterProperties = { SHOOT_SETTINGS: exports.combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster, { recoil: backRecoil }]), TYPE: "bullet", LABEL: gunCalcNames.thruster }; @@ -212,12 +179,21 @@ exports.makeBird = (type, name = -1, frontRecoilFactor = 1, backRecoilFactor = 1 POSITION: [16, 8, 1, 0, 0, 150, 0.1], PROPERTIES: thrusterProperties }, { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], + POSITION: [16, 8, 1, 0, 0, -150, 0.1], PROPERTIES: thrusterProperties }, { POSITION: [18, 8, 1, 0, 0, 180, 0.6], PROPERTIES: thrusterProperties }]; + if (superBird) { + shootyBois.splice(0, 0, { + POSITION: [14, 8, 1, 0, 0, 130, 0.6], + PROPERTIES: thrusterProperties + }, { + POSITION: [14, 8, 1, 0, 0, -130, 0.6], + PROPERTIES: thrusterProperties + }) + } // Assign thruster color if (color) for (let gun of shootyBois) { gun.PROPERTIES.TYPE = [gun.PROPERTIES.TYPE, { COLOR: color }]; @@ -240,378 +216,94 @@ exports.makeBird = (type, name = -1, frontRecoilFactor = 1, backRecoilFactor = 1 return output; } -// SPAWNER FUNCTIONS -exports.makeHybrid = (type, name = -1) => { +// drone functions +exports.makeOver = (type, name = -1, options = {}) => { type = ensureIsClass(type); let output = exports.dereference(type); - let spawner = { - POSITION: [6, 12, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.weak]), - TYPE: ["drone", { INDEPENDENT: true }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: false, - MAX_CHILDREN: 3, - }, - }; - output.GUNS = type.GUNS == null ? [spawner] : type.GUNS.concat([spawner]); - output.LABEL = name == -1 ? "Hybrid " + type.LABEL : name; - return output; -} -exports.makeHybridDrive = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let spawner = { - POSITION: [6, 12, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.weak]), - TYPE: ["turretedDrone", { INDEPENDENT: true }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: false, - MAX_CHILDREN: 3, - }, + + let angle = 180 - (options.angle ?? 125); + let count = options.count ?? 2; + let independent = options.independent ?? false; + let cycle = options.cycle ?? true; + let maxChildren = options.maxDrones ?? 3; + let stats = options.extraStats ?? []; + let spawnerProperties = { + SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer, ...stats]), + TYPE: ["drone", {INDEPENDENT: independent}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: cycle, + MAX_CHILDREN: maxChildren, }; - let spawnerdeco = { - POSITION: [7, 14, 0, 180, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + + let spawners = []; + if (count % 2 == 1) { + spawners.push({ + POSITION: [6, 12, 1.2, 8, 0, 180, 0], + PROPERTIES: spawnerProperties, + }) + } + for (let i = 2; i <= (count - count % 2); i += 2) { + spawners.push({ + POSITION: [6, 12, 1.2, 8, 0, 180 - angle * i / 2, 0], + PROPERTIES: spawnerProperties, + }, { + POSITION: [6, 12, 1.2, 8, 0, 180 + angle * i / 2, 0], + PROPERTIES: spawnerProperties, + }) } - output.GUNS = type.GUNS == null ? [spawner] : type.GUNS.concat([spawner]); - output.TURRETS = type.TURRETS == null ? [spawnerdeco] : type.TURRETS.concat([spawnerdeco]); - output.LABEL = name == -1 ? "Hybrid " + type.LABEL : name; - return output; -} -exports.makeOver = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let spawners = [{ - POSITION: [6, 12, 1.2, 8, 0, 125, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 3, - }, - }, { - POSITION: [6, 12, 1.2, 8, 0, 235, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 3, - }, - }]; + output.GUNS = type.GUNS == null ? spawners : type.GUNS.concat(spawners); output.LABEL = name == -1 ? "Over" + type.LABEL.toLowerCase() : name; return output; } -exports.makeOversplit = (type, name = -1) => { +exports.makeBattle = (type, name = -1, options = {}) => { type = ensureIsClass(type); let output = exports.dereference(type); - let spawners = [{ - POSITION: [6, 12, 1.2, 8, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 3, - }, - }, { - POSITION: [6, 12, 1.2, 8, 0, 270, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 3, - }, - }]; - output.GUNS = type.GUNS == null ? spawners : type.GUNS.concat(spawners); - output.LABEL = name == -1 ? "Over" + type.LABEL.toLowerCase() : name; - return output; -} -exports.makeBattle = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let spawner1 = { - POSITION: [7, 7.5, 0.6, 7, 4, 125, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - let spawner2 = { - POSITION: [7, 7.5, 0.6, 7, -4, 125, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - let spawner3 = { - POSITION: [7, 7.5, 0.6, 7, 4, 235, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - let spawner4 = { - POSITION: [7, 7.5, 0.6, 7, -4, 235, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - if (type.TURRETS != null) { - output.TURRETS = type.TURRETS; - } - if (type.GUNS == null) { - output.GUNS = [spawner1, spawner2, spawner3, spawner4]; - } else { - output.GUNS = [...type.GUNS, spawner1, spawner2, spawner3, spawner4]; - } - if (name == -1) { - output.LABEL = "Battle" + type.LABEL.toLowerCase(); - } else { - output.LABEL = name; - } - return output; -} -exports.makeCap = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let spawner1 = { - POSITION: [4.5, 10, 1, 10.5, 0, 125, 0], - }; - let spawner2 = { - POSITION: [1, 12, 1, 15, 0, 125, 0], - PROPERTIES: { - MAX_CHILDREN: 4, - SHOOT_SETTINGS: exports.combineStats([g.factory, g.babyfactory]), - TYPE: "minion", - STAT_CALCULATOR: gunCalcNames.drone, - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, - }; - let spawner3 = { - POSITION: [11.5, 12, 1, 0, 0, 125, 0], - }; - let spawner4 = { - POSITION: [4.5, 10, 1, 10.5, 0, 235, 0], - }; - let spawner5 = { - POSITION: [1, 12, 1, 15, 0, 235, 0], - PROPERTIES: { - MAX_CHILDREN: 4, - SHOOT_SETTINGS: exports.combineStats([g.factory, g.babyfactory]), - TYPE: "minion", - STAT_CALCULATOR: gunCalcNames.drone, - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, - }; - let spawner6 = { - POSITION: [11.5, 12, 1, 0, 0, 235, 0], - }; - if (type.TURRETS != null) { - output.TURRETS = type.TURRETS; - } - if (type.GUNS == null) { - output.GUNS = [spawner1, spawner2, spawner3, spawner4, spawner5, spawner6]; - } else { - output.GUNS = [ - ...type.GUNS, - spawner1, - spawner2, - spawner3, - spawner4, - spawner5, - spawner6, - ]; - } - if (name == -1) { - output.LABEL = "Cap" + type.LABEL.toLowerCase(); - } else { - output.LABEL = name; - } - return output; -} -exports.makeCross = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let spawner1 = { - POSITION: [6, 12, 1.2, 8, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }; - let spawner2 = { - POSITION: [6, 12, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }; - let spawner3 = { - POSITION: [6, 12, 1.2, 8, 0, 270, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }; - if (type.TURRETS != null) { - output.TURRETS = type.TURRETS; - } - if (type.GUNS == null) { - output.GUNS = [spawner1, spawner2, spawner3]; - } else { - output.GUNS = [...type.GUNS, spawner1, spawner2, spawner3]; - } - if (name == -1) { - output.LABEL = "Cross-" + type.LABEL; - } else { - output.LABEL = name; - } - return output; -} -exports.makeSwarming = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let spawner = { - POSITION: [7, 7.5, 0.6, 7, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - if (type.TURRETS != null) { - output.TURRETS = type.TURRETS; - } - if (type.GUNS == null) { - output.GUNS = [spawner]; - } else { - output.GUNS = [...type.GUNS, spawner]; - } - if (name == -1) { - output.LABEL = "Swarming " + type.LABEL; - } else { - output.LABEL = name; - } - return output; -} -exports.makeBiSwarming = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let spawner1 = { - POSITION: [7, 7.5, 0.6, 7, 0, 25, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - let spawner2 = { - POSITION: [7, 7.5, 0.6, 7, 0, -25, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - if (type.TURRETS != null) { - output.TURRETS = type.TURRETS; - } - if (type.GUNS == null) { - output.GUNS = [spawner1, spawner2]; - } else { - output.GUNS = [...type.GUNS, spawner1, spawner2]; - } - if (name == -1) { - output.LABEL = "Bi-Swarming " + type.LABEL; - } else { - output.LABEL = name; - } - return output; -} -exports.makeTriSwarming = (type, name = -1) => { - type = ensureIsClass(type); - let output = exports.dereference(type); - let spawner1 = { - POSITION: [7, 7.5, 0.6, 7, 0, 45, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - let spawner2 = { - POSITION: [7, 7.5, 0.6, 7, 0, -45, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }; - let spawner3 = { - POSITION: [7, 7.5, 0.6, 7, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: exports.combineStats([g.swarm]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, + + let angle = 180 - (options.angle ?? 125); + let count = options.count ?? 2; + let independent = options.independent ?? false; + let stats = options.extraStats ?? []; + let spawnerProperties = { + SHOOT_SETTINGS: exports.combineStats([g.swarm, ...stats]), + TYPE: independent ? "autoswarm" : "swarm", + STAT_CALCULATOR: gunCalcNames.swarm, }; - if (type.TURRETS != null) { - output.TURRETS = type.TURRETS; - } - if (type.GUNS == null) { - output.GUNS = [spawner1, spawner2, spawner3]; - } else { - output.GUNS = [...type.GUNS, spawner1, spawner2, spawner3]; - } - if (name == -1) { - output.LABEL = "Tri-Swarming " + type.LABEL; - } else { - output.LABEL = name; + + let spawners = []; + if (count % 2 == 1) { + spawners.push({ + POSITION: [7, 7.5, 0.6, 7, 4, 180, 0], + PROPERTIES: spawnerProperties, + }, { + POSITION: [7, 7.5, 0.6, 7, -4, 180, 0.5], + PROPERTIES: spawnerProperties, + }) + } + for (let i = 2; i <= (count - count % 2); i += 2) { + spawners.push({ + POSITION: [7, 7.5, 0.6, 7, 4, 180 - angle * i / 2, 0], + PROPERTIES: spawnerProperties, + }, { + POSITION: [7, 7.5, 0.6, 7, -4, 180 - angle * i / 2, 0.5], + PROPERTIES: spawnerProperties, + }, { + POSITION: [7, 7.5, 0.6, 7, 4, 180 + angle * i / 2, 0], + PROPERTIES: spawnerProperties, + }, { + POSITION: [7, 7.5, 0.6, 7, -4, 180 + angle * i / 2, 0.5], + PROPERTIES: spawnerProperties, + }) } + + output.GUNS = type.GUNS == null ? spawners : type.GUNS.concat(spawners); + output.LABEL = name == -1 ? "Battle" + type.LABEL.toLowerCase() : name; return output; } -// AUTO FUNCTIONS +// turret functions exports.makeAuto = (type, name = -1, options = {}) => { type = ensureIsClass(type); let turret = { @@ -664,58 +356,6 @@ exports.makeAuto = (type, name = -1, options = {}) => { output.DANGER = type.DANGER + 1; return output; } -exports.makeTracker = (type, name = -1, options = {}) => { - let turret = { - type: "tracker3gun", - size: 10, - independent: true, - color: 16, - angle: 180, - }; - if (options.type != null) { - turret.type = options.type; - } - if (options.size != null) { - turret.size = options.size; - } - if (options.independent != null) { - turret.independent = options.independent; - } - if (options.color != null) { - turret.color = options.color; - } - if (options.angle != null) { - turret.angle = options.angle; - } - let output = exports.dereference(type); - let autogun = { - /********* SIZE X Y ANGLE ARC */ - POSITION: [turret.size, 0, 0, turret.angle, 360, 1], - TYPE: [ - turret.type, - { - CONTROLLERS: ["nearestDifferentMaster"], - INDEPENDENT: turret.independent, - COLOR: turret.color, - }, - ], - }; - if (type.GUNS != null) { - output.GUNS = type.GUNS; - } - if (type.TURRETS == null) { - output.TURRETS = [autogun]; - } else { - output.TURRETS = [...type.TURRETS, autogun]; - } - if (name == -1) { - output.LABEL = "Auto-" + type.LABEL; - } else { - output.LABEL = name; - } - output.DANGER = type.DANGER + 1; - return output; -} exports.makeCeption = (type, name = -1, options = {}) => { type = ensureIsClass(type); let turret = { @@ -759,91 +399,6 @@ exports.makeCeption = (type, name = -1, options = {}) => { output.DANGER = type.DANGER + 1; return output; } -exports.makeCeptionNerf = (type, name = -1, options = {}) => { - type = ensureIsClass(type); - let turret = { - type: "autoTurretNerf", - size: 12.5, - independent: true, - }; - if (options.type != null) { - turret.type = options.type; - } - if (options.size != null) { - turret.size = options.size; - } - if (options.independent != null) { - turret.independent = options.independent; - } - let output = exports.dereference(type); - let autogun = { - /********* SIZE X Y ANGLE ARC */ - POSITION: [turret.size, 0, 0, 180, 360, 1], - TYPE: [ - type, - { - CONTROLLERS: ["nearestDifferentMaster"], - INDEPENDENT: turret.independent, - }, - ], - }; - if (type.GUNS != null) { - output.GUNS = type.GUNS; - } - if (type.TURRETS == null) { - output.TURRETS = [autogun]; - } else { - output.TURRETS = [...type.TURRETS, autogun]; - } - if (name == -1) { - output.LABEL = type.LABEL + "-Ception"; - } else { - output.LABEL = name; - } - output.DANGER = type.DANGER + 1; - return output; -} -exports.addBackTurret = (type, name = "", options = {}) => { - type = ensureIsClass(type); - let turret = { - type: "autoTurret", - size: 11, - angle: 180, - }; - if (options.type != null) { - turret.type = options.type; - } - if (options.size != null) { - turret.size = options.size; - } - if (options.color != null) { - turret.color = options.color; - } - if (options.angle != null) { - turret.angle = options.angle; - } - let output = exports.dereference(type); - let autogun = { - POSITION: [turret.size, 8, 0, turret.angle, 190, 1], - TYPE: [ - turret.type, - { - COLOR: turret.color, - }, - ], - }; - if (type.GUNS != null) { - output.GUNS = type.GUNS; - } - if (type.TURRETS == null) { - output.TURRETS = [autogun]; - } else { - output.TURRETS = [...type.TURRETS, autogun]; - } - output.LABEL = name; - output.DANGER = type.DANGER + 1; - return output; -} exports.makeDeco = (shape = 0, color = 16) => { return { PARENT: "genericTank", @@ -851,13 +406,81 @@ exports.makeDeco = (shape = 0, color = 16) => { COLOR: color, }; } -exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor, symbolType) => { +exports.makeRadialAuto = (type, options = {}) => { + + + /* + Available options: + - count: number of turrets + - turret: what turret definition to use (leave null to make a new turret), overrides the `type` parameter + - extraStats: extra stats to append to all turret barrels, on top of g.autoTurret + - turretIdentifier: Class[turretIdentifier] to refer to the turret in other uses if necessary + - size: turret size + - x: turret X + - arc: turret FOV arc + - angle: turret ring offset angle + - label: label of the final tank + - rotation: rotation speed of the final tank + - danger: danger value of the final tank + - body: body stats of the final tank + */ + + let count = options.count ?? 3; + let isTurret = options.isTurret ?? false; + let turretIdentifier = type; + + if (!isTurret) { + type = exports.dereference(ensureIsClass(type)); + + let extraStats = options.extraStats ?? []; + turretIdentifier = options.turretIdentifier ?? `auto${type.LABEL}Gun`; + + Class[turretIdentifier] = { + PARENT: 'genericTank', + LABEL: "", + BODY: { + FOV: 3, + }, + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + COLOR: "grey", + GUNS: type.GUNS, + TURRETS: type.TURRETS, + PROPS: type.PROPS, + } + + for (let gun of Class[turretIdentifier].GUNS) { + if (!gun.PROPERTIES) continue; + if (!gun.PROPERTIES.SHOOT_SETTINGS) continue; + + gun.PROPERTIES.SHOOT_SETTINGS = exports.combineStats([gun.PROPERTIES.SHOOT_SETTINGS, g.autoTurret, ...extraStats]) + } + } + + let LABEL = options.label ?? (type.LABEL + "-" + count); + let turretSize = options.size ?? 11; + let turretX = options.x ?? 8; + let turretArc = options.arc ?? 190; + let turretAngle = options.angle ?? 0; + + return { + PARENT: 'genericTank', + LABEL, + FACING_TYPE: ["spin", {speed: options.rotation ?? 0.02}], + DANGER: options.danger ?? (type.DANGER + 2), + BODY: options.body ?? undefined, + TURRETS: exports.weaponArray({ + POSITION: [turretSize, turretX, 0, turretAngle, turretArc, 0], + TYPE: turretIdentifier + }, count) + } +} +exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor) => { let isHeal = damageFactor < 0; let auraType = isHeal ? "healAura" : "aura"; - if (symbolType == null) symbolType = isHeal ? "healerSymbol" : "auraSymbol"; + let symbolType = isHeal ? "healerSymbol" : "auraSymbol"; auraColor = auraColor ?? (isHeal ? 12 : 0); return { - PARENT: ["genericTank"], + PARENT: "genericTank", INDEPENDENT: true, LABEL: "", COLOR: 17, @@ -881,42 +504,8 @@ exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor, s ] }; } -exports.makeAura = (type, name = -1, options = {}) => { - let turret = { - type: "auraBasicGen", - size: 14, - }; - if (options.type != null) { - turret.type = options.type; - } - if (options.size != null) { - turret.size = options.size; - } - let output = exports.dereference(type); - let aurathing = { - /********* SIZE X Y ANGLE ARC */ - POSITION: [turret.size, 0, 0, 0, 0, 1], - TYPE: [ - turret.type, - ], - }; - if (type.GUNS != null) { - output.GUNS = type.GUNS; - } - if (type.TURRETS == null) { - output.TURRETS = [aurathing]; - } else { - output.TURRETS = [...type.TURRETS, aurathing]; - } - if (name == -1) { - output.LABEL = "Aura " + type.LABEL; - } else { - output.LABEL = name; - } - output.DANGER = type.DANGER + 2; - return output; -} +// misc functions exports.menu = (name = -1, color = -1, shape = 0) => { let gun = { POSITION: [18, 10, -1.4, 0, 0, 0, 0], @@ -935,12 +524,11 @@ exports.menu = (name = -1, color = -1, shape = 0) => { IGNORED_BY_AI: true, }; } - exports.weaponArray = (weapons, count) => { if (!Array.isArray(weapons)) { weapons = [weapons] } - let isTurret = weapons[0].PROPERTIES == undefined; + let isTurret = weapons[0].TYPE != undefined; let angleIndex = isTurret ? 3 : 5; let output = []; @@ -958,7 +546,6 @@ exports.weaponArray = (weapons, count) => { } return output; } - class LayeredBoss { constructor(identifier, NAME, PARENT = "celestial", SHAPE = 9, COLOR = 0, trapTurretType = "baseTrapTurret", trapTurretSize = 6.5, layerScale = 5, BODY, SIZE, VALUE) { this.identifier = identifier ?? NAME.charAt(0).toLowerCase() + NAME.slice(1); diff --git a/server/modules/definitions/groups/bosses.js b/server/modules/definitions/groups/bosses.js index da1007643..e4ba2d6ca 100644 --- a/server/modules/definitions/groups/bosses.js +++ b/server/modules/definitions/groups/bosses.js @@ -1,2943 +1,2943 @@ -const { combineStats, skillSet, makeAuto, addAura, LayeredBoss, makeDeco } = require('../facilitators.js'); -const { base, gunCalcNames, smshskl } = require('../constants.js'); -const g = require('../gunvals.js'); -require('./generics.js'); - -Class.miniboss = { - PARENT: "genericBoss", - CONTROLLERS: ["nearestDifferentMaster", "minion", "canRepel"], - AI: { NO_LEAD: true }, -}; -Class.ramMiniboss = { - PARENT: "genericBoss", - CONTROLLERS: ["nearestDifferentMaster", "canRepel", "mapTargetToGoal"], -}; - -// ELITE CRASHERS -Class.elite = { - PARENT: "miniboss", - LABEL: "Elite Crasher", - COLOR: "pink", - SHAPE: 3, - SIZE: 27, - VARIES_IN_SIZE: true, - VALUE: 15e4, - BODY: { - FOV: 1.25, - SPEED: 0.1 * base.SPEED, - HEALTH: 7 * base.HEALTH, - DAMAGE: 2.5 * base.DAMAGE, - }, -}; -Class.eliteDestroyer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Destroyer", - UPGRADE_COLOR: "pink", - GUNS: [ - { - POSITION: [5, 16, 1, 6, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, { - POSITION: [5, 16, 1, 6, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, { - POSITION: [5, 16, 1, 6, 0, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, - ], - TURRETS: [ - { - POSITION: [11, 0, 0, 180, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, 60, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, -60, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: [ "bigauto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.eliteGunner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Gunner", - UPGRADE_COLOR: "pink", - FACING_TYPE: "toTarget", - GUNS: [ - { - POSITION: [14, 16, 1, 0, 0, 180, 0], - }, { - POSITION: [4, 16, 1.5, 14, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: ["unsetPillbox", {MOTION_TYPE: "glide"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [6, 14, -2, 2, 0, 60, 0], - }, { - POSITION: [6, 14, -2, 2, 0, 300, 0], - }, - ], - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 8, 0, 60, 180, 0], - TYPE: ["auto4gun"], - }, { - POSITION: [14, 8, 0, 300, 180, 0], - TYPE: ["auto4gun"], - }, - ], -}; -Class.eliteSprayer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Sprayer", - UPGRADE_COLOR: "pink", - SKILL: [0, 9, 3, 9, 2, 9, 9, 9, 9, 0], - AI: { NO_LEAD: false }, - HAS_NO_RECOIL: true, - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [6, 0, 0, 0, 360, 1], - TYPE: ["machineTripleTurret", { INDEPENDENT: true }], - }, { - POSITION: [9, 6, -5, 180, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, 180, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, 60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, -5, 60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, -60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, -5, -60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, - ], -}; -Class.eliteBattleship = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Battleship", - UPGRADE_COLOR: "pink", - GUNS: [ - { - POSITION: [4, 6, 0.6, 7, -8, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, 60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, -8, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, -8, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, -60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - ], - TURRETS: [ - { - POSITION: [5, 7, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [5, 7, 0, 120, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [5, 7, 0, 240, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.eliteSpawner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Spawner", - UPGRADE_COLOR: "pink", - MAX_CHILDREN: 9, - AI: { STRAFE: false }, - GUNS: [ - { - POSITION: [11, 16, 1, 0, 0, 60, 0], - }, { - POSITION: [11, 16, 1, 0, 0, 180, 0], - }, { - POSITION: [11, 16, 1, 0, 0, 300, 0], - }, { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [2, 18, 1, 11, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentrySwarm", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [2, 18, 1, 11, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentryTrap", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [2, 18, 1, 11, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentryGun", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, - ], - TURRETS: [ - { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: ["auto4gun", { INDEPENDENT: false, COLOR: -1 }], - }, - ], -}; -Class.eliteTrapGuard = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Trap Guard", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false }, - GUNS: [], - TURRETS: [ - { - POSITION: [9.5, 0, 0, 0, 360, 1], - TYPE: "triTrapGuardTurret", - }, - ], -}; -for (let i = 0; i < 3; i++) { - Class.eliteTrapGuard.GUNS.push( - { - POSITION: [10.5, 6, 1, 0, 0, 120*i+60, 0], - }, { - POSITION: [3, 6, 1.7, 10.5, 0, 120*i+60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ) - Class.eliteTrapGuard.TURRETS.push( - { - POSITION: [5, 8, -7, 120*i+60, 160, 0], - TYPE: ["autoTurret", { INDEPENDENT: false }], - }, { - POSITION: [5, 8, 7, 120*i+60, 160, 0], - TYPE: ["autoTurret", { INDEPENDENT: false }], - }, - ) -}; -Class.eliteSpinner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Spinner", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false }, - FACING_TYPE: ["spin", {speed: 0.1}], - GUNS: [], - TURRETS: [ - { - POSITION: [9.5, 0, 0, 0, 360, 1], - TYPE: ["eliteSpinnerCyclone", {COLOR: -1}], - }, - ], -}; -for (let i = 0; i < 3; i++) { - Class.eliteSpinner.GUNS.push( - { - POSITION: [9.5, 2, 1, -1.5, 11.5, 120*i+10, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [9.5, 2, 1, 3.5, 6.5, 120*i+10, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [9.5, 2, 1, 8.5, 1.5, 120*i+10, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [2, 20, 0.75, 8, 0, 120*i+60, 0], - }, - ) -}; - -// OLD ELITE -Class.oldEliteSprayer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Sprayer (Old)", - UPGRADE_COLOR: "pink", - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 6, 0, 180, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, { - POSITION: [14, 6, 0, 60, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, { - POSITION: [14, 6, 0, -60, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, - ], -}; - -// Legionary Crasher -Class.legionaryCrasherTop = { - PARENT: "elite", - AI: { STRAFE: false, NO_LEAD: false }, - CONTROLLERS: [ ["spin", { independent: true, speed: -0.005 }] ], - INDEPENDENT: true, - GUNS: [], - TURRETS: [], -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasherTop.GUNS.push( - { - POSITION: [4, 9.5, 0.7, 7, 5, 120*i+60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), - TYPE: [ "swarm", { INDEPENDENT: true } ], - STAT_CALCULATOR: gunCalcNames.swarm, - AUTOFIRE: true, - - }, - }, { - POSITION: [4, 9.5, 0.7, 7, -5, 120*i+60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), - TYPE: [ "swarm", { INDEPENDENT: true } ], - STAT_CALCULATOR: gunCalcNames.swarm, - AUTOFIRE: true, - }, - }, - ) - Class.legionaryCrasherTop.TURRETS.push( - { - POSITION: [9.5, 10, 0, 120*i, 190, 0], - TYPE: "auto4gun", - }, - ) -} -Class.legionaryCrasher = { - PARENT: "elite", - LABEL: "Legionary Crasher", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false, NO_LEAD: false }, - HAS_NO_RECOIL: true, - VALUE: 5e6, - SIZE: 75, - BODY: { - FOV: 1.5, - SPEED: 0.1 * base.SPEED, - HEALTH: 2000, - DAMAGE: 5 * base.DAMAGE, - }, - GUNS: [], - TURRETS: [ - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: "legionaryCrasherTop", - } - ], -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasher.GUNS.push( - { - POSITION: [14.5, 13, 1, 0, 0, 120*i, 0], - }, { - POSITION: [3, 13, 1.7, 14.5, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, g.destroyer, { speed: 2.5, size: 0.6, maxSpeed: 3 }]), - TYPE: "legionaryPillbox", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ) -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasher.GUNS.push( - { - POSITION: [5, 12, 1.6, -11, 0, 120*i, 0], - } - ) - Class.legionaryCrasher.TURRETS.push( - { - POSITION: [14, 8, 0, 120*i+60, 180, 0], - TYPE: [ "sprayer", { COLOR: -1, } ], - }, - ) -} - -Class.sprayerLegion = { - PARENT: "elite", - UPGRADE_LABEL: "Sprayer Legion", - UPGRADE_COLOR: "pink", - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 6, 0, 180, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, { - POSITION: [14, 6, 0, 60, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, { - POSITION: [14, 6, 0, -60, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, - ], -}; - -// STRANGE BOSSES -Class.sorcerer = { - PARENT: "miniboss", - LABEL: "Sorcerer", - DANGER: 7, - SHAPE: 0, - COLOR: "veryLightGrey", - UPGRADE_COLOR: "veryLightGrey", - SIZE: 26, - MAX_CHILDREN: 50, - VALUE: 2e5, - BODY: { - FOV: 0.5, - SPEED: 0.12 * base.SPEED, - HEALTH: 6 * base.HEALTH, - DAMAGE: 2 * base.DAMAGE, - }, - GUNS: Array(2).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.machineGun, g.machineGunner, { size: 0.4, spray: 150, speed: 2, shudder: 1.75 }]), - TYPE: "minichip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.summoner = { - PARENT: "miniboss", - LABEL: "Summoner", - DANGER: 8, - SHAPE: 4, - COLOR: "gold", - UPGRADE_COLOR: "gold", - SIZE: 26, - MAX_CHILDREN: 28, - VALUE: 3e5, - BODY: { - FOV: 0.5, - SPEED: 0.1 * base.SPEED, - HEALTH: 7 * base.HEALTH, - DAMAGE: 2.6 * base.DAMAGE, - }, - GUNS: Array(4).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.8 }]), - TYPE: ["sunchip"], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.enchantress = { - PARENT: "miniboss", - LABEL: "Enchantress", - DANGER: 8, - SHAPE: 3.5, - COLOR: "orange", - UPGRADE_COLOR: "orange", - SIZE: 26, - MAX_CHILDREN: 28, - VALUE: 4e5, - BODY: { - FOV: 0.5, - SPEED: 0.09 * base.SPEED, - HEALTH: 10 * base.HEALTH, - DAMAGE: 3 * base.DAMAGE, - }, - GUNS: Array(3).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.9 }]), - TYPE: "dorito", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.exorcistor = { - PARENT: "miniboss", - LABEL: "Exorcistor", - DANGER: 8, - SHAPE: 5.5, - COLOR: "purple", - UPGRADE_COLOR: "purple", - SIZE: 26, - MAX_CHILDREN: 20, - VALUE: 5e5, - BODY: { - FOV: 0.5, - SPEED: 0.08 * base.SPEED, - HEALTH: 15 * base.HEALTH, - DAMAGE: 4 * base.DAMAGE, - }, - GUNS: Array(5).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 72, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), - TYPE: "demonchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.shaman = { - PARENT: "miniboss", - LABEL: "Shaman", - DANGER: 8, - SHAPE: 6, - COLOR: "hexagon", - UPGRADE_COLOR: "hexagon", - SIZE: 26, - MAX_CHILDREN: 20, - VALUE: 6e5, - BODY: { - FOV: 0.5, - SPEED: 0.07 * base.SPEED, - HEALTH: 20 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - }, - GUNS: Array(6).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { size: 1.1 }]), - TYPE: "realchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.eliteSkimmer = { - PARENT: "elite", - LABEL: "Elite Skimmer", - COLOR: "orange", - UPGRADE_COLOR: "orange", - TURRETS: [ - { - POSITION: [15, 5, 0, 60, 170, 0], - TYPE: "skimmerTurret", - }, { - POSITION: [15, 5, 0, 180, 170, 0], - TYPE: "skimmerTurret", - }, { - POSITION: [15, 5, 0, 300, 170, 0], - TYPE: "skimmerTurret", - }, - ], -}; - -// Nesters -Class.nestKeeper = { - PARENT: "miniboss", - LABEL: "Nest Keeper", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - MAX_CHILDREN: 15, - VALUE: 3e5, - GUNS: [ - { - POSITION: [3.5, 6.65, 1.2, 8, 0, 35, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, -35, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, 108, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, -108, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, - ], - TURRETS: [ - { - POSITION: [8, 9, 0, 72, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 0, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 144, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 216, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, -72, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "boomerTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.nestWarden = { - PARENT: "miniboss", - LABEL: "Nest Warden", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - VALUE: 3e5, - GUNS: [], - TURRETS: [ - { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "barricadeTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -for(let i = 0; i < 5; i++) { - Class.nestWarden.GUNS.push( - { - POSITION: [10.7, 8, 1, 0, 0, 72*i+36, 0], - }, { - POSITION: [1.5, 8, 1.2, 10.7, 0, 72*i+36, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { speed: 1.2 }, g.setTrap, g.constructor]), - TYPE: "unsetTrap", - STAT_CALCULATOR: gunCalcNames.block - }, - }, - ); - Class.nestWarden.TURRETS.push( - { - POSITION: [8, 9, 0, 72*i, 120, 0], - TYPE: [ "cruiserTurret", { INDEPENDENT: true, COLOR: -1 } ], - } - ); -}; -Class.nestGuardian = { - PARENT: "miniboss", - LABEL: "Nest Guardian", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - VALUE: 3e5, - GUNS: [], - TURRETS: [ - { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "twisterTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -for(let i = 0; i < 5; i++) { - Class.nestGuardian.GUNS.push( - { - POSITION: [5.5, 7, 1, 6, 0, 72*i+36, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, - ); - Class.nestGuardian.TURRETS.push( - { - POSITION: [8, 9, 0, 72*i, 120, 0], - TYPE: [ "swarmerTurret", { INDEPENDENT: true, COLOR: -1 } ], - } - ); -}; - -// Rogues -Class.roguePalisade = { - PARENT: "miniboss", - LABEL: "Rogue Palisade", - COLOR: "darkGrey", - UPGRADE_COLOR: "darkGrey", - SHAPE: 6, - SIZE: 30, - VALUE: 5e5, - CONTROLLERS: ['nearestDifferentMaster', 'onlyAcceptInArc'], - BODY: { - FOV: 1.4, - SPEED: 0.05 * base.SPEED, - HEALTH: 16 * base.HEALTH, - SHIELD: 3 * base.SHIELD, - DAMAGE: 3 * base.DAMAGE, - }, - GUNS: [ - { POSITION: [4, 6, -1.6, 8, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 60, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 120, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 180, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 240, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 300, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - ], - TURRETS: [ - { POSITION: [5, 10, 0, 30, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 90, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 150, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 210, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 270, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 330, 110, 0], TYPE: "baseTrapTurret" }, - ], -}; -Class.rogueArmada = (() => { - let SHAPE = 7, - GUNS = [], - TURRETS = []; - for (let i = 0; i < SHAPE; i++) { - for (let j = 0; j < 8; j++) { - GUNS.push({ - POSITION: [8, 2 + Math.floor(j / 3), 1, 0, j / 2 - 2, (i + 0.5) * (360 / SHAPE), 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), - TYPE: j % SHAPE < 2 ? "bullet" : "casing" - } - }); - } - GUNS.push({ - POSITION: [8.5, 6, 1, 4, 0, (i + 0.5) * (360 / SHAPE), 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), - TYPE: "casing" - } - }, { - POSITION: [7, 6, -1.6, 4, 0, (i + 0.5) * (360 / SHAPE), 0] - }); - } - for (let i = 0; i < SHAPE; i++) { - TURRETS.push({ - POSITION: [5, 10, 0, i * 360 / SHAPE, 160, 0], - TYPE: "shottrapTurret" - }); - } - return { - PARENT: "miniboss", - LABEL: 'Rogue Armada', - COLOR: "darkGrey", - UPGRADE_COLOR: "darkGrey", - SHAPE, - SIZE: 28, - VALUE: 500000, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.1, - HEALTH: base.HEALTH * 16, - SHIELD: base.SHIELD * 3, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 3, - }, - GUNS, TURRETS - }; -})(); - -// Bob. -Class.bob = { - PARENT: "ramMiniboss", - LABEL: "Bob", - SHAPE: 0, - COLOR: "aqua", - UPGRADE_COLOR: "aqua", - SIZE: 18, - BODY: { - FOV: 2, - SPEED: 2 * base.SPEED, - HEALTH: 5 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - REGEN: 8 * base.REGEN, - FOV: 0.5 * base.FOV, - DENSITY: 6 * base.DENSITY, - }, - CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody", - }, { - POSITION: [21.5, 0, 0, 30, 360, 0], - TYPE: "landmineBody", - }, { - POSITION: [23.75, 0, 0, 0, 360, 0], - TYPE: "spikeBody", - }, - ], -}; -Class.nemesis = { - PARENT: "bob", - LABEL: "Nemesis", - COLOR: "red", - UPGRADE_COLOR: "red", - BODY: { - REGEN: 1e5, - HEALTH: 1e6, - DENSITY: 30, - DAMAGE: 1e5, - FOV: 5, - }, -}; - -// DIEP BOSSES -Class.guardian = { - PARENT: "elite", - LABEL: "Guardian of the Pentagons", - UPGRADE_LABEL: "Guardian", - UPGRADE_COLOR: "pink", - FACING_TYPE: "toTarget", - GUNS: [ - { - POSITION: [4, 12, 1.4, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, { size: 0.5 }]), - TYPE: "swarm", - AUTOFIRE: true, - }, - }, - ], - AI: { NO_LEAD: false }, -}; -Class.defenderAutoTankGun = { - PARENT: "autoTankGun", - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret]), - TYPE: ["bullet", {COLOR: "yellow"}], - }, - }, - ], -}; -Class.defender = { - PARENT: "elite", - LABEL: "Defender", - COLOR: "orange", - UPGRADE_COLOR: "orange", - GUNS: [ - { - POSITION: [15, 7, 1, -3, 0, 60, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [15, 7, 1, -3, 0, 180, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [15, 7, 1, -3, 0, 300, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], - TURRETS: [ - { - POSITION: [5, 7, 0, 0, 190, 1], - TYPE: "defenderAutoTankGun", - }, { - POSITION: [5, 7, 0, 120, 190, 1], - TYPE: "defenderAutoTankGun", - }, { - POSITION: [5, 7, 0, 240, 190, 1], - TYPE: "defenderAutoTankGun", - }, - ], - AI: { NO_LEAD: false }, -}; - -// CELESTIALS -Class.terrestrial = { - PARENT: "miniboss", - LABEL: "Terrestrial", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 5e5, - SHAPE: 7, - SIZE: 35, - BODY: { - FOV: 1, - HEALTH: 1000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 9, - }, -}; -Class.celestial = { - PARENT: "miniboss", - LABEL: "Celestial", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 1e6, - SHAPE: 9, - SIZE: 45, - BODY: { - FOV: 1, - HEALTH: 1000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 12, - }, -}; -Class.rogueCelestial = { - PARENT: "celestial", - LABEL: "Rogue Celestial", - COLOR: "darkGrey", -}; -Class.eternal = { - PARENT: "miniboss", - LABEL: "Eternal", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 4e6, - SHAPE: 11, - SIZE: 90, - BODY: { - FOV: 1, - HEALTH: 3000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 18, - }, -}; - -// Terrestrials -let ares = new LayeredBoss(null, "Ares", "terrestrial", 7, "purple", "terrestrialTrapTurret", 7, 5.5); -ares.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["demonchip", { INDEPENDENT: true, }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, false, null, 18); -ares.addLayer({turret: { - POSITION: [10, 8.5, 0, null, 160, 0], - TYPE: ["protoSwarmerTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let gersemi = new LayeredBoss(null, "Gersemi", "terrestrial", 7, "lightGreen", "terrestrialTrapTurret", 7, 5.5); -gersemi.addLayer({turret: { - POSITION: [9, 8, 0, null, 160, 0], - TYPE: ["swarmTurret", { INDEPENDENT: true }], -}}); -gersemi.addLayer({turret: { - POSITION: [9.5, 7.5, 0, null, 160, 0], - TYPE: ["basicTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let ezekiel = new LayeredBoss(null, "Ezekiel", "terrestrial", 7, "orange", "terrestrialTrapTurret", 7, 5.5); -ezekiel.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["dorito", { COLOR: "orange", INDEPENDENT: true, }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 18); -ezekiel.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["skimmerTurret", { COLOR: "grey", INDEPENDENT: true }], -}}, true, 6.5) - -let eris = new LayeredBoss(null, "Eris", "terrestrial", 7, "pink", "terrestrialTrapTurret", 7, 5.5); -eris.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), - TYPE: ["minion", { INDEPENDENT: true, COLOR: "pink", HAS_NO_RECOIL: true }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, false, null, 14); -eris.addLayer({turret: { - POSITION: [10, 8.5, 0, null, 160, 0], - TYPE: ["rocketeerTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let selene = new LayeredBoss(null, "Selene", "terrestrial", 7, "gold", "terrestrialTrapTurret", 7, 5.5); -selene.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["sunchip", { COLOR: "gold", INDEPENDENT: true }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 18); -selene.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["hyperTwisterTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -// PALADIN -let paladin = new LayeredBoss(null, "Paladin", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); -paladin.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: ["demonchip", {INDEPENDENT: true}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 16); -paladin.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: "swarmerTurret", -}}, true, 6); - -// FREYJA -let freyja = new LayeredBoss(null, "Freyja", "celestial", 9, "lightGreen", "baseTrapTurret", 6.5, 5.5); -freyja.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "cruiserTurret", -}}); -freyja.addLayer({turret: { - POSITION: [10.6, 7.5, 0, null, 160, 0], - TYPE: "auto4gun", -}}, true, 6); - -// ZAPHKIEL -let zaphkiel = new LayeredBoss(null, "Zaphkiel", "celestial", 9, "orange", "baseTrapTurret", 6.5, 5.5); -zaphkiel.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: ["drone", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 16); -zaphkiel.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["skimmerTurret", {COLOR: "grey", INDEPENDENT: true}], -}}, true, 6); - -// NYX -let nyx = new LayeredBoss(null, "Nyx", "celestial", 9, "pink", "baseTrapTurret", 6.5, 5.5); -nyx.addLayer({gun: { - POSITION: [3.8, 7, -1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), - TYPE: ["minion", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 16); -nyx.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: "rocketeerTurret", -}}, true, 6); - -// THEIA -let theia = new LayeredBoss(null, "Theia", "celestial", 9, "gold", "baseTrapTurret", 6.5, 5.5); -theia.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, { size: 0.5 }]), - TYPE: ["summonerDrone", {INDEPENDENT: true}], - AUTOFIRE: true, - WAIT_TO_CYCLE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 35); -theia.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["twisterTurret", {COLOR: "grey"}], -}}, true, 6); - -// ATLAS -let atlas = new LayeredBoss(null, "Atlas", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); -atlas.addLayer({turret: { - POSITION: [7, 9, 0, null, 180, 0], - TYPE: "artilleryTurret", -}}); -atlas.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "nailgunTurret", -}}, true, 6); - -// RHEA -let rhea = new LayeredBoss(null, "Rhea", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -rhea.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "wrenchTurret", -}}); -rhea.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "crowbarTurret", -}}, true, 6); - -// JULIUS -let julius = new LayeredBoss(null, "Julius", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -julius.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "juliusLowerTurret", -}}); -julius.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "launcherTurret", -}}, true, 6); - -// GENGHIS -let genghis = new LayeredBoss(null, "Genghis", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -genghis.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "genghisLowerTurret", -}}); -genghis.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "auto4gun", -}}, true, 6); - -// NAPOLEON -let napoleon = new LayeredBoss(null, "Napoleon", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -napoleon.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "napoleonLowerTurret", -}}); -napoleon.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "napoleonUpperTurret", -}}, true, 6) - -// Eternals -let kronos = new LayeredBoss(null, "Kronos", "eternal", 11, "veryLightGrey", "baseTrapTurret", 6, 5.5); -kronos.addLayer({turret: { - POSITION: [6.5, 9, 0, null, 160, 0], - TYPE: "kronosSkimmerTurret", -}}); -kronos.addLayer({turret: { - POSITION: [6.5, 9, 0, null, 160, 0], - TYPE: "carrierTurret", -}}, true, 4); -kronos.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 160, 0], - TYPE: "tripletTurret", -}}, true, 4); - -let odin = new LayeredBoss(null, "Odin", "eternal", 11, "aqua", "baseTrapTurret", 4.5, 3.5); -odin.addLayer({gun: { - POSITION: [2.25, 3.25, -1.6, 9, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }, g.pounder, {size: 1.7}]), - TYPE: ["gemDrone", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 18); -odin.addLayer({turret: { - POSITION: [7, 8, 0, null, 160, 0], - TYPE: "autosmashTurret", -}}, true, 5.5); -odin.addLayer({turret: { - POSITION: [8, 9, 0, null, 160, 0], - TYPE: "gunnerCruiserTurret", -}}, true, 4.5); - -// Developer Bosses -Class.taureonCoreBase = { - SHAPE: 4, - COLOR: '#00A2E8' -}; -Class.taureonCore = { - PARENT: "genericTank", - LABEL: "Core Turret", - SHAPE: 4.5, - COLOR: '#99D9EA', - CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], - INDEPENDENT: true, - GUNS: [{ - POSITION: [10, 14, -0.5, 14, 0, 0, 0] - },{ - POSITION: [21, 15, -1.1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.destroyer, g.sniper]), - TYPE: "snake", - STAT_CALCULATOR: gunCalcNames.sustained - } - }], - TURRETS: [{ - POSITION: [20 * Math.SQRT2, 0, 0, 0, 0, 0], - TYPE: "taureonCoreBase" - }] -}; -Class.taureonBase = { - SHAPE: 4.5, - COLOR: '#161B54', - MIRROR_MASTER_ANGLE: true -}; -let d = 1/4; -Class.taureonStar = { - SHAPE: [[0,1],[d,d],[1,0],[d,-d],[0,-1],[-d,-d],[-1,0],[-d,d]], - COLOR: '#3F48CC', - MIRROR_MASTER_ANGLE: true -}; -Class.taureonRailgunTurret = { - PARENT: "genericTank", - COLOR: "grey", - LABEL: "Railgun Turret", - CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], - INDEPENDENT: true, - GUNS: [{ - POSITION: [20, 7, 1, 0, 0, 0, 0] - },{ - POSITION: [24, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.destroyer, { speed: 5, penetration: 0.8 }]), - TYPE: "bullet" - } - },{ - POSITION: [5, 7.5, -1.6, 8, 0, 0, 0], - }] -}; -Class.taureonThruster = { - PARENT: "genericTank", - COLOR: "grey", - LABEL: "Thruster", - CONTROLLERS: ["onlyAcceptInArc"], - GUNS: [{ - POSITION: [14, 12, 1, 4, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), - TYPE: ["bullet", { ALPHA: 0.5 }] - } - }, { - POSITION: [12, 12, 1.4, 4, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), - TYPE: ["bullet", { ALPHA: 0.5 }] - }, - }] -}; -Class.taureonMissile = { - PARENT: "bullet", - LABEL: "Missile", - FACING_TYPE: "smoothToTarget", - CONTROLLERS: ["nearestDifferentMaster"], - INDEPENDENT: true, - BODY: { - ACCELERATION: 10, - FOV: base.FOV * 2 - }, - TURRETS: [{/** SIZE X Y ANGLE ARC */ - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - }], - GUNS: [{/* LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [6, 12, 1.4, 8, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] - } - },{ - POSITION: [10, 12, 0.8, 8, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] - } - },...Array(32).fill().map((_, i)=>({ - POSITION: [0, (i % 4) + 1, 0, 0, 0, 0, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, { spray: 1e6, range: 0.5, shudder: 1.5, damage: 1 + (i % 4) }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - SHOOT_ON_DEATH: true - }, - }))] -}; -Class.taureonBoss = { - PARENT: "miniboss", - LABEL: "Diamond Marauder", - NAME: "Taureon", - COLOR: '#2B339B', - UPGRADE_COLOR: "spaceGem", - DANGER: 10, - SHAPE: 4.5, - SIZE: 50, - FACING_TYPE: "smoothToTarget", - UPGRADE_TOOLTIP: "With a powerful Gatling Gun on the front, Rocket Launchers as wings, movable Thrusters on the back, " + - "and equipped with Railgun Turrets, it perfectly excells at terminating those who feel its Wrath.\n" + - "An octahedral carbon robot, exclusively designed to eradicate opponents with sheer brutality alone.\n" + - '"NOW YOU FACE MY ULTIMATE CREATION."', - VALUE: 9e6, - BODY: { - FOV: 1, - SPEED: 0.5 * base.SPEED, - HEALTH: 20 * base.HEALTH, - DAMAGE: 3 * base.DAMAGE, - }, - TURRETS: [{ - POSITION: [23.3, 0, 0, 0, 0, 0], - TYPE: "taureonBase" - },{ - POSITION: [5, 10, 0, -45, 180, 0], - TYPE: "taureonRailgunTurret" - },{ - POSITION: [5, 10, 0, 45, 180, 0], - TYPE: "taureonRailgunTurret" - },{ - POSITION: [5, -10, -2, -45, 90, 0], - TYPE: "taureonThruster" - },{ - POSITION: [5, -10, 2, 45, 90, 0], - TYPE: "taureonThruster" - },{ - POSITION: [25, 0, 0, 0, 0, 1], - TYPE: "taureonStar" - },{ - POSITION: [5, 0, 0, 0, 360, 1], - TYPE: "taureonCore" - }], - GUNS: [...Array(6).fill().map((_, i) => ({ - POSITION: [18, 1.75, 1, 0, Math.cos(Math.PI * i / 3) * 2, 0, i / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, { speed: 2, maxSpeed: 2, damage: 0.75, size: 0.8 }]), - TYPE: "bullet" - } - })),{ - POSITION: [4, 5, -0.5, 12, 0, -90, 0] - },{ - POSITION: [10, 5, -1.2, 5, 0, -90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), - TYPE: "taureonMissile", - STAT_CALCULATOR: gunCalcNames.sustained - } - },{ - POSITION: [4, 5, -0.5, 12, 0, 90, 0] - },{ - POSITION: [10, 5, -1.2, 5, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), - TYPE: "taureonMissile", - STAT_CALCULATOR: gunCalcNames.sustained - } - },{ - POSITION: [5.5, 5, -1.5, 5, 0, -45, 0] - },{ - POSITION: [5.5, 5, -1.5, 5, 0, 45, 0] - },{ - POSITION: [2, 7, 1, 8, 0, 0, 0] - },{ - POSITION: [2, 7, 1, 14.5, 0, 0, 0] - }] -}; - -Class.zephiMiscDeco = makeDeco(4, "white") -Class.zephiMiscDeco2 = makeDeco(4, "black") -Class.zephiSunchip = makeAuto({ - PARENT: "drone", - SHAPE: 4, - HITS_OWN_TYPE: "hard", - BODY: { - FOV: 0.5, - }, - AI: { - BLIND: true, - FARMER: true, - }, - TURRETS: [{ - POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], - TYPE: ["overdriveDeco", { MIRROR_MASTER_ANGLE: true }] - },{ - POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], - TYPE: ["shinySquare", { MIRROR_MASTER_ANGLE: true }] - }] -}, "Robo-Sunchip", {type: 'autoSmasherTurret', size: 6}) -Class.zephiEggchip = { - PARENT: "drone", - LABEL: "Guided Missile", - SHAPE: 0, - HITS_OWN_TYPE: "hard", - BODY: { - FOV: 0.5, - }, - AI: { - BLIND: true, - FARMER: true, - }, - GUNS: [ - { - POSITION: [14, 6, 1, 0, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, g.lowPower, { reload: 0.5, recoil: 1.35, speed: 1.3, maxSpeed: 1.3 }]), - TYPE: ["bullet", { COLOR: "black", PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.thruster, - }, - }, - ], - TURRETS: [{ - POSITION: [10, 0, 0, 45, 0, 1], - TYPE: "gem" - }] -} -Class.zephiGearOuter = makeDeco('M 0.5 0.0929 V -0.0908 L 0.3875 -0.1096 C 0.3792 -0.1409 0.3667 -0.1701 0.3521 -0.1952 L 0.4187 -0.2871 L 0.2896 -0.4186 L 0.1958 -0.3539 C 0.1687 -0.3685 0.1396 -0.381 0.1104 -0.3894 L 0.0917 -0.5 H -0.0917 L -0.1104 -0.3873 C -0.1417 -0.3789 -0.1688 -0.3664 -0.1958 -0.3518 L -0.2875 -0.4165 L -0.4188 -0.2871 L -0.3521 -0.1952 C -0.3667 -0.1681 -0.3792 -0.1388 -0.3875 -0.1075 L -0.5 -0.0908 V 0.0929 L -0.3875 0.1117 C -0.3792 0.143 -0.3667 0.1701 -0.3521 0.1973 L -0.4188 0.2912 L -0.2896 0.4207 L -0.1958 0.3539 C -0.1688 0.3685 -0.1396 0.381 -0.1083 0.3894 L -0.0896 0.5 H 0.0938 L 0.1125 0.3873 C 0.1417 0.3789 0.1708 0.3664 0.1979 0.3518 L 0.2917 0.4186 L 0.4208 0.2891 L 0.3542 0.1952 C 0.3688 0.1681 0.3812 0.1409 0.3896 0.1096 L 0.5 0.0929 Z M 0.3333 0 C 0.3333 0.1841 0.1841 0.3333 0 0.3333 C -0.1841 0.3333 -0.3333 0.1841 -0.3333 0 C -0.3333 -0.1841 -0.1841 -0.3333 0 -0.3333 C 0.1841 -0.3333 0.3333 -0.1841 0.3333 0 Z', '#7F7F7F') -Class.zephiGearOuter.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearOuter.BORDERLESS = true -Class.zephiGearCentre = makeDeco(0, '#1F1F1F') -Class.zephiGearCentre.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearCentre.BORDERLESS = true -Class.zephiGearRed = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#FF1F1F') -Class.zephiGearRed.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearRed.BORDERLESS = true -Class.zephiGearGreen = makeDeco('M 0.0771 -0.2552 C 0.0743 -0.2561 0.0691 -0.2576 0.0657 -0.2585 L 0.0607 -0.2597 C 0.0571 -0.2605 0.0514 -0.2617 0.0479 -0.2623 L 0.0428 -0.2632 C 0.0392 -0.2638 0.0334 -0.2646 0.0299 -0.265 L 0.0247 -0.2655 C 0.0211 -0.2659 0.0153 -0.2662 0.0117 -0.2664 L 0.0066 -0.2666 C 0.003 -0.2667 -0.0029 -0.2667 -0.0065 -0.2666 L -0.0116 -0.2664 C -0.0153 -0.2662 -0.0211 -0.2659 -0.0247 -0.2655 L -0.0298 -0.265 C -0.0334 -0.2646 -0.0392 -0.2638 -0.0427 -0.2632 L -0.0478 -0.2623 C -0.0514 -0.2617 -0.0571 -0.2605 -0.0606 -0.2597 L -0.0656 -0.2585 C -0.0691 -0.2576 -0.0747 -0.256 -0.0782 -0.2549 C -0.081 -0.254 -0.0833 -0.2502 -0.0833 -0.2466 V 0.2466 C -0.0833 0.2502 -0.0805 0.2541 -0.0771 0.2552 C -0.0743 0.2561 -0.0691 0.2576 -0.0656 0.2585 L -0.0606 0.2597 C -0.0571 0.2605 -0.0514 0.2617 -0.0478 0.2623 L -0.0427 0.2632 C -0.0392 0.2638 -0.0334 0.2646 -0.0298 0.265 L -0.0247 0.2655 C -0.0211 0.2659 -0.0153 0.2663 -0.0116 0.2664 L -0.0065 0.2666 C -0.0029 0.2667 0.003 0.2667 0.0066 0.2666 L 0.0117 0.2664 C 0.0153 0.2663 0.0211 0.2659 0.0247 0.2655 L 0.0299 0.265 C 0.0334 0.2646 0.0392 0.2638 0.0428 0.2632 L 0.0479 0.2623 C 0.0514 0.2617 0.0571 0.2605 0.0607 0.2597 L 0.0657 0.2585 C 0.0691 0.2576 0.0748 0.256 0.0782 0.2549 C 0.0811 0.254 0.0834 0.2502 0.0834 0.2466 V -0.2466 C 0.0834 -0.2502 0.0806 -0.2541 0.0771 -0.2552 Z', '#1FDF1F') -Class.zephiGearGreen.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearGreen.BORDERLESS = true -Class.zephiGearBlue = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#1F7FDF') -Class.zephiGearBlue.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearBlue.BORDERLESS = true -Class.zephiBoss = { - PARENT: "miniboss", - LABEL: "Shiny Mecha-Thaumaturge", - NAME: "Zephi", - DANGER: 10, - SHAPE: 4, - COLOR: "lightGreen", - UPGRADE_COLOR: "lightGreen", - SIZE: 50, - VALUE: 5e6, - SKILL: skillSet({ - rld: 1, - dam: 1, - pen: 1, - str: 1, - spd: 1, - atk: 1, - hlt: 1, - shi: 1, - rgn: 1, - mob: 1, - }), - BODY: { - FOV: 0.75, - SPEED: 0.05 * base.SPEED, - HEALTH: 15 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - }, - UPGRADE_TOOLTIP: "Good luck.", - GUNS: Array(4).fill().map((_, i) => ([{ - POSITION: [2.5, 3, 1.2, 8, 5, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 50, speed: 1.25, shudder: 1.25 }]), - TYPE: ["zephiEggchip", {COLOR: "black"}], - MAX_CHILDREN: 8, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - COLOR: "black", - } - },{ - POSITION: [2.5, 3, 1.2, 8, -5, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 150, speed: 1.25, shudder: 1.25 }]), - TYPE: ["zephiEggchip", {COLOR: "black"}], - MAX_CHILDREN: 8, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - COLOR: "black", - } - },{ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, g.destroyer, { speed: 2.5 }, { maxSpeed: 3 }]), - TYPE: ["zephiSunchip", {COLOR: "black"}], - MAX_CHILDREN: 4, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true - } - }])).flat(), - TURRETS: [{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearOuter" - },{ - POSITION: [5.375 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearCentre" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearRed" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearGreen" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 180, 360, 2], - TYPE: "zephiGearBlue" - },{ - POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], - TYPE: "overdriveDeco" - },{ - POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], - TYPE: "zephiMiscDeco2" - },{ - POSITION: [20 * Math.SQRT1_2 ** 3, 0, 0, 45, 0, 1], - TYPE: "zephiMiscDeco" - }] -}; - -Class.dogeiscutBody = { - PARENT: "genericTank", - COLOR: "grey", - SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]] -} -Class.dogeiscutTurret = { - PARENT: "genericTank", - COLOR: "grey", - GUNS: [ { - POSITION: [ 50, 5, 2.5, 0, 0, 0, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.minigun, {reload: 0.1}]), - TYPE: "bullet", - }, - }, { - POSITION: [ 18, 8, -2, 0, 0, 0, 0, ], - }, - ], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], - }, - ] -} -function createDogeiscutMissileTurret(color) { - return { - PARENT: "genericTank", - COLOR: "grey", - GUNS: [ { - POSITION: [ 15, 8, 2.5, 0, 0, 180, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ - g.basic, - g.skimmer, - { reload: 0.5 }, - g.lowPower, - { recoil: 1.35 }, - { speed: 1.3, maxSpeed: 1.3 }, - { speed: 1.3, maxSpeed: 1.3 }, - {reload: 0.15, recoil: 1, range: 0.1}]), - TYPE: ["bullet", - { - PERSISTS_AFTER_DEATH: true, - COLOR: color - }, - ], - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - }, - }, - ], - } -} -function createDogeiscutMissile(color) { - return { - PARENT: "bullet", - LABEL: color + " Missile", - COLOR: color, - GUNS: [...Array(11).fill().map((_, i)=>({ - POSITION: [0, 8, 0, 0, 0, ((360) / 11)*i, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, density: 30 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, COLOR: color }], - SHOOT_ON_DEATH: true, - }, - }))], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutMissileTurret_" + color], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - } - ] - } -} -Class.dogeiscutMissileTurret_red = createDogeiscutMissileTurret('red') -Class.dogeiscutMissile_red = createDogeiscutMissile('red') -Class.dogeiscutMissileTurret_orange = createDogeiscutMissileTurret('orange') -Class.dogeiscutMissile_orange = createDogeiscutMissile('orange') -Class.dogeiscutMissileTurret_yellow = createDogeiscutMissileTurret('yellow') -Class.dogeiscutMissile_yellow = createDogeiscutMissile('yellow') -Class.dogeiscutMissileTurret_green = createDogeiscutMissileTurret('green') -Class.dogeiscutMissile_green = createDogeiscutMissile('green') -Class.dogeiscutMissileTurret_cyan = createDogeiscutMissileTurret('cyan') -Class.dogeiscutMissile_cyan = createDogeiscutMissile('cyan') -Class.dogeiscutMissileTurret_blue = createDogeiscutMissileTurret('blue') -Class.dogeiscutMissile_blue = createDogeiscutMissile('blue') -Class.dogeiscutMissileTurret_purple = createDogeiscutMissileTurret('purple') -Class.dogeiscutMissile_purple = createDogeiscutMissile('purple') -Class.dogeiscutBomb = { - PARENT: "trap", - LABEL: "Bomb", - SHAPE: 0, - GUNS: [...Array(32).fill().map((_, i)=>({ - POSITION: [0, 8, 0, 0, 0, ((360) / 32)*i, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, size: 0.5}]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - SHOOT_ON_DEATH: true, - }, - })),...Array(10).fill().map((_,i)=>({ - POSITION: [12, 3.5, 1, 0, 0, (360/10)*i, (i%3)/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ - g.basic, - g.twin, - g.gunner, - g.cyclone, - {reload: 3} - ]), - TYPE: "bullet", - AUTOFIRE: true, - }, - })) - ], - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - } - ] - } -Class.dogeiscutBoss = { - PARENT: "miniboss", - LABEL: "DOG", - NAME: "DogeisCut", - DANGER: 10, - FACING_TYPE: "smoothToTarget", - SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]], - COLOR: "yellow", - UPGRADE_COLOR: "yellow", - SIZE: 50, - VALUE: 5e6, - BODY: { - FOV: 0.75, - SPEED: 0.25 * base.SPEED, - HEALTH: 14 * base.HEALTH, - DAMAGE: 4 * base.DAMAGE, - }, - GUNS: [ { - POSITION: [ 6, 8, 1.5, 3, 0, 180, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, {size: 1, reload: 3, recoil: 5}]), - TYPE: ["dogeiscutBomb"], - STAT_CALCULATOR: gunCalcNames.sustained, - } - }, { - POSITION: [ 4, 4, 1.5, 3, 0, 180, 0, ], - PROPERTIES: { - COLOR: "black" - } - }, - - { - POSITION: [ 1, 2, 1, 4, -8, 68, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_red"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'red' - } - }, { - POSITION: [ 1, 2, 1, 4, -5.333, 68, 1/7, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_orange"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'orange' - } - }, { - POSITION: [ 1, 2, 1, 4, -2.666, 68, (1/7)*2, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_yellow"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'yellow' - } - }, { - POSITION: [ 1, 2, 1, 4, 0, 68, (1/7)*3, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_green"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'green' - } - }, { - POSITION: [ 1, 2, 1, 4, 2.666, 68, (1/7)*4, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_cyan"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'cyan' - } - }, { - POSITION: [ 1, 2, 1, 4, 5.333, 68, (1/7)*5, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_blue"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'blue' - } - }, { - POSITION: [ 1, 2, 1, 4, 8, 68, (1/7)*6, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_purple"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'purple' - } - }, - - - { - POSITION: [ 1, 2, 1, 4, 8, -68, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_red"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'red' - } - }, { - POSITION: [ 1, 2, 1, 4, 5.333, -68, 1/7, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_orange"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'orange' - } - }, { - POSITION: [ 1, 2, 1, 4, 2.666, -68, (1/7)*2, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_yellow"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'yellow' - } - }, { - POSITION: [ 1, 2, 1, 4, 0, -68, (1/7)*3, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_green"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'green' - } - }, { - POSITION: [ 1, 2, 1, 4, -2.666, -68, (1/7)*4, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_cyan"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'cyan' - } - }, { - POSITION: [ 1, 2, 1, 4, -5.333, -68, (1/7)*5, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_blue"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'blue' - } - }, { - POSITION: [ 1, 2, 1, 4, -8, -68, (1/7)*6, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_purple"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'purple' - } - }, - ], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], - }, - { - POSITION: [5, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutTurret", { INDEPENDENT: true, CONTROLLERS: ["nearestDifferentMaster"], COLOR: "yellow" }], - }, - { - POSITION: [1, 10.5, 0, 0, 360, 0], - TYPE: ["genericTank", {COLOR: "black"}], - }, - ] -} -Class.trplnrBossAuraBulletAura = addAura(1, 0.8) -Class.trplnrBossAuraBullet = { - PARENT: 'genericTank', - LABEL: 'Nest', - SHAPE: -4, - PERSISTS_AFTER_DEATH: true, - BODY: { - HEALTH: 100, - }, - SIZE: 25, - COLOR: '#F49EFF', - GLOW: { - STRENGTH: 25, - COLOR: 'mirror', - ALPHA: 1 - }, - DRAW_HEALTH: true, - GUNS: (() => { - let output = [] - for (let i = 0; i < 4; i++) { - output.push({ - POSITION: { ANGLE: (360/4)*i, ASPECT: -0.35, X: -5 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { size: 0.8 }, {reload: 1.6, damage: 1.5}]), - TYPE: 'autoswarm', - AUTOFIRE: true, - }, - }) - } - return output - })(), - TURRETS: [ - { - POSITION: {SIZE: 10, LAYER: 1}, - TYPE: "trplnrBossAuraBulletAura" - } - ] -} -const trplnrBossDecor = { - COLOR: '#F49EFF', - UPGRADE_COLOR: "lavender", - LABEL: 'Lavender', - NAME: 'Trioplane', - SHAPE: 3, - SIZE: 25, - VALUE: 5e7, - DANGER: 10, - GLOW: { - RADIUS: 15, - COLOR: 'mirror', - ALPHA: 1, - RECURSION: 5 - }, - PROPS: [{ - POSITION: { SIZE: 25 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, - TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] - }, { - POSITION: { SIZE: 25 ** Math.SQRT1_2, LAYER: 1 }, - TYPE: ['triangle', { COLOR: -1, MIRROR_MASTER_ANGLE: true }] - }, { - POSITION: { SIZE: 25 }, - TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] - }], -} -Class.trplnrBoss = { - PARENT: "miniboss", - ...trplnrBossDecor, - UPGRADE_TOOLTIP: "\"Heck, even The Guardians are afraid of him, \n" + - "They usually call him the The Light, Victory, Death and Ruler of the Pentagon Race a.k.a Lvndr. \n" + - "We don't know where his teleportation powers came from, \n" + - "He was secretive of it. \n" + - "Though some say there was an old script found at the Neutrality Point \n" + - "at the middle of the nest when it still existed, It had some \n" + - "sort of drawing of a tank going through walls, and this thing that said '6@D M0|)3 \n" + - "Nest Reseachers still haven't been able to decipher it though. \n" + - "One day, The Neutrality Point left and on that same day, \n" + - "A sentry's child went missing, \n" + - "Coincidence? I think not.\"", - BODY: { - HEALTH: 500, - }, - ON: [ - { - event: 'fire', - handler: ({ body, gun }) => { - if (gun.identifier != 'onHandler') return - const messages = [ - 'Attack my little swarms!', - 'Deploying, Attack swarms', - 'You really think you can defeat me? Heres a little challenge for you.', - 'This thing is really gonna annoy you HAHA!', - 'I don\'t know what to say uhhh, die i guess.' - ] - sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) - sockets.broadcast('Lavender will turn into `BULL3T HELL F0rM`, Run!') - for (let i = 0; i < 24; i++) { - i < 12 ? - setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) - : - setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) - } - setTimeout(() => { - let range = 500 - let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - body.x += whereToGoX - body.y += whereToGoY - }, 12 * 50); - setTimeout(() => body.define('trplnrBossBulletHellForm'), 24 * 50) - } - } - ], - GUNS: [], - GUNS: (() => { - let output = [] - for (let i = 0; i<2; i++) { - output.push({ - POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), - TYPE: "trplnrBossAuraBullet", - INDEPENDENT_CHILDREN: true, - } - }) - } - output.push({ - POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * 2) - 180 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), - TYPE: "trplnrBossAuraBullet", - INDEPENDENT_CHILDREN: true, - IDENTIFIER: 'onHandler', - ALPHA: 0, - } - }) - for (let i = 0; i < 3; i++) { - output.push({ - POSITION: { WIDTH: 5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'black' - } - }) - output.push({ - POSITION: { WIDTH: 5, HEIGHT: 5, X: -30, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'black' - } - }, { - POSITION: { WIDTH: 5, HEIGHT: 5, X: -25, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'white' - } - }) - } - return output - })() -} - -Class.trplnrBossBulletHellFormPentagonsAuraBullet = { - PARENT: 'bullet', - PERSISTS_AFTER_DEATH: true, - TURRETS: [{ - POSITION: {SIZE: 13, LAYER: 1}, - TYPE: "trplnrBossAuraBulletAura" - }] -} - -Class.trplnrBossBulletHellFormPentagons = { - PARENT: 'bullet', - LABEL: 'Pentagon', - SHAPE: -5, - PROPS: [{ - POSITION: { SIZE: 40 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, - TYPE: ['pentagon', {COLOR: 'black', MIRROR_MASTER_ANGLE: true}] - }], - GUNS: (() => { - let output = [] - for (let i = 0; i < 5; i++) { - output.push({ - POSITION: { WIDTH: 10, HEIGHT: 10, ANGLE: ((360/5)*i) - 180, DELAY: 11.5 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 0.4}]), - TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', - AUTOFIRE: true, - COLOR: 'white', - } - }) - } - return output - })() -} -Class.trplnrBossBulletHellForm = { - PARENT: "miniboss", - ...trplnrBossDecor, - LABEL: 'Lavender - Bullet Hell Form', - BODY: { - HEALTH: 500, - }, - ON: [ - { - event: "fire", - handler: ({ body, masterStore, gun }) => { - if (gun.identifier != 'onHandler') return - masterStore.shotsFired ??= 0 - masterStore.shotsFired++ - - for (let i = 0; i < 24; i++) { - i < 12 ? - setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) - : - setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) - } - setTimeout(() => { - let range = 500 - let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - body.x += whereToGoX - body.y += whereToGoY - }, 12 * 50) - - if (masterStore.shotsFired > 5) { - body.define('trplnrBossVulnerableForm') - const messages = [ - 'I\'m a little tired right now', - 'Ouch my leg!', - 'i sleep', - 'Bruh my keyboard isn\'t working', - 'Omg bruh I chose the wrong form' - ] - sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) - sockets.broadcast('Lavender is in its `VULN3RABLE F0RM`, Attack!') - } - } - } - ], - GUNS: [], - GUNS: (() => { - let output = [] - for (let i = 0; i<3; i++) { - output.push({ - POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -25 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 1 }]), - TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', - COLOR: 'black' - } - }, { - POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -20 }, - PROPERTIES: { - COLOR: 'white' - } - }, { - POSITION: { WIDTH: 10, HEIGHT: 5, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 3 }]), - TYPE: 'trplnrBossBulletHellFormPentagons', - COLOR: 'white' - } - }, { - POSITION: { WIDTH: 8, HEIGHT: 3, X: -1, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'pureWhite', - } - }, { - POSITION: { WIDTH: 5, HEIGHT: 10, X: 5, ASPECT: 0.2, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: -1, - } - }) - } - output.push({ - POSITION: { WIDTH: 0, HEIGHT: 0 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 2 }, g.fake]), - TYPE: 'bullet', - IDENTIFIER: 'onHandler', - ALPHA: 0 - } - }) - return output - })() -} -Class.trplnrBossVulnerableForm = { - PARENT: "miniboss", - ...trplnrBossDecor, - LABEL: 'Lavender - Vulnerable Form', - BODY: { - HEALTH: 500, - SPEED: 0.1 - }, - ON: [ - { - event: "tick", - handler: ({ body }) => { - body.store.ticks ??= 0 - body.store.ticks++ - const spawnCrashers = body.store.ticks % 3 == 0 - const spawnSentries = body.store.ticks % 60 == 0 - const sentries = ["sentrySwarm", "sentryGun", "sentryTrap"] - if (spawnCrashers) new Entity(body, body).define("crasher") - if (spawnSentries) new Entity(body, body).define(sentries[Math.floor(Math.random() * sentries.length)]) - } - }, - { - event: "fire", - handler: ({ body, gun }) => { - if (gun.identifier != 'onHandler') return - setTimeout(() => { - body.define('trplnrBoss') - sockets.broadcast('im awake') - }, 15000) - setTimeout(() => sockets.broadcast('Lavender will activate in 10 seconds and turn into S4nctuary F0rM'), 5000) - } - } - ], - GUNS: [{ - POSITION: {LENGTH: 0, WIDTH: 0}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, {reload: 500}]), - TYPE: 'bullet', - AUTOFIRE: true, - IDENTIFIER: 'onHandler', - ALPHA: 0 - } - }] -} - -Class.frostAuraSmall = { - PARENT: "aura", - LAYER: 30, - FACING_TYPE: ["spin", {speed: -0.04}], - BORDERLESS: true, - SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraSmallOutline' - }] -} -Class.frostAuraSmallOutline = { - PARENT: "aura", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0" + - "L 0.309 0.951 L -0.809 0.588 L -0.809 -0.588 L 0.309 -0.951 L 1 0" + - "L 0 0 L 0.309 0.951 M 0 0 L -0.809 0.588 M 0 0 L -0.809 -0.588 M 0 0 L 0.309 -0.951", -} -Class.frostAuraLarge = { - PARENT: "aura", - LAYER: 30, - FACING_TYPE: ["spin", {speed: -0.04}], - BORDERLESS: true, - SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraLargeOutline' - }] -} -Class.frostAuraLargeOutline = { - PARENT: "aura", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0" + - "M 0.988 -0.156 L 0.988 0.156 L 0.891 0.454 L 0.707 0.707 L 0.454 0.891 L 0.156 0.988 L -0.156 0.988 L -0.454 0.891 L -0.707 0.707 L -0.891 0.454 L -0.988 0.156 L -0.988 -0.156 L -0.891 -0.454 L -0.707 -0.707 L -0.454 -0.891 L -0.156 -0.988 L 0.156 -0.988 L 0.454 -0.891 L 0.707 -0.707 L 0.891 -0.454 L 0.988 -0.156 L 0.949 0" + - "L 0.988 0.156 L 0.891 0.256 L 0.891 0.454 L 0.739 0.537 L 0.707 0.707 L 0.519 0.769 L 0.454 0.891 L 0.293 0.902 L 0.156 0.988 L 0.032 0.927 L -0.156 0.988 L -0.282 0.869 L -0.454 0.891 L -0.571 0.731 L -0.707 0.707 L -0.768 0.558 L -0.891 0.454 L -0.871 0.317 L -0.988 0.156 L -0.914 0 L -0.988 -0.156 L -0.871 -0.317 L -0.891 -0.454 L -0.768 -0.558 L -0.707 -0.707 L -0.571 -0.731 L -0.454 -0.891 L -0.282 -0.869 L -0.156 -0.988 L 0.032 -0.927 L 0.156 -0.988 L 0.293 -0.902 L 0.454 -0.891 L 0.519 -0.769 L 0.707 -0.707 L 0.739 -0.537 L 0.891 -0.454 L 0.891 -0.256 L 0.988 -0.156 L 0.949 0" + - "L 0.891 0.256 L 0.739 0.537 L 0.519 0.769 L 0.293 0.902 L 0.032 0.927 L -0.282 0.869 L -0.571 0.731 L -0.768 0.558 L -0.871 0.317 L -0.914 0 L -0.871 -0.317 L -0.768 -0.558 L -0.571 -0.731 L -0.282 -0.869 L 0.032 -0.927 L 0.293 -0.902 L 0.519 -0.769 L 0.739 -0.537 L 0.891 -0.256 L 0.949 0" + - "M 0.834 0 L 0.891 0.256 L 0.704 0.291 L 0.739 0.537 L 0.495 0.579 L 0.519 0.769 L 0.258 0.793 L 0.032 0.927 L -0.06 0.759 L -0.282 0.869 L -0.398 0.649 L -0.571 0.731 L -0.674 0.49 L -0.871 0.317 L -0.741 0.178 L -0.914 0 L -0.741 -0.178 L -0.871 -0.317 L -0.674 -0.49 L -0.571 -0.731 L -0.398 -0.649 L -0.282 -0.869 L -0.06 -0.759 L 0.032 -0.927 L 0.258 -0.793 L 0.519 -0.769 L 0.495 -0.579 L 0.739 -0.537 L 0.704 -0.291 L 0.891 -0.256 L 0.834 0" + - "L 0.704 0.291 L 0.495 0.579 L 0.258 0.793 L -0.06 0.759 L -0.398 0.649 L -0.674 0.49 L -0.741 0.178 L -0.741 -0.178 L -0.674 -0.49 L -0.398 -0.649 L -0.06 -0.759 L 0.258 -0.793 L 0.495 -0.579 L 0.704 -0.291 L 0.834 0" + - "M 0.592 0 L 0.704 0.291 L 0.413 0.3 L 0.495 0.579 L 0.183 0.563 L -0.06 0.759 L -0.158 0.485 L -0.398 0.649 L -0.479 0.348 L -0.741 0.178 L -0.51 0 L -0.741 -0.178 L -0.479 -0.348 L -0.398 -0.649 L -0.158 -0.485 L -0.06 -0.759 L 0.183 -0.563 L 0.495 -0.579 L 0.413 -0.3 L 0.704 -0.291 L 0.592 0" + - "L 0.413 0.3 L 0.183 0.563 L -0.158 0.485 L -0.479 0.348 L -0.51 0 L -0.479 -0.348 L -0.158 -0.485 L 0.183 -0.563 L 0.413 -0.3 L 0.592 0" + - "M 0.292 0 L 0.413 0.3 L 0.09 0.277 L -0.158 0.485 L -0.236 0.171 L -0.51 0 L -0.236 -0.171 L -0.158 -0.485 L 0.09 -0.277 L 0.413 -0.3 L 0.292 0 L 0.09 0.277" + - "L -0.236 0.171 L -0.236 -0.171 L 0.09 -0.277 L 0.292 0 M 0 0 L 0.949 0" + - "M 0 0 L 0.293 0.902 M 0 0 L -0.768 0.558 M 0 0 L -0.768 -0.558 M 0 0 L 0.293 -0.902", -} -Class.frostAuraSymbol = { - PARENT: "genericTank", - CONTROLLERS: [["spin", { speed: -0.04 }]], - INDEPENDENT: true, - BORDERLESS: true, - COLOR: 'teal', - SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraSymbolOutline' - }] -} -Class.frostAuraSymbolOutline = { - PARENT: "genericTank", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z" + - "M 0.52 0.3 L 0.52 -0.3 L 0.797 -0.46 M 0.52 -0.3 L 0 -0.6 L 0 -0.92 M 0 -0.6 L -0.52 -0.3 L -0.797 -0.46 M -0.52 -0.3 L -0.52 0.3 L -0.797 0.46 M -0.52 0.3 L 0 0.6 L 0 0.92 M 0 0.6 L 0.52 0.3 L 0.797 0.46" -} - -function addIcosphereAura(damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraSize = "Medium") { - let auraType = "frostAura" + auraSize; - return { - PARENT: "genericTank", - INDEPENDENT: true, - LABEL: "", - COLOR: 17, - GUNS: [ - { - POSITION: [0, 20, 1, 0, 0, 0, 0,], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.aura, { size: sizeFactor, damage: damageFactor }]), - TYPE: [auraType, {ALPHA: opacity}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, - }, - ], - TURRETS: [ - { - POSITION: [20, 0, 0, 0, 360, 1], - TYPE: "frostAuraSymbol" - }, - ] - }; -} -Class.frostAuraBlockTop = { - SHAPE: "M -1.3 -0.15 L -1.3 0.15 L -0.3 0.3 L -0.15 1.3 L 0.15 1.3 L 0.3 0.3 L 1.3 0.15 L 1.3 -0.15 L 0.3 -0.3 L 0.15 -1.3 L -0.15 -1.3 L -0.3 -0.3 Z", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 5 }, - MIRROR_MASTER_ANGLE: true, -} -Class.frostAuraBlockTurret = { - PARENT: "genericTank", - INDEPENDENT: true, - COLOR: 17, - CONTROLLERS: ["nearestDifferentMaster"], - LABEL: "", - BODY: { - FOV: 2, - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [18, 15, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} - }, - }, { - POSITION: [23, 11, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, {density: 0.2}]), - TYPE: "bullet", - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [15, 13, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ], -} -Class.frostAuraBlockAura = addIcosphereAura(0.25, 1.6, 0.15, "Small"); -Class.frostAuraBlock = { - PARENT: 'unsetTrap', - TURRETS: [ - { - POSITION: [20, 0, 0, 45, 0, 1], - TYPE: 'frostAuraBlockTop' - }, { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: 'frostAuraBlockTurret' - }, { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: 'frostAuraBlockAura' - } - ] -} -Class.frostBossBigAura = addIcosphereAura(1.5, 1.45, 0.3, "Large"); - -Class.frostBossAutoTurret = { - PARENT: "autoTankGun", - INDEPENDENT: true, - COLOR: 17, - GUNS: [ - { - POSITION: [17, 14, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} - }, - }, { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.2}]), - TYPE: "bullet", - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [14, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ], - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 0, 1], - TYPE: ["egg", {COLOR: -1, BORDERLESS: true}], - }, - ], -} - -Class.frostBossBaseDeco = { - SHAPE: "M -1.1 0 L -0.956 0.292 L -0.669 0.205 L -0.669 -0.205 L -0.956 -0.292 Z" + - "M -0.55 0.952 L -0.225 0.974 L -0.157 0.682 L -0.512 0.477 L -0.731 0.682 Z" + - "M -0.55 -0.952 L -0.225 -0.974 L -0.157 -0.682 L -0.512 -0.477 L -0.731 -0.682 Z" + - "M 0.55 0.952 L 0.225 0.974 L 0.157 0.682 L 0.512 0.477 L 0.731 0.682 Z" + - "M 0.55 -0.952 L 0.225 -0.974 L 0.157 -0.682 L 0.512 -0.477 L 0.731 -0.682 Z" + - "M 1.1 0 L 0.956 0.292 L 0.669 0.205 L 0.669 -0.205 L 0.956 -0.292 Z", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, - MIRROR_MASTER_ANGLE: true, - GUNS: Array(6).fill().flatMap((_, i) => ([ - { - POSITION: [1.75, 3, -0.75, 7.5, 0, 60 * i, 0], - PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 2.5, SATURATION_SHIFT: 0.9 }, DRAW_ABOVE: true }, - }, { - POSITION: [1, 9, 0, 8.5, 0, 60 * i + 30, 0], - PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 10, SATURATION_SHIFT: 1.15 } }, - }, - ])) -} - -const trebuchetStats = [g.basic, g.sniper, g.predator, g.predator, g.predator, g.predator, {speed: 0.93, maxSpeed: 0.93, reload: 1.7, health: 1.7, damage: 1.4, size: 2}]; -const hielamanStats = [g.trap, g.setTrap, g.hexaTrapper, {reload: 2.4, health: 3.2, range: 1.2}]; -Class.frostBoss = { - PARENT: 'miniboss', - LABEL: 'Extrasolar', - NAME: 'Frostbyte', - FACING_TYPE: 'toTarget', - SHAPE: 6, - COLOR: "aqua", - UPGRADE_COLOR: "aqua", - SIZE: 31, - DANGER: 12, - VALUE: 888888, - UPGRADE_TOOLTIP: "\"When the golden rays of sun shine through this world's\n" + - "darkened skies and looming clouds, the legend of the warrior\n" + - "and his eternal blade will finally come to fruition.\"", - BODY: { - SPEED: base.SPEED * 0.6, - HEALTH: base.HEALTH * 11, - SHIELD: base.SHIELD * 7, - REGEN: base.REGEN * 2.5, - FOV: base.FOV * 1.4, - RESIST: base.RESIST * 1.2, - DENSITY: base.DENSITY * 7.5, - }, - GUNS: [ - ...Array(6).fill().flatMap((_, i) => ({ - // Speed - POSITION: [8, 14.5, 0.001, 9.5, 0, 60*i, 0], - PROPERTIES: {COLOR: 9}, - })), - ...Array(3).fill().flatMap((_, i) => ([ - { // Heavy Snipers - POSITION: [26.5, 9.5, 1, 0, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats(trebuchetStats), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6 }, - }, - }, { - POSITION: [24, 6.65, -1.3, 0, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, - BORDERLESS: true - }, - }, { - POSITION: [19.5, 3.8, -1.4, 0, 0, 120 * i, 0], - PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 10 } }, - }, { - POSITION: [4, 11.5, 1, 19.5, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, - }, - }, { - POSITION: [2, 12, 1, 20.5, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, - }, - }, - { // Aura Blocks - POSITION: [15, 9, 1, 0, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6}} - }, { - POSITION: [4, 7.5, -1.6, 9, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5}} - }, { - POSITION: [15, 5.4, -0.1, 0, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.75}} - }, { - POSITION: [3, 9, 1.6, 15, 0, 120 * i + 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats(hielamanStats), - TYPE: 'frostAuraBlock', - STAT_CALCULATOR: gunCalcNames.trap, - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [2, 7, 1.6, 16, 0, 120 * i + 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...hielamanStats, g.fake]), - TYPE: 'bullet', - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ])), - ], - TURRETS: [ - ...Array(6).fill().flatMap((_, i) => ([ - { - POSITION: [2.95, 8.55, 0, 60 * i + 30, 180, 2], - TYPE: "frostBossAutoTurret", - }, - ])), - { - POSITION: [8.55, 0, 0, 0, 360, 2], - TYPE: "frostBossBigAura", - }, - ], - PROPS: [ - { - POSITION: [12, 0, 0, 180, 1], - TYPE: ["hexagon", {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 7.5}}], - }, { - POSITION: [20, 0, 0, 0, 1], - TYPE: ["frostBossBaseDeco"], - }, - ] -} - -const divide = 1000; -const arraySize = 10; -const colorArray = []; -const damageMultiplayer = 3.5; -const reloadMultiplayer = 2; -for (let i = 0; i < arraySize; i++) { - const rgb = Math.round(255 * i / (arraySize - 1)); - colorArray.push('#' + ((1 << 24) + (rgb << 16) + (rgb << 8) + rgb).toString(16).slice(1)); -} -class io_nearestDifferentMaster2 extends ioTypes.nearestDifferentMaster { - constructor(body, opts = {}) { - super(body); - this.lookAtDanger = opts.lookAtDanger ?? true; - this.firingAtMe = opts.firingAtMe ?? false; - this.timeout = opts.timeout || 90; - } - buildList(range) { - // Establish whom we judge in reference to - let mostDangerous = 0, - keepTarget = false; - // Filter through everybody... - let out = entities.filter(e => - // Only look at those within our view, and our parent's view, not dead, not invisible, not our kind, not a bullet/trap/block etc - this.validate(e, this.body, this.body.master.master, range * range, range * range * 4 / 3) - ).filter((e) => { - // Only look at those within range and arc (more expensive, so we only do it on the few) - if (this.body.firingArc == null || this.body.aiSettings.view360 || Math.abs(util.angleDifference(util.getDirection(this.body, e), this.body.firingArc[0])) < this.body.firingArc[1]) { - mostDangerous = Math.max(e.dangerValue, mostDangerous); - return true; - } - }).filter((e) => { - // Even more expensive - return !this.wouldHitWall(this.body, e); - }).filter((e) => { - // Only return the highest tier of danger - if (!this.lookAtDanger) return true; - if (this.body.aiSettings.farm || e.dangerValue === mostDangerous) { - if (this.targetLock && e.id === this.targetLock.id) keepTarget = true; - return true; - } - }); - // Reset target if it's not in there - if (!keepTarget) this.targetLock = undefined; - return out; - } - think(input) { - // Override target lock upon other commands - if (input.main || input.alt || this.body.master.autoOverride) { - this.targetLock = undefined; - return {}; - } - // Otherwise, consider how fast we can either move to ram it or shoot at a potiential target. - let tracking = this.body.topSpeed, - damageRef = (this.body.bond == null) ? this.body : this.body.bond, - range = this.body.fov; - // Use whether we have functional guns to decide - for (let i = 0; i < this.body.guns.length; i++) { - if (this.body.guns[i].canShoot && !this.body.aiSettings.SKYNET) { - let v = this.body.guns[i].getTracking(); - if (v.speed == 0 || v.range == 0) continue; - tracking = v.speed; - range = Math.min(range, (v.speed || 1.5) * (v.range < (this.body.size * 2) ? this.body.fov : v.range)); - break; - } - } - if (!Number.isFinite(tracking)) { - tracking = this.body.topSpeed + .01; - } - if (!Number.isFinite(range)) { - range = 640 * this.body.FOV; - } - // Check if my target's alive - if (this.targetLock && ( - !this.validate(this.targetLock, this.body, this.body.master.master, range * range, range * range * 4 / 3) || - this.wouldHitWall(this.body, this.targetLock) // Very expensive - )) { - this.targetLock = undefined; - this.tick = 100; - } - // Think damn hard - if (this.tick++ > 15 * c.runSpeed) { - this.tick = 0; - this.validTargets = this.buildList(range); - // Ditch our old target if it's invalid - if (this.targetLock && this.validTargets.indexOf(this.targetLock) === -1) { - this.targetLock = undefined; - } - // Lock new target if we still don't have one. - if (this.targetLock == null && this.validTargets.length) { - this.targetLock = (this.validTargets.length === 1) ? this.validTargets[0] : nearest(this.validTargets, { - x: this.body.x, - y: this.body.y - }); - this.tick = -this.timeout; - } - } - // Lock onto whoever's shooting me. - if (this.firingAtMe && damageRef.collisionArray.length && damageRef.health.display() < this.oldHealth) { - this.oldHealth = damageRef.health.display(); - if (this.validTargets.indexOf(damageRef.collisionArray[0]) === -1) { - let a = (damageRef.collisionArray[0].master.id === -1) - ? damageRef.collisionArray[0].source - : damageRef.collisionArray[0].master; - if ( - this.body.firingArc == null || - this.body.aiSettings.view360 || - Math.abs(util.angleDifference(util.getDirection(this.body, a), this.body.firingArc[0])) < this.body.firingArc[1] - ) { - this.targetLock = a; - this.tick = -(this.timeout * 5); - } - } - } - // Consider how fast it's moving and shoot at it - if (this.targetLock != null) { - let radial = this.targetLock.velocity; - let diff = { - x: this.targetLock.x - this.body.x, - y: this.targetLock.y - this.body.y, - } - /// Refresh lead time - if (this.tick % 4 === 0) { - this.lead = 0 - // Find lead time (or don't) - if (!this.body.aiSettings.chase) { - let toi = timeOfImpact(diff, radial, tracking) - this.lead = toi - } - } - if (!Number.isFinite(this.lead)) { - this.lead = 0; - } - if (!this.accountForMovement) this.lead = 0; - // And return our aim - return { - target: { - x: diff.x + this.lead * radial.x, - y: diff.y + this.lead * radial.y, - }, - fire: true, - main: true - }; - } - return {}; - } -} -ioTypes.nearestDifferentMaster2 = io_nearestDifferentMaster2; -Class.toothlessBase = { - PARENT: "genericTank", - LABEL: "NightFury", - UPGRADE_TOOLTIP: "A power league...", - GLOW: { - RADIUS: 2, - COLOR: 42, - ALPHA: 0.6, - RECURSION: 6, - }, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.5 * base.FOV, - HEALTH: 6 * base.HEALTH, - DAMAGE: 2 * base.DAMAGE, - }, - LEVEL_CAP: 45, - EXTRA_SKILL: 78, // 120 - 42 - SHAPE: 3, - VALUE: 30e+3, - SIZE: 24, - COLOR: "purple", - SKILL_CAP: Array(10).fill(smshskl + 3), - LEVEL_SKILL_POINT_FUNCTION: level => { - if (level < 2) return 0; - if (level <= 40) return 1; - if (level <= 45 && level & 1 == 1) return 1; - return 0; - }, -} -Class.toothlessBossTurret = { - PARENT: "genericTank", - LABEL: "", - BODY: { - FOV: 2, - }, - CONTROLLERS: [ - "onlyAcceptInArc", - [ "nearestDifferentMaster2", { lookAtDanger: false, firingAtMe: true, timeout: 10 } ], - ], - COLOR: "grey", - GUNS: [ - { - POSITION: [32, 8, 1, 0, 0, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, { - pen: 0.8, - health: 0.6, - damage: 0.6, - recoil: 0, - }]), - TYPE: "bullet", - }, - }, - ], - ON: [{ - event: "fire", - handler: ({ body }) => { - const master = body.master; - body._damage ??= []; - body._reload ??= []; - - if (!body._loaded) { - let _temp = 0; - master._maxPower ??= 0; - - body.guns.forEach((gun, i) => { - body._damage[i] = gun.settings.damage; - body._reload[i] = gun.settings.reload; - - _temp += (body._damage[i] * 3) / body._damage[i]; - _temp += body._reload[i] / (body._reload[i] / 3); - _temp /= 2; - }); - - _temp /= body.guns.length; - - master._maxPower += (_temp - 1) * divide * 2; - if (master._maxPower > _temp) master._maxPower /= 2; - - body._loaded = true; - } - - if (master._mode) { - master._power -= 1; - if (master._power < 1) { - master._mode = 0; - master.color.base = 14; - } - } - - if (!master._oldPower) return; - const power = master._oldPower / (divide * 2) + 1; - - body.guns.forEach((gun, i) => { - let _1 = body._damage[i] * (master._mode ? power : 1); - let _2 = body._reload[i] / (master._mode ? power : 1); - let max_damage = body._damage[i] * damageMultiplayer; - let min_reload = body._reload[i] / reloadMultiplayer; - - gun.settings.damage = _1 > max_damage ? max_damage : _1; - gun.settings.reload = _2 < min_reload ? min_reload : _2; - }); - }, - }], -}; -Class.toothlessBossDeco = { - PARENT: "genericTank", - LABEL: "", - SHAPE: 3, - SIZE: 10, - ON: [{ - event: "tick", - handler: ({ body }) => { - const master = body.master; - if (master._maxPower) - body.color.base = colorArray[ - Math.floor(master._power / (master._maxPower / arraySize)) > arraySize - 1 - ? arraySize - 1 - : Math.floor(master._power / (master._maxPower / arraySize) - ) - ]; - }, - }], -}; -Class.toothlessBoss = { - PARENT: "toothlessBase", - UPGRADE_COLOR: "magenta", - TURRETS: [{ - POSITION: { SIZE: 15, LAYER: 1 }, - TYPE: ["toothlessBossDeco", { MIRROR_MASTER_ANGLE: true }], - }, { - POSITION: { SIZE: 23 }, - TYPE: ["triangle", { COLOR: "black", MIRROR_MASTER_ANGLE: true }], - }], - GUNS: [{ - POSITION: { LENGTH: 0, WIDTH: 0 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ g.basic, { - range: 0.1, - speed: 0.1, - maxSpeed: 0.1, - recoil: 0, - }]), - TYPE: "bullet", - ALT_FIRE: true, - }, - }], - ON: [{ - event: "altFire", - handler: ({ body }) => { - if (!body._power || body._mode) return; - const power = Math.floor(body._power); - - if (power >= 1) { - body.sendMessage(`Your power level ${power}`); - body._oldPower = body._power; - body._mode = 1; - body.color.base = 5; - } - }, - }, { - event: "kill", - handler: ({ body, entity }) => { - body._power ??= 0; - body._mode ??= 0; - if (!body._mode) body._power += (entity.skill.score / divide) ** 0.8; - }, - }], -} -for (let b = 0; b < 3; b++) - Class.toothlessBoss.TURRETS.push({ - POSITION: [8, 6, -5.6, 120 * b + 180, 180, 0], - TYPE: "toothlessBossTurret", - }, { - POSITION: [8, 6, 5.6, 120 * b + 180, 180, 0], - TYPE: "toothlessBossTurret", - }); \ No newline at end of file +const { combineStats, skillSet, makeAuto, addAura, LayeredBoss, makeDeco } = require('../facilitators.js'); +const { base, gunCalcNames, smshskl } = require('../constants.js'); +const g = require('../gunvals.js'); +require('./generics.js'); + +Class.miniboss = { + PARENT: "genericBoss", + CONTROLLERS: ["nearestDifferentMaster", "minion", "canRepel"], + AI: { NO_LEAD: true }, +}; +Class.ramMiniboss = { + PARENT: "genericBoss", + CONTROLLERS: ["nearestDifferentMaster", "canRepel", "mapTargetToGoal"], +}; + +// ELITE CRASHERS +Class.elite = { + PARENT: "miniboss", + LABEL: "Elite Crasher", + COLOR: "pink", + SHAPE: 3, + SIZE: 27, + VARIES_IN_SIZE: true, + VALUE: 15e4, + BODY: { + FOV: 1.25, + SPEED: 0.1 * base.SPEED, + HEALTH: 7 * base.HEALTH, + DAMAGE: 2.5 * base.DAMAGE, + }, +}; +Class.eliteDestroyer = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Destroyer", + UPGRADE_COLOR: "pink", + GUNS: [ + { + POSITION: [5, 16, 1, 6, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, { + POSITION: [5, 16, 1, 6, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, { + POSITION: [5, 16, 1, 6, 0, -60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, + ], + TURRETS: [ + { + POSITION: [11, 0, 0, 180, 360, 0], + TYPE: ["crasherSpawner"], + }, { + POSITION: [11, 0, 0, 60, 360, 0], + TYPE: ["crasherSpawner"], + }, { + POSITION: [11, 0, 0, -60, 360, 0], + TYPE: ["crasherSpawner"], + }, { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: [ "bigauto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +Class.eliteGunner = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Gunner", + UPGRADE_COLOR: "pink", + FACING_TYPE: "toTarget", + GUNS: [ + { + POSITION: [14, 16, 1, 0, 0, 180, 0], + }, { + POSITION: [4, 16, 1.5, 14, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: ["unsetPillbox", {MOTION_TYPE: "glide"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, { + POSITION: [6, 14, -2, 2, 0, 60, 0], + }, { + POSITION: [6, 14, -2, 2, 0, 300, 0], + }, + ], + AI: { NO_LEAD: false }, + TURRETS: [ + { + POSITION: [14, 8, 0, 60, 180, 0], + TYPE: ["auto4gun"], + }, { + POSITION: [14, 8, 0, 300, 180, 0], + TYPE: ["auto4gun"], + }, + ], +}; +Class.eliteSprayer = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Sprayer", + UPGRADE_COLOR: "pink", + SKILL: [0, 9, 3, 9, 2, 9, 9, 9, 9, 0], + AI: { NO_LEAD: false }, + HAS_NO_RECOIL: true, + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [6, 0, 0, 0, 360, 1], + TYPE: ["machineTripleTurret", { INDEPENDENT: true }], + }, { + POSITION: [9, 6, -5, 180, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, 5, 180, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, 5, 60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, -5, 60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, 5, -60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, -5, -60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, + ], +}; +Class.eliteBattleship = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Battleship", + UPGRADE_COLOR: "pink", + GUNS: [ + { + POSITION: [4, 6, 0.6, 7, -8, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 0, 60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 8, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, -8, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 0, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 8, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, -8, -60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 0, -60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 8, -60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], + TURRETS: [ + { + POSITION: [5, 7, 0, 0, 360, 1], + TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [5, 7, 0, 120, 360, 1], + TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [5, 7, 0, 240, 360, 1], + TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +Class.eliteSpawner = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Spawner", + UPGRADE_COLOR: "pink", + MAX_CHILDREN: 9, + AI: { STRAFE: false }, + GUNS: [ + { + POSITION: [11, 16, 1, 0, 0, 60, 0], + }, { + POSITION: [11, 16, 1, 0, 0, 180, 0], + }, { + POSITION: [11, 16, 1, 0, 0, 300, 0], + }, { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [2, 18, 1, 11, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), + TYPE: ["sentrySwarm", {GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [2, 18, 1, 11, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), + TYPE: ["sentryTrap", {GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [2, 18, 1, 11, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), + TYPE: ["sentryGun", {GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, + ], + TURRETS: [ + { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: ["auto4gun", { INDEPENDENT: false, COLOR: -1 }], + }, + ], +}; +Class.eliteTrapGuard = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Trap Guard", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false }, + GUNS: [], + TURRETS: [ + { + POSITION: [9.5, 0, 0, 0, 360, 1], + TYPE: "triTrapGuardTurret", + }, + ], +}; +for (let i = 0; i < 3; i++) { + Class.eliteTrapGuard.GUNS.push( + { + POSITION: [10.5, 6, 1, 0, 0, 120*i+60, 0], + }, { + POSITION: [3, 6, 1.7, 10.5, 0, 120*i+60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ) + Class.eliteTrapGuard.TURRETS.push( + { + POSITION: [5, 8, -7, 120*i+60, 160, 0], + TYPE: ["autoTurret", { INDEPENDENT: false }], + }, { + POSITION: [5, 8, 7, 120*i+60, 160, 0], + TYPE: ["autoTurret", { INDEPENDENT: false }], + }, + ) +}; +Class.eliteSpinner = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Spinner", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false }, + FACING_TYPE: ["spin", {speed: 0.1}], + GUNS: [], + TURRETS: [ + { + POSITION: [9.5, 0, 0, 0, 360, 1], + TYPE: ["eliteSpinnerCyclone", {COLOR: -1}], + }, + ], +}; +for (let i = 0; i < 3; i++) { + Class.eliteSpinner.GUNS.push( + { + POSITION: [9.5, 2, 1, -1.5, 11.5, 120*i+10, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [9.5, 2, 1, 3.5, 6.5, 120*i+10, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [9.5, 2, 1, 8.5, 1.5, 120*i+10, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [2, 20, 0.75, 8, 0, 120*i+60, 0], + }, + ) +}; + +// OLD ELITE +Class.oldEliteSprayer = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Sprayer (Old)", + UPGRADE_COLOR: "pink", + AI: { NO_LEAD: false }, + TURRETS: [ + { + POSITION: [14, 6, 0, 180, 190, 0], + TYPE: [ "sprayer", { COLOR: -1 } ], + }, { + POSITION: [14, 6, 0, 60, 190, 0], + TYPE: [ "sprayer", { COLOR: -1 } ], + }, { + POSITION: [14, 6, 0, -60, 190, 0], + TYPE: [ "sprayer", { COLOR: -1 } ], + }, + ], +}; + +// Legionary Crasher +Class.legionaryCrasherTop = { + PARENT: "elite", + AI: { STRAFE: false, NO_LEAD: false }, + CONTROLLERS: [ ["spin", { independent: true, speed: -0.005 }] ], + INDEPENDENT: true, + GUNS: [], + TURRETS: [], +} +for (let i = 0; i < 3; i++) { + Class.legionaryCrasherTop.GUNS.push( + { + POSITION: [4, 9.5, 0.7, 7, 5, 120*i+60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), + TYPE: [ "swarm", { INDEPENDENT: true } ], + STAT_CALCULATOR: gunCalcNames.swarm, + AUTOFIRE: true, + + }, + }, { + POSITION: [4, 9.5, 0.7, 7, -5, 120*i+60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), + TYPE: [ "swarm", { INDEPENDENT: true } ], + STAT_CALCULATOR: gunCalcNames.swarm, + AUTOFIRE: true, + }, + }, + ) + Class.legionaryCrasherTop.TURRETS.push( + { + POSITION: [9.5, 10, 0, 120*i, 190, 0], + TYPE: "auto4gun", + }, + ) +} +Class.legionaryCrasher = { + PARENT: "elite", + LABEL: "Legionary Crasher", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false, NO_LEAD: false }, + HAS_NO_RECOIL: true, + VALUE: 5e6, + SIZE: 75, + BODY: { + FOV: 1.5, + SPEED: 0.1 * base.SPEED, + HEALTH: 2000, + DAMAGE: 5 * base.DAMAGE, + }, + GUNS: [], + TURRETS: [ + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: "legionaryCrasherTop", + } + ], +} +for (let i = 0; i < 3; i++) { + Class.legionaryCrasher.GUNS.push( + { + POSITION: [14.5, 13, 1, 0, 0, 120*i, 0], + }, { + POSITION: [3, 13, 1.7, 14.5, 0, 120*i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, g.destroyer, { speed: 2.5, size: 0.6, maxSpeed: 3 }]), + TYPE: "legionaryPillbox", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ) +} +for (let i = 0; i < 3; i++) { + Class.legionaryCrasher.GUNS.push( + { + POSITION: [5, 12, 1.6, -11, 0, 120*i, 0], + } + ) + Class.legionaryCrasher.TURRETS.push( + { + POSITION: [14, 8, 0, 120*i+60, 180, 0], + TYPE: [ "sprayer", { COLOR: -1, } ], + }, + ) +} + +Class.sprayerLegion = { + PARENT: "elite", + UPGRADE_LABEL: "Sprayer Legion", + UPGRADE_COLOR: "pink", + AI: { NO_LEAD: false }, + TURRETS: [ + { + POSITION: [14, 6, 0, 180, 190, 0], + TYPE: ["machineGun", {COLOR: -1}], + }, { + POSITION: [14, 6, 0, 60, 190, 0], + TYPE: ["machineGun", {COLOR: -1}], + }, { + POSITION: [14, 6, 0, -60, 190, 0], + TYPE: ["machineGun", {COLOR: -1}], + }, + ], +}; + +// STRANGE BOSSES +Class.sorcerer = { + PARENT: "miniboss", + LABEL: "Sorcerer", + DANGER: 7, + SHAPE: 0, + COLOR: "veryLightGrey", + UPGRADE_COLOR: "veryLightGrey", + SIZE: 26, + MAX_CHILDREN: 50, + VALUE: 2e5, + BODY: { + FOV: 0.5, + SPEED: 0.12 * base.SPEED, + HEALTH: 6 * base.HEALTH, + DAMAGE: 2 * base.DAMAGE, + }, + GUNS: Array(2).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.machineGun, g.machineGunner, { size: 0.4, spray: 150, speed: 2, shudder: 1.75 }]), + TYPE: "minichip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.summoner = { + PARENT: "miniboss", + LABEL: "Summoner", + DANGER: 8, + SHAPE: 4, + COLOR: "gold", + UPGRADE_COLOR: "gold", + SIZE: 26, + MAX_CHILDREN: 28, + VALUE: 3e5, + BODY: { + FOV: 0.5, + SPEED: 0.1 * base.SPEED, + HEALTH: 7 * base.HEALTH, + DAMAGE: 2.6 * base.DAMAGE, + }, + GUNS: Array(4).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.8 }]), + TYPE: ["sunchip"], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.enchantress = { + PARENT: "miniboss", + LABEL: "Enchantress", + DANGER: 8, + SHAPE: 3.5, + COLOR: "orange", + UPGRADE_COLOR: "orange", + SIZE: 26, + MAX_CHILDREN: 28, + VALUE: 4e5, + BODY: { + FOV: 0.5, + SPEED: 0.09 * base.SPEED, + HEALTH: 10 * base.HEALTH, + DAMAGE: 3 * base.DAMAGE, + }, + GUNS: Array(3).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.9 }]), + TYPE: "dorito", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.exorcistor = { + PARENT: "miniboss", + LABEL: "Exorcistor", + DANGER: 8, + SHAPE: 5.5, + COLOR: "purple", + UPGRADE_COLOR: "purple", + SIZE: 26, + MAX_CHILDREN: 20, + VALUE: 5e5, + BODY: { + FOV: 0.5, + SPEED: 0.08 * base.SPEED, + HEALTH: 15 * base.HEALTH, + DAMAGE: 4 * base.DAMAGE, + }, + GUNS: Array(5).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 72, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), + TYPE: "demonchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.shaman = { + PARENT: "miniboss", + LABEL: "Shaman", + DANGER: 8, + SHAPE: 6, + COLOR: "hexagon", + UPGRADE_COLOR: "hexagon", + SIZE: 26, + MAX_CHILDREN: 20, + VALUE: 6e5, + BODY: { + FOV: 0.5, + SPEED: 0.07 * base.SPEED, + HEALTH: 20 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + }, + GUNS: Array(6).fill().map((_, i) => ({ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { size: 1.1 }]), + TYPE: "realchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + })) +}; +Class.eliteSkimmer = { + PARENT: "elite", + LABEL: "Elite Skimmer", + COLOR: "orange", + UPGRADE_COLOR: "orange", + TURRETS: [ + { + POSITION: [15, 5, 0, 60, 170, 0], + TYPE: "skimmerTurret", + }, { + POSITION: [15, 5, 0, 180, 170, 0], + TYPE: "skimmerTurret", + }, { + POSITION: [15, 5, 0, 300, 170, 0], + TYPE: "skimmerTurret", + }, + ], +}; + +// Nesters +Class.nestKeeper = { + PARENT: "miniboss", + LABEL: "Nest Keeper", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + MAX_CHILDREN: 15, + VALUE: 3e5, + GUNS: [ + { + POSITION: [3.5, 6.65, 1.2, 8, 0, 35, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [3.5, 6.65, 1.2, 8, 0, -35, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [3.5, 6.65, 1.2, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [3.5, 6.65, 1.2, 8, 0, 108, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [3.5, 6.65, 1.2, 8, 0, -108, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, + ], + TURRETS: [ + { + POSITION: [8, 9, 0, 72, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [8, 9, 0, 0, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [8, 9, 0, 144, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [8, 9, 0, 216, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [8, 9, 0, -72, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "boomerTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +Class.nestWarden = { + PARENT: "miniboss", + LABEL: "Nest Warden", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + VALUE: 3e5, + GUNS: [], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "barricadeTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +for(let i = 0; i < 5; i++) { + Class.nestWarden.GUNS.push( + { + POSITION: [10.7, 8, 1, 0, 0, 72*i+36, 0], + }, { + POSITION: [1.5, 8, 1.2, 10.7, 0, 72*i+36, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { speed: 1.2 }, g.setTrap, g.constructor]), + TYPE: "unsetTrap", + STAT_CALCULATOR: gunCalcNames.block + }, + }, + ); + Class.nestWarden.TURRETS.push( + { + POSITION: [8, 9, 0, 72*i, 120, 0], + TYPE: [ "cruiserTurret", { INDEPENDENT: true, COLOR: -1 } ], + } + ); +}; +Class.nestGuardian = { + PARENT: "miniboss", + LABEL: "Nest Guardian", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + VALUE: 3e5, + GUNS: [], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "twisterTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +for(let i = 0; i < 5; i++) { + Class.nestGuardian.GUNS.push( + { + POSITION: [5.5, 7, 1, 6, 0, 72*i+36, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, + ); + Class.nestGuardian.TURRETS.push( + { + POSITION: [8, 9, 0, 72*i, 120, 0], + TYPE: [ "swarmerTurret", { INDEPENDENT: true, COLOR: -1 } ], + } + ); +}; + +// Rogues +Class.roguePalisade = { + PARENT: "miniboss", + LABEL: "Rogue Palisade", + COLOR: "darkGrey", + UPGRADE_COLOR: "darkGrey", + SHAPE: 6, + SIZE: 30, + VALUE: 5e5, + CONTROLLERS: ['nearestDifferentMaster', 'onlyAcceptInArc'], + BODY: { + FOV: 1.4, + SPEED: 0.05 * base.SPEED, + HEALTH: 16 * base.HEALTH, + SHIELD: 3 * base.SHIELD, + DAMAGE: 3 * base.DAMAGE, + }, + GUNS: [ + { POSITION: [4, 6, -1.6, 8, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 60, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 120, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 180, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 240, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + { POSITION: [4, 6, -1.6, 8, 0, 300, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, + ], + TURRETS: [ + { POSITION: [5, 10, 0, 30, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 90, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 150, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 210, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 270, 110, 0], TYPE: "baseTrapTurret" }, + { POSITION: [5, 10, 0, 330, 110, 0], TYPE: "baseTrapTurret" }, + ], +}; +Class.rogueArmada = (() => { + let SHAPE = 7, + GUNS = [], + TURRETS = []; + for (let i = 0; i < SHAPE; i++) { + for (let j = 0; j < 8; j++) { + GUNS.push({ + POSITION: [8, 2 + Math.floor(j / 3), 1, 0, j / 2 - 2, (i + 0.5) * (360 / SHAPE), 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: j % SHAPE < 2 ? "bullet" : "casing" + } + }); + } + GUNS.push({ + POSITION: [8.5, 6, 1, 4, 0, (i + 0.5) * (360 / SHAPE), 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), + TYPE: "casing" + } + }, { + POSITION: [7, 6, -1.6, 4, 0, (i + 0.5) * (360 / SHAPE), 0] + }); + } + for (let i = 0; i < SHAPE; i++) { + TURRETS.push({ + POSITION: [5, 10, 0, i * 360 / SHAPE, 160, 0], + TYPE: "shottrapTurret" + }); + } + return { + PARENT: "miniboss", + LABEL: 'Rogue Armada', + COLOR: "darkGrey", + UPGRADE_COLOR: "darkGrey", + SHAPE, + SIZE: 28, + VALUE: 500000, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.1, + HEALTH: base.HEALTH * 16, + SHIELD: base.SHIELD * 3, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 3, + }, + GUNS, TURRETS + }; +})(); + +// Bob. +Class.bob = { + PARENT: "ramMiniboss", + LABEL: "Bob", + SHAPE: 0, + COLOR: "aqua", + UPGRADE_COLOR: "aqua", + SIZE: 18, + BODY: { + FOV: 2, + SPEED: 2 * base.SPEED, + HEALTH: 5 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + REGEN: 8 * base.REGEN, + FOV: 0.5 * base.FOV, + DENSITY: 6 * base.DENSITY, + }, + CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody", + }, { + POSITION: [21.5, 0, 0, 30, 360, 0], + TYPE: "landmineBody", + }, { + POSITION: [23.75, 0, 0, 0, 360, 0], + TYPE: "spikeBody", + }, + ], +}; +Class.nemesis = { + PARENT: "bob", + LABEL: "Nemesis", + COLOR: "red", + UPGRADE_COLOR: "red", + BODY: { + REGEN: 1e5, + HEALTH: 1e6, + DENSITY: 30, + DAMAGE: 1e5, + FOV: 5, + }, +}; + +// DIEP BOSSES +Class.guardian = { + PARENT: "elite", + LABEL: "Guardian of the Pentagons", + UPGRADE_LABEL: "Guardian", + UPGRADE_COLOR: "pink", + FACING_TYPE: "toTarget", + GUNS: [ + { + POSITION: [4, 12, 1.4, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, { size: 0.5 }]), + TYPE: "swarm", + AUTOFIRE: true, + }, + }, + ], + AI: { NO_LEAD: false }, +}; +Class.defenderAutoTankGun = { + PARENT: "autoTankGun", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret]), + TYPE: ["bullet", {COLOR: "yellow"}], + }, + }, + ], +}; +Class.defender = { + PARENT: "elite", + LABEL: "Defender", + COLOR: "orange", + UPGRADE_COLOR: "orange", + GUNS: [ + { + POSITION: [15, 7, 1, -3, 0, 60, 0], + }, { + POSITION: [3, 7, 1.7, 12, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: ["trap", {COLOR: "yellow"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, { + POSITION: [15, 7, 1, -3, 0, 180, 0], + }, { + POSITION: [3, 7, 1.7, 12, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: ["trap", {COLOR: "yellow"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, { + POSITION: [15, 7, 1, -3, 0, 300, 0], + }, { + POSITION: [3, 7, 1.7, 12, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: ["trap", {COLOR: "yellow"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], + TURRETS: [ + { + POSITION: [5, 7, 0, 0, 190, 1], + TYPE: "defenderAutoTankGun", + }, { + POSITION: [5, 7, 0, 120, 190, 1], + TYPE: "defenderAutoTankGun", + }, { + POSITION: [5, 7, 0, 240, 190, 1], + TYPE: "defenderAutoTankGun", + }, + ], + AI: { NO_LEAD: false }, +}; + +// CELESTIALS +Class.terrestrial = { + PARENT: "miniboss", + LABEL: "Terrestrial", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 5e5, + SHAPE: 7, + SIZE: 35, + BODY: { + FOV: 1, + HEALTH: 1000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 9, + }, +}; +Class.celestial = { + PARENT: "miniboss", + LABEL: "Celestial", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 1e6, + SHAPE: 9, + SIZE: 45, + BODY: { + FOV: 1, + HEALTH: 1000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 12, + }, +}; +Class.rogueCelestial = { + PARENT: "celestial", + LABEL: "Rogue Celestial", + COLOR: "darkGrey", +}; +Class.eternal = { + PARENT: "miniboss", + LABEL: "Eternal", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 4e6, + SHAPE: 11, + SIZE: 90, + BODY: { + FOV: 1, + HEALTH: 3000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 18, + }, +}; + +// Terrestrials +let ares = new LayeredBoss(null, "Ares", "terrestrial", 7, "purple", "terrestrialTrapTurret", 7, 5.5); +ares.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["demonchip", { INDEPENDENT: true, }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, false, null, 18); +ares.addLayer({turret: { + POSITION: [10, 8.5, 0, null, 160, 0], + TYPE: ["protoSwarmerTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let gersemi = new LayeredBoss(null, "Gersemi", "terrestrial", 7, "lightGreen", "terrestrialTrapTurret", 7, 5.5); +gersemi.addLayer({turret: { + POSITION: [9, 8, 0, null, 160, 0], + TYPE: ["swarmTurret", { INDEPENDENT: true }], +}}); +gersemi.addLayer({turret: { + POSITION: [9.5, 7.5, 0, null, 160, 0], + TYPE: ["basicTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let ezekiel = new LayeredBoss(null, "Ezekiel", "terrestrial", 7, "orange", "terrestrialTrapTurret", 7, 5.5); +ezekiel.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["dorito", { COLOR: "orange", INDEPENDENT: true, }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 18); +ezekiel.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["skimmerTurret", { COLOR: "grey", INDEPENDENT: true }], +}}, true, 6.5) + +let eris = new LayeredBoss(null, "Eris", "terrestrial", 7, "pink", "terrestrialTrapTurret", 7, 5.5); +eris.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), + TYPE: ["minion", { INDEPENDENT: true, COLOR: "pink", HAS_NO_RECOIL: true }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, false, null, 14); +eris.addLayer({turret: { + POSITION: [10, 8.5, 0, null, 160, 0], + TYPE: ["rocketeerTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let selene = new LayeredBoss(null, "Selene", "terrestrial", 7, "gold", "terrestrialTrapTurret", 7, 5.5); +selene.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["sunchip", { COLOR: "gold", INDEPENDENT: true }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 18); +selene.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["hyperTwisterTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +// PALADIN +let paladin = new LayeredBoss(null, "Paladin", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); +paladin.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: ["demonchip", {INDEPENDENT: true}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 16); +paladin.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: "swarmerTurret", +}}, true, 6); + +// FREYJA +let freyja = new LayeredBoss(null, "Freyja", "celestial", 9, "lightGreen", "baseTrapTurret", 6.5, 5.5); +freyja.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "cruiserTurret", +}}); +freyja.addLayer({turret: { + POSITION: [10.6, 7.5, 0, null, 160, 0], + TYPE: "auto4gun", +}}, true, 6); + +// ZAPHKIEL +let zaphkiel = new LayeredBoss(null, "Zaphkiel", "celestial", 9, "orange", "baseTrapTurret", 6.5, 5.5); +zaphkiel.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: ["drone", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 16); +zaphkiel.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["skimmerTurret", {COLOR: "grey", INDEPENDENT: true}], +}}, true, 6); + +// NYX +let nyx = new LayeredBoss(null, "Nyx", "celestial", 9, "pink", "baseTrapTurret", 6.5, 5.5); +nyx.addLayer({gun: { + POSITION: [3.8, 7, -1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), + TYPE: ["minion", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 16); +nyx.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: "rocketeerTurret", +}}, true, 6); + +// THEIA +let theia = new LayeredBoss(null, "Theia", "celestial", 9, "gold", "baseTrapTurret", 6.5, 5.5); +theia.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, { size: 0.5 }]), + TYPE: ["summonerDrone", {INDEPENDENT: true}], + AUTOFIRE: true, + WAIT_TO_CYCLE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 35); +theia.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["twisterTurret", {COLOR: "grey"}], +}}, true, 6); + +// ATLAS +let atlas = new LayeredBoss(null, "Atlas", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); +atlas.addLayer({turret: { + POSITION: [7, 9, 0, null, 180, 0], + TYPE: "artilleryTurret", +}}); +atlas.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "nailgunTurret", +}}, true, 6); + +// RHEA +let rhea = new LayeredBoss(null, "Rhea", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +rhea.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "wrenchTurret", +}}); +rhea.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "crowbarTurret", +}}, true, 6); + +// JULIUS +let julius = new LayeredBoss(null, "Julius", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +julius.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "juliusLowerTurret", +}}); +julius.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "launcherTurret", +}}, true, 6); + +// GENGHIS +let genghis = new LayeredBoss(null, "Genghis", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +genghis.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "genghisLowerTurret", +}}); +genghis.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "auto4gun", +}}, true, 6); + +// NAPOLEON +let napoleon = new LayeredBoss(null, "Napoleon", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +napoleon.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "napoleonLowerTurret", +}}); +napoleon.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "napoleonUpperTurret", +}}, true, 6) + +// Eternals +let kronos = new LayeredBoss(null, "Kronos", "eternal", 11, "veryLightGrey", "baseTrapTurret", 6, 5.5); +kronos.addLayer({turret: { + POSITION: [6.5, 9, 0, null, 160, 0], + TYPE: "kronosSkimmerTurret", +}}); +kronos.addLayer({turret: { + POSITION: [6.5, 9, 0, null, 160, 0], + TYPE: "carrierTurret", +}}, true, 4); +kronos.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 160, 0], + TYPE: "tripletTurret", +}}, true, 4); + +let odin = new LayeredBoss(null, "Odin", "eternal", 11, "aqua", "baseTrapTurret", 4.5, 3.5); +odin.addLayer({gun: { + POSITION: [2.25, 3.25, -1.6, 9, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }, g.pounder, {size: 1.7}]), + TYPE: ["gemDrone", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 18); +odin.addLayer({turret: { + POSITION: [7, 8, 0, null, 160, 0], + TYPE: "autosmashTurret", +}}, true, 5.5); +odin.addLayer({turret: { + POSITION: [8, 9, 0, null, 160, 0], + TYPE: "gunnerCruiserTurret", +}}, true, 4.5); + +// Developer Bosses +Class.taureonCoreBase = { + SHAPE: 4, + COLOR: '#00A2E8' +}; +Class.taureonCore = { + PARENT: "genericTank", + LABEL: "Core Turret", + SHAPE: 4.5, + COLOR: '#99D9EA', + CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], + INDEPENDENT: true, + GUNS: [{ + POSITION: [10, 14, -0.5, 14, 0, 0, 0] + },{ + POSITION: [21, 15, -1.1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.destroyer, g.sniper]), + TYPE: "snake", + STAT_CALCULATOR: gunCalcNames.sustained + } + }], + TURRETS: [{ + POSITION: [20 * Math.SQRT2, 0, 0, 0, 0, 0], + TYPE: "taureonCoreBase" + }] +}; +Class.taureonBase = { + SHAPE: 4.5, + COLOR: '#161B54', + MIRROR_MASTER_ANGLE: true +}; +let d = 1/4; +Class.taureonStar = { + SHAPE: [[0,1],[d,d],[1,0],[d,-d],[0,-1],[-d,-d],[-1,0],[-d,d]], + COLOR: '#3F48CC', + MIRROR_MASTER_ANGLE: true +}; +Class.taureonRailgunTurret = { + PARENT: "genericTank", + COLOR: "grey", + LABEL: "Railgun Turret", + CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], + INDEPENDENT: true, + GUNS: [{ + POSITION: [20, 7, 1, 0, 0, 0, 0] + },{ + POSITION: [24, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.destroyer, { speed: 5, penetration: 0.8 }]), + TYPE: "bullet" + } + },{ + POSITION: [5, 7.5, -1.6, 8, 0, 0, 0], + }] +}; +Class.taureonThruster = { + PARENT: "genericTank", + COLOR: "grey", + LABEL: "Thruster", + CONTROLLERS: ["onlyAcceptInArc"], + GUNS: [{ + POSITION: [14, 12, 1, 4, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), + TYPE: ["bullet", { ALPHA: 0.5 }] + } + }, { + POSITION: [12, 12, 1.4, 4, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), + TYPE: ["bullet", { ALPHA: 0.5 }] + }, + }] +}; +Class.taureonMissile = { + PARENT: "bullet", + LABEL: "Missile", + FACING_TYPE: "smoothToTarget", + CONTROLLERS: ["nearestDifferentMaster"], + INDEPENDENT: true, + BODY: { + ACCELERATION: 10, + FOV: base.FOV * 2 + }, + TURRETS: [{/** SIZE X Y ANGLE ARC */ + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + }], + GUNS: [{/* LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [6, 12, 1.4, 8, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] + } + },{ + POSITION: [10, 12, 0.8, 8, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] + } + },...Array(32).fill().map((_, i)=>({ + POSITION: [0, (i % 4) + 1, 0, 0, 0, 0, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, { spray: 1e6, range: 0.5, shudder: 1.5, damage: 1 + (i % 4) }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true + }, + }))] +}; +Class.taureonBoss = { + PARENT: "miniboss", + LABEL: "Diamond Marauder", + NAME: "Taureon", + COLOR: '#2B339B', + UPGRADE_COLOR: "spaceGem", + DANGER: 10, + SHAPE: 4.5, + SIZE: 50, + FACING_TYPE: "smoothToTarget", + UPGRADE_TOOLTIP: "With a powerful Gatling Gun on the front, Rocket Launchers as wings, movable Thrusters on the back, " + + "and equipped with Railgun Turrets, it perfectly excells at terminating those who feel its Wrath.\n" + + "An octahedral carbon robot, exclusively designed to eradicate opponents with sheer brutality alone.\n" + + '"NOW YOU FACE MY ULTIMATE CREATION."', + VALUE: 9e6, + BODY: { + FOV: 1, + SPEED: 0.5 * base.SPEED, + HEALTH: 20 * base.HEALTH, + DAMAGE: 3 * base.DAMAGE, + }, + TURRETS: [{ + POSITION: [23.3, 0, 0, 0, 0, 0], + TYPE: "taureonBase" + },{ + POSITION: [5, 10, 0, -45, 180, 0], + TYPE: "taureonRailgunTurret" + },{ + POSITION: [5, 10, 0, 45, 180, 0], + TYPE: "taureonRailgunTurret" + },{ + POSITION: [5, -10, -2, -45, 90, 0], + TYPE: "taureonThruster" + },{ + POSITION: [5, -10, 2, 45, 90, 0], + TYPE: "taureonThruster" + },{ + POSITION: [25, 0, 0, 0, 0, 1], + TYPE: "taureonStar" + },{ + POSITION: [5, 0, 0, 0, 360, 1], + TYPE: "taureonCore" + }], + GUNS: [...Array(6).fill().map((_, i) => ({ + POSITION: [18, 1.75, 1, 0, Math.cos(Math.PI * i / 3) * 2, 0, i / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, { speed: 2, maxSpeed: 2, damage: 0.75, size: 0.8 }]), + TYPE: "bullet" + } + })),{ + POSITION: [4, 5, -0.5, 12, 0, -90, 0] + },{ + POSITION: [10, 5, -1.2, 5, 0, -90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), + TYPE: "taureonMissile", + STAT_CALCULATOR: gunCalcNames.sustained + } + },{ + POSITION: [4, 5, -0.5, 12, 0, 90, 0] + },{ + POSITION: [10, 5, -1.2, 5, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), + TYPE: "taureonMissile", + STAT_CALCULATOR: gunCalcNames.sustained + } + },{ + POSITION: [5.5, 5, -1.5, 5, 0, -45, 0] + },{ + POSITION: [5.5, 5, -1.5, 5, 0, 45, 0] + },{ + POSITION: [2, 7, 1, 8, 0, 0, 0] + },{ + POSITION: [2, 7, 1, 14.5, 0, 0, 0] + }] +}; + +Class.zephiMiscDeco = makeDeco(4, "white") +Class.zephiMiscDeco2 = makeDeco(4, "black") +Class.zephiSunchip = makeAuto({ + PARENT: "drone", + SHAPE: 4, + HITS_OWN_TYPE: "hard", + BODY: { + FOV: 0.5, + }, + AI: { + BLIND: true, + FARMER: true, + }, + TURRETS: [{ + POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], + TYPE: ["overdriveDeco", { MIRROR_MASTER_ANGLE: true }] + },{ + POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], + TYPE: ["shinySquare", { MIRROR_MASTER_ANGLE: true }] + }] +}, "Robo-Sunchip", {type: 'autoSmasherTurret', size: 6}) +Class.zephiEggchip = { + PARENT: "drone", + LABEL: "Guided Missile", + SHAPE: 0, + HITS_OWN_TYPE: "hard", + BODY: { + FOV: 0.5, + }, + AI: { + BLIND: true, + FARMER: true, + }, + GUNS: [ + { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, g.lowPower, { reload: 0.5, recoil: 1.35, speed: 1.3, maxSpeed: 1.3 }]), + TYPE: ["bullet", { COLOR: "black", PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], + TURRETS: [{ + POSITION: [10, 0, 0, 45, 0, 1], + TYPE: "gem" + }] +} +Class.zephiGearOuter = makeDeco('M 0.5 0.0929 V -0.0908 L 0.3875 -0.1096 C 0.3792 -0.1409 0.3667 -0.1701 0.3521 -0.1952 L 0.4187 -0.2871 L 0.2896 -0.4186 L 0.1958 -0.3539 C 0.1687 -0.3685 0.1396 -0.381 0.1104 -0.3894 L 0.0917 -0.5 H -0.0917 L -0.1104 -0.3873 C -0.1417 -0.3789 -0.1688 -0.3664 -0.1958 -0.3518 L -0.2875 -0.4165 L -0.4188 -0.2871 L -0.3521 -0.1952 C -0.3667 -0.1681 -0.3792 -0.1388 -0.3875 -0.1075 L -0.5 -0.0908 V 0.0929 L -0.3875 0.1117 C -0.3792 0.143 -0.3667 0.1701 -0.3521 0.1973 L -0.4188 0.2912 L -0.2896 0.4207 L -0.1958 0.3539 C -0.1688 0.3685 -0.1396 0.381 -0.1083 0.3894 L -0.0896 0.5 H 0.0938 L 0.1125 0.3873 C 0.1417 0.3789 0.1708 0.3664 0.1979 0.3518 L 0.2917 0.4186 L 0.4208 0.2891 L 0.3542 0.1952 C 0.3688 0.1681 0.3812 0.1409 0.3896 0.1096 L 0.5 0.0929 Z M 0.3333 0 C 0.3333 0.1841 0.1841 0.3333 0 0.3333 C -0.1841 0.3333 -0.3333 0.1841 -0.3333 0 C -0.3333 -0.1841 -0.1841 -0.3333 0 -0.3333 C 0.1841 -0.3333 0.3333 -0.1841 0.3333 0 Z', '#7F7F7F') +Class.zephiGearOuter.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearOuter.BORDERLESS = true +Class.zephiGearCentre = makeDeco(0, '#1F1F1F') +Class.zephiGearCentre.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearCentre.BORDERLESS = true +Class.zephiGearRed = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#FF1F1F') +Class.zephiGearRed.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearRed.BORDERLESS = true +Class.zephiGearGreen = makeDeco('M 0.0771 -0.2552 C 0.0743 -0.2561 0.0691 -0.2576 0.0657 -0.2585 L 0.0607 -0.2597 C 0.0571 -0.2605 0.0514 -0.2617 0.0479 -0.2623 L 0.0428 -0.2632 C 0.0392 -0.2638 0.0334 -0.2646 0.0299 -0.265 L 0.0247 -0.2655 C 0.0211 -0.2659 0.0153 -0.2662 0.0117 -0.2664 L 0.0066 -0.2666 C 0.003 -0.2667 -0.0029 -0.2667 -0.0065 -0.2666 L -0.0116 -0.2664 C -0.0153 -0.2662 -0.0211 -0.2659 -0.0247 -0.2655 L -0.0298 -0.265 C -0.0334 -0.2646 -0.0392 -0.2638 -0.0427 -0.2632 L -0.0478 -0.2623 C -0.0514 -0.2617 -0.0571 -0.2605 -0.0606 -0.2597 L -0.0656 -0.2585 C -0.0691 -0.2576 -0.0747 -0.256 -0.0782 -0.2549 C -0.081 -0.254 -0.0833 -0.2502 -0.0833 -0.2466 V 0.2466 C -0.0833 0.2502 -0.0805 0.2541 -0.0771 0.2552 C -0.0743 0.2561 -0.0691 0.2576 -0.0656 0.2585 L -0.0606 0.2597 C -0.0571 0.2605 -0.0514 0.2617 -0.0478 0.2623 L -0.0427 0.2632 C -0.0392 0.2638 -0.0334 0.2646 -0.0298 0.265 L -0.0247 0.2655 C -0.0211 0.2659 -0.0153 0.2663 -0.0116 0.2664 L -0.0065 0.2666 C -0.0029 0.2667 0.003 0.2667 0.0066 0.2666 L 0.0117 0.2664 C 0.0153 0.2663 0.0211 0.2659 0.0247 0.2655 L 0.0299 0.265 C 0.0334 0.2646 0.0392 0.2638 0.0428 0.2632 L 0.0479 0.2623 C 0.0514 0.2617 0.0571 0.2605 0.0607 0.2597 L 0.0657 0.2585 C 0.0691 0.2576 0.0748 0.256 0.0782 0.2549 C 0.0811 0.254 0.0834 0.2502 0.0834 0.2466 V -0.2466 C 0.0834 -0.2502 0.0806 -0.2541 0.0771 -0.2552 Z', '#1FDF1F') +Class.zephiGearGreen.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearGreen.BORDERLESS = true +Class.zephiGearBlue = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#1F7FDF') +Class.zephiGearBlue.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearBlue.BORDERLESS = true +Class.zephiBoss = { + PARENT: "miniboss", + LABEL: "Shiny Mecha-Thaumaturge", + NAME: "Zephi", + DANGER: 10, + SHAPE: 4, + COLOR: "lightGreen", + UPGRADE_COLOR: "lightGreen", + SIZE: 50, + VALUE: 5e6, + SKILL: skillSet({ + rld: 1, + dam: 1, + pen: 1, + str: 1, + spd: 1, + atk: 1, + hlt: 1, + shi: 1, + rgn: 1, + mob: 1, + }), + BODY: { + FOV: 0.75, + SPEED: 0.05 * base.SPEED, + HEALTH: 15 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + }, + UPGRADE_TOOLTIP: "Good luck.", + GUNS: Array(4).fill().map((_, i) => ([{ + POSITION: [2.5, 3, 1.2, 8, 5, i * 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 50, speed: 1.25, shudder: 1.25 }]), + TYPE: ["zephiEggchip", {COLOR: "black"}], + MAX_CHILDREN: 8, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + COLOR: "black", + } + },{ + POSITION: [2.5, 3, 1.2, 8, -5, i * 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 150, speed: 1.25, shudder: 1.25 }]), + TYPE: ["zephiEggchip", {COLOR: "black"}], + MAX_CHILDREN: 8, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + COLOR: "black", + } + },{ + POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, g.destroyer, { speed: 2.5 }, { maxSpeed: 3 }]), + TYPE: ["zephiSunchip", {COLOR: "black"}], + MAX_CHILDREN: 4, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true + } + }])).flat(), + TURRETS: [{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearOuter" + },{ + POSITION: [5.375 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearCentre" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearRed" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearGreen" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 180, 360, 2], + TYPE: "zephiGearBlue" + },{ + POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], + TYPE: "overdriveDeco" + },{ + POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], + TYPE: "zephiMiscDeco2" + },{ + POSITION: [20 * Math.SQRT1_2 ** 3, 0, 0, 45, 0, 1], + TYPE: "zephiMiscDeco" + }] +}; + +Class.dogeiscutBody = { + PARENT: "genericTank", + COLOR: "grey", + SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]] +} +Class.dogeiscutTurret = { + PARENT: "genericTank", + COLOR: "grey", + GUNS: [ { + POSITION: [ 50, 5, 2.5, 0, 0, 0, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.minigun, {reload: 0.1}]), + TYPE: "bullet", + }, + }, { + POSITION: [ 18, 8, -2, 0, 0, 0, 0, ], + }, + ], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], + }, + ] +} +function createDogeiscutMissileTurret(color) { + return { + PARENT: "genericTank", + COLOR: "grey", + GUNS: [ { + POSITION: [ 15, 8, 2.5, 0, 0, 180, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ + g.basic, + g.skimmer, + { reload: 0.5 }, + g.lowPower, + { recoil: 1.35 }, + { speed: 1.3, maxSpeed: 1.3 }, + { speed: 1.3, maxSpeed: 1.3 }, + {reload: 0.15, recoil: 1, range: 0.1}]), + TYPE: ["bullet", + { + PERSISTS_AFTER_DEATH: true, + COLOR: color + }, + ], + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], + } +} +function createDogeiscutMissile(color) { + return { + PARENT: "bullet", + LABEL: color + " Missile", + COLOR: color, + GUNS: [...Array(11).fill().map((_, i)=>({ + POSITION: [0, 8, 0, 0, 0, ((360) / 11)*i, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, density: 30 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, COLOR: color }], + SHOOT_ON_DEATH: true, + }, + }))], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutMissileTurret_" + color], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + } + ] + } +} +Class.dogeiscutMissileTurret_red = createDogeiscutMissileTurret('red') +Class.dogeiscutMissile_red = createDogeiscutMissile('red') +Class.dogeiscutMissileTurret_orange = createDogeiscutMissileTurret('orange') +Class.dogeiscutMissile_orange = createDogeiscutMissile('orange') +Class.dogeiscutMissileTurret_yellow = createDogeiscutMissileTurret('yellow') +Class.dogeiscutMissile_yellow = createDogeiscutMissile('yellow') +Class.dogeiscutMissileTurret_green = createDogeiscutMissileTurret('green') +Class.dogeiscutMissile_green = createDogeiscutMissile('green') +Class.dogeiscutMissileTurret_cyan = createDogeiscutMissileTurret('cyan') +Class.dogeiscutMissile_cyan = createDogeiscutMissile('cyan') +Class.dogeiscutMissileTurret_blue = createDogeiscutMissileTurret('blue') +Class.dogeiscutMissile_blue = createDogeiscutMissile('blue') +Class.dogeiscutMissileTurret_purple = createDogeiscutMissileTurret('purple') +Class.dogeiscutMissile_purple = createDogeiscutMissile('purple') +Class.dogeiscutBomb = { + PARENT: "trap", + LABEL: "Bomb", + SHAPE: 0, + GUNS: [...Array(32).fill().map((_, i)=>({ + POSITION: [0, 8, 0, 0, 0, ((360) / 32)*i, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, size: 0.5}]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + }, + })),...Array(10).fill().map((_,i)=>({ + POSITION: [12, 3.5, 1, 0, 0, (360/10)*i, (i%3)/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ + g.basic, + g.twin, + g.gunner, + g.cyclone, + {reload: 3} + ]), + TYPE: "bullet", + AUTOFIRE: true, + }, + })) + ], + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + } + ] + } +Class.dogeiscutBoss = { + PARENT: "miniboss", + LABEL: "DOG", + NAME: "DogeisCut", + DANGER: 10, + FACING_TYPE: "smoothToTarget", + SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]], + COLOR: "yellow", + UPGRADE_COLOR: "yellow", + SIZE: 50, + VALUE: 5e6, + BODY: { + FOV: 0.75, + SPEED: 0.25 * base.SPEED, + HEALTH: 14 * base.HEALTH, + DAMAGE: 4 * base.DAMAGE, + }, + GUNS: [ { + POSITION: [ 6, 8, 1.5, 3, 0, 180, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, {size: 1, reload: 3, recoil: 5}]), + TYPE: ["dogeiscutBomb"], + STAT_CALCULATOR: gunCalcNames.sustained, + } + }, { + POSITION: [ 4, 4, 1.5, 3, 0, 180, 0, ], + PROPERTIES: { + COLOR: "black" + } + }, + + { + POSITION: [ 1, 2, 1, 4, -8, 68, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_red"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'red' + } + }, { + POSITION: [ 1, 2, 1, 4, -5.333, 68, 1/7, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_orange"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'orange' + } + }, { + POSITION: [ 1, 2, 1, 4, -2.666, 68, (1/7)*2, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_yellow"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'yellow' + } + }, { + POSITION: [ 1, 2, 1, 4, 0, 68, (1/7)*3, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_green"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'green' + } + }, { + POSITION: [ 1, 2, 1, 4, 2.666, 68, (1/7)*4, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_cyan"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'cyan' + } + }, { + POSITION: [ 1, 2, 1, 4, 5.333, 68, (1/7)*5, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_blue"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'blue' + } + }, { + POSITION: [ 1, 2, 1, 4, 8, 68, (1/7)*6, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_purple"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'purple' + } + }, + + + { + POSITION: [ 1, 2, 1, 4, 8, -68, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_red"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'red' + } + }, { + POSITION: [ 1, 2, 1, 4, 5.333, -68, 1/7, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_orange"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'orange' + } + }, { + POSITION: [ 1, 2, 1, 4, 2.666, -68, (1/7)*2, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_yellow"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'yellow' + } + }, { + POSITION: [ 1, 2, 1, 4, 0, -68, (1/7)*3, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_green"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'green' + } + }, { + POSITION: [ 1, 2, 1, 4, -2.666, -68, (1/7)*4, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_cyan"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'cyan' + } + }, { + POSITION: [ 1, 2, 1, 4, -5.333, -68, (1/7)*5, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_blue"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'blue' + } + }, { + POSITION: [ 1, 2, 1, 4, -8, -68, (1/7)*6, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_purple"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'purple' + } + }, + ], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], + }, + { + POSITION: [5, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutTurret", { INDEPENDENT: true, CONTROLLERS: ["nearestDifferentMaster"], COLOR: "yellow" }], + }, + { + POSITION: [1, 10.5, 0, 0, 360, 0], + TYPE: ["genericTank", {COLOR: "black"}], + }, + ] +} +Class.trplnrBossAuraBulletAura = addAura(1, 0.8) +Class.trplnrBossAuraBullet = { + PARENT: 'genericTank', + LABEL: 'Nest', + SHAPE: -4, + PERSISTS_AFTER_DEATH: true, + BODY: { + HEALTH: 100, + }, + SIZE: 25, + COLOR: '#F49EFF', + GLOW: { + STRENGTH: 25, + COLOR: 'mirror', + ALPHA: 1 + }, + DRAW_HEALTH: true, + GUNS: (() => { + let output = [] + for (let i = 0; i < 4; i++) { + output.push({ + POSITION: { ANGLE: (360/4)*i, ASPECT: -0.35, X: -5 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { size: 0.8 }, {reload: 1.6, damage: 1.5}]), + TYPE: 'autoswarm', + AUTOFIRE: true, + }, + }) + } + return output + })(), + TURRETS: [ + { + POSITION: {SIZE: 10, LAYER: 1}, + TYPE: "trplnrBossAuraBulletAura" + } + ] +} +const trplnrBossDecor = { + COLOR: '#F49EFF', + UPGRADE_COLOR: "lavender", + LABEL: 'Lavender', + NAME: 'Trioplane', + SHAPE: 3, + SIZE: 25, + VALUE: 5e7, + DANGER: 10, + GLOW: { + RADIUS: 15, + COLOR: 'mirror', + ALPHA: 1, + RECURSION: 5 + }, + PROPS: [{ + POSITION: { SIZE: 25 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, + TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] + }, { + POSITION: { SIZE: 25 ** Math.SQRT1_2, LAYER: 1 }, + TYPE: ['triangle', { COLOR: -1, MIRROR_MASTER_ANGLE: true }] + }, { + POSITION: { SIZE: 25 }, + TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] + }], +} +Class.trplnrBoss = { + PARENT: "miniboss", + ...trplnrBossDecor, + UPGRADE_TOOLTIP: "\"Heck, even The Guardians are afraid of him, \n" + + "They usually call him the The Light, Victory, Death and Ruler of the Pentagon Race a.k.a Lvndr. \n" + + "We don't know where his teleportation powers came from, \n" + + "He was secretive of it. \n" + + "Though some say there was an old script found at the Neutrality Point \n" + + "at the middle of the nest when it still existed, It had some \n" + + "sort of drawing of a tank going through walls, and this thing that said '6@D M0|)3 \n" + + "Nest Reseachers still haven't been able to decipher it though. \n" + + "One day, The Neutrality Point left and on that same day, \n" + + "A sentry's child went missing, \n" + + "Coincidence? I think not.\"", + BODY: { + HEALTH: 500, + }, + ON: [ + { + event: 'fire', + handler: ({ body, gun }) => { + if (gun.identifier != 'onHandler') return + const messages = [ + 'Attack my little swarms!', + 'Deploying, Attack swarms', + 'You really think you can defeat me? Heres a little challenge for you.', + 'This thing is really gonna annoy you HAHA!', + 'I don\'t know what to say uhhh, die i guess.' + ] + sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) + sockets.broadcast('Lavender will turn into `BULL3T HELL F0rM`, Run!') + for (let i = 0; i < 24; i++) { + i < 12 ? + setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) + : + setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) + } + setTimeout(() => { + let range = 500 + let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + body.x += whereToGoX + body.y += whereToGoY + }, 12 * 50); + setTimeout(() => body.define('trplnrBossBulletHellForm'), 24 * 50) + } + } + ], + GUNS: [], + GUNS: (() => { + let output = [] + for (let i = 0; i<2; i++) { + output.push({ + POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), + TYPE: "trplnrBossAuraBullet", + INDEPENDENT_CHILDREN: true, + } + }) + } + output.push({ + POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * 2) - 180 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), + TYPE: "trplnrBossAuraBullet", + INDEPENDENT_CHILDREN: true, + IDENTIFIER: 'onHandler', + ALPHA: 0, + } + }) + for (let i = 0; i < 3; i++) { + output.push({ + POSITION: { WIDTH: 5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'black' + } + }) + output.push({ + POSITION: { WIDTH: 5, HEIGHT: 5, X: -30, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'black' + } + }, { + POSITION: { WIDTH: 5, HEIGHT: 5, X: -25, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'white' + } + }) + } + return output + })() +} + +Class.trplnrBossBulletHellFormPentagonsAuraBullet = { + PARENT: 'bullet', + PERSISTS_AFTER_DEATH: true, + TURRETS: [{ + POSITION: {SIZE: 13, LAYER: 1}, + TYPE: "trplnrBossAuraBulletAura" + }] +} + +Class.trplnrBossBulletHellFormPentagons = { + PARENT: 'bullet', + LABEL: 'Pentagon', + SHAPE: -5, + PROPS: [{ + POSITION: { SIZE: 40 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, + TYPE: ['pentagon', {COLOR: 'black', MIRROR_MASTER_ANGLE: true}] + }], + GUNS: (() => { + let output = [] + for (let i = 0; i < 5; i++) { + output.push({ + POSITION: { WIDTH: 10, HEIGHT: 10, ANGLE: ((360/5)*i) - 180, DELAY: 11.5 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 0.4}]), + TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', + AUTOFIRE: true, + COLOR: 'white', + } + }) + } + return output + })() +} +Class.trplnrBossBulletHellForm = { + PARENT: "miniboss", + ...trplnrBossDecor, + LABEL: 'Lavender - Bullet Hell Form', + BODY: { + HEALTH: 500, + }, + ON: [ + { + event: "fire", + handler: ({ body, masterStore, gun }) => { + if (gun.identifier != 'onHandler') return + masterStore.shotsFired ??= 0 + masterStore.shotsFired++ + + for (let i = 0; i < 24; i++) { + i < 12 ? + setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) + : + setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) + } + setTimeout(() => { + let range = 500 + let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + body.x += whereToGoX + body.y += whereToGoY + }, 12 * 50) + + if (masterStore.shotsFired > 5) { + body.define('trplnrBossVulnerableForm') + const messages = [ + 'I\'m a little tired right now', + 'Ouch my leg!', + 'i sleep', + 'Bruh my keyboard isn\'t working', + 'Omg bruh I chose the wrong form' + ] + sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) + sockets.broadcast('Lavender is in its `VULN3RABLE F0RM`, Attack!') + } + } + } + ], + GUNS: [], + GUNS: (() => { + let output = [] + for (let i = 0; i<3; i++) { + output.push({ + POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -25 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 1 }]), + TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', + COLOR: 'black' + } + }, { + POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -20 }, + PROPERTIES: { + COLOR: 'white' + } + }, { + POSITION: { WIDTH: 10, HEIGHT: 5, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 3 }]), + TYPE: 'trplnrBossBulletHellFormPentagons', + COLOR: 'white' + } + }, { + POSITION: { WIDTH: 8, HEIGHT: 3, X: -1, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'pureWhite', + } + }, { + POSITION: { WIDTH: 5, HEIGHT: 10, X: 5, ASPECT: 0.2, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: -1, + } + }) + } + output.push({ + POSITION: { WIDTH: 0, HEIGHT: 0 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 2 }, g.fake]), + TYPE: 'bullet', + IDENTIFIER: 'onHandler', + ALPHA: 0 + } + }) + return output + })() +} +Class.trplnrBossVulnerableForm = { + PARENT: "miniboss", + ...trplnrBossDecor, + LABEL: 'Lavender - Vulnerable Form', + BODY: { + HEALTH: 500, + SPEED: 0.1 + }, + ON: [ + { + event: "tick", + handler: ({ body }) => { + body.store.ticks ??= 0 + body.store.ticks++ + const spawnCrashers = body.store.ticks % 3 == 0 + const spawnSentries = body.store.ticks % 60 == 0 + const sentries = ["sentrySwarm", "sentryGun", "sentryTrap"] + if (spawnCrashers) new Entity(body, body).define("crasher") + if (spawnSentries) new Entity(body, body).define(sentries[Math.floor(Math.random() * sentries.length)]) + } + }, + { + event: "fire", + handler: ({ body, gun }) => { + if (gun.identifier != 'onHandler') return + setTimeout(() => { + body.define('trplnrBoss') + sockets.broadcast('im awake') + }, 15000) + setTimeout(() => sockets.broadcast('Lavender will activate in 10 seconds and turn into S4nctuary F0rM'), 5000) + } + } + ], + GUNS: [{ + POSITION: {LENGTH: 0, WIDTH: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, {reload: 500}]), + TYPE: 'bullet', + AUTOFIRE: true, + IDENTIFIER: 'onHandler', + ALPHA: 0 + } + }] +} + +Class.frostAuraSmall = { + PARENT: "aura", + LAYER: 30, + FACING_TYPE: ["spin", {speed: -0.04}], + BORDERLESS: true, + SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraSmallOutline' + }] +} +Class.frostAuraSmallOutline = { + PARENT: "aura", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0" + + "L 0.309 0.951 L -0.809 0.588 L -0.809 -0.588 L 0.309 -0.951 L 1 0" + + "L 0 0 L 0.309 0.951 M 0 0 L -0.809 0.588 M 0 0 L -0.809 -0.588 M 0 0 L 0.309 -0.951", +} +Class.frostAuraLarge = { + PARENT: "aura", + LAYER: 30, + FACING_TYPE: ["spin", {speed: -0.04}], + BORDERLESS: true, + SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraLargeOutline' + }] +} +Class.frostAuraLargeOutline = { + PARENT: "aura", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0" + + "M 0.988 -0.156 L 0.988 0.156 L 0.891 0.454 L 0.707 0.707 L 0.454 0.891 L 0.156 0.988 L -0.156 0.988 L -0.454 0.891 L -0.707 0.707 L -0.891 0.454 L -0.988 0.156 L -0.988 -0.156 L -0.891 -0.454 L -0.707 -0.707 L -0.454 -0.891 L -0.156 -0.988 L 0.156 -0.988 L 0.454 -0.891 L 0.707 -0.707 L 0.891 -0.454 L 0.988 -0.156 L 0.949 0" + + "L 0.988 0.156 L 0.891 0.256 L 0.891 0.454 L 0.739 0.537 L 0.707 0.707 L 0.519 0.769 L 0.454 0.891 L 0.293 0.902 L 0.156 0.988 L 0.032 0.927 L -0.156 0.988 L -0.282 0.869 L -0.454 0.891 L -0.571 0.731 L -0.707 0.707 L -0.768 0.558 L -0.891 0.454 L -0.871 0.317 L -0.988 0.156 L -0.914 0 L -0.988 -0.156 L -0.871 -0.317 L -0.891 -0.454 L -0.768 -0.558 L -0.707 -0.707 L -0.571 -0.731 L -0.454 -0.891 L -0.282 -0.869 L -0.156 -0.988 L 0.032 -0.927 L 0.156 -0.988 L 0.293 -0.902 L 0.454 -0.891 L 0.519 -0.769 L 0.707 -0.707 L 0.739 -0.537 L 0.891 -0.454 L 0.891 -0.256 L 0.988 -0.156 L 0.949 0" + + "L 0.891 0.256 L 0.739 0.537 L 0.519 0.769 L 0.293 0.902 L 0.032 0.927 L -0.282 0.869 L -0.571 0.731 L -0.768 0.558 L -0.871 0.317 L -0.914 0 L -0.871 -0.317 L -0.768 -0.558 L -0.571 -0.731 L -0.282 -0.869 L 0.032 -0.927 L 0.293 -0.902 L 0.519 -0.769 L 0.739 -0.537 L 0.891 -0.256 L 0.949 0" + + "M 0.834 0 L 0.891 0.256 L 0.704 0.291 L 0.739 0.537 L 0.495 0.579 L 0.519 0.769 L 0.258 0.793 L 0.032 0.927 L -0.06 0.759 L -0.282 0.869 L -0.398 0.649 L -0.571 0.731 L -0.674 0.49 L -0.871 0.317 L -0.741 0.178 L -0.914 0 L -0.741 -0.178 L -0.871 -0.317 L -0.674 -0.49 L -0.571 -0.731 L -0.398 -0.649 L -0.282 -0.869 L -0.06 -0.759 L 0.032 -0.927 L 0.258 -0.793 L 0.519 -0.769 L 0.495 -0.579 L 0.739 -0.537 L 0.704 -0.291 L 0.891 -0.256 L 0.834 0" + + "L 0.704 0.291 L 0.495 0.579 L 0.258 0.793 L -0.06 0.759 L -0.398 0.649 L -0.674 0.49 L -0.741 0.178 L -0.741 -0.178 L -0.674 -0.49 L -0.398 -0.649 L -0.06 -0.759 L 0.258 -0.793 L 0.495 -0.579 L 0.704 -0.291 L 0.834 0" + + "M 0.592 0 L 0.704 0.291 L 0.413 0.3 L 0.495 0.579 L 0.183 0.563 L -0.06 0.759 L -0.158 0.485 L -0.398 0.649 L -0.479 0.348 L -0.741 0.178 L -0.51 0 L -0.741 -0.178 L -0.479 -0.348 L -0.398 -0.649 L -0.158 -0.485 L -0.06 -0.759 L 0.183 -0.563 L 0.495 -0.579 L 0.413 -0.3 L 0.704 -0.291 L 0.592 0" + + "L 0.413 0.3 L 0.183 0.563 L -0.158 0.485 L -0.479 0.348 L -0.51 0 L -0.479 -0.348 L -0.158 -0.485 L 0.183 -0.563 L 0.413 -0.3 L 0.592 0" + + "M 0.292 0 L 0.413 0.3 L 0.09 0.277 L -0.158 0.485 L -0.236 0.171 L -0.51 0 L -0.236 -0.171 L -0.158 -0.485 L 0.09 -0.277 L 0.413 -0.3 L 0.292 0 L 0.09 0.277" + + "L -0.236 0.171 L -0.236 -0.171 L 0.09 -0.277 L 0.292 0 M 0 0 L 0.949 0" + + "M 0 0 L 0.293 0.902 M 0 0 L -0.768 0.558 M 0 0 L -0.768 -0.558 M 0 0 L 0.293 -0.902", +} +Class.frostAuraSymbol = { + PARENT: "genericTank", + CONTROLLERS: [["spin", { speed: -0.04 }]], + INDEPENDENT: true, + BORDERLESS: true, + COLOR: 'teal', + SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraSymbolOutline' + }] +} +Class.frostAuraSymbolOutline = { + PARENT: "genericTank", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z" + + "M 0.52 0.3 L 0.52 -0.3 L 0.797 -0.46 M 0.52 -0.3 L 0 -0.6 L 0 -0.92 M 0 -0.6 L -0.52 -0.3 L -0.797 -0.46 M -0.52 -0.3 L -0.52 0.3 L -0.797 0.46 M -0.52 0.3 L 0 0.6 L 0 0.92 M 0 0.6 L 0.52 0.3 L 0.797 0.46" +} + +function addIcosphereAura(damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraSize = "Medium") { + let auraType = "frostAura" + auraSize; + return { + PARENT: "genericTank", + INDEPENDENT: true, + LABEL: "", + COLOR: 17, + GUNS: [ + { + POSITION: [0, 20, 1, 0, 0, 0, 0,], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.aura, { size: sizeFactor, damage: damageFactor }]), + TYPE: [auraType, {ALPHA: opacity}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, + }, + ], + TURRETS: [ + { + POSITION: [20, 0, 0, 0, 360, 1], + TYPE: "frostAuraSymbol" + }, + ] + }; +} +Class.frostAuraBlockTop = { + SHAPE: "M -1.3 -0.15 L -1.3 0.15 L -0.3 0.3 L -0.15 1.3 L 0.15 1.3 L 0.3 0.3 L 1.3 0.15 L 1.3 -0.15 L 0.3 -0.3 L 0.15 -1.3 L -0.15 -1.3 L -0.3 -0.3 Z", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 5 }, + MIRROR_MASTER_ANGLE: true, +} +Class.frostAuraBlockTurret = { + PARENT: "genericTank", + INDEPENDENT: true, + COLOR: 17, + CONTROLLERS: ["nearestDifferentMaster"], + LABEL: "", + BODY: { + FOV: 2, + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [18, 15, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} + }, + }, { + POSITION: [23, 11, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, {density: 0.2}]), + TYPE: "bullet", + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [15, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ], +} +Class.frostAuraBlockAura = addIcosphereAura(0.25, 1.6, 0.15, "Small"); +Class.frostAuraBlock = { + PARENT: 'unsetTrap', + TURRETS: [ + { + POSITION: [20, 0, 0, 45, 0, 1], + TYPE: 'frostAuraBlockTop' + }, { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: 'frostAuraBlockTurret' + }, { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: 'frostAuraBlockAura' + } + ] +} +Class.frostBossBigAura = addIcosphereAura(1.5, 1.45, 0.3, "Large"); + +Class.frostBossAutoTurret = { + PARENT: "autoTankGun", + INDEPENDENT: true, + COLOR: 17, + GUNS: [ + { + POSITION: [17, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} + }, + }, { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}]), + TYPE: "bullet", + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [14, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ], + TURRETS: [ + { + POSITION: [13, 0, 0, 0, 0, 1], + TYPE: ["egg", {COLOR: -1, BORDERLESS: true}], + }, + ], +} + +Class.frostBossBaseDeco = { + SHAPE: "M -1.1 0 L -0.956 0.292 L -0.669 0.205 L -0.669 -0.205 L -0.956 -0.292 Z" + + "M -0.55 0.952 L -0.225 0.974 L -0.157 0.682 L -0.512 0.477 L -0.731 0.682 Z" + + "M -0.55 -0.952 L -0.225 -0.974 L -0.157 -0.682 L -0.512 -0.477 L -0.731 -0.682 Z" + + "M 0.55 0.952 L 0.225 0.974 L 0.157 0.682 L 0.512 0.477 L 0.731 0.682 Z" + + "M 0.55 -0.952 L 0.225 -0.974 L 0.157 -0.682 L 0.512 -0.477 L 0.731 -0.682 Z" + + "M 1.1 0 L 0.956 0.292 L 0.669 0.205 L 0.669 -0.205 L 0.956 -0.292 Z", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, + MIRROR_MASTER_ANGLE: true, + GUNS: Array(6).fill().flatMap((_, i) => ([ + { + POSITION: [1.75, 3, -0.75, 7.5, 0, 60 * i, 0], + PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 2.5, SATURATION_SHIFT: 0.9 }, DRAW_ABOVE: true }, + }, { + POSITION: [1, 9, 0, 8.5, 0, 60 * i + 30, 0], + PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 10, SATURATION_SHIFT: 1.15 } }, + }, + ])) +} + +const trebuchetStats = [g.basic, g.sniper, g.predator, g.predator, g.predator, g.predator, {speed: 0.93, maxSpeed: 0.93, reload: 1.7, health: 1.7, damage: 1.4, size: 2}]; +const hielamanStats = [g.trap, g.setTrap, g.hexaTrapper, {reload: 2.4, health: 3.2, range: 1.2}]; +Class.frostBoss = { + PARENT: 'miniboss', + LABEL: 'Extrasolar', + NAME: 'Frostbyte', + FACING_TYPE: 'toTarget', + SHAPE: 6, + COLOR: "aqua", + UPGRADE_COLOR: "aqua", + SIZE: 31, + DANGER: 12, + VALUE: 888888, + UPGRADE_TOOLTIP: "\"When the golden rays of sun shine through this world's\n" + + "darkened skies and looming clouds, the legend of the warrior\n" + + "and his eternal blade will finally come to fruition.\"", + BODY: { + SPEED: base.SPEED * 0.6, + HEALTH: base.HEALTH * 11, + SHIELD: base.SHIELD * 7, + REGEN: base.REGEN * 2.5, + FOV: base.FOV * 1.4, + RESIST: base.RESIST * 1.2, + DENSITY: base.DENSITY * 7.5, + }, + GUNS: [ + ...Array(6).fill().flatMap((_, i) => ({ + // Speed + POSITION: [8, 14.5, 0.001, 9.5, 0, 60*i, 0], + PROPERTIES: {COLOR: 9}, + })), + ...Array(3).fill().flatMap((_, i) => ([ + { // Heavy Snipers + POSITION: [26.5, 9.5, 1, 0, 0, 120 * i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats(trebuchetStats), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6 }, + }, + }, { + POSITION: [24, 6.65, -1.3, 0, 0, 120 * i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, + BORDERLESS: true + }, + }, { + POSITION: [19.5, 3.8, -1.4, 0, 0, 120 * i, 0], + PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 10 } }, + }, { + POSITION: [4, 11.5, 1, 19.5, 0, 120 * i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, + }, + }, { + POSITION: [2, 12, 1, 20.5, 0, 120 * i, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, + }, + }, + { // Aura Blocks + POSITION: [15, 9, 1, 0, 0, 120 * i + 60, 0], + PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6}} + }, { + POSITION: [4, 7.5, -1.6, 9, 0, 120 * i + 60, 0], + PROPERTIES: {COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5}} + }, { + POSITION: [15, 5.4, -0.1, 0, 0, 120 * i + 60, 0], + PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.75}} + }, { + POSITION: [3, 9, 1.6, 15, 0, 120 * i + 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats(hielamanStats), + TYPE: 'frostAuraBlock', + STAT_CALCULATOR: gunCalcNames.trap, + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [2, 7, 1.6, 16, 0, 120 * i + 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...hielamanStats, g.fake]), + TYPE: 'bullet', + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ])), + ], + TURRETS: [ + ...Array(6).fill().flatMap((_, i) => ([ + { + POSITION: [2.95, 8.55, 0, 60 * i + 30, 180, 2], + TYPE: "frostBossAutoTurret", + }, + ])), + { + POSITION: [8.55, 0, 0, 0, 360, 2], + TYPE: "frostBossBigAura", + }, + ], + PROPS: [ + { + POSITION: [12, 0, 0, 180, 1], + TYPE: ["hexagon", {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 7.5}}], + }, { + POSITION: [20, 0, 0, 0, 1], + TYPE: ["frostBossBaseDeco"], + }, + ] +} + +const divide = 1000; +const arraySize = 10; +const colorArray = []; +const damageMultiplayer = 3.5; +const reloadMultiplayer = 2; +for (let i = 0; i < arraySize; i++) { + const rgb = Math.round(255 * i / (arraySize - 1)); + colorArray.push('#' + ((1 << 24) + (rgb << 16) + (rgb << 8) + rgb).toString(16).slice(1)); +} +class io_nearestDifferentMaster2 extends ioTypes.nearestDifferentMaster { + constructor(body, opts = {}) { + super(body); + this.lookAtDanger = opts.lookAtDanger ?? true; + this.firingAtMe = opts.firingAtMe ?? false; + this.timeout = opts.timeout || 90; + } + buildList(range) { + // Establish whom we judge in reference to + let mostDangerous = 0, + keepTarget = false; + // Filter through everybody... + let out = entities.filter(e => + // Only look at those within our view, and our parent's view, not dead, not invisible, not our kind, not a bullet/trap/block etc + this.validate(e, this.body, this.body.master.master, range * range, range * range * 4 / 3) + ).filter((e) => { + // Only look at those within range and arc (more expensive, so we only do it on the few) + if (this.body.firingArc == null || this.body.aiSettings.view360 || Math.abs(util.angleDifference(util.getDirection(this.body, e), this.body.firingArc[0])) < this.body.firingArc[1]) { + mostDangerous = Math.max(e.dangerValue, mostDangerous); + return true; + } + }).filter((e) => { + // Even more expensive + return !this.wouldHitWall(this.body, e); + }).filter((e) => { + // Only return the highest tier of danger + if (!this.lookAtDanger) return true; + if (this.body.aiSettings.farm || e.dangerValue === mostDangerous) { + if (this.targetLock && e.id === this.targetLock.id) keepTarget = true; + return true; + } + }); + // Reset target if it's not in there + if (!keepTarget) this.targetLock = undefined; + return out; + } + think(input) { + // Override target lock upon other commands + if (input.main || input.alt || this.body.master.autoOverride) { + this.targetLock = undefined; + return {}; + } + // Otherwise, consider how fast we can either move to ram it or shoot at a potiential target. + let tracking = this.body.topSpeed, + damageRef = (this.body.bond == null) ? this.body : this.body.bond, + range = this.body.fov; + // Use whether we have functional guns to decide + for (let i = 0; i < this.body.guns.length; i++) { + if (this.body.guns[i].canShoot && !this.body.aiSettings.SKYNET) { + let v = this.body.guns[i].getTracking(); + if (v.speed == 0 || v.range == 0) continue; + tracking = v.speed; + range = Math.min(range, (v.speed || 1.5) * (v.range < (this.body.size * 2) ? this.body.fov : v.range)); + break; + } + } + if (!Number.isFinite(tracking)) { + tracking = this.body.topSpeed + .01; + } + if (!Number.isFinite(range)) { + range = 640 * this.body.FOV; + } + // Check if my target's alive + if (this.targetLock && ( + !this.validate(this.targetLock, this.body, this.body.master.master, range * range, range * range * 4 / 3) || + this.wouldHitWall(this.body, this.targetLock) // Very expensive + )) { + this.targetLock = undefined; + this.tick = 100; + } + // Think damn hard + if (this.tick++ > 15 * c.runSpeed) { + this.tick = 0; + this.validTargets = this.buildList(range); + // Ditch our old target if it's invalid + if (this.targetLock && this.validTargets.indexOf(this.targetLock) === -1) { + this.targetLock = undefined; + } + // Lock new target if we still don't have one. + if (this.targetLock == null && this.validTargets.length) { + this.targetLock = (this.validTargets.length === 1) ? this.validTargets[0] : nearest(this.validTargets, { + x: this.body.x, + y: this.body.y + }); + this.tick = -this.timeout; + } + } + // Lock onto whoever's shooting me. + if (this.firingAtMe && damageRef.collisionArray.length && damageRef.health.display() < this.oldHealth) { + this.oldHealth = damageRef.health.display(); + if (this.validTargets.indexOf(damageRef.collisionArray[0]) === -1) { + let a = (damageRef.collisionArray[0].master.id === -1) + ? damageRef.collisionArray[0].source + : damageRef.collisionArray[0].master; + if ( + this.body.firingArc == null || + this.body.aiSettings.view360 || + Math.abs(util.angleDifference(util.getDirection(this.body, a), this.body.firingArc[0])) < this.body.firingArc[1] + ) { + this.targetLock = a; + this.tick = -(this.timeout * 5); + } + } + } + // Consider how fast it's moving and shoot at it + if (this.targetLock != null) { + let radial = this.targetLock.velocity; + let diff = { + x: this.targetLock.x - this.body.x, + y: this.targetLock.y - this.body.y, + } + /// Refresh lead time + if (this.tick % 4 === 0) { + this.lead = 0 + // Find lead time (or don't) + if (!this.body.aiSettings.chase) { + let toi = timeOfImpact(diff, radial, tracking) + this.lead = toi + } + } + if (!Number.isFinite(this.lead)) { + this.lead = 0; + } + if (!this.accountForMovement) this.lead = 0; + // And return our aim + return { + target: { + x: diff.x + this.lead * radial.x, + y: diff.y + this.lead * radial.y, + }, + fire: true, + main: true + }; + } + return {}; + } +} +ioTypes.nearestDifferentMaster2 = io_nearestDifferentMaster2; +Class.toothlessBase = { + PARENT: "genericTank", + LABEL: "NightFury", + UPGRADE_TOOLTIP: "A power league...", + GLOW: { + RADIUS: 2, + COLOR: 42, + ALPHA: 0.6, + RECURSION: 6, + }, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.5 * base.FOV, + HEALTH: 6 * base.HEALTH, + DAMAGE: 2 * base.DAMAGE, + }, + LEVEL_CAP: 45, + EXTRA_SKILL: 78, // 120 - 42 + SHAPE: 3, + VALUE: 30e+3, + SIZE: 24, + COLOR: "purple", + SKILL_CAP: Array(10).fill(smshskl + 3), + LEVEL_SKILL_POINT_FUNCTION: level => { + if (level < 2) return 0; + if (level <= 40) return 1; + if (level <= 45 && level & 1 == 1) return 1; + return 0; + }, +} +Class.toothlessBossTurret = { + PARENT: "genericTank", + LABEL: "", + BODY: { + FOV: 2, + }, + CONTROLLERS: [ + "onlyAcceptInArc", + [ "nearestDifferentMaster2", { lookAtDanger: false, firingAtMe: true, timeout: 10 } ], + ], + COLOR: "grey", + GUNS: [ + { + POSITION: [32, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, { + pen: 0.8, + health: 0.6, + damage: 0.6, + recoil: 0, + }]), + TYPE: "bullet", + }, + }, + ], + ON: [{ + event: "fire", + handler: ({ body }) => { + const master = body.master; + body._damage ??= []; + body._reload ??= []; + + if (!body._loaded) { + let _temp = 0; + master._maxPower ??= 0; + + body.guns.forEach((gun, i) => { + body._damage[i] = gun.settings.damage; + body._reload[i] = gun.settings.reload; + + _temp += (body._damage[i] * 3) / body._damage[i]; + _temp += body._reload[i] / (body._reload[i] / 3); + _temp /= 2; + }); + + _temp /= body.guns.length; + + master._maxPower += (_temp - 1) * divide * 2; + if (master._maxPower > _temp) master._maxPower /= 2; + + body._loaded = true; + } + + if (master._mode) { + master._power -= 1; + if (master._power < 1) { + master._mode = 0; + master.color.base = 14; + } + } + + if (!master._oldPower) return; + const power = master._oldPower / (divide * 2) + 1; + + body.guns.forEach((gun, i) => { + let _1 = body._damage[i] * (master._mode ? power : 1); + let _2 = body._reload[i] / (master._mode ? power : 1); + let max_damage = body._damage[i] * damageMultiplayer; + let min_reload = body._reload[i] / reloadMultiplayer; + + gun.settings.damage = _1 > max_damage ? max_damage : _1; + gun.settings.reload = _2 < min_reload ? min_reload : _2; + }); + }, + }], +}; +Class.toothlessBossDeco = { + PARENT: "genericTank", + LABEL: "", + SHAPE: 3, + SIZE: 10, + ON: [{ + event: "tick", + handler: ({ body }) => { + const master = body.master; + if (master._maxPower) + body.color.base = colorArray[ + Math.floor(master._power / (master._maxPower / arraySize)) > arraySize - 1 + ? arraySize - 1 + : Math.floor(master._power / (master._maxPower / arraySize) + ) + ]; + }, + }], +}; +Class.toothlessBoss = { + PARENT: "toothlessBase", + UPGRADE_COLOR: "magenta", + TURRETS: [{ + POSITION: { SIZE: 15, LAYER: 1 }, + TYPE: ["toothlessBossDeco", { MIRROR_MASTER_ANGLE: true }], + }, { + POSITION: { SIZE: 23 }, + TYPE: ["triangle", { COLOR: "black", MIRROR_MASTER_ANGLE: true }], + }], + GUNS: [{ + POSITION: { LENGTH: 0, WIDTH: 0 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ g.basic, { + range: 0.1, + speed: 0.1, + maxSpeed: 0.1, + recoil: 0, + }]), + TYPE: "bullet", + ALT_FIRE: true, + }, + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + if (!body._power || body._mode) return; + const power = Math.floor(body._power); + + if (power >= 1) { + body.sendMessage(`Your power level ${power}`); + body._oldPower = body._power; + body._mode = 1; + body.color.base = 5; + } + }, + }, { + event: "kill", + handler: ({ body, entity }) => { + body._power ??= 0; + body._mode ??= 0; + if (!body._mode) body._power += (entity.skill.score / divide) ** 0.8; + }, + }], +} +for (let b = 0; b < 3; b++) + Class.toothlessBoss.TURRETS.push({ + POSITION: [8, 6, -5.6, 120 * b + 180, 180, 0], + TYPE: "toothlessBossTurret", + }, { + POSITION: [8, 6, 5.6, 120 * b + 180, 180, 0], + TYPE: "toothlessBossTurret", + }); diff --git a/server/modules/definitions/groups/dev.js b/server/modules/definitions/groups/dev.js index 0eac57216..acae1892f 100644 --- a/server/modules/definitions/groups/dev.js +++ b/server/modules/definitions/groups/dev.js @@ -1,6 +1,8 @@ -const { combineStats, menu, addAura, makeDeco, makeHybrid, makeAuto, LayeredBoss, newWeapon, weaponArray } = require('../facilitators.js'); +const { combineStats, menu, addAura, makeDeco, LayeredBoss, newWeapon, weaponArray, makeRadialAuto } = require('../facilitators.js'); const { base, gunCalcNames, basePolygonDamage, basePolygonHealth, dfltskl, statnames } = require('../constants.js'); const g = require('../gunvals.js'); +require('./tanks.js'); +require('./food.js'); // Menus Class.developer = { @@ -132,7 +134,7 @@ function compileMatrix(matrix, matrix2Entrance) { GUNS: [{ POSITION: [14, 12, 1, 4, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.fake]), + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }, g.fake]), TYPE: "bullet" } }, { @@ -191,97 +193,88 @@ compileMatrix(gemRelicMatrix); // Tensor = N-Dimensional Array, BASICALLY let labyTensor = []; -for (let tier = 0; tier < 6; tier++) { +for (let poly = 0; poly < 5; poly++) { let row = []; - for (let poly of [ "Egg", "Square", "Triangle", "Pentagon", "Hexagon" ]) { + for (let tier = 0; tier < 6; tier++) { let column = []; - for (let shiny of [ "", "Shiny", "Legendary", "Shadow", "Rainbow", "Trans" ]) { - let str = `laby${tier}${shiny}${poly}`, - LABEL = str[0].toUpperCase() + str.slice(1).replace(/\d/, d => ["", "Beta", "Alpha", "Omega", "Gamma", "Delta"][d]).replace(/[A-Z]/g, m => ' ' + m) + " Generator", - code = str + 'Generator'; - column.push(Class[code] = { - PARENT: "spectator", - LABEL, - SKILL_CAP: [31, 0, 0, 0, 0, 0, 0, 0, 0, 31], - TURRETS: [{ - POSITION: [5 + tier * 2, 0, 0, 0, 0, 1], - TYPE: str, - }], - GUNS: [{ - POSITION: [14, 12, 1, 4, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.fake]), - TYPE: "bullet" - } - }, { - POSITION: [12, 12, 1.4, 4, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), - INDEPENDENT_CHILDREN: true, - TYPE: str - }, - }], - }); + for (let shiny = 0; shiny < 6; shiny++) { + let tube = []; + for (let rank = 0; rank < 2; rank++) { + let str = `laby_${poly}_${tier}_${shiny}_${rank}`, + LABEL = ensureIsClass(str).LABEL + " Generator"; + Class['generator_' + str] = { + PARENT: "spectator", + LABEL, + SKILL_CAP: [31, 0, 0, 0, 0, 0, 0, 0, 0, 31], + TURRETS: [{ + POSITION: [5 + tier * 2, 0, 0, 0, 0, 1], + TYPE: str, + }], + GUNS: [{ + POSITION: [14, 12, 1, 4, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }, g.fake]), + TYPE: "bullet" + } + }, { + POSITION: [12, 12, 1.4, 4, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + INDEPENDENT_CHILDREN: true, + TYPE: str + }, + }], + }; + tube.push('generator_' + str); + } + column.push(tube); } - let str = `laby${tier}${poly}Crasher`, - LABEL = str[0].toUpperCase() + str.slice(1).replace(/\d/, d => ["", "Beta", "Alpha", "Omega", "Gamma", "Delta"][d]).replace(/[A-Z]/g, m => ' ' + m) + " Generator", - code = str + 'Generator'; - column.push(Class[code] = { - PARENT: "spectator", - LABEL, - SKILL_CAP: [31, 0, 0, 0, 0, 0, 0, 0, 0, 31], - TURRETS: [{ - POSITION: [5 + tier * 2, 0, 0, 0, 0, 1], - TYPE: str, - }], - GUNS: [{ - POSITION: [14, 12, 1, 4, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.fake]), - TYPE: "bullet" - } - }, { - POSITION: [12, 12, 1.4, 4, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), - INDEPENDENT_CHILDREN: true, - TYPE: str - }, - }], - }); row.push(column); } labyTensor.push(row); } connectMatrix(generatorMatrix, 'PowerGemGenerator'); -connectMatrix(gemRelicMatrix, 'laby0EggGenerator'); +connectMatrix(gemRelicMatrix, 'generator_laby_0_0_0_0'); + +let tensorWidth = labyTensor.length, + tensorHeight = labyTensor[0].length, + tensorLength = labyTensor[0][0].length, + tensorDepth = labyTensor[0][0][0].length; -let tensorLength = labyTensor[0][0].length, - tensorWidth = labyTensor[0].length, - tensorHeight = labyTensor.length; -for (let x = 0; x < tensorWidth; x++) for (let y = 0; y < tensorHeight; y++) for (let z = 0; z < tensorLength; z++) { - let top = (y + tensorHeight - 1) % tensorHeight, - bottom = (y + tensorHeight + 1) % tensorHeight, - left = (x + tensorWidth - 1) % tensorWidth, - right = (x + tensorWidth + 1) % tensorWidth, - front = (z + tensorLength - 1) % tensorLength, - back = (z + tensorLength + 1) % tensorLength, +for (let x = 0; x < tensorWidth; x++) { + for (let y = 0; y < tensorHeight; y++) { + for (let z = 0; z < tensorLength; z++) { + for (let w = 0; w < tensorDepth; w++) { - center = labyTensor[y ][x ][z ]; - top = labyTensor[top ][x ][z ]; - bottom = labyTensor[bottom][x ][z ]; - left = labyTensor[y ][left ][z ]; - right = labyTensor[y ][right][z ]; - front = labyTensor[y ][x ][front]; - back = labyTensor[y ][x ][back ]; + let left = (x + tensorWidth - 1) % tensorWidth, + right = (x + tensorWidth + 1) % tensorWidth, + top = (y + tensorHeight - 1) % tensorHeight, + bottom = (y + tensorHeight + 1) % tensorHeight, + front = (z + tensorLength - 1) % tensorLength, + back = (z + tensorLength + 1) % tensorLength, + past = (w + tensorDepth - 1) % tensorDepth, + future = (w + tensorDepth + 1) % tensorDepth, + + center = labyTensor[x ][y ][z ][w ]; + top = labyTensor[x ][top ][z ][w ]; + bottom = labyTensor[x ][bottom][z ][w ]; + left = labyTensor[left ][y ][z ][w ]; + right = labyTensor[right][y ][z ][w ]; + front = labyTensor[x ][y ][front][w ]; + back = labyTensor[x ][y ][back ][w ]; + past = labyTensor[x ][y ][z ][past ]; + future = labyTensor[x ][y ][z ][future]; - labyTensor[y][x][z].UPGRADES_TIER_0 = [ - "developer" , top , "spectator", - left , center , right , - "basic" , bottom , "eggGenerator", - front , "PowerGemGenerator" , back - ]; + Class[labyTensor[x][y][z][w]].UPGRADES_TIER_0 = [ + "developer" , left , right , + "teams" , top , bottom , + "eggGenerator" , front , back , + "PowerGemGenerator" , past , future + ]; + } + } + } } // Testing tanks @@ -291,12 +284,6 @@ Class.diamondShape = { SHAPE: 4.5 }; -Class.rotatedTrap = { - PARENT: "basic", - LABEL: "Rotated Inverted Body", - SHAPE: -3.5 -}; - Class.mummyHat = { SHAPE: 4.5, COLOR: -1 @@ -344,39 +331,6 @@ Class.mummifier = { TYPE: ["mummyHat"] }] }; - -Class.colorMan = { - PARENT: "genericTank", - LABEL: "Testing Animated Colors", - SHAPE: 4, - COLOR: "rainbow", - TURRETS: [{ - POSITION: [20, -20, -20, 0, 0, 1], - TYPE: { SHAPE: 4, COLOR: "animatedBlueRed" } - },{ - POSITION: [20, 0 , -20, 0, 0, 1], - TYPE: { SHAPE: 4, COLOR: "animatedBlueGrey" } - },{ - POSITION: [20, 20, -20, 0, 0, 1], - TYPE: { SHAPE: 4, COLOR: "animatedGreyBlue" } - },{ - POSITION: [20, -20, 0 , 0, 0, 1], - TYPE: { SHAPE: 4, COLOR: "animatedRedGrey" } - },{ - POSITION: [20, 20, 0 , 0, 0, 1], - TYPE: { SHAPE: 4, COLOR: "animatedGreyRed" } - },{ - POSITION: [20, 20, 20, 0, 0, 1], - TYPE: { SHAPE: 4, COLOR: "animatedLesbian" } - },{ - POSITION: [20, 0 , 20, 0, 0, 1], - TYPE: { SHAPE: 4, COLOR: "animatedTrans" } - },{ - POSITION: [20, 20, 20, 0, 0, 1], - TYPE: { SHAPE: 4, COLOR: "animatedBi" } - }] -}; - Class.miscTestHelper2 = { PARENT: "genericTank", LABEL: "Turret Reload 3", @@ -553,6 +507,35 @@ Class.alphaGunTest = { }] } +Class.radialAutoTest = makeRadialAuto("gunner", { + count: 5, + isTurret: false, + extraStats: [{spray: 4, speed: 1.4, maxSpeed: 1.4, recoil: 0.2}], + turretIdentifier: "radialAutoTestTurret", + size: 8, + x: 10, + arc: 220, + angle: 36, + label: "Radial Auto Test", + rotation: 0.04, + danger: 10, +}) + +Class.imageShapeTest = { + PARENT: 'genericTank', + LABEL: "Image Shape Test", + SHAPE: 'round.png', + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + } + } + ] +} + // unfinished Class.strokeWidthTest = { PARENT: "basic", @@ -630,7 +613,7 @@ Class.onTest = { }] } -Class.auraBasicGen = addAura(3, 1.3); +Class.auraBasicGen = addAura(); Class.auraBasic = { PARENT: "genericTank", LABEL: "Aura Basic", @@ -758,6 +741,7 @@ Class.vanquisher = { DANGER: 8, LABEL: "Vanquisher", STAT_NAMES: statnames.generic, + CONTROLLERS: ['stackGuns'], BODY: { SPEED: 0.8 * base.SPEED, }, @@ -861,49 +845,6 @@ Class.armyOfOne = { } ], }; -Class.godbasic = { - PARENT: "genericTank", - LABEL: "God Basic", - SKILL_CAP: [31, 31, 31, 31, 31, 31, 31, 31, 31, 31], - SKILL: [ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 ], - BODY: { - ACCELERATION: base.ACCEL * 1, - SPEED: base.SPEED * 1, - HEALTH: base.HEALTH * 1, - DAMAGE: base.DAMAGE * 1, - PENETRATION: base.PENETRATION * 1, - SHIELD: base.SHIELD * 1, - REGEN: base.REGEN * 1, - FOV: base.FOV * 1, - DENSITY: base.DENSITY * 1, - PUSHABILITY: 1, - HETERO: 3, - }, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet", - COLOR: "grey", - LABEL: "", - STAT_CALCULATOR: 0, - WAIT_TO_CYCLE: false, - AUTOFIRE: false, - SYNCS_SKILLS: false, - MAX_CHILDREN: 0, - ALT_FIRE: false, - NEGATIVE_RECOIL: false, - }, - }, - ], -}; -Class.maximumOverdrive = { - PARENT: "overdrive", - LABEL: "Maximum Overdrive", - SKILL_CAP: Array(10).fill(255), - SKILL: Array(10).fill(255), -}; Class.weirdAutoBasic = { PARENT: "genericTank", LABEL: "Weirdly defined Auto-Basic", @@ -956,6 +897,7 @@ Class.bulletSpawnTest = { } ] } + Class.propTestProp = { PARENT: 'genericTank', SHAPE: 6, @@ -970,7 +912,6 @@ Class.propTestProp = { } ] } - Class.propTest = { PARENT: 'genericTank', LABEL: 'Deco Prop Test', @@ -1054,15 +995,8 @@ Class['Team' + TEAM_ENEMIES] = { }; Class.teams.UPGRADES_TIER_0.push('Team' + TEAM_ROOM, 'Team' + TEAM_ENEMIES); -Class.testing = menu("Beta Tanks") -Class.features = menu("Features") -Class.overpowered = menu("Dev Funny", "rainbow") -Class.overpowered.UPGRADE_COLOR = "rainbow" -Class.goofytanks = menu("Goofy Shit", "rainbow") -Class.goofytanks.UPGRADE_COLOR = "rainbow" -Class.overpowered.UPGRADE_TOOLTIP = "The Funny v2" -Class.goofytanks.UPGRADE_TOOLTIP = "The Funny v3" - +Class.testing = menu("Testing") + Class.addons = menu("Addon Entities") Class.addons.UPGRADES_TIER_0 = [] @@ -1134,7 +1068,6 @@ Class.sidewinderOld = { }, ], } - Class.whirlwindDeco = makeDeco(6) Class.whirlwindDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]] Class.whirlwind = { @@ -1171,7 +1104,6 @@ Class.whirlwind = { return output })() } - let testLayeredBoss = new LayeredBoss("testLayeredBoss", "Test Layered Boss", "terrestrial", 7, 3, "terrestrialTrapTurret", 5, 7, {SPEED: 10}); testLayeredBoss.addLayer({gun: { POSITION: [3.6, 7, -1.4, 8, 0, null, 0], @@ -1197,14 +1129,6 @@ Class.flailBallSpike = { Class.flailBall = { PARENT: "genericTank", COLOR: "grey", - TYPE: "flail", - BODY: { - DENSITY: 2 * base.DENSITY, - HEALTH: 10000, - SHIELD: 10000, - DAMAGE: 4.5, - REGEN: 10000 - }, HITS_OWN_TYPE: 'hard', INDEPENDENT: true, TURRETS: [{ @@ -1221,8 +1145,7 @@ Class.flailBolt1 = { }], TURRETS: [{ POSITION: [48, 56, 0, 0, 360, 1], - TYPE: "flailBall", - VULNERABLE: true + TYPE: "flailBall" }], }; Class.flailBolt2 = { @@ -1302,1184 +1225,25 @@ Class.tripleFlail = { }] } -Class.Trapper_guy = { - PARENT: "trapper", - LABEL: "Trapper_guy", - UPGRADE_COLOR: "blue", - SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png?v=1705291478159", - GUNS: [ - { - POSITION: [15, 7, 1, 0, 0, 0, 0] - }, - { - POSITION: [3, 7, 1.7, 15, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap - } - }, { - POSITION: [3, 7, 1.7, 15, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.nomove, g.halfrange, g.shockwave]), - TYPE: "shockwave", - STAT_CALCULATOR: gunCalcNames.trap, - ALT_FIRE: true - } - } - ] -}; -Class.shockwave = { - PARENT: "bullet", - LABEL: "funy", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - MOTION_TYPE: "trappershockwave" -}; -Class.watergun = { - LABEL: 'Auto Turret', - SYNCS_SKILLS: true, - SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png?v=1705294702951", - BODY: { - FOV: 1, - }, - COLOR: "blue", - CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], - GUNS: [{ - POSITION: [10, 8, 1, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.op, g.shockwave, g.shockwave]), - TYPE: "bullet", - HAS_NO_RECOIL: true - } - } - ] -} -Class.watergundormant = { - LABEL: 'Auto Turret', - SYNCS_SKILLS: true, - SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png?v=1705294702951", - BODY: { - FOV: 1 - }, - COLOR: 16, - GUNS: [{ - POSITION: [13.5, 10, 1, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.fake]), - TYPE: "bullet" - } - } - ] -} -Class.waterpet = { - PARENT: "boomerang", - LABEL: "Base", - SHAPE: 0, - INDEPENDENT: true, - TURRETS: [{ - POSITION: [25, 0, 0, 180, 360, 1], - TYPE: "watergun", - }], -ON: [{ - event: "death", - handler: ({ body }) => { - if (!body.master.isDead) return - body.master.define(Class.watertank) - } - } - ] -}; -Class.watertank = { - PARENT: "triAngle", - LABEL: "Waduh", - DANGER: 6, - SYNC_TURRET_SKILLS: true, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), - TYPE: "bullet", - LABEL: "Front", - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, { - POSITION: [1, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.bitlessspeed, g.shockwave, g.xtrahealth]), - TYPE: "waterpet", - ALT_FIRE: true, - } - }], - TURRETS: [{ - POSITION: [17, 9.85, 0, 180, 360, 1], - TYPE: "watergundormant", - }], - ON: [{ - event: "altFire", - handler: ({ body }) => { - body.define(Class.watertankFire) - } - } - ] -}; -Class.watertankFire = { - PARENT: "genericTank", - LABEL: "Waduh", - DANGER: 6, - GUNS: [{ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), - TYPE: "bullet", - LABEL: "Front", - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 150, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - { - POSITION: [16, 8, 1, 0, 0, 210, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), - TYPE: "bullet", - LABEL: gunCalcNames.thruster, - }, - }, - ] -}; -Class.piszerbeam = { - PARENT: "genericTank", - LABEL: "Pissliner", - COLOR: "yellow", - TEAM: TEAM_ROOM, - DANGER: 7, - BODY: { - ACCELERATION: base.ACCEL * 0.6, - SPEED: base.SPEED * 0.85, - FOV: base.FOV * 3, - }, - GUNS: [ - { - POSITION: [25, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - { - POSITION: [23, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - { - POSITION: [21, 8, 1, 0, 0, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - { - POSITION: [19, 8, 1, 0, 0, 0, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, - { - POSITION: [17, 8, 1, 0, 0, 0, 0.8], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), - TYPE: "bullet", - }, - }, { - POSITION: [25, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), - TYPE: "oplaser", - ALT_FIRE: true - }, - }, - { - POSITION: [23, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), - TYPE: "oplaser", - ALT_FIRE: true - - }, - }, - { - POSITION: [21, 8, 1, 0, 0, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), - TYPE: "oplaser", - ALT_FIRE: true - - }, - }, - { - POSITION: [19, 8, 1, 0, 0, 0, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), - TYPE: "oplaser", - ALT_FIRE: true - - }, - }, - { - POSITION: [17, 8, 1, 0, 0, 0, 0.8], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), - TYPE: "oplaser", - ALT_FIRE: true +Class.developer.UPGRADES_TIER_0 = ["tanks", "bosses", "spectator", "levels", "teams", "eggGenerator", "testing", "addons"] + Class.tanks.UPGRADES_TIER_0 = ["basic", "unavailable", "arenaCloser", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun"] + Class.unavailable.UPGRADES_TIER_0 = ["flail", "healer", "volute", "whirlwind"] + Class.flail.UPGRADES_TIER_2 = ["doubleFlail"] + Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] + Class.volute.UPGRADES_TIER_3 = ["sidewinderOld"] + Class.dominators.UPGRADES_TIER_0 = ["destroyerDominator", "gunnerDominator", "trapperDominator"] + Class.sanctuaries.UPGRADES_TIER_0 = ["sanctuaryTier1", "sanctuaryTier2", "sanctuaryTier3", "sanctuaryTier4", "sanctuaryTier5", "sanctuaryTier6"] - }, - }, - ], -}; -Class.oplaser = { - PARENT: "bullet", - SHAPE: -1, - MOTION_TYPE: "fuckingnuclearbomb", - BODY: { - PENETRATION: 10, - SPEED: 30, - RANGE: 155, - DENSITY: 1.25, - HEALTH: 999, - DAMAGE: 999, - PUSHABILITY: 0.3, - }, - BUFF_VS_FOOD: true, -} -Class.deltabaseBullet = { - PARENT: "boomerang", - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - CONTROLLERS: [["spin", { independent: true, speed: 0.1 }]], - INDEPENDENT: true, - COLOR: "rainbow", - BODY: { - COLOR: "rainbow" - }, - TURRETS: [{ - POSITION: [4.65, 9.85, 0, 90, 220, 1], - TYPE: ["deltagun", { COLOR: "rainbow" }] - }, { - POSITION: [4.65, 9.85, 0, 270, 220, 1], - TYPE: ["deltagun", { COLOR: "rainbow" }] - }], -ON: [{ - event: "death", - handler: ({ body }) => { - if (!body.master.isDead) return - body.master.define(Class.baseThrowerDelta) - } - } - ] -}; -Class.deltagun = { - LABEL: 'Auto Turret', - SYNCS_SKILLS: true, - BODY: { - FOV: 1 - }, - COLOR: 16, - CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], - GUNS: [{ - POSITION: [13.5, 10, 1, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.halfreload, g.halfspeed, g.op, g.op, g.op]), - TYPE: "grenade", - HAS_NO_RECOIL: true - } - } - ] -} -Class.turretBaseDelta = { - LABEL: "Basethingygygyyasgsdgajskhg", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: "rainbow",//iT WonT FUckING SpIN - SYNC_TURRET_SKILLS: true, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [4.65, 9.85, 0, 90, 220, 1], - TYPE: ["deltagun", { COLOR: "rainbow" }] - }, { - POSITION: [4.65, 9.85, 0, 270, 220, 1], - TYPE: ["deltagun", { COLOR: "rainbow" }] - }] -}; -Class.deltaDeco = { - SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png", -}; -Class.baseThrowerDelta = { - PARENT: "genericTank", - LABEL: "Delta", - DANGER: 6, - SYNC_TURRET_SKILLS: true, - GUNS: [ - { - POSITION: [26, 7, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [23, 10, 1, 0, 0, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), - TYPE: "bullet", - }, - }, { - POSITION: [1, 38, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.bitlessspeed, g.op, g.xxtrahealth]), - TYPE: ["deltabaseBullet", { COLOR: "rainbow" }], - ALT_FIRE: true, - ALPHA: 0, - HAS_NO_RECOIL: true, - } - }], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "turretBaseDelta" - }, { - POSITION: [34, 0, 0, 0, 360, 3], - TYPE: "deltaDeco" - }], - ON: [{ - event: "altFire", - handler: ({ body }) => { - body.define(Class.baseThrowerFireDelta) - } - } - ] -}; -Class.baseThrowerFireDelta = { - PARENT: "genericTank", - LABEL: "Delta Congregation", - DANGER: 6, - GUNS: [ - { - POSITION: [26, 7, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.halfrecoil, g.machineGun, g.op, g.op, { recoil: 1.15 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [23, 10, 1, 0, 0, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.halfrecoil, g.machineGun, g.op, g.op, { recoil: 1.15 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.halfrecoil, g.op, g.op]), - TYPE: "bullet", - }, - }, { - POSITION: [24, 1, 1, 0, 0, 0, 2 / 3], - PROPERTIES: { - COLOR: 'red', - SHOOT_SETTINGS: combineStats([g.basic, g.op, g.op, g.halfrecoil, g.op]), - TYPE: "laser", - HAS_NO_RECOIL: true, - }, - }], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 3], - TYPE: "deltaDeco" - } - ] -}; -Class.pounerbullet = { - PARENT: "bullet", - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png?v=1705772359444' -}; -Class.pouner = { - PARENT: "genericTank", - LABEL: "PouNer", - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled979_20240120123618.png?v=1705772311845', - GUNS: [ - { - POSITION: [20.5, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.op]), - TYPE: "pounerbullet" - } - } - ] -} - -Class.grappletest = { - PARENT: "genericTank", - LABEL: "GrappleTest", - DANGER: 4, - ON: [ - { - event: "define", - handler: ({ body }) => { - if (body.hasDefined) { - body.children = [] - body.hasDefined = false - } else { - body.hasDefined = true - } - } - }, - { - event: "tick", - handler: ({ body }) => { - if (body.children != null) { - for (let instance of body.children) { - let deltaX = instance.x - body.x, - deltaY = instance.y - body.y, - distance = util.getDistance(instance, body) - angle = Math.atan2(deltaY, deltaX), - combinedRadii = instance.realSize + body.realSize; - body.velocity.x += 5 * Math.cos(angle) - body.velocity.y += 5 * Math.sin(angle) - if (combinedRadii * 1.3 > distance) { - body.children = [] - break - } - - } - } - if (body.control.fire) { - for (instance of entities) { - if (instance != body && instance.type == "wall" && util.getDistance(instance, { - x: body.control.target.x + body.x, - y: body.control.target.y + body.y - }) < instance.size * 1.3) { - if (body.children == 0) { - body.children.push(instance) - } - } - } - } - } - } - ] -} -Class.hook = { - PARENT: "bullet", - LABEL: "boolet", - ON: [ - { - event: "define", - handler: ({ body }) => { - if (body.master.hasDefined) { - body.master.children = [] - body.master.hasDefined = false - } else { - body.master.hasDefined = true - } - } - }, - { - event: "tick", - handler: ({ body }) => { - if (body.master.children != null) { - for (let instance of body.master.children) { - let deltaX = instance.x - body.master.x, - deltaY = instance.y - body.master.y, - distance = util.getDistance(instance, body) - angle = Math.atan2(deltaY, deltaX), - combinedRadii = instance.realSize + body.realSize; - body.master.velocity.x += 5 * Math.cos(angle) - body.master.velocity.y += 5 * Math.sin(angle) - if (combinedRadii * 1.3 > distance) { - body.master.children = [] - break - } - - } - } - if (body.master.control.fire) { - for (instance of entities) { - if (instance != body.master && instance.type == "wall" && util.getDistance(instance, { - x: body.master.control.target.x + body.master.x, - y: body.master.control.target.y + body.master.y - }) < instance.size * 1.3) { - if (body.master.children == 0) { - body.master.children.push(instance) - } - } - } - } - } - } - ] -}, - -Class.devtesttemplate = { - PARENT: "genericTank", - LABEL: "Single", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet" - } - }, - { - POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] - } - ] -}; -Class.speedoflight = { - PARENT: "genericTank", - LABEL: "SpeedOfLight", - DANGER: 7, - GUNS: [ - { - POSITION: [24, 4, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.acceltospeedoflight, { range: 999 }]), - TYPE: ["bullet", { MOTION_TYPE: "acceleratetothespeedoflight" }] - } - } - ] -}; -Class.maxStatTank = { - PARENT: ['genericTank'], - DANGER: 11, - BODY: { - ACCELERATION: base.ACCEL*2, - SPEED: base.SPEED*2, - HEALTH: base.HEALTH*2, - DAMAGE: base.DAMAGE*2, - PENETRATION: base.PENETRATION*2, - SHIELD: base.SHIELD*2, - REGEN: base.REGEN*2, - FOV: base.FOV*2, - DENSITY: base.DENSITY*2, - PUSHABILITY: 2, - HETERO: 6, - }, - SKILL_CAP: Array(10).fill(255), - SKILL: Array(10).fill(255), -} -Class.qlamgSpinnerTurret = { - PARENT: "genericTank", - LABEL: "Spinner Turret", - GUNS: [ - { - POSITION: [15, 3.5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.7], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.8], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, { - POSITION: [15, 3.5, 1, 0, 0, 0, 0.9], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), - TYPE: "bullet" - } - }, - ] -} -Class.quiteliterallyAMachineGun = { - PARENT: "genericTank", - LABEL: "Quite Literally a Motherfucking Machine Gun", - UPGRADE_COLOR: "red", - DANGER: 7, - BODY: { - FOV: base.FOV * 1.2 - }, - TURRETS: [ - { - POSITION: [10, 14, 0, 0, 0, 1], - TYPE: "qlamgSpinnerTurret" - }, { - POSITION: [5, 14, 0, 0, 0, 3], - TYPE: "lamgSpinnerTurret" - }, { - POSITION: [10, 14, 0, 0, 0, 2], - TYPE: "lamgSpinnerTurret" - } - ], - GUNS: [ - { - POSITION: [22, 8, 1, 0, 0, 0, 0] - }, { - POSITION: [2, 3.5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun, g.op]), - TYPE: "bullet" - } - } - ] -} -Class.goofysatellite = { - LABEL: "Satellite", - TYPE: "bullet", - ACCEPTS_SCORE: false, - CONTROLLERS: ["orbit"], - DANGER: 2, - SHAPE: 0, - LAYER: 13, - BODY: { - PENETRATION: 1.2, - PUSHABILITY: 0.6, - ACCELERATION: 0.75, - HEALTH: 0.3, - DAMAGE: 3.375, - SPEED: 10, - RANGE: 10, - DENSITY: 0.03, - RESIST: 1.5, - FOV: 0.5, - }, - COLOR: 'nero', - DRAW_HEALTH: true, - CLEAR_ON_MASTER_UPGRADE: true, - BUFF_VS_FOOD: true, - DIE_AT_RANGE: true, -} - -Class.goofywhirlwind = { - PARENT: "genericTank", - LABEL: "Goofy Whirlwind", - ANGLE: 60, - CONTROLLERS: ["whirlwind"], - HAS_NO_RECOIL: true, - STAT_NAMES: statnames.whirlwind, - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: "whirlwindDeco" - } - ], - AI: { - SPEED: 2, - }, - GUNS: (() => { - let output = [] - for (let i = 0; i < 5; i++) { - output.push({ - POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.satellite]), - TYPE: ["goofysatellite", {ANGLE: i * 72}], - MAX_CHILDREN: 4, - AUTOFIRE: true, - SYNCS_SKILLS: false, - } - }) - } - return output - })() -} - -Class.pisseroo = { - PARENT: ['basic'], - LABEL: 'Winsor', - UPGRADES_TIER_0: [], - RESET_UPGRADE_MENU: true, - ON: [ - { - event: "fire", - handler: ({ body, globalMasterStore: store, gun }) => { - if (gun.identifier != 'pisserooGun') return - store.pisseroo_i ??= 0; - store.pisseroo_i++; - store.pisseroo_i %= 4; - body.define(Class.winsor0.UPGRADES_TIER_0[store.pisseroo_i]); - setTimeout(() => body.define("pisseroo"), 3000); - } - } - ], - GUNS: [{ - POSITION: {}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: 'bullet', - IDENTIFIER: 'pisserooGun' - } - }] -} -Class.adsfoipuasdfiopu = { - PARENT: "genericTank", - LABEL: "Random tank i made in music class because i can", - UPGRADE_TOOLTIP: "send this * to the penis explosion chamber and have his penis exploded immediately", - GUNS: [{ - POSITION: [21, 10, 0, 0, 1, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.op]), - TYPE: "bullet" - } - } - ] -} -Class.adsfoipuasdfiopu.UPGRADE_COLOR = "animatednero", -Class.adsfoipuasdfiopu2 = { - PARENT: "genericTank", - LABEL: "Random tank i made on the bus because i can", - UPGRADE_TOOLTIP: "send this non-* to the asshole explosion chamber and have his ashole exploded immediately", - GUNS: [{ - POSITION: [21, 0, 0, 0, 1, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.op]), - TYPE: "bullet" - } - }, { - POSITION: [17, 0, 0, 0, 2, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.op]), - TYPE: "bee", - MAX_CHILDREN: 30, - } - } - ] -} -Class.adsfoipuasdfiopu2.UPGRADE_COLOR = "animatednero", -//wait whats stuff -Class.placeableWall = { - PARENT: "rock", - LABEL: "Wall", - SIZE: 30, - SHAPE: 4, - CLEAR_ON_MASTER_UPGRADE: false, - TEAM: TEAM_ENEMIES, - VARIES_IN_SIZE: false, -}; -Class.placeableWallSmall = { - PARENT: "rock", - LABEL: "Wall", - SIZE: 15, - SHAPE: 4, - CLEAR_ON_MASTER_UPGRADE: false, - TEAM: TEAM_ENEMIES, - VARIES_IN_SIZE: false, -}; -Class.wallPlacerThing = { - PARENT: "genericTank", - SHAPE:0, - MIRROR_MASTER_ANGLE: true, - INTANGIBLE: true, - DRAW_SELF: false, - COLOR: 16, - CLEAR_ON_MASTER_UPGRADE: false, - BODY: { - ACCELERATION: 0.1, - SPEED: true, - HEALTH: 340282366920938463463374607431768211455, - RESIST: 1, - SHIELD: 340282366920938463463374607431768211455, - REGEN: 340282366920938463463374607431768211455, - DAMAGE: false, - PENETRATION: true, - RANGE: true, - FOV: true, - SHOCK_ABSORB: 340282366920938463463374607431768211455, - RECOIL_MULTIPLIER: false, - DENSITY: 340282366920938463463374607431768211455, - STEALTH: true, - PUSHABILITY: false, - HETERO: false, - }, - MOTION_TYPE: "aimassist", - GUNS: [ - { - POSITION: [0, 20, 1, 10, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([{reload:10, speed:0, maxSpeed:0, shudder:0.0001, spray:0.0001}]), - TYPE: "placeableWall", - COLOR: 16, - LABEL: "", - STAT_CALCULATOR: 0, - WAIT_TO_CYCLE: false, - AUTOFIRE: false, - SYNCS_SKILLS: false, - MAX_CHILDREN: 0, - ALT_FIRE: false, - NEGATIVE_RECOIL: false, - DRAW_FILL:false, - BORDERLESS:true, - }, - }, - ], - -}; -Class.wallPlacer = { - PARENT: "genericTank", - LABEL: "Messin' Around", - BODY: { - ACCELERATION: base.ACCEL * 1, - SPEED: base.SPEED * 1, - HEALTH: base.HEALTH * 1, - DAMAGE: base.DAMAGE * 1, - PENETRATION: base.PENETRATION * 1, - SHIELD: base.SHIELD * 1, - REGEN: base.REGEN * 1, - FOV: base.FOV * 1, - DENSITY: base.DENSITY * 1, - PUSHABILITY: 1, - HETERO: 3, - }, - GUNS: [ - { - POSITION: [16, 20, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic,{reload:1/8}]), - TYPE: "wallPlacerThing", - COLOR: 16, - LABEL: "", - STAT_CALCULATOR: 0, - WAIT_TO_CYCLE: false, - AUTOFIRE: false, - SYNCS_SKILLS: false, - MAX_CHILDREN: 1, - ALT_FIRE: false, - NEGATIVE_RECOIL: false, - }, - }, - ], -}; -Class.imagetest = { - PARENT: "genericTank", - UPGRADE_COLOR: "black", - LABEL: "PapyrusButBlackHoleOfDeath.exe", - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', - DANGER: 7, - GUNS: [ - { - POSITION: [2, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "spaghetti" - } - } - ], - ON: [ - { - event: "damage", - handler: ({ body, damageInflictor, damageTool }) => { - damageTool[0].kill() - } - }, - { - event: "tick", - handler: ({ body }) => { - for (let instance of entities) { - let diffX = instance.x - body.x, - diffY = instance.y - body.y, - dist2 = diffX ** 2 + diffY ** 2, - number1 = 1, - number2 = 1, - number3 = 1/7, - number4 = 1, - number5 = 1, - distance = 250, - forceMulti = (((((body.size / 12)*250) ** 2)** number1) * number2) / dist2; - if (dist2 <= ((body.size / 12)*250) ** 2) { - if (instance.id != body.id /*&& !instance.ac && instance.alpha*/) { - instance.velocity.x += util.clamp(body.x - instance.x, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 - instance.velocity.y += util.clamp(body.y - instance.y, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 - } - } - if (dist2 < body.size ** 2 + instance.size ** 2) { - if (instance.id != body.id) { - instance.isProtected = false; - instance.invuln = false; - instance.damageReceived = Infinity, - instance.kill(), - instance.destroy(), - instance.removeFromGrid(), - instance.isGhost = true; - } - } - } - } - }, - ], -} -Class.papyrus = { - PARENT: "genericTank", - LABEL: "Papyrus", - UPGRADE_COLOR: 23, - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', - DANGER: 7, - GUNS: [ - { - POSITION: [2, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "spaghetti" - } - } - ] -} -Class.oppenheimer = { - PARENT: "genericTank", - LABEL: "Oppen Heimer", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "nuke" - } - }, - { - POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] - } - ] -} -Class.homingdevbullet = { - PARENT: "bullet", - TYPE: "swarm", - SHAPE: [[-1, -1], [1, -1], [2, 0], [1, 1], [-1, 1]], - ACCEPTS_SCORE: false, - MOTION_TYPE: "swarm", - CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], - BUFF_VS_FOOD: true, - AI: { - FARMER: true - }, - INDEPENDENT: true -} -Class.homingdev = { - PARENT: "developer", - LABEL: "Homing Developer", - GUNS: [ - { - POSITION: [18, 10, -1.4, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.op]), - TYPE: "homingdevbullet" - } - } - ] -} -Class.brella = { - PARENT: "genericTank", - LABEL: "Nero-Brella", - DANGER: 7, - SYNC_TURRET_SKILLS: true, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet" - } - }, { - POSITION: [1, 10, 0, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.brella]), - TYPE: "brellaShield", - ALT_FIRE: true, - MAX_CHILDREN: 1, - //ALPHA: 1 - } - }] -}; -Class.winsor0 = { - PARENT: "genericTank", - LABEL: "Wi3nsor", - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', - DANGER: 7, - GUNS: [ - { - POSITION: [2, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet" - } - } - ] -} - -Class.winsor1 = { - PARENT: "genericTank", - LABEL: "Winsor has no Friends 🧐", - SIZE: 30, - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144411762_LAYER.jpg?v=1701714034323', - DANGER: 7, - GUNS: [ - { - POSITION: [2, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet" - } - } - ] -} -Class.winsor2 = { - PARENT: "genericTank", - LABEL: "Winsor has no Brain 🧐🧐", - SIZE: 30, - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144409218_LAYER.jpg?v=1701714037274', - DANGER: 7, - GUNS: [ - { - POSITION: [2, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet" - } - } - ] -} -Class.winsor3 = { - PARENT: "genericTank", - LABEL: "Winsor has no Muscle 🧐🧐🧐", - SIZE: 30, - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144406913_LAYER.jpg?v=1701714040278', - DANGER: 7, - GUNS: [ - { - POSITION: [2, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet" - } - } - ] -} -Class.winsor4 = { - PARENT: "genericTank", - LABEL: "And Winsor certainly, has no Bitches 🧐🧐🧐🧐", - SIZE: 30, - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144358408_LAYER.jpg?v=1701714043765', - DANGER: 7, - GUNS: [ - { - POSITION: [2, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet" - } - } - ] -} - -Class.utilities = { - PARENT: "genericTank", - LABEL: "Utilities", - SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381' -}; -Class.AIT = menu("AIT") - -Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons"] - Class.tanks.UPGRADES_TIER_0 = ["developer", "overpowered", "testing", "unavailable", "features"] - Class.AIT.UPGRADES_TIER_0 = ["developer", "bosses", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun", "arenaCloser"] - Class.utilities.UPGRADES_TIER_0 = ["developer", "levels", "teams", "eggGenerator", "spectator", "wallPlacer"] - Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "doubleFlail", "winsor0", "volute"] - Class.volute.UPGRADES_TIER_3 = ["sidewinderOld"] - //Class.flail.UPGRADES_TIER_2 = ["doubleFlail"] - Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] - Class.testing.UPGRADES_TIER_0 = ["tanks", "vanquisher", "mummifier", "tracker3", ["grappletest", "basic"], "brella"] - Class.dominators.UPGRADES_TIER_0 = ["AIT", "destroyerDominator", "gunnerDominator", "trapperDominator"] - Class.sanctuaries.UPGRADES_TIER_0 = ["AIT", "sanctuaryTier1", "sanctuaryTier2", "sanctuaryTier3", "sanctuaryTier4", "sanctuaryTier5", "sanctuaryTier6"] - - Class.bosses.UPGRADES_TIER_0 = ["AIT", "sentries", "elites", "mysticals", "nesters", "rogues", "rammers", "terrestrials", "celestials", "eternals", "devBosses"] - Class.sentries.UPGRADES_TIER_0 = ["bosses", "sentrySwarm", "sentryGun", "sentryTrap", "shinySentrySwarm", "shinySentryGun", "shinySentryTrap", "sentinelMinigun", "sentinelLauncher", "sentinelCrossbow"] - Class.elites.UPGRADES_TIER_0 = ["bosses", "eliteDestroyer", "eliteGunner", "eliteSprayer", "eliteBattleship", "eliteSpawner", "eliteTrapGuard", "eliteSpinner", "eliteSkimmer", "legionaryCrasher", "guardian", "defender", "sprayerLegion"] - Class.mysticals.UPGRADES_TIER_0 = ["bosses", "sorcerer", "summoner", "enchantress", "exorcistor", "shaman"] - Class.nesters.UPGRADES_TIER_0 = ["bosses", "nestKeeper", "nestWarden", "nestGuardian"] - Class.rogues.UPGRADES_TIER_0 = ["bosses", "roguePalisade", "rogueArmada", "julius", "genghis", "napoleon"] - Class.rammers.UPGRADES_TIER_0 = ["bosses", "bob", "nemesis"] - Class.terrestrials.UPGRADES_TIER_0 = ["bosses", "ares", "gersemi", "ezekiel", "eris", "selene"] - Class.celestials.UPGRADES_TIER_0 = ["bosses", "paladin", "freyja", "zaphkiel", "nyx", "theia", "atlas", "rhea", "julius", "genghis", "napoleon"] - Class.eternals.UPGRADES_TIER_0 = ["bosses", "odin", "kronos"] + Class.bosses.UPGRADES_TIER_0 = ["sentries", "elites", "mysticals", "nesters", "rogues", "rammers", "terrestrials", "celestials", "eternals", "devBosses"] + Class.sentries.UPGRADES_TIER_0 = ["sentrySwarm", "sentryGun", "sentryTrap", "shinySentrySwarm", "shinySentryGun", "shinySentryTrap", "sentinelMinigun", "sentinelLauncher", "sentinelCrossbow"] + Class.elites.UPGRADES_TIER_0 = ["eliteDestroyer", "eliteGunner", "eliteSprayer", "eliteBattleship", "eliteSpawner", "eliteTrapGuard", "eliteSpinner", "eliteSkimmer", "legionaryCrasher", "guardian", "defender", "sprayerLegion"] + Class.mysticals.UPGRADES_TIER_0 = ["sorcerer", "summoner", "enchantress", "exorcistor", "shaman"] + Class.nesters.UPGRADES_TIER_0 = ["nestKeeper", "nestWarden", "nestGuardian"] + Class.rogues.UPGRADES_TIER_0 = ["roguePalisade", "rogueArmada", "julius", "genghis", "napoleon"] + Class.rammers.UPGRADES_TIER_0 = ["bob", "nemesis"] + Class.terrestrials.UPGRADES_TIER_0 = ["ares", "gersemi", "ezekiel", "eris", "selene"] + Class.celestials.UPGRADES_TIER_0 = ["paladin", "freyja", "zaphkiel", "nyx", "theia", "atlas", "rhea", "julius", "genghis", "napoleon"] + Class.eternals.UPGRADES_TIER_0 = ["odin", "kronos"] Class.devBosses.UPGRADES_TIER_0 = ["taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss"] - Class.features.UPGRADES_TIER_0 = ["tanks", "diamondShape", "rotatedTrap", "colorMan", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] - Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight"] - Class.goofytanks.UPGRADES_TIER_0 = ["overpowered", "pisseroo", "papyrus", "Trapper_guy", "watertank", "piszerbeam", "baseThrowerDelta", "pouner", "adsfoipuasdfiopu", "goofywhirlwind"] - - //the "winsor" tank needs this to function, it worked before the "ON" thing was added - Class.winsor0.UPGRADES_TIER_0 = ["winsor1", "winsor2", "winsor3", "winsor4"] - Class.papyrus.UPGRADES_TIER_0 = ["imagetest"] - Class.adsfoipuasdfiopu.UPGRADES_TIER_0 = ["adsfoipuasdfiopu2"] \ No newline at end of file + Class.testing.UPGRADES_TIER_0 = ["diamondShape", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "radialAutoTest", "imageShapeTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] diff --git a/server/modules/definitions/groups/food.js b/server/modules/definitions/groups/food.js index ffaa8cb09..9e82ca96d 100644 --- a/server/modules/definitions/groups/food.js +++ b/server/modules/definitions/groups/food.js @@ -1,4 +1,4 @@ -const { basePolygonDamage, basePolygonHealth } = require('../constants.js'), +const { basePolygonDamage, basePolygonHealth, base } = require('../constants.js'), // Code by Damocles (https://discord.com/channels/366661839620407297/508125275675164673/1090010998053818488) // Albeit heavily modified because the math in the original didn't work LOL @@ -88,18 +88,24 @@ makeRelic = (type, scale = 1, gem, SIZE) => { makeCrasher = type => ({ PARENT: type, COLOR: 'pink', + TYPE: "crasher", LABEL: 'Crasher ' + type.LABEL, - CONTROLLERS: ['nearestDifferentMaster', 'canRepel', 'mapTargetToGoal'], + CONTROLLERS: ['nearestDifferentMaster', 'mapTargetToGoal'], MOTION_TYPE: "motor", FACING_TYPE: "smoothWithMotion", HITS_OWN_TYPE: "hard", HAS_NO_MASTER: true, DRAW_HEALTH: true, + BODY: { + SPEED: 1 + 5 / Math.max(2, type.TURRETS.length + type.SHAPE), + ACCELERATION: 5, + DAMAGE: 5, + PUSHABILITY: 0.5, + DENSITY: 10, + RESIST: 2, + }, AI: { NO_LEAD: true, - }, - BODY: { - DAMAGE: type.BODY.DAMAGE * 4 } }), @@ -107,11 +113,11 @@ makeRare = (type, level) => { type = ensureIsClass(type); return { PARENT: "food", - LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Transgender"][level] + " " + type.LABEL, + LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Trans"][level] + " " + type.LABEL, VALUE: [100, 500, 2000, 4000, 5000][level] * type.VALUE, SHAPE: type.SHAPE, SIZE: type.SIZE + level, - COLOR: ["lightGreen", "teal", "pureBlack", "rainbow", "trans"][level], + COLOR: ["lightGreen", "teal", "darkGrey", "rainbow", "trans"][level], ALPHA: level == 2 ? 0.25 : 1, BODY: { DAMAGE: type.BODY.DAMAGE + level, @@ -172,7 +178,7 @@ Class.egg = { BODY: { DAMAGE: 0, DENSITY: 2, - HEALTH: 0.0011, + HEALTH: 0.5 * basePolygonHealth, PUSHABILITY: 0, ACCELERATION: 0.015 }, @@ -361,7 +367,7 @@ Class.hexagon = { BODY: { DAMAGE: 3 * basePolygonDamage, DENSITY: 8, - HEALTH: 500 * basePolygonHealth, + HEALTH: 20 * basePolygonHealth, RESIST: 1.3, SHIELD: 50 * basePolygonHealth, PENETRATION: 1.1, @@ -558,13 +564,24 @@ Class.tesseract = { }; // LABY +let polyNames = [ "egg", "square", "triangle", "pentagon", "hexagon" ], + shinyNames = [ "", "shiny", "legendary", "shadow", "rainbow", "trans" ]; for (let tier = 0; tier < 6; tier++) { - for (let poly of [ "egg", "square", "triangle", "pentagon", "hexagon" ]) { - for (let shiny of [ "", "shiny", "legendary", "shadow", "rainbow", "trans" ]) { - let food = shiny + poly[0].toUpperCase() + poly.slice(1); + for (let poly in polyNames) { + + let polyName = polyNames[poly]; + polyName = polyName[0].toUpperCase() + polyName.slice(1); + + for (let shiny in shinyNames) { + + let shinyName = shinyNames[shiny]; + let food = shinyName + polyName; food = food[0].toLowerCase() + food.slice(1); - Class[`laby${tier}${food[0].toUpperCase() + food.slice(1)}`] = makeLaby(Class[food], tier); + + Class[`laby${tier}${food}`] = // backwards compatability, DO NOT ADD A SEMICOLON HERE. javascript is funny about whitespace characters :)))))) + Class[`laby_${poly}_${tier}_${shiny}_0`] = makeLaby(Class[food], tier); + + Class[`laby_${poly}_${tier}_${shiny}_1`] = makeCrasher(Class[`laby_${poly}_${tier}_${shiny}_0`]); } - Class[`laby${tier}${poly[0].toUpperCase() + poly.slice(1)}Crasher`] = makeCrasher(Class[`laby${tier}${poly[0].toUpperCase() + poly.slice(1)}`]); } } \ No newline at end of file diff --git a/server/modules/definitions/groups/generics.js b/server/modules/definitions/groups/generics.js index 2fd4e9f0a..a4f57a39f 100644 --- a/server/modules/definitions/groups/generics.js +++ b/server/modules/definitions/groups/generics.js @@ -138,12 +138,6 @@ Class.genericSmasher = { DENSITY: 2 * base.DENSITY } } -Class.genericLancer = { - PARENT: "genericTank", - DANGER: 6, - SKILL_CAP: [dfltskl, dfltskl, dfltskl, dfltskl, 0, dfltskl, dfltskl, dfltskl, dfltskl, dfltskl], - STAT_NAMES: statnames.lancer, -} Class.genericBoss = { PARENT: "genericTank", TYPE: "miniboss", @@ -242,6 +236,7 @@ Class.drone = { CLEAR_ON_MASTER_UPGRADE: true, BUFF_VS_FOOD: true, }; + Class.swarm = { LABEL: "Swarm Drone", TYPE: "swarm", @@ -267,6 +262,7 @@ Class.swarm = { DIE_AT_RANGE: true, BUFF_VS_FOOD: true, }; + Class.trap = { LABEL: "Thrown Trap", TYPE: "trap", @@ -327,7 +323,7 @@ Class.auraBase = { ALPHA: 0.3, CLEAR_ON_MASTER_UPGRADE: true, CAN_GO_OUTSIDE_ROOM: true, - CONTROLLERS: ["disableOnOverride"], + CONTROLLERS: ["disableOnOverride", "scaleWithMaster"], BODY: { SHIELD: 1e9, REGEN: 1e6, @@ -361,10 +357,3 @@ Class.auraSymbol = { COLOR: "teal", SHAPE: [[-0.598,-0.7796],[-0.3817,-0.9053],[0.9688,-0.1275],[0.97,0.125],[-0.3732,0.9116],[-0.593,0.785]] }; -Class.rangeAuraSymbol = { - PARENT: "genericTank", - CONTROLLERS: [["spin", {speed: -0.04}]], - INDEPENDENT: true, - COLOR: "teal", - SHAPE: "M -0.7671 0.6521 L -0.7671 -0.6521 L -0.6521 -0.7671 L -0.6521 -0.7671 L 0.6521 -0.7671 L 0.7671 -0.6521 L 0.7671 0.6521 L 0.6521 0.7671 L -0.6521 0.7671 L -0.7671 0.6521" -}; \ No newline at end of file diff --git a/server/modules/definitions/groups/misc.js b/server/modules/definitions/groups/misc.js index 1832360f1..d868c7879 100644 --- a/server/modules/definitions/groups/misc.js +++ b/server/modules/definitions/groups/misc.js @@ -46,17 +46,6 @@ Class.wall = { SHAPE: "M 1 1 L -1 1 L -1 -1 L 1 -1 Z", VARIES_IN_SIZE: false } -Class.dfxwall = { - PARENT: "rock", - LABEL: "Wall", - SIZE: 25, - SHAPE: "M 1 1 L -1 1 L -1 -1 L 1 -1 Z", - VARIES_IN_SIZE: false, - TURRETS: [{ - POSITION: [7, -5, -5, 0, 0, 3], - TYPE: "dfxskin" - },] -} Class.moon = { PARENT: "rock", LABEL: "Moon", @@ -836,4 +825,4 @@ Class.tagMode = { PARENT: "bullet", LABEL: "Players", SHAPE: "" -}; \ No newline at end of file +}; diff --git a/server/modules/definitions/groups/projectiles.js b/server/modules/definitions/groups/projectiles.js index 1768a1b53..f4eddd911 100644 --- a/server/modules/definitions/groups/projectiles.js +++ b/server/modules/definitions/groups/projectiles.js @@ -1,4 +1,4 @@ -const { combineStats, makeAuto, makeHybrid } = require('../facilitators.js'); +const { combineStats, makeAuto } = require('../facilitators.js'); const { gunCalcNames, base } = require('../constants.js'); const g = require('../gunvals.js'); @@ -743,389 +743,3 @@ Class.homingBullet = { }, CAN_GO_OUTSIDE_ROOM: true } - -//delta projectiles -Class.autobullet = makeAuto('bullet', "AutoBullet", {type: 'projectileAutoTurret'}) -Class.heavyautobullet = makeAuto('bullet', "HeavyAutoBullet", {type: 'pillboxTurret'}) -Class.shrapnel = { - PARENT: "bullet", - SHAPE: 5, - LABEL: "expold heheahah", - BODY: { - RANGE: 1, - FOV: 0.5, - }, - INDEPENDENT: true, - CONTROLLERS: ["alwaysFire"], - AI: { - NO_LEAD: true, - }, - GUNS: [ - { - POSITION: [7, 9.5, 1, 7, 0, 72, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfspeed, g.halfrange, g.halfrange]), - TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 9.5, 1, 7, 0, 72*2, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), - TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 9.5, 1, 7, 0, 72*3, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), - TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 9.5, 1, 7, 0, 72*4, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), - TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 9.5, 1, 7, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), - TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - ], -} -Class.grenade = { - PARENT: "bullet", - INDEPENDENT: true, - BODY: { RANGE: 80 }, - GUNS: [{ - POSITION: [1, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.grenade_explosion]), - TYPE: ["shrapnel", { PERSISTS_AFTER_DEATH: true }], - SHOOT_ON_DEATH: true, - } - }, { - POSITION: [14, 6, 1, 0, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, { reload: 0.5 }, g.lowPower, { recoil: 1.35 }, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.thruster, - } - } - ], - TURRETS: [{ - POSITION: [9, -8, 0, 0, 0, 1], - TYPE: ["grenadeDeco"] - } - ] -} -Class.firecrackerbomb = { - PARENT: "bullet", - INDEPENDENT: true, - BODY: { RANGE: 70 }, - GUNS: [{ - POSITION: [1, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.explosion]), - TYPE: ["growBullet", { PERSISTS_AFTER_DEATH: true }], - SHOOT_ON_DEATH: true, - } - }, { - POSITION: [14, 6, 1, 0, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0.5 }, g.lowPower]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.thruster, - }, - }, - ], - TURRETS: [{ - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: "firecrackerDeco" - }] -} -Class.baseBullet = { - PARENT: "boomerang", - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - CONTROLLERS: [["spin", { independent: true, speed: 0.1 }]], - INDEPENDENT: true, - COLOR: "orange", - TURRETS: [{ - POSITION: [4.65, 9.85, 0, 90, 220, 1], - TYPE: ["revogun", { COLOR: "orange", BODY: { FOV: 2 } }] - }, { - POSITION: [4.65, 9.85, 0, 270, 220, 1], - TYPE: ["revogun", { COLOR: "orange", BODY: { FOV: 2 } }] - }], -ON: [{ - event: "death", - handler: ({ body }) => { - if (!body.master.isDead) return - body.master.define(Class.baseThrower) - } - } - ] -}; -Class.brellaShield = { - PARENT: "bullet", - TYPE: "brella", - LABEL: "Base", - SIZE: 7, - //SHAPE: 'M 1 3.5 L 2 2 L 2 0 L 1 -1.5 L 0 -1.8 L 0 -1 L 2 0.5 L 0 -1 L 0 0 L 2 0.85 L 0 0 L 0 1 L 2 1 L 0 1 L 0 1 L 0 2 L 2 1.15 L 0 2 L 0 3 L 2 1.5 L 0 3 L 0 3.8 L 1 3.5', - SHAPE: 'M -0 2.2587 L 0.9 0.905 L 0.9 -0.9 L -0 -2.2537 L -0.9 -2.5245 L -0.9 2.5295 L -0 2.2587', - INDEPENDENT: true, - COLOR: "grey", - GUNS: [ - { - POSITION: [14, 6, 1, 0, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0.35 }, g.lowPower]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.thruster, - }, - }, - ], -}; -Class.laser = { - PARENT: ["bullet"], - SHAPE: -1, - BODY: { - PENETRATION: 1.15, - SPEED: 5.8, - RANGE: 100, - DENSITY: 0.9, - HEALTH: 0.155, - DAMAGE: 5.6, - }, - BUFF_VS_FOOD: true, -} -Class.fastdrone = { - PARENT: "drone", - LABEL: 'Drone', - BODY: { - PENETRATION: 1.2, - PUSHABILITY: 0.6, - ACCELERATION: 0.05, - HEALTH: 0.5, - DAMAGE: 3.125, - SPEED: 6, - RANGE: 200, - DENSITY: 0.03, - RESIST: 1.5, - FOV: 0.8, - }, - GUNS: [ { /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [ 15, 5, 1, 0, 0, 180, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.muchmorerecoil, g.muchmorerecoil, g.weak]), - TYPE: "bullet", - AUTOFIRE: true - }, }, - ], - HITS_OWN_TYPE: 'hard', - DRAW_HEALTH: false, - CLEAR_ON_MASTER_UPGRADE: true, - BUFF_VS_FOOD: true, -}; - -Class.revoorbitdrone = { - PARENT: "drone", - LABEL: 'Drone', - SYNC_TURRET_SKILLS: true, - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "droneturretBase", - }, - ], -}; -Class.hiveprobe = { - PARENT: "genericTank", - LABEL: "Probe", - TYPE: "drone", - HITS_OWN_TYPE: "hardWithBuffer", - DRAW_HEALTH: true, - BODY: { - FOV: 0.5, - SPEED: 3, - ACCELERATION: 0.4, - HEALTH: 2.5, - SHIELD: 0, - DAMAGE: 1.2, - RESIST: 1, - PENETRATION: 1, - DENSITY: 0.4 - }, - AI: { - BLIND: true - }, - CLEAR_ON_MASTER_UPGRADE: true, - GIVE_KILL_MESSAGE: false, - ACCEPTS_SCORE: false, - CONTROLLERS: [ - "nearestDifferentMaster", - "mapAltToFire", - "minion", - "canRepel", - "hangOutNearMaster" - ], - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lowPower]), - TYPE: "bullet" - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [27, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -}; -Class.clonerprobe = { - PARENT: "hiveprobe", - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lowPower]), - TYPE: "bullet" - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [24, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -} -Class.autoclonerprobe = makeAuto(Class.clonerprobe) -Class.spaghetti = { - PARENT: "bullet", - SHOOT_ON_DEATH: true, - SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg?v=1701450288242", - GUNS: [ - { - POSITION: [2, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet" - } - } - ] -} -const timer = (run, duration) => { - let timer = setInterval(() => run(), 31.25); - setTimeout(() => { - clearInterval(timer); - }, duration * 1000); -}; - const damageOnTick = (body, instance, multiplier, duration, stopAtSetHealth, hitsOwnTeam) => { - if (!instance) return - if (!instance.damageOnTicking && !instance.godmode && !instance.invuln && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) { - instance.damageOnTicking = true; - setTimeout(() => { - instance.damageOnTicking = false; - }, 2 * duration * 1000); - timer(() => { - if (instance.damageOnTicking && instance.health.amount > stopAtSetHealth && instance.health.amount - (multiplier * 0.5) > stopAtSetHealth) { - instance.health.amount -= multiplier * 0.5; - } //else {if (instance.health.amount - (multiplier * 0.5) < stopAtSetHealth) {instance.health.amount === stopAtSetHealth}} - }, 2 * duration); - } -}; -const iceOnTick = (body, instance, multiplier, duration, hitsOwnTeam) => { - if (!instance) return - if (!instance.invuln && !instance.godmode && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) timer(() => { - instance.velocity.x /= 1.05 * multiplier; - instance.velocity.y /= 1.05 * multiplier; - }, 1.5 * duration); -}; -Class.poisonbullet = { - PARENT: "bullet", - GLOW: { - RADIUS: 2, - COLOR: "green", - ALPHA: 1, - RECURSION: 4, - }, - TURRETS: [{ - POSITION: [5.5, 0, 0, 0, 0, 1], - TYPE: ["effectBulletDeco", { color: "green" }] - }], - ON: [{ - event: "damage", - handler: ({ body, damageTool }) => { - damageOnTick(body, damageTool[0], 1, 1, 1, true); - } - }] -} -Class.icebullet = { - PARENT: "bullet", - GLOW: { - RADIUS: 2, - COLOR: "#28B1DE", - ALPHA: 1, - RECURSION: 4, - }, - TURRETS: [{ - POSITION: [5.5, 0, 0, 0, 0, 1], - TYPE: ["effectBulletDeco", { color: "#28B1DE" }] - }], - ON: [{ - event: "damage", - handler: ({ body, damageTool }) => { - iceOnTick(body, damageTool[0], 1, 1, true); - } - }] -} -Class.ceptionistbullet = { - PARENT: "bullet", - GUNS: [{ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.slightlyweaker, g.slightlyweaker, g.halfreload, g.halfreload, g.turret]), - TYPE: "bullet", - COLOR: "black", - AUTOFIRE: true - } - } - ] -} -Class.autoturretswarm = makeAuto('swarm', "AutoturretSwarm", {type: 'droneAutoTurret'}) -Class.hybridclonerprobe = makeHybrid('clonerprobe', "hybrid-cloner-probe") -Class.nuke = { - PARENT: "growBullet", - LABEL: "Nuke", - MOTION_TYPE: "fuckingnuclearbomb", - BODY: { - PENETRATION: 100, - SPEED: 7, - RANGE: 600, - DENSITY: 99999999999, - HEALTH: 99999, - DAMAGE: 999999, - PUSHABILITY: -99999999, - }, -}; \ No newline at end of file diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 6afc808fc..49ccee8bd 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -1,4 +1,4 @@ -const { combineStats, makeAuto, makeHybrid, makeHybridDrive, makeOver, makeDeco, makeGuard, makeBird, makeMulti, makeCeption, makeCeptionNerf, makeTracker, addBackTurret, makeAura } = require('../facilitators.js'); +const { combineStats, makeAuto, makeOver, makeDeco, makeGuard, makeBird, makeMulti, makeRadialAuto, weaponArray } = require('../facilitators.js'); const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); require('./generics.js'); const g = require('../gunvals.js'); @@ -8,8 +8,6 @@ Class.basic = { PARENT: "genericTank", LABEL: "Basic", DANGER: 4, - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - SKILL: Array(10).fill(12), /*BODY: { ACCELERATION: base.ACCEL * 1, SPEED: base.SPEED * 1, @@ -91,21 +89,20 @@ Class.machineGun = { } ] } -Class.flankGuard = makeMulti({ +Class.flankGuard = { PARENT: "genericTank", + LABEL: "Flank Guard", BODY: { SPEED: 1.1 * base.SPEED }, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet" - } + GUNS: weaponArray({ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" } - ] -}, 3, "Flank Guard") + }, 3) +} Class.director = { PARENT: "genericTank", LABEL: "Director", @@ -215,11 +212,11 @@ Class.healer = { } // Twin upgrades -Class.doubleTwin = makeMulti({ +Class.doubleTwin = { PARENT: "genericTank", - LABEL: "Twin", + LABEL: "Double Twin", DANGER: 6, - GUNS: [ + GUNS: weaponArray([ { POSITION: [20, 8, 1, 0, 5.5, 0, 0], PROPERTIES: { @@ -234,8 +231,8 @@ Class.doubleTwin = makeMulti({ TYPE: "bullet" } } - ] -}, 2) + ], 2) +} Class.tripleShot = { PARENT: "genericTank", LABEL: "Triple Shot", @@ -269,11 +266,11 @@ Class.tripleShot = { } // Double Twin upgrades -Class.tripleTwin = makeMulti({ +Class.tripleTwin = { PARENT: "genericTank", - LABEL: "Twin", + LABEL: "Triple Twin", DANGER: 7, - GUNS: [ + GUNS: weaponArray([ { POSITION: [20, 8, 1, 0, 5.5, 0, 0], PROPERTIES: { @@ -288,8 +285,8 @@ Class.tripleTwin = makeMulti({ TYPE: "bullet" } } - ] -}, 3) + ], 3) +} Class.hewnDouble = { PARENT: "genericTank", LABEL: "Hewn Double", @@ -480,10 +477,11 @@ Class.spreadshot = { } ] } -Class.bentDouble = makeMulti({ +Class.bentDouble = { PARENT: "genericTank", + LABEL: "Bent Double", DANGER: 7, - GUNS: [ + GUNS: weaponArray([ { POSITION: [19, 8, 1, 0, -2, -17.5, 0.5], PROPERTIES: { @@ -505,8 +503,8 @@ Class.bentDouble = makeMulti({ TYPE: "bullet" } } - ] -}, 2, "Bent Double") + ], 2) +} Class.triplet = { PARENT: "genericTank", DANGER: 7, @@ -1194,10 +1192,11 @@ Class.focal = { } // Flank Guard upgrades -Class.hexaTank = makeMulti({ +Class.hexaTank = { PARENT: "genericTank", + LABEL: "Hexa Tank", DANGER: 6, - GUNS: [ + GUNS: weaponArray([ { POSITION: [18, 8, 1, 0, 0, 0, 0], PROPERTIES: { @@ -1212,8 +1211,8 @@ Class.hexaTank = makeMulti({ TYPE: "bullet" } } - ] -}, 3, "Hexa Tank") + ], 3) +} Class.triAngle = { PARENT: "genericTank", LABEL: "Tri-Angle", @@ -1250,52 +1249,35 @@ Class.triAngle = { }, ], } -Class.auto3 = { - PARENT: "genericTank", - LABEL: "Auto-3", - DANGER: 6, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [11, 8, 0, 0, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 120, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 240, 190, 0], - TYPE: "autoTankGun", - }, - ], -} +Class.auto3 = makeRadialAuto("autoTankGun", {isTurret: true, danger: 6, label: "Auto-3"}) // Hexa Tank upgrades -Class.octoTank = makeMulti({ +Class.octoTank = { PARENT: "genericTank", - DANGER: 6, - GUNS: [ + LABEL: "Octo Tank", + DANGER: 7, + GUNS: weaponArray([ { - POSITION: [18, 8, 1, 0, 0, 45, 0.5], + POSITION: [18, 8, 1, 0, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.spam]), TYPE: "bullet" } }, { - POSITION: [18, 8, 1, 0, 0, 0, 0], + POSITION: [18, 8, 1, 0, 0, 45, 0.5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.spam]), TYPE: "bullet" } } - ] -}, 4, "Octo Tank") -Class.cyclone = makeMulti({ + ], 4) +} +Class.cyclone = { PARENT: "genericTank", + LABEL: "Cyclone", DANGER: 7, - GUNS: [ + GUNS: weaponArray([ { POSITION: [15, 3.5, 1, 0, 0, 0, 0], PROPERTIES: { @@ -1324,8 +1306,8 @@ Class.cyclone = makeMulti({ TYPE: "bullet" } } - ] -}, 3, "Cyclone") + ], 3) +} // Tri-Angle upgrades Class.fighter = { @@ -1482,147 +1464,27 @@ Class.surfer = { } // Auto-3 upgrades -Class.auto5 = { - PARENT: "genericTank", - LABEL: "Auto-5", - DANGER: 7, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [11, 8, 0, 0, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 72, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 144, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 216, 190, 0], - TYPE: "autoTankGun", - }, - { - POSITION: [11, 8, 0, 288, 190, 0], - TYPE: "autoTankGun", - }, - ], -} -Class.mega3 = { - PARENT: "genericTank", - LABEL: "Mega-3", - BODY: { - SPEED: 0.95 * base.SPEED, - }, - DANGER: 7, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [14, 8, 0, 0, 190, 0], - TYPE: "megaAutoTankGun", - }, - { - POSITION: [14, 8, 0, 120, 190, 0], - TYPE: "megaAutoTankGun", - }, - { - POSITION: [14, 8, 0, 240, 190, 0], - TYPE: "megaAutoTankGun", - }, - ], -} -Class.auto4 = { - PARENT: "genericTank", - LABEL: "Auto-4", - FACING_TYPE: ["spin", {speed: 0.02}], - DANGER: 7, - TURRETS: [ - { - POSITION: [13, 6, 0, 45, 160, 0], - TYPE: "auto4gun", - }, - { - POSITION: [13, 6, 0, 135, 160, 0], - TYPE: "auto4gun", - }, - { - POSITION: [13, 6, 0, 225, 160, 0], - TYPE: "auto4gun", - }, - { - POSITION: [13, 6, 0, 315, 160, 0], - TYPE: "auto4gun", - }, - ], -} -Class.banshee = { - PARENT: "genericTank", - LABEL: "Banshee", - DANGER: 7, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.1 * base.FOV, +Class.auto5 = makeRadialAuto("autoTankGun", {isTurret: true, danger: 7, label: "Auto-5", count: 5}) +Class.mega3 = makeRadialAuto("megaAutoTankGun", {isTurret: true, danger: 7, size: 14, label: "Mega-5", body: {SPEED: 0.95 * base.SPEED}}) +Class.auto4 = makeRadialAuto("auto4gun", {isTurret: true, danger: 7, size: 13, x: 6, angle: 45, label: "Auto-4", count: 4}) +Class.banshee = makeRadialAuto("bansheegun", {isTurret: true, danger: 7, size: 10, arc: 80, label: "Banshee", body: {SPEED: 0.8 * base.SPEED, FOV: 1.1 * base.FOV}}) +Class.banshee.GUNS = weaponArray({ + POSITION: [6, 11, 1.2, 8, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 2, }, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ - { - POSITION: [10, 8, 0, 0, 80, 0], - TYPE: "bansheegun", - }, - { - POSITION: [10, 8, 0, 120, 80, 0], - TYPE: "bansheegun", - }, - { - POSITION: [10, 8, 0, 240, 80, 0], - TYPE: "bansheegun", - }, - ], - GUNS: [ - { - POSITION: [6, 11, 1.2, 8, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }, - { - POSITION: [6, 11, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }, - { - POSITION: [6, 11, 1.2, 8, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 2, - }, - }, - ], -} +}, 3) // Director upgrades -Class.overseer = makeMulti({ +Class.overseer = { PARENT: "genericTank", + LABEL: "Overseer", DANGER: 6, STAT_NAMES: statnames.drone, BODY: { @@ -1630,20 +1492,18 @@ Class.overseer = makeMulti({ FOV: 1.1 * base.FOV, }, MAX_CHILDREN: 8, - GUNS: [ - { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true - } + GUNS: weaponArray({ + POSITION: [6, 12, 1.2, 8, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true } - ] -}, 2, "Overseer", 90) + }, 2) +} Class.cruiser = { PARENT: "genericTank", LABEL: "Cruiser", @@ -1672,8 +1532,9 @@ Class.cruiser = { }, ], } -Class.underseer = makeMulti({ +Class.underseer = { PARENT: "genericTank", + LABEL: "Underseer", DANGER: 6, STAT_NAMES: statnames.drone, BODY: { @@ -1681,19 +1542,17 @@ Class.underseer = makeMulti({ }, SHAPE: 4, MAX_CHILDREN: 14, - GUNS: [ - { - POSITION: [5.25, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - } + GUNS: weaponArray({ + POSITION: [5.25, 12, 1.2, 8, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, } - ] -}, 2, "Underseer", 90) + }, 2) +} Class.spawner = { PARENT: "genericTank", LABEL: "Spawner", @@ -1772,8 +1631,9 @@ Class.bigCheese = { } // Overseer upgrades -Class.overlord = makeMulti({ +Class.overlord = { PARENT: "genericTank", + LABEL: "Overlord", DANGER: 7, STAT_NAMES: statnames.drone, BODY: { @@ -1781,22 +1641,21 @@ Class.overlord = makeMulti({ FOV: 1.1 * base.FOV, }, MAX_CHILDREN: 8, - GUNS: [ - { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true - } + GUNS: weaponArray({ + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true } - ] -}, 4, "Overlord", 90) -Class.overdrive = makeMulti({ + }, 4) +} +Class.overdrive = { PARENT: "genericTank", + LABEL: "Overdrive", DANGER: 7, STAT_NAMES: statnames.drone, BODY: { @@ -1809,29 +1668,28 @@ Class.overdrive = makeMulti({ TYPE: "overdriveDeco", }, ], - GUNS: [ - { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "turretedDrone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 4 - } + GUNS: weaponArray({ + POSITION: [6, 12, 1.2, 8, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "turretedDrone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 4 } - ] -}, 2, "Overdrive", 90) -Class.commander = makeMulti({ + }, 2) +} +Class.commander = { PARENT: "genericTank", + LABEL: "Commander", STAT_NAMES: statnames.drone, DANGER: 7, BODY: { FOV: base.FOV * 1.15, }, - GUNS: [ + GUNS: weaponArray([ { POSITION: [8, 11, 1.3, 6, 0, 0, 0], PROPERTIES: { @@ -1851,8 +1709,8 @@ Class.commander = makeMulti({ STAT_CALCULATOR: gunCalcNames.swarm, }, } - ] -}, 3, "Commander") + ], 3) +} // Cruiser upgrades Class.carrier = { @@ -1914,7 +1772,7 @@ Class.battleship = { POSITION: [7, 7.5, 0.6, 7, -4, 90, 0.5], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: ["autoswarm"], + TYPE: "autoswarm", STAT_CALCULATOR: gunCalcNames.swarm, LABEL: "Autonomous" } @@ -1923,7 +1781,7 @@ Class.battleship = { POSITION: [7, 7.5, 0.6, 7, 4, 270, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: ["autoswarm"], + TYPE: "autoswarm", STAT_CALCULATOR: gunCalcNames.swarm, LABEL: "Autonomous" } @@ -1953,12 +1811,7 @@ Class.fortress = { POSITION: [7, 7.5, 0.6, 7, 0, 60, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: [ - "swarm", - { - CONTROLLERS: ["canRepel"], - }, - ], + TYPE: "swarm", STAT_CALCULATOR: gunCalcNames.swarm, }, }, @@ -1966,12 +1819,7 @@ Class.fortress = { POSITION: [7, 7.5, 0.6, 7, 0, 180, 1 / 3], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: [ - "swarm", - { - CONTROLLERS: ["canRepel"], - }, - ], + TYPE: "swarm", STAT_CALCULATOR: gunCalcNames.swarm, }, }, @@ -1979,48 +1827,23 @@ Class.fortress = { POSITION: [7, 7.5, 0.6, 7, 0, 300, 2 / 3], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: [ - "swarm", - { - CONTROLLERS: ["canRepel"], - }, - ], + TYPE: "swarm", STAT_CALCULATOR: gunCalcNames.swarm, }, }, - { - POSITION: [14, 9, 1, 0, 0, 0, 0], - }, - { - POSITION: [4, 9, 1.5, 14, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [14, 9, 1, 0, 0, 120, 0], - }, - { - POSITION: [4, 9, 1.5, 14, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [14, 9, 1, 0, 0, 240, 0], - }, - { - POSITION: [4, 9, 1.5, 14, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5 }, { speed: 0.7, maxSpeed: 0.7 }]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, + ...weaponArray([ + { + POSITION: [14, 9, 1, 0, 0, 0, 0], }, - }, + { + POSITION: [4, 9, 1.5, 14, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { range: 0.5, speed: 0.7, maxSpeed: 0.7 }]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + } + ], 3) ], } @@ -2109,17 +1932,18 @@ Class.maleficitor = { }, ], } -Class.infestor = makeMulti({ +Class.infestor = { PARENT: "genericTank", + LABEL: "Infestor", DANGER: 7, STAT_NAMES: statnames.drone, BODY: { SPEED: base.SPEED * 0.9, }, MAX_CHILDREN: 20, - GUNS: [ + GUNS: weaponArray([ { - POSITION: [7.25, 6, 1.2, 6, -5, 0, 0], + POSITION: [7.25, 6, 1.2, 6, -5, 90, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), TYPE: "eggchip", @@ -2129,7 +1953,7 @@ Class.infestor = makeMulti({ } }, { - POSITION: [7.25, 6, 1.2, 6, 5, 0, 0], + POSITION: [7.25, 6, 1.2, 6, 5, 90, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), TYPE: "eggchip", @@ -2138,8 +1962,8 @@ Class.infestor = makeMulti({ STAT_CALCULATOR: gunCalcNames.necro } } - ] -}, 2, "Infestor", 90) + ], 2) +} // Spawner upgrades Class.factory = { @@ -2610,11 +2434,12 @@ Class.builder = { } ] } -Class.triTrapper = makeMulti({ +Class.triTrapper = { PARENT: "genericTank", + LABEL: "Tri-Trapper", DANGER: 6, STAT_NAMES: statnames.trap, - GUNS: [ + GUNS: weaponArray([ { POSITION: [15, 7, 1, 0, 0, 0, 0], }, @@ -2626,8 +2451,8 @@ Class.triTrapper = makeMulti({ STAT_CALCULATOR: gunCalcNames.trap } } - ] -}, 3, "Tri-Trapper") + ], 3) +} Class.trapGuard = makeGuard({ PARENT: "genericTank", LABEL: "Trap", @@ -2759,15 +2584,16 @@ Class.assembler = { } // Tri-Trapper upgrades -Class.hexaTrapper = makeAuto(makeMulti({ +Class.hexaTrapper = makeAuto({ PARENT: "genericTank", + LABEL: "Hexa-Trapper", DANGER: 7, BODY: { SPEED: 0.8 * base.SPEED, }, STAT_NAMES: statnames.trap, HAS_NO_RECOIL: true, - GUNS: [ + GUNS: weaponArray([ { POSITION: [15, 7, 1, 0, 0, 0, 0], }, @@ -2790,124 +2616,98 @@ Class.hexaTrapper = makeAuto(makeMulti({ STAT_CALCULATOR: gunCalcNames.trap, }, }, - ], -}, 3), "Hexa-Trapper") -Class.septaTrapper = (() => { - let a = 360 / 7, - d = 1 / 7; - return { - PARENT: "genericTank", - LABEL: "Septa-Trapper", - DANGER: 7, - BODY: { - SPEED: base.SPEED * 0.8, - }, - STAT_NAMES: statnames.trap, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [15, 7, 1, 0, 0, 0, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, a, 4 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, a, 4 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 2 * a, 1 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 2 * a, 1 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 3 * a, 5 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 3 * a, 5 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 4 * a, 2 * d], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 4 * a, 2 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, + ], 3), +}) +Class.septaTrapper = { + PARENT: "genericTank", + LABEL: "Septa-Trapper", + DANGER: 7, + BODY: { + SPEED: base.SPEED * 0.8, + }, + STAT_NAMES: statnames.trap, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [15, 7, 1, 0, 0, 0, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, }, - { - POSITION: [15, 7, 1, 0, 0, 5 * a, 6 * d], + }, + { + POSITION: [15, 7, 1, 0, 0, 360 / 7, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 360 / 7, 1 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, }, - { - POSITION: [3, 7, 1.7, 15, 0, 5 * a, 6 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, + }, + { + POSITION: [15, 7, 1, 0, 0, -360 / 7, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, -360 / 7, 1 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, }, - { - POSITION: [15, 7, 1, 0, 0, 6 * a, 3 * d], + }, + { + POSITION: [15, 7, 1, 0, 0, 360 / 7 * 2, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, 360 / 7 * 2, 2 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, }, - { - POSITION: [3, 7, 1.7, 15, 0, 6 * a, 3 * d], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, + }, + { + POSITION: [15, 7, 1, 0, 0, -360 / 7 * 2, 0], + }, + { + POSITION: [3, 7, 1.7, 15, 0, -360 / 7 * 2, 2 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, }, - ], - }; -})() -Class.architect = { - PARENT: "genericTank", - LABEL: "Architect", - DANGER: 7, - BODY: { - SPEED: 1.1 * base.SPEED, - }, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [ + }, + { + POSITION: [15, 7, 1, 0, 0, 360 / 7 * 3, 0], + }, { - POSITION: [12, 8, 0, 0, 190, 0], - TYPE: "architectGun", + POSITION: [3, 7, 1.7, 15, 0, 360 / 7 * 3, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, }, { - POSITION: [12, 8, 0, 120, 190, 0], - TYPE: "architectGun", + POSITION: [15, 7, 1, 0, 0, -360 / 7 * 3, 0], }, { - POSITION: [12, 8, 0, 240, 190, 0], - TYPE: "architectGun", + POSITION: [3, 7, 1.7, 15, 0, -360 / 7 * 3, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, }, ], } +Class.architect = makeRadialAuto("architectGun", {isTurret: true, danger: 7, size: 12, label: "Architect", body: {SPEED: 1.1 * base.SPEED}}) // Trap Guard upgrades Class.bushwhacker = makeGuard("sniper", "Bushwhacker") @@ -3225,7 +3025,7 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, 45, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25}]}] } }, @@ -3238,7 +3038,7 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, -45, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25, invert: true}]}] } }, @@ -3251,8 +3051,8 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, 135, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10}]}] + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 12.5}]}] } }, { @@ -3403,6 +3203,7 @@ Class.riptide = { } ] } + // Repeater upgrades Class.iterator = { PARENT: "genericTank", @@ -3478,8 +3279,6 @@ Class.duplicator = { ] } - - // Smasher upgrades Class.megaSmasher = { PARENT: "genericSmasher", @@ -3700,7 +3499,6 @@ Class.paramedic = { // Bird tanks Class.falcon = makeBird("assassin", "Falcon") - Class.vulture = makeBird({ PARENT: "genericTank", DANGER: 7, @@ -3734,6 +3532,13 @@ Class.vulture = makeBird({ Class.phoenix = makeBird("sprayer", "Phoenix") Class.eagle = makeBird("pounder", "Eagle") +// Hybrid tanks +Class.bentHybrid = makeOver('tripleShot', "Bent Hybrid", {count: 1, independent: true, cycle: false}) +Class.poacher = makeOver('hunter', "Poacher", {count: 1, independent: true, cycle: false}) +Class.armsman = makeOver('rifle', "Armsman", {count: 1, independent: true, cycle: false}) +Class.cropDuster = makeOver('minigun', "Crop Duster", {count: 1, independent: true, cycle: false}) +Class.hybrid = makeOver('destroyer', "Hybrid", {count: 1, independent: true, cycle: false}) + // Over tanks Class.overgunner = makeOver({ PARENT: "genericTank", @@ -3783,2041 +3588,76 @@ Class.overtrapper = makeOver({ ] }) -//delta upgrades -Class.minilaser = { - PARENT: "genericTank", - LABEL: "Plasma SMG", - DANGER: 6, - BODY: { - FOV: 1.2, - }, - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [21, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), - TYPE: "laser", - }, - }, - { - POSITION: [19, 8, 1, 0, 0, 0, 1 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), - TYPE: "laser", - }, - }, - { - POSITION: [17, 8, 1, 0, 0, 0, 2 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), - TYPE: "laser", - }, - }, - { - POSITION: [24, 1, 1, 0, 0, 0, 2 / 3], - PROPERTIES: { - COLOR: 'red', - SHOOT_SETTINGS: combineStats([g.fake]), - TYPE: "laser", - }, - } - ], -} -Class.cruiserdrive = { - PARENT: "genericTank", - LABEL: "Swarmdrive", +// Auto tanks +Class.autoDouble = makeAuto("doubleTwin", "Auto-Double") +Class.autoAssassin = makeAuto("assassin") +Class.autoGunner = makeAuto("gunner") +Class.autoTriAngle = makeAuto("triAngle") +Class.autoOverseer = makeAuto("overseer") +Class.autoCruiser = makeAuto("cruiser") +Class.autoSpawner = makeAuto("spawner") +Class.autoBuilder = makeAuto("builder") +Class.autoSmasher = makeAuto({ + PARENT: "genericSmasher", DANGER: 6, - FACING_TYPE: "locksFacing", - STAT_NAMES: statnames.swarm, - BODY: { - FOV: 1.2 * base.FOV, - }, - GUNS: [ - { - POSITION: [7, 7.5, 0.6, 7, 4, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: "autoturretswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 7.5, 0.6, 7, -4, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: "autoturretswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - ], -} -Class.shrapnelgun = { - PARENT: "genericTank", - LABEL: "Albuquerque", - DANGER: 7, - GUNS: [{ - POSITION: [17, 13, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, { reload: 1.8 }]), - TYPE: "grenade" - } - } - ], - TURRETS: [{ - POSITION: [8.2, 16.7, 0, 0, 0, 0], - TYPE: ["grenadeDeco", { MIRROR_MASTER_ANGLE: true }], - } - ] -} -Class.firecracker = { - PARENT: "genericTank", - LABEL: "Firecracker", - DANGER: 7, - GUNS: [{ - POSITION: [17, 13, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, g.halfspeed, { reload: 2.5 }]), - TYPE: "firecrackerbomb" - } - } - ], - TURRETS: [{ - POSITION: [8.2, 13, 0, 0, 0, 2], - TYPE: ["firecrackerDeco", { MIRROR_MASTER_ANGLE: true }], - } - ] -} -Class.inception = { - PARENT: "genericTank", - LABEL: "Inception", - DANGER: 4, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "autobullet", - } - } - ], - TURRETS: [{ - POSITION: [5.5, 18, 0, 0, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.inceptionist = { - PARENT: "genericTank", - LABEL: "Ceptionist", - DANGER: 4, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "ceptionistbullet", - } - } - ], - TURRETS: [{ - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.twinceptionist = { - PARENT: "genericTank", - LABEL: "Twinceptionist", - DANGER: 4, - GUNS: [ - { - POSITION: [20, 8, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin]), - TYPE: "ceptionistbullet" - } - }, + TURRETS: [ { - POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin]), - TYPE: "ceptionistbullet" - } - } - ], - TURRETS: [{ - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.machinception = { - PARENT: "genericTank", - LABEL: "Machceptioner", - DANGER: 4, - GUNS: [ - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), - TYPE: "autobullet" - } - } - ], - TURRETS: [{ - POSITION: [6.5, 20, 0, 0, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.machceptionist = { - PARENT: "genericTank", - LABEL: "Machceptionist", - DANGER: 4, - GUNS: [ - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), - TYPE: "ceptionistbullet" - } - } - ], - TURRETS: [{ - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.flankinception = makeMulti({ - PARENT: "genericTank", - BODY: { - SPEED: 1.1 * base.SPEED - }, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "autobullet" - } - } - ], - TURRETS: [{ - POSITION: [5.5, 18, 0, 0, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - },{ - POSITION: [5.5, 18, 0, 120, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - },{ - POSITION: [5.5, 18, 0, 240, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -}, 3, "Flankceptioner") -Class.flankceptionist = makeMulti({ - PARENT: "genericTank", - BODY: { - SPEED: 1.1 * base.SPEED - }, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "ceptionistbullet" - } - } - ], - TURRETS: [{ - POSITION: [5.5, 18, 0, 0, 0, 0], - TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - },{ - POSITION: [5.5, 18, 0, 120, 0, 0], - TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - },{ - POSITION: [5.5, 18, 0, 240, 0, 0], - TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -}, 3, "Flankceptionist") -Class.flankdue = makeMulti({ - PARENT: "genericTank", - DANGER: 5, - BODY: { - ACCELERATION: base.ACCEL * 0.9, - FOV: 1.1, - SPEED: base.SPEED * 1.1, - }, - GUNS: [{ - POSITION: [23, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, { - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter]), - TYPE: "bullet" - } - }] -}, 3, "Flankduer") -Class.tailgator = { - PARENT: "genericTank", - LABEL: "Tailgator", - DANGER: 4, - GUNS: [ - { - POSITION: [20.5, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), - TYPE: "heavyautobullet" - } - } - ], - TURRETS: [{ - POSITION: [7.5, 20, 0, 0, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.poundceptionist = { - PARENT: "genericTank", - LABEL: "PoundCeptionist", - DANGER: 4, - GUNS: [ - { - POSITION: [20.5, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), - TYPE: "ceptionistbullet" - } - } - ], - TURRETS: [{ - POSITION: [10, 0, 0, 0, 0, 1], - TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.interceptor = { - PARENT: "genericTank", - LABEL: "Interceptor", - DANGER: 4, - GUNS: [ - { - POSITION: [21, 14, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), - TYPE: "heavyautobullet" - } - } - ], - TURRETS: [{ - POSITION: [7.5, 20, 0, 0, 0, 0], - TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] - } - ] -} -Class.revolutionist = { - PARENT: "genericTank", - LABEL: "Revolutionist", - DANGER: 6, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet", - }, - }, - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "turretBase", - }, - ], -}; -Class.proton = { - PARENT: "genericTank", - LABEL: "Proton", - DANGER: 6, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet", - }, - }, - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "protonturretBase", - }, - ], -}; -Class.baseThrower = { - PARENT: "genericTank", - LABEL: "Kivaaritehdas", - DANGER: 6, - SYNC_TURRET_SKILLS: true, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet" - } - }, { - POSITION: [1, 38, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.bitlessspeed, g.halfdamage, g.halfpen, g.kiva]), - TYPE: ["baseBullet", { COLOR: "orange", KEEP_OWN_COLOR: false }], - ALT_FIRE: true, - ALPHA: 0 - } - }], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "turretBaseKiva" - }], - ON: [{ - event: "altFire", - handler: ({ body }) => { - body.define(Class.baseThrowerFire) - } - } - ] -}; -Class.baseThrowerFire = { - PARENT: "genericTank", - LABEL: "Kivaaritehdas", - DANGER: 6, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet" - } - }] -}; -Class.subverter = { - PARENT: "genericTank", - LABEL: "Subverter", - DANGER: 6, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet", - }, - }, - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "subverterturretBase", - }, - ], -}; -Class.pion = { - PARENT: "genericSmasher", - LABEL: "Pion", - DANGER: 6, - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody" - }, { - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "pionturretBase", - }] -} -Class.equilibrium = { - PARENT: "genericTank", - LABEL: "Equilibrium", - DANGER: 6, - GUNS: [ - { - POSITION: [20, 8, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.twin]), - TYPE: "bullet" - } - }, - { - POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.twin]), - TYPE: "bullet" - } - } - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "turretBase", - }, - ], -}; -Class.hadron = { - PARENT: "genericTank", - LABEL: "Hadron", - DANGER: 6, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), - TYPE: "bullet", - }, - }, - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "hadronturretBase", - } - ], -}; -Class.hivemind = { - PARENT: "genericTank", - LABEL: "Hivemind", - //CONTROLLERS: ['nearestDifferentMaster'], - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet" - } - }, - { - POSITION: [0, 20, 1, 0, 0, 90, 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow]), - TYPE: "hiveprobe", - MAX_CHILDREN: 1 - } - }, - { - POSITION: [0, 20, 1, 0, 0, 270, 3.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow]), - TYPE: "hiveprobe", - MAX_CHILDREN: 1 - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [27, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -}; -Class.cloner = { - PARENT: ["genericTank"], - LABEL: "Cloner", - //CONTROLLERS: ['nearestDifferentMaster'], - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet" - } - }, - { - POSITION: [0, 20, 1, 0, 0, 180, 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow]), - TYPE: "clonerprobe", - MAX_CHILDREN: 1 - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [24, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -}; - Class.dictator = { - PARENT: ["genericTank"], - LABEL: "Dictator", - STAT_NAMES: statnames.drone, - DANGER: 5, - SHAPE: 8, - BODY: { - ACCELERATION: base.ACCEL * 0.75, - FOV: base.FOV * 1.1, - }, - MAX_CHILDREN: 4, - GUNS: [ { /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [ 6, 12, 1.2, 8, 0, 0, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: "fastdrone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, }, - ], - }; -Class.littleHunter = { - PARENT: "genericTank", - LABEL: "Subduer", - DANGER: 5, - BODY: { - ACCELERATION: base.ACCEL * 0.9, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [23, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, { - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter]), - TYPE: "bullet" - } - }] -}; -Class.subway = makeBird({ - PARENT: "genericTank", - DANGER: 5, - BODY: { - ACCELERATION: base.ACCEL * 0.9, - FOV: 1.05 - }, - GUNS: [{ - POSITION: [23, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.triAngle, g.triAngleFront, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, { - POSITION: [20, 8, 1, 0, 0, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.triAngle, g.triAngleFront, g.hunter]), - TYPE: "bullet" - } - }] -}, "Subway") -Class.binary = { - PARENT: "genericTank", - LABEL: "Binary", - DANGER: 5, - BODY: { - ACCELERATION: base.ACCEL * 0.9, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [20, 5, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, { - POSITION: [17, 8, 1, 0, 5.5, 0, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter]), - TYPE: "bullet" - } - }, { - POSITION: [20, 5, 1, 0, -5.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter, g.hunterSecondary]), - TYPE: "bullet" - } - }, { - POSITION: [17, 8, 1, 0, -5.5, 0, 0.7], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter]), - TYPE: "bullet" - } - }] -} -Class.trinary = { - PARENT: "genericTank", - LABEL: 'Trinary', - DANGER: 7, - BODY: { - ACCELERATION: base.ACCEL * .7, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [22, 5, 1, 0, 2, 20, .5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, { - POSITION: [19, 8, 1, 0, 2, 20, .7], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, { - POSITION: [22, 5, 1, 0, -2, -20, .5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, { - POSITION: [19, 8, 1, 0, -2, -20, .7], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, { - POSITION: [25, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }, { - POSITION: [22, 8, 1, 0, 0, 0, .2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), - TYPE: "bullet" - } - }] -}; -Class.bigSubduer = { - PARENT: "genericTank", - LABEL: 'Mitochondrion', - DANGER: 7, - BODY: { - ACCELERATION: base.ACCEL * .9, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [26, 2, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator]), - TYPE: "bullet" - } - }, { - POSITION: [23, 5, 1, 0, 0, 0, .15], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.predator]), - TYPE: "bullet" - } - }, { - POSITION: [20, 8, 1, 0, 0, 0, .3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.predator]), - TYPE: "bullet" - } - }] -} -Class.clubbin = makeMulti({ - PARENT: "genericTank", - LABEL: 'Mitochondrion', - DANGER: 7, - BODY: { - ACCELERATION: base.ACCEL * .9, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [26, 2, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator]), - TYPE: "bullet" - } - }, { - POSITION: [23, 5, 1, 0, 0, 0, .15], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.hunterSecondary, g.predator]), - TYPE: "bullet" - } - }, { - POSITION: [20, 8, 1, 0, 0, 0, .3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.predator]), - TYPE: "bullet" - } - }] -}, 3, "Clubbin") -Class.biggerSubduer = { - PARENT: "genericTank", - LABEL: 'Cytochrome', - DANGER: 7, - BODY: { - ACCELERATION: base.ACCEL * 0.8, - SPEED: base.SPEED * 0.95, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [29, 2, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.hunterSecondary, g.predator, g.lessrecoil]), - TYPE: "bullet" - } - }, { - POSITION: [26, 4, 1, 0, 0, 0, 2/15], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator, g.lessrecoil]), - TYPE: "bullet" - } - }, { - POSITION: [23, 6, 1, 0, 0, 0, 4/15], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.predator]), - TYPE: "bullet" - } - }, { - POSITION: [20, 8, 1, 0, 0, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.predator]), - TYPE: "bullet" - } - }] -} -Class.accelminigun = { - PARENT: "genericTank", - LABEL: "Rainmaker", - DANGER: 6, - BODY: { - FOV: base.FOV * 1.4 - }, - GUNS: [ - { - POSITION: [8, .1, -54, 21, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.fake, g.triplereload]), - TYPE: "bullet", - COLOR: 12 - } - }, - { - POSITION: [21, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), - TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] - } - }, - { - POSITION: [19, 8, 1, 0, 0, 0, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), - TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] - } - }, - { - POSITION: [17, 8, 1, 0, 0, 0, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), - TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] - } - } - ] -} -Class.railgun = { - PARENT: "genericTank", - DANGER: 6, - LABEL: "Railgun", - BODY: { - SPEED: 0.9 * base.SPEED, - FOV: 1.25 * base.FOV - }, - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [1, 6.5, 1, 25, 0, 0, 0.15], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.fast, g.fast, g.railgun]), - TYPE: "bullet" - } - }, { - POSITION: [1, 6.5, 1, 10, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.railgun]), - TYPE: "bullet" - } - }, { - POSITION: [1, 6.5, 1, 15, 0, 0, 0.05], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.railgun]), - TYPE: "bullet" - } - }, - { - POSITION: [1, 6.5, 1, 20, 0, 0, 0.1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.fast, g.railgun]), - TYPE: "bullet" - } - }, - { - POSITION: [22, 1.9, 1, 5, 4, 0, 0] - }, - { - POSITION: [22, 1.9, 1, 5, -4, 0, 0] - } - ] -} -Class.skater = { - PARENT: "genericSmasher", - LABEL: "Skater", - DANGER: 6, - BODY: { - SPEED: base.SPEED * 2.4, - ACCELERATION: base.ACCEL * 0.56, - }, - - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody" - }, { - POSITION: [15, 0, 0, 0, 360, 1], - TYPE: ["skaterDeco", { COLOR: "#49bdde" }] - } - ] -} -Class.revodirector = { - PARENT: "genericTank", - LABEL: "Solar System", - STAT_NAMES: statnames.drone, - BODY: { - FOV: base.FOV * 1.1 - }, - GUNS: [ - { - POSITION: [6, 11, 1.3, 7, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone]), - TYPE: "revoorbitdrone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - MAX_CHILDREN: 5 - } - } - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "turretBasenoguns", - }, { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: "overdriveDeco", - }, - ], -} -Class.directdrive = { - PARENT: "genericTank", - LABEL: "Motor", - STAT_NAMES: statnames.drone, - BODY: { - FOV: base.FOV * 1.1 - }, - GUNS: [ - { - POSITION: [6, 11, 1.3, 7, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone]), - TYPE: "turretedDrone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - MAX_CHILDREN: 6 - } - } - ], - TURRETS: [ - { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: "overdriveDeco", - }, - ] -} -Class.contagion = { - PARENT: "genericTank", - LABEL: 'Contagion', - DANGER: 6, - BODY: { - FOV: 1.1, - ACCELERATION: base.ACCEL * 0.9 - }, - STAT_NAMES: statnames.mixed, - GUNS: [{ - POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), - TYPE: "bullet" - } - }, { - POSITION: [13, 8, 1, 0, 0, 0, 0] - }, { - POSITION: [4, 8, 1.7, 13, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.morerange, g.lessspread]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap - } - }] -}; -Class.triContagion = makeMulti({ - PARENT: "genericTank", - DANGER: 6, - BODY: { - FOV: 1.1, - ACCELERATION: base.ACCEL * 0.9 - }, - STAT_NAMES: statnames.mixed, - GUNS: [{ - POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), - TYPE: "bullet" - } - }, { - POSITION: [13, 8, 1, 0, 0, 0, 0] - }, { - POSITION: [4, 8, 1.7, 13, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.morerange, g.lessspread, g.flankGuard]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap - } - }] -}, 3, "Tri-Contagion"); -Class.autoContagion = makeAuto("contagion"); -Class.fort = { - PARENT: "genericTank", - LABEL: "Fort", - DANGER: 7, - BODY: { - SPEED: base.SPEED * 0.8, - ACCELERATION: base.ACCEL * 0.9, - FOV: 1.15 - }, - STAT_NAMES: statnames.mixed, - GUNS: [{ - POSITION: [22, 5.5, 1, 0, 0, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), - TYPE: "bullet" - } - }, { - POSITION: [18, 12, 1, 0, 0, 0, 0] - }, { - POSITION: [2, 12, 1.1, 18, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), - TYPE: "setTrap" - } - }] -}; -Class.droneTrapper = { - PARENT: "genericTank", - LABEL: "Magician", - DANGER: 7, - BODY: { - FOV: 1.1, - ACCELERATION: base.ACCEL * .9 - }, - STAT_NAMES: statnames.mixed, - GUNS: [{ - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.lesspower]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - MAX_CHILDREN: 6 - } - }, { - POSITION: [13, 8, 1, 0, 0, 0, 0] - }, { - POSITION: [4, 8, 1.7, 13, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap - } - }] -} -Class.trojan = { - PARENT: "genericTank", - LABEL: "Trojan", - STAT_NAMES: statnames.mixed, - DANGER: 7, - BODY: { - ACCELERATION: base.ACCEL * 0.675, - SPEED: base.SPEED * 0.875, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [19, 5.5, 1, 0, 0, 0, .5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), - TYPE: "bullet" - } - }, { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.bitlessreload]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 4 - } - }, { - POSITION: [19, 5.5, 1, 0, 0, 180, .5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), - TYPE: "bullet" - } - }, { - POSITION: [6, 12, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.bitlessreload]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - MAX_CHILDREN: 4 - } - }] -} -Class.gundirector = { - PARENT: "genericTank", - LABEL: "Pathogen", - STAT_NAMES: statnames.mixed, - DANGER: 6, - BODY: { - ACCELERATION: base.ACCEL * 0.75, - SPEED: base.SPEED * 0.95, - FOV: 1.1 - }, - GUNS: [{ - POSITION: [19, 5.5, 1, 0, 0, 0, .5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), - TYPE: "bullet" - } - }, { - POSITION: [6, 12, 1.2, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.bitlessreload]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - MAX_CHILDREN: 6 - } - }] -} -Class.protist = { - PARENT: "genericTank", - LABEL: "Protist", - DANGER: 7, - BODY: { - ACCELERATION: base.ACCEL * .9, - SPEED: base.SPEED * .8, - FOV: 1.1 - }, - STAT_NAMES: statnames.mixed, - GUNS: [{ - POSITION: [18, 5.5, 1, 0, 0, 0, .5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), - TYPE: "bullet" - } - }, { - POSITION: [4.5, 10, 1, 10.5, 0, 0, 0] - }, { - POSITION: [1, 12, 1.01, 15, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory]), - TYPE: "minion", - STAT_CALCULATOR: gunCalcNames.drone, - AUTOFIRE: true, - SYNCS_SKILLS: true, - MAX_CHILDREN: 4 - } - }, { - POSITION: [3.5, 12, 1, 8, 0, 0, 0] - }] -}; -Class.acid = { - PARENT: "genericTank", - LABEL: 'Acid', - DANGER: 6, - GLOW: { - RADIUS: 2, - COLOR: "green", - ALPHA: 1, - RECURSION: 4, - }, - BODY: { - ACCELERATION: base.ACCEL * 0.75, - SPEED: base.SPEED * 0.85, - FOV: base.FOV * 1.2, - }, - GUNS: [{ - POSITION: [24, 8.5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), - TYPE: "poisonbullet", - } - }, { - POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], - PROPERTIES: { - COLOR: "green" - } - }] -}; -Class.disintegrator = { - PARENT: "genericTank", - DANGER: 6, - LABEL: "Disintegrator", - GLOW: { - RADIUS: 2, - COLOR: "green", - ALPHA: 1, - RECURSION: 4, - }, - BODY: { - ACCELERATION: base.ACCEL * 0.75, - SPEED: 0.7 * base.SPEED, - FOV: 1.4 * base.FOV - }, - GUNS: [ - { - POSITION: [27, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), - TYPE: "poisonbullet" - } - }, { - POSITION: [16, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - COLOR: "green" - } - }, { - POSITION: [5, 8, -1.4, 8, 0, 0, 0] - } - ] -} -Class.chiller = { - PARENT: "genericTank", - LABEL: 'Chiller', - DANGER: 6, - GLOW: { - RADIUS: 2, - COLOR: "#28B1DE", - ALPHA: 1, - RECURSION: 4, - }, - BODY: { - ACCELERATION: base.ACCEL * 0.7, - FOV: 1.2 - }, - GUNS: [{ - POSITION: [24, 8.5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), - TYPE: "icebullet" - } - }, { - POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], - PROPERTIES: { - COLOR: "#28B1DE" - } - }] -}; -Class.freezer = { - PARENT: "genericTank", - DANGER: 6, - LABEL: "Freezer", - GLOW: { - RADIUS: 2, - COLOR: "#28B1DE", - ALPHA: 1, - RECURSION: 4, - }, - BODY: { - ACCELERATION: base.ACCEL * 0.75, - SPEED: 0.7 * base.SPEED, - FOV: 1.4 * base.FOV - }, - GUNS: [ - { - POSITION: [27, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), - TYPE: "icebullet" - } - }, { - POSITION: [16, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - COLOR: "#28B1DE" - } - }, { - POSITION: [5, 8, -1.4, 8, 0, 0, 0] - } - ] -} -Class.helecopter = { - PARENT: "genericTank", - LABEL: "Attack Helicopter", - BODY: { - SPEED: 6, - PUSHABILITY: 0, - ACCELERATION: 0.8, - }, - DANGER: 6, - GUNS: [{ - POSITION: [19, 2, 1, 0, -2.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), - TYPE: "bullet", - HAS_NO_RECOIL: true, - }, - }, - { - POSITION: [19, 2, 1, 0, 2.5, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), - TYPE: "bullet", - HAS_NO_RECOIL: true, - }, - }, { - POSITION: [2, 2, 1, 0, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.triAngle, g.thruster, g.thruster, g.fakewithrecoil]), - TYPE: "bullet", - AUTOFIRE: true, - }, - }, { - POSITION: [12, 11, 1, 0, 0, 0, 0], - }, - { - POSITION: [26.5, 8, 0.7, 0, 0, 180, 0], - }, - { - POSITION: [5.5, 8, -1.8, 6.5, 0, 180, 0], - }, - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [20, -27.5, 0, 0, 360, 1], - TYPE: "helecoptersblade", - }, - { - /* SIZE X Y ANGLE ARC */ - POSITION: [25, 0, 0, 0, 360, 1], - TYPE: "helecopterblade", - }, - ], -}; -Class.twinsniper = { - PARENT: "genericTank", - LABEL: "Twiper", - DANGER: 7, - BODY: { - FOV: 1.1 * base.FOV - }, - CONTROLLERS: ["zoom"], - TOOLTIP: "Hold right click to zoom.", - GUNS: [ - { - POSITION: [24, 8.5, 1, 0, 5.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sniper]), - TYPE: "bullet" - } - }, - { - POSITION: [24, 8.5, 1, 0, -5.5, 0, .5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sniper]), - TYPE: "bullet" - } - } - ] -} -Class.backShield = { - PARENT: "genericTank", - LABEL: 'BackShield', - DANGER: 7, - GUNS: [{ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet" - } - }], - TURRETS: [{ - POSITION: [18, 18, 0, 180, 360, 1], - TYPE: ["backshieldturret", { SHAPE: 12 }], - VULNERABLE: true - }] -}; -Class.mirrorBackShield = { - PARENT: "genericTank", - LABEL: 'BackMirror', - DANGER: 7, - GUNS: [{ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet" - } - }], - TURRETS: [{ - POSITION: [16.7, -18.5, 0, 0, 360, 1], - TYPE: ["mirrorbackshieldturret", { SHAPE: 14 }], - VULNERABLE: true - }] -}; -Class.waterfall = { - PARENT: "genericTank", - LABEL: "Waterfall", - DANGER: 6, - GUNS: [ - { - POSITION: [21, 14, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), - TYPE: "bullet", - }, - }, - { - POSITION: [19, 2, 1, 0, -2.5, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [19, 2, 1, 0, 2.5, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [12, 11, 1, 0, 0, 180, 0], - }, - ], -} -Class.auto2 = { - PARENT: "genericTank", - LABEL: "Auto-2", - DANGER: 5, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [{ - POSITION: [11, 8, 0, 0, 190, 0], - TYPE: "autoTankGun" - }, { - POSITION: [11, 8, 0, 180, 190, 0], - TYPE: "autoTankGun" - }] -} -Class.swivel2 = { - PARENT: "genericTank", - LABEL: "Swivel-2", - DANGER: 5, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [{ - POSITION: [9, 7, 0, 0, 360, 1], - TYPE: "autoTankGun" - }, { - POSITION: [9, 7, 0, 180, 360, 1], - TYPE: "autoTankGun" - }] -} -Class.swivel3 = { - PARENT: "genericTank", - LABEL: "Swivel-3", - DANGER: 5, - FACING_TYPE: ["spin", {speed: 0.02}], - TURRETS: [{ - POSITION: [11, 8, 0, 0, 360, 1], - TYPE: "autoTankGun" - }, { - POSITION: [11, 8, 0, 120, 360, 1], - TYPE: "autoTankGun" - }, { - POSITION: [11, 8, 0, 240, 360, 1], - TYPE: "autoTankGun" - }] -} -const timer = (run, duration) => { - let timer = setInterval(() => run(), 31.25); - setTimeout(() => { - clearInterval(timer); - }, duration * 1000); -}; - const damageOnTick = (body, instance, multiplier, duration, stopAtSetHealth, hitsOwnTeam) => { - if (!instance) return - if (!instance.damageOnTicking && !instance.godmode && !instance.invuln && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) { - instance.damageOnTicking = true; - setTimeout(() => { - instance.damageOnTicking = false; - }, 2 * duration * 1000); - timer(() => { - if (instance.damageOnTicking && instance.health.amount > stopAtSetHealth && instance.health.amount - (multiplier * 0.5) > stopAtSetHealth) { - instance.health.amount -= multiplier * 0.5; - } //else {if (instance.health.amount - (multiplier * 0.5) < stopAtSetHealth) {instance.health.amount === stopAtSetHealth}} - }, 2 * duration); - } -}; -const iceOnTick = (body, instance, multiplier, duration, hitsOwnTeam) => { - if (!instance) return - if (!instance.invuln && !instance.godmode && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) timer(() => { - instance.velocity.x /= 1.05 * multiplier; - instance.velocity.y /= 1.05 * multiplier; - }, 1.5 * duration); -}; -Class.acidsmasher = { - PARENT: "genericSmasher", - LABEL: "Injector", - DANGER: 6, - BODY: { - DAMAGE: base.DAMAGE * 0.87, - }, - TURRETS: [ - { - POSITION: [21.8, 0, 0, 0, 360, 0], - TYPE: "greenSmasherBody", - }, { - POSITION: [22.3, 0, 0, 0, 360, -1], - TYPE: "smasherBody" - } - ], - ON: [{ - event: "damage", - handler: ({ body, damageTool }) => { - damageOnTick(body, damageTool[0], 1, 1, 1, true); - } - }] -} -Class.autoinceptionistbody = { - PARENT: "genericTank", - LABEL: "Auto-Inceptionist base", - DANGER: 4, - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "ceptionistbullet", - } - } - ] -} - -// Auto tanks -Class.autoBasic = makeAuto("basic", "Auto-Basic"); -Class.autoTwin = makeAuto("twin", "Auto-Twin"); -Class.autoMach = makeAuto("machineGun", "Auto-Mach"); -Class.autoSniper = makeAuto("sniper", "Auto-Sniper"); -Class.autoFlank = makeAuto("flankGuard", "Auto-Flank"); -Class.autoDirector = makeAuto("director", "Chairman"); -Class.autoPound = makeAuto("pounder", "Scratcher"); -Class.autoTrap = makeAuto("trapper", "Auto-Trapper"); -Class.autoDesmos = makeAuto("desmos", "Auto-Desmos"); -Class.autolittleHunter = makeAuto("littleHunter", "Auto-Subduer") -Class.autoinception = makeAuto("inception", "Auto-inception"); -Class.autoauto2 = makeAuto("auto2", "Auto-Auto-2"); -Class.autoCloner = makeAuto({ - PARENT: "genericTank", - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet" - } - }, - { - POSITION: [0, 20, 1, 0, 0, 180, 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow]), - TYPE: "autoclonerprobe", - MAX_CHILDREN: 1 - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [24, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -}, "Auto-Cloner"); -Class.autoDouble = makeAuto("doubleTwin", "Auto-Double") -Class.autoAssassin = makeAuto("assassin") -Class.autoGunner = makeAuto("gunner") -Class.autoTriAngle = makeAuto("triAngle") -Class.autoOverseer = makeAuto("overseer") -Class.autoRevolutionist = makeAuto("revolutionist", "Audioboard"); -Class.autoCruiser = makeAuto("cruiser") -Class.autoSpawner = makeAuto("spawner") -Class.autoBuilder = makeAuto("builder") -Class.autoBinary = makeAuto("binary", "Auto-Binary") -Class.autoinceptionist = makeAuto("autoinceptionistbody", "Auto-Inceptionist", {type: 'ceptionistturret'}); -Class.autoGundirector = makeAuto("gundirector", "Auto-Pathogen") -Class.autoBigSubduer = makeAuto("bigSubduer", "Auto-Mitochondrion") -Class.autoFlankdue = makeAuto("flankdue", "Auto-Flankduer") -Class.autoTripleShot = makeAuto("tripleShot", "Auto-Triple Shot"); -Class.autoHunter = makeAuto("hunter", "Auto-Hunter"); -Class.autoRifle = makeAuto("rifle", "Auto-Rifle"); -Class.autoTwinsniper = makeAuto("twinsniper", "Auto-Twiper"); -Class.autoAcid = makeAuto("acid", "Cyanide"); -Class.autoChill = makeAuto("chiller", "Auto-Chiller"); -Class.autoMini = makeAuto("minigun", "Auto-Minigun"); -Class.autoSprayer = makeAuto("sprayer", "Auto-Sprayer"); -Class.autoHexaTank = makeAuto("hexaTank", "Auto-HexaTank"); -Class.autoAuto3 = makeAuto("auto3", "Auto-Auto3"); -Class.autoUnderseer = makeAuto("underseer", "Auto-Underseer"); -Class.autoDestroy = makeAuto("destroyer", "Auto-Destroyer"); -Class.autoArtillery = makeAuto("artillery", "Auto-Artillery"); -Class.autoLaunch = makeAuto("launcher", "Auto-Launcher"); -Class.autoTriTrapper = makeAuto("triTrapper", "Auto-Tri Trapper"); -Class.autoTrapGuard = makeAuto("trapGuard", "Auto-TrapGuard"); -Class.autoSidewinder = makeAuto("sidewinder", "Auto-Sidewinder"); -Class.autoHelix = makeAuto("helix", "Auto-Helix"); -Class.autoUndertow = makeAuto("undertow", "Auto-Undertow"); -Class.autoRepeater = makeAuto("repeater", "Auto-Repeater"); -Class.automachinception = makeAuto("machinception", "Auto-Machceptioner"); -Class.autotailgator = makeAuto("tailgator", "Auto-Tailgator"); -Class.autoflankinception = makeAuto("flankinception", "Auto-Flankceptioner"); -Class.autoBackShield = makeAuto("backShield", "Auto-BackShield"); -Class.autoSmasher = makeAuto({ - PARENT: "genericSmasher", - DANGER: 6, - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody" + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" } ], SKILL_CAP: [smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl] -}, "Auto-Smasher", { - type: "autoSmasherTurret", - size: 11, -}) - -//Hybrid Tanks -Class.bascrid = makeHybrid('basic', "Basic-Hybrid") -Class.twinbrid = makeHybrid('twin', "Twin-Hybrid") -Class.machbrid = makeHybrid('machineGun', "Machine-Hybrid") -Class.snipebrid = makeHybrid('sniper', "Snipe-Hybrid") -Class.flankbrid = makeHybrid('flankGuard', "Flank-Hybrid") -Class.poundbrid = makeHybrid('pounder', "Pound-Hybrid") -Class.trapbrid = makeHybrid('trapper', "Trapper-Hybrid") -Class.desmosbrid = makeHybrid('desmos', "Desmos-Hybrid") -Class.littleHunterbrid = makeHybrid('littleHunter', "Subduer-Hybrid") -Class.inceptionbrid = makeHybrid('inception', "Inception-Hybrid") -Class.auto2brid = makeHybrid('auto2', "Auto-2-Hybrid") -Class.doubletwinbrid = makeHybrid('doubleTwin', "Double Twin-Hybrid") -Class.hexatankbrid = makeHybrid('hexaTank', "Hexatank-Hybrid") -Class.auto3brid = makeHybrid('auto3', "Auto3-Hybrid") -Class.binarybrid = makeHybrid('binary', "Binary-Hybrid") -Class.flankduebrid = makeHybrid('flankdue', "Flankduer-Hybrid") -Class.bigsubduerbrid = makeHybrid('bigSubduer', "Mitochondrion-Hybrid") -Class.clonebrid = makeHybrid({ - PARENT: "genericTank", - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet" - } - }, - { - POSITION: [0, 20, 1, 0, 0, 180, 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow]), - TYPE: "hybridclonerprobe", - MAX_CHILDREN: 1 - } - } - ], - TURRETS: [ - { - POSITION: [24, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -}, "Cloner-Hybrid") -Class.bentHybrid = makeHybrid('tripleShot', "Bent Hybrid") -Class.revobrid = makeHybrid(Class.revolutionist, "Revobrid"); -Class.contagionbrid = makeHybrid('contagion', "Contagion-Hybrid") -Class.poacher = makeHybrid('hunter', "Poacher") -Class.armsman = makeHybrid('rifle', "Armsman") -Class.cropDuster = makeHybrid('minigun', "Crop Duster") -Class.hybrid = makeHybrid('destroyer', "Hybrid") -Class.assbrid = makeHybrid('assassin', "Assassin-Hybrid") -Class.twipebrid = makeHybrid('twinsniper', "Twiper-Hybrid") -Class.acidbrid = makeHybrid('acid', "Acid-Hybrid") -Class.chillbrid = makeHybrid('chiller', "Chiller-Hybrid") -Class.artilbrid = makeHybrid('artillery', "Artillery-Hybrid") -Class.spraybrid = makeHybrid('sprayer', "Sprayer-Hybrid") -Class.trapguardbrid = makeHybrid('trapGuard', "TG-Hybrid") -Class.builderbrid = makeHybrid('builder', "Builder-Hybrid") -Class.launchbrid = makeHybrid('launcher', "Launcher-Hybrid") -Class.tritrapperbrid = makeHybrid('triTrapper', "Tri-Trapper-Hybrid") -Class.helixbrid = makeHybrid('helix', "Helix-Hybrid") -Class.sidewinderbrid = makeHybrid('sidewinder', "Sidewinder-Hybrid") -Class.undertowbrid = makeHybrid('undertow', "Undertow-Hybrid") -Class.repeaterbrid = makeHybrid('repeater', "Repeater-Hybrid") -Class.inceptionistbrid = makeHybrid('inceptionist', "Inceptionist-Hybrid") -Class.machinceptionbrid = makeHybrid('machinception', "Flankceptioner-Hybrid") -Class.tailgatorbrid = makeHybrid('tailgator', "Tailgator-Hybrid") -Class.flankinceptionbrid = makeHybrid('flankinception', "Flankceptioner-Hybrid") - -//auto hybrid tanks -Class.autotwinbrid = makeHybrid('autoTwin', "Auto-Twin-Hybrid") -Class.autosnipebrid = makeHybrid('autoSniper', "Auto-Sniper-Hybrid") -Class.automachbrid = makeHybrid('autoMach', "Auto-Machine-Hybrid") -Class.autoflankbrid = makeHybrid('autoFlank', "Auto-Flank-Hybrid") -Class.autopoundbrid = makeHybrid('autoPound', "Auto-Pound-Hybrid") -Class.autotrapbrid = makeHybrid('autoTrap', "Auto-Trapper-Hybrid") -Class.autodesmosbrid = makeHybrid('autoDesmos', "Auto-Desmos-Hybrid") -Class.autobascrid = makeHybrid('autoBasic', "Auto-Basic-Hybrid") -Class.autoinceptionbrid = makeHybrid('autoinception', "Auto-Inception-Hybrid") -Class.autolittleHunterbrid = makeHybrid('autolittleHunter', "Auto-Subduer-Hybrid") -Class.autoauto2brid = makeHybrid('auto2', "Auto-Auto-2-Hybrid") - - -//hybrid drive tanks -Class.car = makeHybridDrive('basic', "Car") -Class.mercedes = makeHybridDrive('twin', "Mercedes") -Class.tesla = makeHybridDrive('sniper', "Tesla") -Class.toyota = makeHybridDrive('machineGun', "Toyota") -Class.ford = makeHybridDrive('flankGuard', "Ford") -Class.honda = makeHybridDrive('pounder', "Honda") -Class.gmc = makeHybridDrive('trapper', "GMC") -Class.porsche = makeHybridDrive('autoBasic', "Porsche") -Class.mazda = makeHybridDrive('desmos', "Mazda") -Class.volkswagen = makeHybridDrive('littleHunter', "Volkswagen") -Class.audi = makeHybridDrive('inception', "Audi") -Class.ferrari = makeHybridDrive('auto2', "Ferrari") - -//Ceptions -Class.basicCeption = makeCeptionNerf(Class.basic, "Basic-Ception"); -Class.twinCeption = makeCeptionNerf(Class.twin, "Twin-Ception"); -Class.snipeCeption = makeCeptionNerf(Class.sniper, "Snipe-Ception"); -Class.machCeption = makeCeptionNerf(Class.machineGun, "Mach-Ception"); -Class.flankCeption = makeCeptionNerf(Class.flankGuard, "Flank-Ception"); -Class.directCeption = makeCeptionNerf(Class.director, "Drone-Ception"); -Class.poundCeption = makeCeptionNerf(Class.pounder, "Pound-Ception"); -Class.trapCeption = makeCeptionNerf(Class.trapper, "Trap-Ception"); -Class.desmosCeption = makeCeptionNerf(Class.desmos, "Desmos-Ception"); -Class.bascridCeption = makeCeptionNerf(Class.bascrid, "Basic-Hybrid-Ception"); -Class.littleHunterCeption = makeCeptionNerf(Class.littleHunter, "Subduer-Ception"); -Class.inceptCeption = makeCeptionNerf(Class.inception, "Incept-Ception"); -Class.auto2Ception = makeCeptionNerf(Class.auto2, "Auto-2-Ception"); -Class.revoception = makeCeption(Class.revolutionist, "revoception"); - -//Trackers -Class.trackerSmasher = makeTracker(Class.smasher, "Scanner"); -Class.trackerSniper = makeTracker(Class.sniper, "Marksman"); -Class.trackerAssassin = makeTracker(Class.assassin, "Hitman"); -Class.trackerHunter = makeTracker(Class.hunter, "Pinner"); -Class.trackerMini = makeTracker(Class.minigun, "Scout"); -Class.trackerRifle = makeTracker(Class.rifle, "DMR"); -Class.trackerTwinsniper = makeTracker(Class.twinsniper, "Bolt Action"); -Class.trackerSniperHybrid = makeTracker(Class.snipebrid, "Camper"); -Class.trackerAcid = makeTracker(Class.acid, "Acidilizer"); -Class.trackerChill = makeTracker(Class.chiller, "Icilizer"); - -//Homing Auto Tanks -Class.homingautoBasic = makeAuto("basic", "Homing Auto-Basic", {type: 'homingAutoTurret'}); -Class.homingautoTwin = makeAuto("twin", "Homing Auto-Twin", {type: 'homingAutoTurret'}); -Class.homingautoMach = makeAuto("machineGun", "Homing Auto-Mach", {type: 'homingAutoTurret'}); -Class.homingautoSniper = makeAuto("sniper", "Homing-Auto Sniper", {type: 'homingAutoTurret'}); -Class.homingautoFlank = makeAuto("flankGuard", "Homing Auto-Flank", {type: 'homingAutoTurret'}); -Class.homingautoDirector = makeAuto("director", "Homing Auto-Director", {type: 'homingAutoTurret'}); -Class.homingautoPound = makeAuto("pounder", "Homing Auto-Pounder", {type: 'homingAutoTurret'}); -Class.homingautoTrap = makeAuto("trapper", "Homing Auto-Trapper", {type: 'homingAutoTurret'}); -Class.homingautoDesmos = makeAuto("desmos", "Homing Auto-Desmos", {type: 'homingAutoTurret'}); -Class.homingautobascrid = makeAuto("bascrid", "Homing Auto-Bascrid", {type: 'homingAutoTurret'}) -Class.homingautolittleHunter = makeAuto("littleHunter", "Homing Auto-Subduer", {type: 'homingAutoTurret'}) -Class.homingautoinception = makeAuto("inception", "Auto Inception", {type: 'homingAutoTurret'}); -Class.homingautoauto2 = makeAuto("auto2", "Auto-2", {type: 'homingAutoTurret'}); - -//Reveries -Class.reverie = addBackTurret(Class.basic, "Reverie", {type: 'autoTankGun'}); -Class.twinreverie = addBackTurret(Class.basic, "Tyverie", {type: 'fastbigauto4gun'}); -Class.poundreverie = addBackTurret(Class.basic, "Pyverie", {type: 'megaAutoTankGun'}); -Class.dualreverie = addBackTurret(Class.basic, "Douverie", {type: 'dualAutoTankGun'}); -Class.autoReverie = makeAuto("reverie", "Auto-Reverie"); -Class.reveriebrid = makeHybrid('reverie', "Reverie-Hybrid"); - -//Auras -Class.auraTwin = makeAura(Class.twin); -Class.auraSniper = makeAura(Class.sniper); -Class.auraMachineGun = makeAura(Class.machineGun); -Class.auraFlankGuard = makeAura(Class.flankGuard); -Class.auraDirector = makeAura(Class.director); -Class.auraPounder = makeAura(Class.pounder); -Class.auraTrapper = makeAura(Class.trapper); -Class.auraAutoBasic = makeAura(Class.autoBasic); -Class.auraBascrid = makeAura(Class.bascrid); -Class.auraLittleHunter = makeAura(Class.littleHunter); -Class.auraInception = makeAura(Class.inception); -Class.auraDesmos = makeAura(Class.desmos); -Class.auraAuto2 = makeAura(Class.auto2); -Class.auraSmasher = makeAura(Class.smasher); - -Class.damageAuraBasic = makeAura(Class.basic, "Omen Basic", {type: 'auraDamageGen'}); -Class.damageAuraTwin = makeAura(Class.twin, "Omen Twin", {type: 'auraDamageGen'}); -Class.damageAuraSniper = makeAura(Class.sniper, "Omen Sniper", {type: 'auraDamageGen'}); -Class.damageAuraMachineGun = makeAura(Class.machineGun, "Omen Machine Gun", {type: 'auraDamageGen'}); -Class.damageAuraFlankGuard = makeAura(Class.flankGuard, "Omen Flank Guard", {type: 'auraDamageGen'}); -Class.damageAuraDirector = makeAura(Class.director, "Omen Director", {type: 'auraDamageGen'}); -Class.damageAuraPounder = makeAura(Class.pounder, "Omen Pounder", {type: 'auraDamageGen'}); -Class.damageAuraTrapper = makeAura(Class.trapper, "Omen Trapper", {type: 'auraDamageGen'}); -Class.damageAuraAutoBasic = makeAura(Class.autoBasic, "Omen Auto-Basic", {type: 'auraDamageGen'}); -Class.damageAuraBascrid = makeAura(Class.bascrid, "Omen Bascrid", {type: 'auraDamageGen'}); -Class.damageAuraLittleHunter = makeAura(Class.littleHunter, "Omen Subduer", {type: 'auraDamageGen'}); -Class.damageAuraInception = makeAura(Class.inception, "Omen Inception", {type: 'auraDamageGen'}); -Class.damageAuraDesmos = makeAura(Class.desmos, "Omen Desmos", {type: 'auraDamageGen'}); -Class.damageAuraAuto2 = makeAura(Class.auto2, "Omen Auto-2", {type: 'auraDamageGen'}); - -Class.rangeAuraBasic = makeAura(Class.basic, "Mega-Aura Basic", {type: 'auraRangeGen'}); -Class.rangeAuraTwin = makeAura(Class.twin, "Mega-Aura Twin", {type: 'auraRangeGen'}); -Class.rangeAuraSniper = makeAura(Class.sniper, "Mega-Aura Sniper", {type: 'auraRangeGen'}); -Class.rangeAuraMachineGun = makeAura(Class.machineGun, "Mega-Aura Machine Gun", {type: 'auraRangeGen'}); -Class.rangeAuraFlankGuard = makeAura(Class.flankGuard, "Mega-Aura Flank Guard", {type: 'auraRangeGen'}); -Class.rangeAuraDirector = makeAura(Class.director, "Mega-Aura Director", {type: 'auraRangeGen'}); -Class.rangeAuraPounder = makeAura(Class.pounder, "Mega-Aura Pounder", {type: 'auraRangeGen'}); -Class.rangeAuraTrapper = makeAura(Class.trapper, "Mega-Aura Trapper", {type: 'auraRangeGen'}); -Class.rangeAuraAutoBasic = makeAura(Class.autoBasic, "Mega-Aura Auto-Basic", {type: 'auraRangeGen'}); -Class.rangeAuraBascrid = makeAura(Class.bascrid, "Mega-Aura Bascrid", {type: 'auraRangeGen'}); -Class.rangeAuraLittleHunter = makeAura(Class.littleHunter, "Mega-Aura Subduer", {type: 'auraRangeGen'}); -Class.rangeAuraInception = makeAura(Class.inception, "Mega-Aura Inception", {type: 'auraRangeGen'}); -Class.rangeAuraDesmos = makeAura(Class.desmos, "Mega-Aura Desmos", {type: 'auraRangeGen'}); -Class.rangeAuraAuto2 = makeAura(Class.auto2, "Mega-Aura Auto-2", {type: 'auraRangeGen'}); - -Class.damagerangeAuraBasic = makeAura(Class.basic, "Mega-Omen Basic", {type: 'auraDamageRangeGen'}); -Class.moredamageAuraBasic = makeAura(Class.basic, "X-Omen Basic", {type: 'auraMoreDamageGen'}); -Class.morerangeAuraBasic = makeAura(Class.basic, "X-Mega-Aura Basic", {type: 'auraMoreRangeGen'}); - - -Class.auraDoubleTwin = makeAura(Class.doubleTwin); -Class.auraTripleShot = makeAura(Class.tripleShot); - -Class.auraAssassin = makeAura(Class.assassin); -Class.auraHunter = makeAura(Class.hunter); -Class.auraRifle = makeAura(Class.rifle); -Class.auraTrackerSniper = makeAura(Class.trackerSniper); -Class.auraTwinSniper = makeAura(Class.twinsniper); -Class.auraAcid = makeAura(Class.acid); -Class.auraChiller = makeAura(Class.chiller); - -Class.auraMinigun = makeAura(Class.minigun); -Class.auraGunner = makeAura(Class.gunner); -Class.auraSprayer = makeAura(Class.sprayer); +}, "Auto-Smasher", {type: "autoSmasherTurret", size: 11}) -Class.auraHexaTank = makeAura(Class.hexaTank); -Class.auraTriAngle = makeAura(Class.triAngle); -Class.auraAuto3 = makeAura(Class.auto3); -Class.auraReverie = makeAura(Class.reverie); -Class.auraBackShield = makeAura(Class.backShield); - -Class.auraOverseer = makeAura(Class.overseer); -Class.auraCruiser = makeAura(Class.cruiser); -Class.auraUnderseer = makeAura(Class.underseer); -Class.auraSpawner = makeAura(Class.spawner); -Class.auraDirectdrive = makeAura(Class.directdrive); - -Class.auraDestroyer = makeAura(Class.destroyer); -Class.auraArtillery = makeAura(Class.artillery); -Class.auraLauncher = makeAura(Class.launcher); - -Class.auraBuilder = makeAura(Class.builder); -Class.auraTriTrapper = makeAura(Class.triTrapper); -Class.auraTrapGuard = makeAura(Class.trapGuard); - -Class.auraAutoTwin = makeAura(Class.autoTwin); -Class.auraAutoSniper = makeAura(Class.autoSniper); -Class.auraAutoMach = makeAura(Class.autoMach); -Class.auraAutoFlank = makeAura(Class.autoFlank); -Class.auraAutoDirector = makeAura(Class.autoDirector); -Class.auraAutoPound = makeAura(Class.autoPound); -Class.auraAutoTrap = makeAura(Class.autoTrap); -Class.auraAutoDesmos = makeAura(Class.autoDesmos); -Class.auraRevolutionist = makeAura(Class.revolutionist); -Class.auraAutoLittleHunter = makeAura(Class.autolittleHunter); -Class.auraAutoInception = makeAura(Class.autoinception); -Class.auraAutoAuto2 = makeAura(Class.autoauto2); -Class.auraBasicCeption = makeAura(Class.basicCeption); -Class.auraHomingautoBasic = makeAura(Class.homingautoBasic); - -Class.auratwinbrid = makeAura(Class.launcher); -Class.aurasnipebrid = makeAura(Class.launcher); -Class.auramachbrid = makeAura(Class.machbrid); -Class.auraflankbrid = makeAura(Class.flankbrid); -Class.aurapoundbrid = makeAura(Class.poundbrid); -Class.auratrapbrid = makeAura(Class.trapbrid); -Class.auraautobascrid = makeAura(Class.autobascrid); -Class.auradesmosbrid = makeAura(Class.desmosbrid); -Class.auralittlehunterbrid = makeAura(Class.littleHunterbrid); -Class.aurainceptionbrid = makeAura(Class.inceptionbrid); -Class.auraauto2brid = makeAura(Class.auto2brid); -Class.jeep = makeAura(Class.car, "jeep"); - -Class.auraBinary = makeAura(Class.binary); -Class.auraContagion = makeAura(Class.contagion); -Class.auraGundirector = makeAura(Class.gundirector); -Class.auraBigSubduer = makeAura(Class.bigSubduer); -Class.auraFlankdue = makeAura(Class.flankdue); - -Class.auraMachinception = makeAura(Class.machinception); -Class.auraTailgator = makeAura(Class.tailgator); -Class.auraFlankinception = makeAura(Class.flankinception); - -Class.auraSidewinder = makeAura(Class.sidewinder); -Class.auraHelix = makeAura(Class.helix); -Class.auraUndertow = makeAura(Class.undertow); -Class.auraRepeater = makeAura(Class.repeater); - -// TANK UPGRADE PATHS -Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "autoBasic", "desmos", "bascrid", "littleHunter", "inception", "auraBasic", "auto2"] - Class.basic.UPGRADES_TIER_2 = ["smasher", "cloner"] - Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "landmine", "cocci", "pion", "trackerSmasher", "skater", "acidsmasher", "flail", "autoSmasher", "auraSmasher"] +// Upgrade paths +Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "desmos"] + Class.basic.UPGRADES_TIER_2 = ["smasher"] + Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "autoSmasher", "landmine", "cocci"] Class.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] - Class.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner"] - Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "autoTwin", "helix", "twinbrid", "binary", "twinsniper", "auraTwin"] - Class.twin.UPGRADES_TIER_3 = ["bulwark"] - Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble", "doubletwinbrid", "auraDoubleTwin"] - Class.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentDouble", "triplet", "autoTripleShot", "triplex", "bentHybrid", "trinary", "auraTripleShot"] + Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "helix"] + Class.twin.UPGRADES_TIER_3 = ["dual", "bulwark", "musket"] + Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble"] + Class.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentHybrid", "bentDouble", "triplet", "triplex"] - Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "twinsniper", "autoSniper", "snipebrid", "trackerSniper", "acid", "chiller", "auraSniper"] + Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle"] Class.sniper.UPGRADES_TIER_3 = ["bushwhacker"] - Class.assassin.UPGRADES_TIER_3 = ["ranger", "xHunter", "falcon", "stalker", "autoAssassin", "assbrid", "trackerAssassin", "disintegrator", "freezer", "auraAssassin", "single"] - Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "railgun", "dual","autoHunter", "trackerHunter", 'auraHunter'] - Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman", "autoRifle", "trackerRifle", "auraRifle"] - Class.trackerSniper.UPGRADES_TIER_3 = ["trackerAssassin", "trackerHunter", "trackerMini", "trackerRifle", "trackerTwinsniper", "trackerSniperHybrid", "trackerAcid", "trackerChill", "auraTrackerSniper"] - Class.twinsniper.UPGRADES_TIER_3 = ["dual", "musket", "autoTwinsniper", "twipebrid", "trackerTwinsniper", "auraTwinSniper"] - Class.acid.UPGRADES_TIER_3 = ["disintegrator", "acidsmasher", "autoAcid", "acidbrid", "trackerAcid", "auraAcid"] - Class.chiller.UPGRADES_TIER_3 = ["freezer", "autoChill", "chillbrid", "trackerChill", "auraChiller"] + Class.assassin.UPGRADES_TIER_3 = ["ranger", "falcon", "stalker", "autoAssassin", "single"] + Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "dual"] + Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman"] - Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "autoMach", "machbrid", "machinception", "auraMachineGun"] - Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture", "minilaser", "autoMini", "trackerMini", "accelminigun", "auraMinigun"] - Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner", "waterfall", "helecopter", "auraGunner"] - Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "autoSprayer", "spraybrid", "auraSprayer"] + Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer"] + Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture"] + Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner"] + Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal"] - Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank", "flankbrid", "flankdue", "flankinception", "backShield", "auraBackShield"] + Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper"] Class.flankGuard.UPGRADES_TIER_3 = ["tripleTwin", "quadruplex"] - Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper", "autoHexaTank", "hexatankbrid", "auraHexaTank", "auraTriAngle"] - Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "surfer", "eagle", "phoenix", "vulture", "subway", "helecopter"] - Class.backShield.UPGRADES_TIER_3 = ["mirrorBackShield", "brella", "autoBackShield", "auraBackShield"] + Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper"] + Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "surfer", "eagle", "phoenix", "vulture"] + Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee"] - Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "gundirector", "spawner", "directdrive", "autoDirector", "auraDirector"] + Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "spawner"] Class.director.UPGRADES_TIER_3 = ["manager", "bigCheese"] - Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "trojan", "overdrive", "commander", "auraOverseer"] - Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "autoCruiser", "commander", "auraCruiser"] - Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor", "autoUnderseer", "auraUnderseer"] - Class.spawner.UPGRADES_TIER_3 = ["factory", "protist", "ranch", "autoSpawner", "auraSpawner"] - Class.directdrive.UPGRADES_TIER_3 = ["overdrive", "cruiserdrive", "revodirector", "honda", "dictator", "auraDirectdrive"] + Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "overdrive", "commander"] + Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "autoCruiser", "commander"] + Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor"] + Class.spawner.UPGRADES_TIER_3 = ["factory", "autoSpawner", "ranch"] - Class.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher", "autoPound", "sidewinder", "poundbrid", "tailgator", "auraPounder"] + Class.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher"] Class.pounder.UPGRADES_TIER_3 = ["shotgun", "eagle"] - Class.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct", "autoDestroy", "waterfall", "interceptor", "auraDestroyer"] - Class.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun", "autoArtillery", "artilbrid", "auraArtillery"] - Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun", "shrapnelgun", "firecracker", "autoLaunch", "launchbrid", "auraLauncher"] - - Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "contagion", "autoTrap", "trapbrid", "auraTrapper"] - Class.trapper.UPGRADES_TIER_3 = ["barricade"] - Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "builderbrid"] - Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "triContagion", "autoTriTrapper", "tritrapperbrid"] - Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "autoTrapGuard", "trapguardbrid"] - - Class.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "autoDesmos", "basicCeption", "autobascrid", "autolittleHunter", "autoinception", "autoauto2", "revolutionist", "reverie", "auraAutoBasic", "homingautoBasic"] - Class.autoBasic.UPGRADES_TIER_3 = ["autoSmasher", "autoCloner"] - Class.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "equilibrium", "autoBinary", "autoTwinsniper", "twinCeption", "autotwinbrid", "auraAutoTwin", "homingautoTwin"] - Class.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "autoTwinsniper", "autoAcid", "autoChill", "snipeCeption", "autosnipebrid", "auraAutoSniper", "homingautoSniper"] - Class.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "machCeption", "automachbrid", "automachinception", "auraAutoMach", "homingautoMach"] - Class.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "autoTriTrapper", "flankCeption", "autoflankbrid", "autoFlankdue", "autoflankinception", "auraAutoFlank", "homingautoFlank"] - Class.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoGundirector", "autoSpawner", "directCeption", "auraAutoDirector", "homingautoDirector"] - Class.autoPound.UPGRADES_TIER_3 = ["autoDestroy", "autoBuilder", "autoArtillery", "autoLaunch", "poundCeption", "autoSidewinder", "autopoundbrid", "autotailgator", "auraAutoPound", "homingautoPound"] - Class.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "autoTriTrapper", "autoTrapGuard", "autoContagion", "trapCeption", "autotrapbrid", "auraAutoTrap", "homingautoTrap"] - Class.autoDesmos.UPGRADES_TIER_3 = ["autoSidewinder", "autoHelix", "autoUndertow", "autoRepeater", "desmosCeption", "autodesmosbrid", "auraAutoDesmos", "homingautoDesmos"] - Class.autolittleHunter.UPGRADES_TIER_3 = ["autoMini", "autoBinary", "autoHunter", "autoSprayer", "autoContagion", "autoGundirector", "autoBigSubduer", "autoFlankdue", "autolittleHunterbrid", "littleHunterCeption", "auraAutoLittleHunter", "homingautolittleHunter"] - Class.autoinception.UPGRADES_TIER_3 = ["autoinceptionist", "automachinception", "autotailgator", "autoflankinception", "autoinceptionbrid", "inceptCeption", "auraAutoInception", "homingautoinception"] - Class.autoauto2.UPGRADES_TIER_3 = ["autoAuto3", "autoRevolutionist", "autoReverie", "autoauto2brid", "auto2Ception", "auraAutoAuto2", "homingautoauto2"] - Class.reverie.UPGRADES_TIER_3 = ["twinreverie", "poundreverie", "dualreverie", "autoReverie", "reveriebrid", "auraReverie"] - Class.basicCeption.UPGRADES_TIER_3 = ["twinCeption", "snipeCeption", "machCeption", "flankCeption", "directCeption", "poundCeption", "trapCeption", "desmosCeption", "bascridCeption", "littleHunterCeption", "inceptCeption", "auraBasicCeption"] - Class.homingautoBasic.UPGRADES_TIER_3 = ["homingautoTwin", "homingautoSniper", "homingautoMach", "homingautoFlank", "homingautoDirector", "homingautoPound", "homingautoTrap", "homingautoDesmos", "homingautobascrid", "homingautolittleHunter", "homingautoinception", "auraHomingautoBasic"] - - Class.bascrid.UPGRADES_TIER_2 = ["twinbrid", "snipebrid", "machbrid", "flankbrid", "overseer", "poundbrid", "trapbrid", "autobascrid", "desmosbrid", "littleHunterbrid", "inceptionbrid", "auto2brid", "car", "auraBascrid"] - Class.bascrid.UPGRADES_TIER_3 = ["clonebrid"] - Class.twinbrid.UPGRADES_TIER_3 = ["doubletwinbrid", "bentHybrid", "overgunner", "hexatankbrid", "autotwinbrid", "helixbrid", "binarybrid", "twipebrid", "mercedes", "auratwinbrid"] - Class.snipebrid.UPGRADES_TIER_3 = ["assbrid", "poacher", "cropDuster", "armsman", "twipebrid", "autosnipebrid", "trackerSniperHybrid", "acidbrid", "chillbrid", "tesla", "aurasnipebrid"] - Class.machbrid.UPGRADES_TIER_3 = ["artilbrid", "cropDuster", "overgunner", "spraybrid", "automachbrid", "machinceptionbrid", "toyota", "auramachbrid"] - Class.flankbrid.UPGRADES_TIER_3 = ["hexatankbrid", "surfer", "auto3brid", "trapguardbrid", "tritrapperbrid", "autoflankbrid", "flankduebrid", "flankinceptionbrid", "ford", "auraflankbrid"] - Class.poundbrid.UPGRADES_TIER_3 = ["hybrid", "builderbrid", "artilbrid", "launchbrid", "autopoundbrid", "sidewinderbrid", "tailgatorbrid", "honda", "aurapoundbrid"] - Class.trapbrid.UPGRADES_TIER_3 = ["builderbrid", "tritrapperbrid", "trapguardbrid", "contagionbrid", "autotrapbrid", "overtrapper", "gmc", "auratrapbrid"] - Class.autobascrid.UPGRADES_TIER_3 = ["autotwinbrid", "autosnipebrid", "automachbrid", "autoflankbrid", "autopoundbrid", "autotrapbrid", "autodesmosbrid", "autolittleHunterbrid", "autoinceptionbrid", "revobrid", "reveriebrid", "bascridCeption", "porsche", "auraautobascrid"] - Class.desmosbrid.UPGRADES_TIER_3 = ["sidewinderbrid", "helixbrid", "undertowbrid", "repeaterbrid", "autodesmosbrid", "mazda", "auradesmosbrid"] - Class.littleHunterbrid.UPGRADES_TIER_3 = ["cropDuster", "binarybrid", "poacher", "spraybrid", "contagionbrid", "bigsubduerbrid", "flankduebrid", "autolittleHunterbrid", "volkswagen", "auralittlehunterbrid"] - Class.inceptionbrid.UPGRADES_TIER_3 = ["inceptionistbrid", "machinceptionbrid", "tailgatorbrid", "flankinceptionbrid", "overdrive", "autoinceptionbrid", "audi", "aurainceptionbrid"] - Class.auto2brid.UPGRADES_TIER_3 = ["auto3brid", "revobrid", "reveriebrid", "autoauto2brid", "ferrari", "auraauto2brid"] - Class.car.UPGRADES_TIER_3 = ["mercedes", "tesla", "toyota", "ford", "overdrive", "honda", "gmc", "porsche", "mazda", "volkswagen", "audi", "jeep"] - - Class.littleHunter.UPGRADES_TIER_2 = ["minigun", "binary", "hunter", "sprayer", "contagion", "gundirector", "bigSubduer", "flankdue", "autolittleHunter", "littleHunterbrid", "auraLittleHunter"] - Class.binary.UPGRADES_TIER_3 = ["trinary", "dual", "autoBinary", "binarybrid", "auraBinary"] - Class.contagion.UPGRADES_TIER_3 = ["fort", "triContagion", "autoContagion", "droneTrapper", "contagionbrid", "auraContagion"] - Class.gundirector.UPGRADES_TIER_3 = ["trojan", "protist", "droneTrapper", "autoGundirector"] - Class.bigSubduer.UPGRADES_TIER_3 = ["predator", "redistributor", "biggerSubduer", "clubbin", "autoBigSubduer", "bigsubduerbrid", "auraBigSubduer"] - Class.flankdue.UPGRADES_TIER_3 = ["subway", "triContagion", "clubbin", "autoFlankdue", "flankduebrid", "auraFlankdue"] - - Class.inception.UPGRADES_TIER_2 = ["inceptionist", "machinception", "tailgator", "launcher", "flankinception", "directdrive", "autoinception", "inceptionbrid", "auraInception"] - Class.inceptionist.UPGRADES_TIER_3 = ["twinceptionist", "machceptionist", "poundceptionist", "flankceptionist", "factory", "autoinceptionist", "inceptionistbrid"] - Class.machinception.UPGRADES_TIER_3 = ["machceptionist", "automachinception", "machinceptionbrid", "auraMachinception", "auraTailgator"] - Class.tailgator.UPGRADES_TIER_3 = ["poundceptionist", "interceptor", "engineer", "shrapnelgun", "autotailgator", "tailgatorbrid"] - Class.flankinception.UPGRADES_TIER_3 = ["flankceptionist", "autoflankinception", "flankinceptionbrid", "auraFlankinception"] - - Class.desmos.UPGRADES_TIER_2 = ["helix", "sidewinder", "undertow", "repeater", "autoDesmos", "desmosbrid", "auraDesmos"] + Class.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct"] + Class.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun"] + Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun"] + + Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard"] + Class.trapper.UPGRADES_TIER_3 = ["barricade", "overtrapper"] + Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror"] + Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect"] + Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark"] + + Class.desmos.UPGRADES_TIER_2 = ["helix", "sidewinder", "undertow", "repeater"] + Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "coil", "duplicator"] Class.sidewinder.UPGRADES_TIER_3 = ["coil", "python", "ranch", "oroboros", "cocci"] - Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "coil", "duplicator", "autoHelix", "helixbrid", "auraHelix"] - Class.undertow.UPGRADES_TIER_3 = ["riptide", "autoUndertow", "undertowbrid", "auraUndertow"] - Class.repeater.UPGRADES_TIER_3 = ["iterator", "duplicator", "autoRepeater", "repeaterbrid", "auraRepeater"] - - Class.auraBasic.UPGRADES_TIER_2 = ["auraTwin", "auraSniper", "auraMachineGun", "auraFlankGuard", "auraDirector", "auraPounder", "auraTrapper", "auraAutoBasic", "auraDesmos", "auraBascrid", "auraLittleHunter", "auraInception", "auraAuto2", "damageAuraBasic", "rangeAuraBasic"] - Class.auraBasic.UPGRADES_TIER_3 = ["auraSmasher"] - Class.auraTwin.UPGRADES_TIER_3 = ["auraDoubleTwin", "auraTripleShot", "auraGunner", "auraHexaTank", "auraAutoTwin", "auraHelix", "auratwinbrid", "auraBinary", "auraTwinSniper"] - Class.auraSniper.UPGRADES_TIER_3 = ["auraAssassin", "auraHunter", "auraMinigun", "auraRifle", "auraTwinSniper", "auraAutoSniper", "aurasnipebrid", "auraTrackerSniper", "auraAcid", "auraChiller", "damageAuraSniper", "rangeAuraSniper"] - Class.auraMachineGun.UPGRADES_TIER_3 = ["auraArtillery", "auraMinigun", "auraGunner", "auraSprayer", "auraAutoMach", "auramachbrid", "auraMachinception", "damageAuraMachineGun", "rangeAuraMachineGun"] - Class.auraFlankGuard.UPGRADES_TIER_3 = ["auraHexaTank", "auraTriAngle", "auraAuto3", "auraTrapGuard", "auraTriTrapper", "auraAutoFlank", "auraflankbrid", "auraFlankdue", "auraFlankinception", "auraBackShield", "damageAuraFlankGuard", "rangeAuraFlankGuard"] - Class.auraDirector.UPGRADES_TIER_3 = ["auraOverseer", "auraCruiser", "auraUnderseer", "auraSpawner", "auraDirectdrive", "auraAutoDirector", "damageAuraDirector", "rangeAuraDirector"] - Class.auraPounder.UPGRADES_TIER_3 = ["auraBuilder", "auraArtillery", "auraLauncher", "auraAutoPound", "auraSidewinder", "aurapoundbrid", "auraTailgator", "damageAuraPounder", "rangeAuraPounder"] - Class.auraTrapper.UPGRADES_TIER_3 = ["auraBuilder", "auraTriTrapper", "auraTrapGuard", "auraContagion", "auraAutoTrap", "auratrapbrid", "damageAuraTrapper", "rangeAuraTrapper"] - Class.auraAutoBasic.UPGRADES_TIER_3 = ["auraAutoTwin", "auraAutoSniper", "auraAutoMach", "auraAutoFlank", "auraAutoDirector", "auraAutoPound", "auraAutoTrap", "auraAutoDesmos", "auraautobascrid", "auraAutoLittleHunter", "auraAutoInception", "auraRevolutionist", "auraReverie", "auraBasicCeption", "auraHomingautoBasic", "damageAuraAutoBasic", "rangeAuraAutoBasic"] - Class.auraBascrid.UPGRADES_TIER_3 = ["auratwinbrid", "aurasnipebrid", "auramachbrid", "auraflankbrid", "aurapoundbrid", "auratrapbrid", "auradesmosbrid", "auraautobascrid", "auralittlehunterbrid", "aurainceptionbrid", "jeep", "damageAuraBascrid", "rangeAuraBascrid"] - Class.auraDesmos.UPGRADES_TIER_3 = ["auraSidewinder", "auraHelix", "auraUndertow", "auraRepeater", "auraAutoDesmos", "auradesmosbrid", "damageAuraDesmos", "rangeAuraDesmos"] - Class.auraLittleHunter.UPGRADES_TIER_3 = ["auraMinigun", "auraBinary", "auraHunter", "auraSprayer", "auraContagion", "auraGundirector", "auraBigSubduer", "auraFlankdue", "auraAutoLittleHunter", "auralittlehunterbrid", "damageAuraLittleHunter", "rangeAuraLittleHunter"] - Class.auraInception.UPGRADES_TIER_3 = ["auraMachinception", "auraTailgator", "auraFlankinception", "auraAutoInception", "aurainceptionbrid", "damageAuraInception", "rangeAuraInception"] - Class.auraAuto2.UPGRADES_TIER_3 = ["auraAuto3", "auraRevolutionist", "auraReverie", "auraAutoAuto2", "auraauto2brid", "damageAuraAuto2", "rangeAuraAuto2"] - Class.damageAuraBasic.UPGRADES_TIER_3 = ["damageAuraTwin", "damageAuraSniper", "damageAuraMachineGun", "damageAuraFlankGuard", "damageAuraDirector", "damageAuraPounder", "damageAuraTrapper", "damageAuraAutoBasic", "damageAuraBascrid", "damageAuraDesmos", "damageAuraLittleHunter", "damageAuraInception", "damageAuraAuto2", "moredamageAuraBasic", "damagerangeAuraBasic"] - Class.rangeAuraBasic.UPGRADES_TIER_3 = ["rangeAuraTwin", "rangeAuraSniper", "rangeAuraMachineGun", "rangeAuraFlankGuard", "rangeAuraDirector", "rangeAuraPounder", "rangeAuraTrapper", "rangeAuraAutoBasic", "rangeAuraBascrid", "rangeAuraDesmos", "rangeAuraLittleHunter", "rangeAuraInception", "rangeAuraAuto2", "morerangeAuraBasic", "damagerangeAuraBasic"] - - Class.auto2.UPGRADES_TIER_2 = ["auto3", "revolutionist", "swivel2", "reverie", "autoauto2", "auto2brid", "auraAuto2"] - Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee", "autoAuto3", "auto3brid", "auraAuto3"] - Class.revolutionist.UPGRADES_TIER_3 = ["subverter", "autoRevolutionist", "proton", "pion", "hadron", "equilibrium", "revobrid", "baseThrower", "revodirector", "auraRevolutionist"] - Class.swivel2.UPGRADES_TIER_3 = ["swivel3"] \ No newline at end of file + Class.undertow.UPGRADES_TIER_3 = ["riptide"] + Class.repeater.UPGRADES_TIER_3 = ["iterator", "duplicator"] diff --git a/server/modules/definitions/groups/turrets.js b/server/modules/definitions/groups/turrets.js index c88b37572..e3d95cfb1 100644 --- a/server/modules/definitions/groups/turrets.js +++ b/server/modules/definitions/groups/turrets.js @@ -1,4 +1,4 @@ -const { combineStats, makeDeco, addAura } = require('../facilitators.js'); +const { combineStats, makeDeco } = require('../facilitators.js'); const { gunCalcNames, base } = require('../constants.js'); const g = require('../gunvals.js'); @@ -1269,365 +1269,3 @@ Class.dominationBody = { SHAPE: 6, INDEPENDENT: true } - -//delta turrets -Class.projectileAutoTurret = { - PARENT: "autoTurret", - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret, g.overdrive]), - TYPE: "bullet", - }, - }, - ], -} -Class.homingAutoTurret = { - PARENT: "genericTank", - LABEL: "Turret", - COLOR: "orange", - INDEPENDENT: true, - CONTROLLERS: ['nearestDifferentMaster'], - BODY: { - FOV: 0.8, - }, - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret]), - TYPE: "homingBullet", - COLOR: "orange", - }, - }, - ], -} -Class.ceptionistturret = { - PARENT: "genericTank", - LABEL: "Turret", - COLOR: "darkGray", - BODY: { - FOV: 0.8, - }, - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret]), - TYPE: "ceptionistbullet", - COLOR: "darkGray", - }, - }, - ], -} -Class.fastbigauto4gun = { - PARENT: "auto4gun", - GUNS: [ - { - POSITION: [14, 5, 1, 0, -4.5, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 1.2 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [14, 5, 1, 0, 4.5, 0, 0.33], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 1.2 }]), - TYPE: "bullet", - }, - }, - { - POSITION: [16, 5, 1, 0, 0, 0, 0.67], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 2 }]), - TYPE: "bullet", - }, - }, - ], -} -Class.helecopterblade = { - LABEL: "whatat", - CONTROLLERS: [["spin", { independent: true, speed: 0.16 }]], - COLOR: 16, - // M 0.1 -1.3 C 0.1 -1.4 0.1 -1.5 -0.1 -1.6 L -0.1 -0.3 A 0.5 0.5 -180 0 0 -0.3 -0.1 L -1.3 -0.1 C -1.4 -0.1 -1.5 -0.1 -1.6 0.1 L -0.3 0.1 A 0.5 0.5 -180 0 0 -0.1 0.3 L -0.1 1.3 C -0.1 1.4 -0.1 1.5 0.1 1.6 L 0.1 0.3 A 0.5 0.5 -180 0 0 0.3 0.1 L 1.3 0.1 C 1.4 0.1 1.5 0.1 1.6 -0.1 L 0.3 -0.1 A 0.5 0.5 -180 0 0 0.1 -0.3 Z - SHAPE: "M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.4 0.1 A 0.5 0.5 90 0 0 -0.1 0.4 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.4 A 0.5 0.5 90 0 0 0.4 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.4 -0.1 A 0.5 0.5 90 0 0 0.1 -0.4 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.4 A 0.5 0.5 90 0 0 -0.4 -0.1 Z", - // SHAPE: 'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.5 0.1 A 0.5 0.5 90 0 0 -0.1 0.5 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.5 A 0.5 0.5 90 0 0 0.5 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.5 -0.1 A 0.5 0.5 90 0 0 0.1 -0.5 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.5 A 0.5 0.5 90 0 0 -0.5 -0.1 Z', - INDEPENDENT: true, -}; -Class.helecoptersblade = { - LABEL: "what", - CONTROLLERS: [["spin", { independent: true, speed: 0.16 }]], - COLOR: 16, - SHAPE: "M -0.1 1 C -0.1 1.1 -0.1 1.2 0.1 1.3 L 0.1 0.3 A 0.5 0.5 0 0 0 0.3 0.1 L 1 0.1 C 1.1 0.1 1.2 0.1 1.3 -0.1 L 0.3 -0.1 A 0.5 0.5 0 0 0 0.1 -0.3 L 0.1 -1 C 0.1 -1.1 0.1 -1.2 -0.1 -1.3 L -0.1 -0.3 A 0.5 0.5 0 0 0 -0.3 -0.1 L -1 -0.1 C -1.1 -0.1 -1.2 -0.1 -1.3 0.1 L -0.3 0.1 A 0.5 0.5 0 0 0 -0.1 0.3 Z", - // M 0.1 -1.3 C 0.1 -1.4 0.1 -1.5 -0.1 -1.6 L -0.1 -0.3 A 0.5 0.5 -180 0 0 -0.3 -0.1 L -1.3 -0.1 C -1.4 -0.1 -1.5 -0.1 -1.6 0.1 L -0.3 0.1 A 0.5 0.5 -180 0 0 -0.1 0.3 L -0.1 1.3 C -0.1 1.4 -0.1 1.5 0.1 1.6 L 0.1 0.3 A 0.5 0.5 -180 0 0 0.3 0.1 L 1.3 0.1 C 1.4 0.1 1.5 0.1 1.6 -0.1 L 0.3 -0.1 A 0.5 0.5 -180 0 0 0.1 -0.3 Z - // SHAPE:'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.4 0.1 A 0.5 0.5 90 0 0 -0.1 0.4 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.4 A 0.5 0.5 90 0 0 0.4 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.4 -0.1 A 0.5 0.5 90 0 0 0.1 -0.4 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.4 A 0.5 0.5 90 0 0 -0.4 -0.1 Z', - // SHAPE: 'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.5 0.1 A 0.5 0.5 90 0 0 -0.1 0.5 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.5 A 0.5 0.5 90 0 0 0.5 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.5 -0.1 A 0.5 0.5 90 0 0 0.1 -0.5 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.5 A 0.5 0.5 90 0 0 -0.5 -0.1 Z', - INDEPENDENT: true, -}; -Class.turretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [4.65, 10.5, 0, 90, 220, 1], - TYPE: "revogun", - }, { - POSITION: [4.65, 10.5, 0, 270, 220, 1], - TYPE: "revogun", - }] -}; -Class.turretBasenoguns = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, -}; -Class.grenadeDeco = makeDeco(0); -Class.turretBaseKiva = { - LABEL: "Basethingygygyyasgsdgajskhg", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: "orange",//iT WonT FUckING SpIN - SYNC_TURRET_SKILLS: true, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [4.65, 9.85, 0, 90, 220, 1], - TYPE: ["revogun", { COLOR: "orange" }] - }, { - POSITION: [4.65, 9.85, 0, 270, 220, 1], - TYPE: ["revogun", { COLOR: "orange" }] - }] -}; -Class.hadronturretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 'red', - CONTROLLERS: ["hadron"], - TURRETS: [{ - POSITION: [4.65, 10.5, 0, 90, 220, 1], - TYPE: "revogun", - }, { - POSITION: [4.65, 10.5, 0, 270, 220, 1], - TYPE: "revogun", - }] -}; -Class.subverterturretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [4.65, 10.5, 0, 90, 220, 1], - TYPE: "revogun", - }, { - POSITION: [4.65, 10.5, 0, 180, 220, 1], - TYPE: "revogun", - }, { - POSITION: [4.65, 10.5, 0, 270, 220, 1], - TYPE: "revogun", - }, { - POSITION: [4.65, 10.5, 0, 0, 220, 1], - TYPE: "revogun", - }] -}; -Class.protonturretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [5, 10.5, 0, 0, 220, 1], - TYPE: ["revosheild", { SHAPE: 12 }], - VULNERABLE: true, - - }, { - POSITION: [5, 10.5, 0, 360/3, 220, 1], - TYPE: ["revosheild", { SHAPE: 12 }], - VULNERABLE: true, - - }, { - POSITION: [5, 10.5, 0, 360/3*2, 220, 1], - TYPE: ["revosheild", { SHAPE: 12 }], - VULNERABLE: true, - }] -}; -Class.pionturretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [5, 10.5, 0, 90, 220, 1], - TYPE: ["revosheild", { SHAPE: 12 }], - VULNERABLE: true, - }, { - POSITION: [5, 10.5, 0, 270, 220, 1], - TYPE: ["revosheild", { SHAPE: 12 }], - VULNERABLE: true, - }] -}; -Class.revogun = { - LABEL: 'Auto Turret', - SYNCS_SKILLS: true, - BODY: { - FOV: 1 - }, - COLOR: 16, - CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], - GUNS: [{ - POSITION: [13.5, 10, 1, 8, 0, 0, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.halfreload]), - TYPE: "bullet" - } - } - ] -} -Class.revosheild = { - PARENT: "genericTank", - DAMAGE_CLASS: 1, - TYPE: "shield", - COLOR: "darkGray", - SHAPE: 0, - INDEPENDENT: true, - BODY: { - PUSHABILITY: 0, - HEALTH: 10000, - SHIELD: 10000, - REGEN: 1000, - DAMAGE: 1, - RESIST: 100, - STEALTH: 1, - DENSITY: 10000, - }, -} -Class.backshieldturret = { - PARENT: "genericTank", - TYPE: "shield", - DAMAGE_CLASS: 1, - SHAPE: "m -0.702 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099", - COLOR: "#FF7F00", - INDEPENDENT: true, - BODY: { - HEALTH: 10000, - SHIELD: 10000, - REGEN: 1000, - }, -} -Class.mirrorDeco = makeDeco("M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -0.9 A 0.001 0.001 0 0 1 0 0.9 A 0.001 0.001 0 0 1 0 -0.9") -Class.mirrorbackshieldturret = { - PARENT: "genericTank", - TYPE: "shield", - INDEPENDENT: true, - BODY: { - HEALTH: 10000, - SHIELD: 10000, - REGEN: 1000, - }, - SHAPE: "m -0.7020 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099", - COLOR: "#FF7F00", - TURRETS: [{ - POSITION: [5.7, 0, 0, 0, 360, 1], - TYPE: "mirrorDeco" - }] -} -// The sheild uses the hitbox like an aura, but it can hit bullets -Class.autoTurretNerf = { - PARENT: "genericTank", - LABEL: "Turret", - BODY: { - FOV: 0.8, - }, - COLOR: "grey", - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.weak, g.fake, g.basic, g.morerecoil, g.turret, g.autoTurret]), - TYPE: "bullet", - }, - }, - ], -} -Class.mindindicator = { - SHAPE: 'M 0 -1.0 A 1 1 0 0 0 0 1.0 A 1 1 0 0 0 0 -1.0 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, -}; -Class.crosshair1 = { - SHAPE: 'M 0 0 l 1 0 L 0 0 L -1 0 L 0 0 L 0 1 L 0 -1', - COLOR: 9, -}; -Class.greenSmasherBody = { - LABEL: "", - GLOW: { - RADIUS: 2, - COLOR: "green", - ALPHA: 1, - RECURSION: 4, - }, - CONTROLLERS: [["spin", { independent: true, speed: 0.1 }]], - COLOR: "green", - SHAPE: 6, - INDEPENDENT: true, - BORDERLESS: true, -} -Class.droneturretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - SYNC_TURRET_SKILLS: true, - TURRETS: [{ - POSITION: [4.65, 10.5, 0, 90, 220, 1], - TYPE: "droneAutoTurret", - }, { - POSITION: [4.65, 10.5, 0, 270, 220, 1], - TYPE: "droneAutoTurret", - }] -} -Class.dualAutoTankGun = { - TURRETS: [{ - POSITION: [11, 0, 0, 0, 190, 0], - TYPE: "autoTankGun" - }, { - POSITION: [11, 0, 0, 180, 190, 0], - TYPE: "autoTankGun" - }] -} -Class.swivelAutoTankGun = { - PARENT: "genericTank", - LABEL: "", - BODY: { - FOV: 3, - }, - CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], - COLOR: "grey", - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret, g.slightlyweaker]), - TYPE: "bullet", - }, - }, - ], -} -Class.skaterDeco = makeDeco("M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1"); -Class.skaterDeco.STROKE_WIDTH = 2; -Class.switcherDeco = makeDeco('M 0 0 M 2 -1 L -2 -1 L -2 8 L -1 8 L 1 8 L 2 8') -Class.effectBulletDeco = makeDeco(0) -Class.firecrackerDeco = makeDeco(-6) -Class.auraDamageGen = addAura(4.5, 1.3, 0.3, "red"); -Class.auraRangeGen = addAura(3, 1.8, 0.3, "teal", "rangeAuraSymbol"); -Class.auraDamageRangeGen = addAura(4.5, 1.8, 0.3, "red", "rangeAuraSymbol"); -Class.auraMoreDamageGen = addAura(6, 1.3, 0.3, "orange"); -Class.auraMoreRangeGen = addAura(3, 2.3, 0.3, "aqua", "rangeAuraSymbol"); \ No newline at end of file diff --git a/server/modules/definitions/gunvals.js b/server/modules/definitions/gunvals.js index de37a1830..fd4d5850b 100644 --- a/server/modules/definitions/gunvals.js +++ b/server/modules/definitions/gunvals.js @@ -19,7 +19,6 @@ module.exports = { triplet: { reload: 1.2, recoil: 0.667, shudder: 0.9, health: 0.85, damage: 0.85, pen: 0.9, density: 1.1, spray: 0.9, resist: 0.95 }, turret: { reload: 2, health: 0.8, damage: 0.6, pen: 0.7, density: 0.1 }, autoTurret: { reload: 0.9, recoil: 0.75, shudder: 0.5, size: 0.8, health: 0.9, damage: 0.6, pen: 1.2, speed: 1.1, range: 0.8, density: 1.3, resist: 1.25 }, - littleHunter: { recoil: 0.9, shudder: 0.9, health: 0.9, damage: 0.7, pen: 0.9 }, // Snipers sniper: { reload: 1.35, shudder: 0.25, damage: 0.8, pen: 1.1, speed: 1.5, maxSpeed: 1.5, density: 1.5, spray: 0.2, resist: 1.15 }, @@ -30,7 +29,6 @@ module.exports = { predator: { reload: 1.4, size: 0.8, health: 1.5, damage: 0.9, pen: 1.2, speed: 0.9, maxSpeed: 0.9 }, dual: { reload: 2, shudder: 0.8, health: 1.5, speed: 1.3, maxSpeed: 1.1, resist: 1.25 }, rifle: { reload: 0.8, recoil: 0.8, shudder: 1.5, health: 0.8, damage: 0.8, pen: 0.9, spray: 2 }, - railgun: { reload: 2, health: 0.85, damage: 0.5, pen: 0.9 }, // Machine guns machineGun: { reload: 0.5, recoil: 0.8, shudder: 1.7, health: 0.7, damage: 0.7, maxSpeed: 0.8, spray: 2.5 }, @@ -69,7 +67,6 @@ module.exports = { bigCheese: { reload: 1.5, size: 1.8, health: 2.5, speed: 1.25 }, mothership: { reload: 1.25, pen: 1.1, speed: 0.775, maxSpeed: 0.8, range: 15, resist: 1.15 }, satellite: { size: 0.8, reload: 3, damage: 1.875 }, - contagi: { reload: 1, recoil: 0.5, shudder: 1.5, size: 1, health: 0.6, damage: 0.6, pen: 0.75, speed: 1.05, maxSpeed: 1, range: 1, density: 0.9, spray: 0.75, resist: 0.7 }, // Heavy cannons pounder: { reload: 2, recoil: 1.6, damage: 2, speed: 0.85, maxSpeed: 0.8, density: 1.5, resist: 1.15 }, @@ -80,7 +77,7 @@ module.exports = { mortar: { reload: 1.2, health: 1.1, speed: 0.8, maxSpeed: 0.8 }, shotgun: { reload: 8, recoil: 0.4, size: 1.5, damage: 0.4, pen: 0.8, speed: 1.8, maxSpeed: 0.6, density: 1.2, spray: 1.2 }, destroyerDominator: { reload: 6.5, recoil: 0, size: 0.975, health: 6, damage: 6, pen: 6, speed: 0.575, maxSpeed: 0.475, spray: 0.5 }, - + // Missiles launcher: { reload: 1.5, recoil: 1.5, shudder: 0.1, size: 0.72, health: 1.05, damage: 0.925, speed: 0.9, maxSpeed: 1.2, range: 1.1, resist: 1.5 }, skimmer: { recoil: 0.8, shudder: 0.8, size: 0.9, health: 1.35, damage: 0.8, pen: 2, speed: 0.85, maxSpeed: 0.85, resist: 1.1 }, @@ -103,68 +100,12 @@ module.exports = { blank: { reload: 1, recoil: 1, shudder: 1, size: 1, health: 1, damage: 1, pen: 1, speed: 1, maxSpeed: 1, range: 1, density: 1, spray: 1, resist: 1 }, weak: { reload: 2, health: 0.6, damage: 0.6, pen: 0.8, speed: 0.5, maxSpeed: 0.7, range: 0.25, density: 0.3 }, power: { shudder: 0.6, size: 1.2, pen: 1.25, speed: 2, maxSpeed: 1.7, density: 2, spray: 0.5, resist: 1.5 }, - fake: { recoil: 0.00001, size: 0.00001, health: 0.0001, speed: 0, maxSpeed: 0, shudder: 0, spray: 0, recoil: 0, range: 0 }, + fake: { size: 0.00001, health: 0.0001, speed: 0, maxSpeed: 0, shudder: 0, spray: 0, recoil: 0, range: 0 }, op: { reload: 0.5, recoil: 1.3, health: 4, damage: 4, pen: 4, speed: 3, maxSpeed: 2, density: 5, spray: 2 }, arenaCloser: { reload: 1.25, recoil: 0.25, health: 1000, damage: 1000, pen: 1000, speed: 2.5, maxSpeed: 2.25, range: 1.4, density: 4, spray: 0.25 }, healer: { damage: -1, speed: 0.5, maxSpeed: 0.5, recoil: 0.5 }, lowPower: { shudder: 2, health: 0.5, damage: 0.5, pen: 0.7, spray: 0.5, resist: 0.7 }, - aura: { reload: 0.001, recoil: 0.001, shudder: 0.001, size: 6, speed: 0.001, maxSpeed: 0.001, spray: 0.001 }, - noSpread: { shudder: 0, spray: 0 }, - lessspread: { shudder: 0.75, spread: 0.75 }, - - // Range - doublerange: { range: 2 }, - morerange: { range: 1.15 }, halfrange: { range: 0.5 }, - norange: { range: 0.2 }, - literallynorange: { range: 0 }, - - // Recoil - tonsmorerecoil: { recoil: 4 }, - lotsmorrecoil: { recoil: 1.8 }, - muchmorerecoil: { recoil: 1.35 }, - morerecoil: { recoil: 1.15 }, - lessrecoil: { recoil: 0.65 }, - halfrecoil: { recoil: 0.5 }, - - // Reload - halfreload: { reload: 2 }, - lessreload: { reload: 1.5 }, - one_third_reload: { reload: 1.333 }, - bitlessreload: { reload: 0.9 }, - morereload: { reload: 0.75 }, - doublereload: { reload: 0.5 }, - triplereload: { reload: 1/3 }, - - // Speed - fast: { speed: 1.2 }, - veryfast: { speed: 2.5 }, - morespeed: { speed: 1.3, maxSpeed: 1.3 }, - bitlessspeed: { speed: 0.93, maxSpeed: 0.93 }, - slow: { speed: 0.7, maxSpeed: 0.7 }, - halfspeed: { speed: 0.5, maxSpeed: 0.5 }, - nomove: { speed: 0, maxSpeed: 0 }, - - // Misc 2 - lancer: { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1 }, - celeslower: { size: 0.5 }, - notdense: { density: 0.1 }, - acc: { shudder: 0.1 }, - fakewithrecoil: { recoil: 1, size: 0.00001, health: 0.0001, speed: 0.00001, maxSpeed: 2, range: 0 }, - halfdamage: { damage: 0.5 }, - halfpen: { pen: 0.5 }, - kiva: { damage: 0.3, pen: 2.2 }, - shockwave: { damage: 5, pen: 5 }, - xtrahealth: { health: 5 }, - xxtrahealth: { health: 999 }, - lance: { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1, pen: 0.9, damage: 0.9, health: 0.75 }, - shield: { reload: 4, recoil: 0, shudder: 0.1, size: 4, health: 387420489, damage: 0, pen: 0.9, speed: 0.7, maxSpeed: 1, range: 0.02, density: 3387420489, spray: 1, resist: 9 }, - lesspower: { reload: 1, recoil: 1, shudder: 1, size: 1, health: .9, damage: .9, pen: .9, speed: 1, maxSpeed: 1, range: 1, density: 1, spray: 1, resist: 1 }, - slightlyweaker: { health: 0.8, damage: 0.8, pen: 0.8 }, - grenade_explosion: { reload: 8, recoil: 0, shudder: 4.25, size: 2, health: 2.25, damage: 1.75, pen: 1.5, speed: 1.35, maxSpeed: 1, range: 1, density: 1, spray: 4, resist: 1 }, - literallyamachinegun: { reload: 0.2, speed: 5, maxSpeed: 5, spray: 0.3, shudder: 0.6 }, - rainmaker: { speed: 0.03, maxSpeed: 0.5, health: 0.9, damage: 0.85, pen: 1 }, - acceltospeedoflight: { speed: 0.001, maxSpeed: 1000 }, - explosion: { speed: 0.01, maxSpeed: 0.01, health: 5, damage: 4, pen: 5, density: 3.7, resist: 3 }, - brella: { reload: 2.5, health: 35, pen: 0, damage: 0.2, density: 1, resist: 1, speed: 1, maxSpeed: 0.8, spray: 0, range: 2.25, size: 2.4, shudder: 0.1 } + aura: { reload: 0.001, recoil: 0.001, shudder: 0.001, size: 6, speed: 0.001, maxSpeed: 0.001, spray: 0.001 }, + noSpread: { shudder: 0, spray: 0 } } \ No newline at end of file diff --git a/server/modules/global.js b/server/modules/global.js index 7a7ddee20..bb0c618fc 100644 --- a/server/modules/global.js +++ b/server/modules/global.js @@ -8,7 +8,6 @@ global.protocol = require(".././lib/fasttalk.js"); // Global Variables (These must come before we import from the modules folder.) global.fps = "Unknown"; -global.playerskin = ""; global.minimap = []; global.entities = []; global.walls = []; @@ -18,9 +17,6 @@ global.entitiesToAvoid = []; global.grid = new hshg.HSHG(); global.arenaClosed = false; global.mockupsLoaded = false; -const d = new Date(); -global.dayofweek = d.getUTCDay(); -global.cangrappleonceagain = "yes" global.loadedAddons = []; global.TEAM_BLUE = -1; @@ -145,6 +141,7 @@ global.makeHitbox = wall => { Math.atan2( _size, 0 - _size) + wall.angle ], distance = Math.sqrt(_size ** 2 + _size ** 2); + //convert 4 corners into 4 lines for (let i = 0; i < 4; i++) { relativeCorners[i] = { @@ -152,6 +149,7 @@ global.makeHitbox = wall => { y: distance * Math.cos(relativeCorners[i]) }; } + wall.hitbox = [ [relativeCorners[0], relativeCorners[1]], [relativeCorners[1], relativeCorners[2]], @@ -196,4 +194,4 @@ for (let file of requires) { } } -module.exports = { creationDate: new Date() }; \ No newline at end of file +module.exports = { creationDate: new Date() }; diff --git a/server/modules/live/controllers.js b/server/modules/live/controllers.js index 67f38b96e..c35c02960 100644 --- a/server/modules/live/controllers.js +++ b/server/modules/live/controllers.js @@ -152,7 +152,7 @@ class io_moveInCircles extends IO { this.timer = ran.irandom(10) + 3 this.goal = { x: this.body.x + 10 * Math.cos(-this.body.facing), - y: this.body.y + 10 * Math.sin(-this.body.facing), + y: this.body.y + 10 * Math.sin(-this.body.facing) } } think() { @@ -160,7 +160,7 @@ class io_moveInCircles extends IO { this.timer = 10 this.goal = { x: this.body.x + 10 * Math.cos(-this.body.facing), - y: this.body.y + 10 * Math.sin(-this.body.facing), + y: this.body.y + 10 * Math.sin(-this.body.facing) } } return { @@ -574,24 +574,18 @@ class io_avoid extends IO { super(body) } think(input) { - let masterId = this.body.master.id - let range = this.body.size * this.body.size * 100 - this.avoid = nearest(entities, { - x: this.body.x, - y: this.body.y - }, function (test, sqrdst) { - return (test.master.id !== masterId && (test.type === 'bullet' || test.type === 'drone' || test.type === 'swarm' || test.type === 'satellite' || test.type === 'trap' || test.type === 'block') && sqrdst < range); - }) + let range = (this.body.size ** 2) * 100 + this.avoid = nearest(entities, this.body, (test, sqrdst) => test.team !== this.body.team && (test.type === 'bullet' || test.type === 'drone' || test.type === 'swarm' || test.type === 'satellite' || test.type === 'trap' || test.type === 'block') && sqrdst < range) // Aim at that target if (this.avoid != null) { // Consider how fast it's moving. let delt = new Vector(this.body.velocity.x - this.avoid.velocity.x, this.body.velocity.y - this.avoid.velocity.y) let diff = new Vector(this.avoid.x - this.body.x, this.avoid.y - this.body.y); - let comp = (delt.x * diff.x + delt.y * diff.y) / delt.length / diff.length + let comp = (delt.x * diff.x + delt.y * diff.y) / (delt.length * diff.length) let goal = {} if (comp > 0) { if (input.goal) { - let goalDist = Math.sqrt(range / (input.goal.x * input.goal.x + input.goal.y * input.goal.y)) + let goalDist = Math.sqrt(range / (input.goal.x ** 2 + input.goal.y ** 2)) goal = { x: input.goal.x * goalDist - diff.x * comp, y: input.goal.y * goalDist - diff.y * comp, @@ -609,7 +603,7 @@ class io_avoid extends IO { } class io_minion extends IO { constructor(body, opts = {}) { - super(body) + super(body); this.turnwise = 1; this.leashRange = opts.leash ?? 82; this.orbitRange = opts.orbit ?? 140; @@ -741,6 +735,7 @@ class io_spin2 extends IO { this.reverseOnAlt = opts.reverseOnAlt ?? true; this.lastAlt = -1; this.reverseOnTheFly = opts.reverseOnTheFly ?? false; + // On spawn logic let alt = this.body.master.control.alt; let reverse = (this.reverseOnAlt && alt) ? -1 : 1; @@ -748,6 +743,7 @@ class io_spin2 extends IO { } think(input) { if (!this.reverseOnTheFly) return; + // Live logic let alt = this.body.master.control.alt; if (this.lastAlt != alt) { @@ -840,7 +836,7 @@ class io_formulaTarget extends IO { // if (this.updateOriginAngle) { // this.originAngle = this.masterAngle ? b.master.facing : getTheGunThatSpawnedMe("how do i do that????").angle; // } - + let angle = this.originAngle + this.formula(this.frame += 1 / c.runSpeed, this.body); return { goal: { @@ -881,80 +877,6 @@ class io_whirlwind extends IO { this.body.inverseDist = Math.min(trueMaxDistance, Math.max(trueMinDistance, this.body.inverseDist)); } } -class io_hadron extends IO { - constructor(b, opts = {}) { - super(b) - this.a = opts.startAngle || 0; - this.speed = opts.speed ?? 0.04; - this.onlyWhenIdle = opts.onlyWhenIdle; - this.independent = opts.independent; - } - think(input) { - if (input.alt){ - if (this.onlyWhenIdle && input.target) { - this.a = Math.atan2(input.target.y, input.target.x); - return input; - } - this.a -= this.speed / c.runSpeed; - let offset = (this.independent && this.body.bond != null) ? this.body.bound.angle : 0; - return { - target: { - x: Math.cos(this.a - offset), - y: Math.sin(this.a - offset) - }, - main: true, - }; - } else { - if (this.onlyWhenIdle && input.target) { - this.a = Math.atan2(input.target.y, input.target.x); - return input; - } - this.a += this.speed / c.runSpeed; - let offset = (this.independent && this.body.bond != null) ? this.body.bound.angle : 0; - return { - target: { - x: Math.cos(this.a + offset), - y: Math.sin(this.a + offset), - }, - main: true, - }; - } - } -} -class io_AimAssist extends IO { - constructor(body) { - super(body); - } - think(input) { - this.body.velocity.x = 0; - this.body.velocity.y = 0; - if (!input.fire && !input.target) { - this.body.x = this.body.source.x; - this.body.y = this.body.source.y; - } - if (input.fire && input.target) { - this.body.x = this.body.x + input.target.x; - this.body.y = this.body.y + input.target.y; - } - // else if (input.alt) { - // if(this.body.dist >= 75) this.body.dist -= this.radiusScalingSpeed - // } - } -} -/*class io_AimAssistLock extends IO { - constructor(body) { - super(body) - } - think(input) { - if (!input.alt && input.target) { - this.body.x = this.body.x + input.target.x; - this.body.y = this.body.y + input.target.y; - } - // else if (input.alt) { - // if(this.body.dist >= 75) this.body.dist -= this.radiusScalingSpeed - // } - } -}*/ class io_orbit extends IO { constructor(body, opts = {}) { super(body); @@ -980,11 +902,13 @@ class io_orbit extends IO { this.body.facing = angle; } } + class io_disableOnOverride extends IO { constructor(body) { super(body); this.pacify = false; this.lastPacify = false; + this.savedDamage = 0; } think(input) { @@ -996,11 +920,12 @@ class io_disableOnOverride extends IO { this.pacify = (this.body.parent.master.autoOverride || this.body.parent.master.master.autoOverride); if (this.pacify && !this.lastPacify) { this.targetAlpha = 0; - this.body.pacify = true; + this.savedDamage = this.body.DAMAGE; + this.body.DAMAGE = 0; this.body.refreshBodyAttributes(); } else if (!this.pacify && this.lastPacify) { this.targetAlpha = this.initialAlpha; - this.body.pacify = false; + this.body.DAMAGE = this.savedDamage; this.body.refreshBodyAttributes(); } this.lastPacify = this.pacify; @@ -1012,6 +937,26 @@ class io_disableOnOverride extends IO { } } +class io_scaleWithMaster extends IO { + constructor(body) { + super(body); + let handler = ({body: b}) => { + this.sizeFactor = b.size / b.master.size; + }; + this.body.definitionEvents.push({ event: 'define', handler, once: false }); + this.body.on('define', handler, false); + + this.storedSize = 0; + } + think(input) { + let masterSize = this.body.master.size; + if (masterSize != this.storedSize) { + this.storedSize = masterSize; + this.body.SIZE = masterSize * this.sizeFactor; + } + } +} + let ioTypes = { //misc zoom: io_zoom, @@ -1022,13 +967,12 @@ let ioTypes = { mapFireToAlt: io_mapFireToAlt, whirlwind: io_whirlwind, disableOnOverride: io_disableOnOverride, + scaleWithMaster: io_scaleWithMaster, //aiming related stackGuns: io_stackGuns, - nearestDifferentMaster: io_nearestDifferentMaster, + nearestDifferentMaster: io_nearestDifferentMaster, targetSelf: io_targetSelf, - hadron: io_hadron, - AimAssist: io_AimAssist, onlyAcceptInArc: io_onlyAcceptInArc, spin: io_spin, spin2: io_spin2, diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index d013b25ed..9452360c6 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -287,19 +287,6 @@ class Gun extends EventEmitter { child.refreshBodyAttributes(); } } - } - syncTurretSkills() { - if (this.syncTurretSkills) { - let self = this; - for (let i = 0; i < this.turret.length; i++) { - let turret = this.turrets[i]; - turret.define({ - BODY: self.interpret(), - SKILL: self.getSkillRaw(), - }); - turret.refreshBodyAttributes(); - } - } } fire(gx, gy, sk) { // Recoil @@ -336,7 +323,7 @@ class Gun extends EventEmitter { } } - //create an independent entity + //create an independent entity if (this.independentChildren) { var o = new Entity({ x: this.body.x + this.body.size * gx - s.x, @@ -704,6 +691,7 @@ class Prop { this.borderless = false; this.drawFill = true; this.strokeWidth = 1; + // Bind prop this.bond = bond; this.bond.props.push(this); @@ -744,6 +732,7 @@ class Prop { } define(def) { let set = ensureIsClass(def); + if (set.PARENT != null) { if (Array.isArray(set.PARENT)) { for (let i = 0; i < set.PARENT.length; i++) { @@ -1222,7 +1211,6 @@ class Entity extends EventEmitter { } for (let child of this.children) child.team = set.TEAM } - if (set.SYNC_TURRET_SKILLS != null) this.syncTurretSkills = set.SYNC_TURRET_SKILLS; if (set.VARIES_IN_SIZE != null) { this.settings.variesInSize = set.VARIES_IN_SIZE; this.squiggle = this.settings.variesInSize ? ran.randomRange(0.8, 1.2) : 1; @@ -1378,6 +1366,7 @@ class Entity extends EventEmitter { } } } + if (set.ON != null) { for (let { event, handler, once = false } of set.ON) { this.definitionEvents.push({ event, handler, once }); @@ -1493,7 +1482,7 @@ class Entity extends EventEmitter { } } } - if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; + if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; if (Array.isArray(this.rerootUpgradeTree)) { let finalRoot = ""; for (let root of this.rerootUpgradeTree) finalRoot += root + "\\/"; @@ -1588,7 +1577,7 @@ class Entity extends EventEmitter { this.health.set(((this.settings.healthWithLevel ? 2 * this.level : 0) + this.HEALTH) * this.skill.hlt * healthMultiplier); this.health.resist = 1 - 1 / Math.max(1, this.RESIST + this.skill.brst); this.shield.set(((this.settings.healthWithLevel ? 0.6 * this.level : 0) + this.SHIELD) * this.skill.shi, Math.max(0, ((this.settings.healthWithLevel ? 0.006 * this.level : 0) + 1) * this.REGEN * this.skill.rgn * regenMultiplier)); - this.damage = damageMultiplier * this.DAMAGE * this.skill.atk * !this.pacify; + this.damage = damageMultiplier * this.DAMAGE * this.skill.atk; this.penetration = penetrationMultiplier * (this.PENETRATION + 1.5 * (this.skill.brst + 0.8 * (this.skill.atk - 1))); if (!this.settings.dieAtRange || !this.range) this.range = rangeMultiplier * this.RANGE; this.fov = fovMultiplier * this.FOV * 275 * Math.sqrt(this.size); @@ -1641,7 +1630,7 @@ class Entity extends EventEmitter { // Initalize. this.activation.update(); this.facing = this.bond.facing + this.bound.angle; - if (this.facingType[0].includes('Target')) { + if (this.facingType[0].includes('Target') || this.facingType[0].includes('Speed')) { this.facingType = ["bound", {}]; } this.motionType = ["bound", {}]; @@ -1746,7 +1735,11 @@ class Entity extends EventEmitter { } this.emit("upgrade", { body: this }); if (this.color.base == '-1' || this.color.base == 'mirror') { - this.color.base = getTeamColor((c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) ? TEAM_RED : this.team); + if (c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) { + this.color.base = this.isBot ? "darkGrey" : getTeamColor(TEAM_RED); + } else { + this.color.base = getTeamColor(this.team); + } } this.sendMessage("You have upgraded to " + this.label + "."); for (let def of this.defs) { @@ -1804,12 +1797,6 @@ class Entity extends EventEmitter { case "fastgrow": this.SIZE += args.growSpeed ?? 5; break; - case "fuckingnuclearbomb": - this.SIZE += args.growSpeed ?? 10; - break; - case "trappershockwave": - this.SIZE += args.growSpeed ?? 20; - break; case "glide": this.maxSpeed = this.topSpeed; this.damp = args.damp ?? 0.05; @@ -1837,20 +1824,6 @@ class Entity extends EventEmitter { this.maxSpeed = this.topSpeed; this.damp = args.damo ?? -0.025; break; - case "accelerate": - this.velocity.x = this.velocity.x + (4.5 * Math.cos(this.facing)) - this.velocity.y = this.velocity.y + (4.5 * Math.sin(this.facing)) - this.topSpeed += 10; - this.maxSpeed += 10; - this.damp = -0.0125; - break; - case "acceleratetothespeedoflight": - this.velocity.x = this.velocity.x + ((1 * this.maxSpeed + 0.5) * Math.cos(this.facing)) - this.velocity.y = this.velocity.y + ((1 * this.maxSpeed + 0.5) * Math.sin(this.facing)) - this.topSpeed += 0.5; - this.maxSpeed += 0.5; - this.damp = -0.0001; - break; case "swarm": this.maxSpeed = this.topSpeed; let l = @@ -1898,20 +1871,6 @@ class Entity extends EventEmitter { this.maxSpeed = 0; } break; - case "aimassist": - this.x = this.source.x + this.master.control.target.x; - this.y = this.source.y + this.master.control.target.y; - this.velocity.x = this.source.velocity.x; - this.velocity.y = this.source.velocity.y; - break; - case "aimassistlock": - if (!this.control.alt) { - this.x = this.source.x + this.master.control.target.x; - this.y = this.source.y + this.master.control.target.y; - this.velocity.x = this.source.velocity.x; - this.velocity.y = this.source.velocity.y; - }; - break; case "drift": this.maxSpeed = 0; engine = { @@ -1954,22 +1913,22 @@ class Entity extends EventEmitter { y: this.master.y, }; let target = { - x: save.x + this.master.control.target.x, - y: save.y + this.master.control.target.y, + x: this.master.x + this.master.control.target.x, + y: this.master.y + this.master.control.target.y, }; - let amount = (util.getDistance(target, save) / 10) | 0; this.damp = 0; + let amount = (util.getDistance(target, save) / 100) | 0; + //sockets.broadcast(this.velocity.x.toString()) if (this.waveReversed == null) this.waveReversed = this.master.control.alt ? -1 : 1; if (this.waveAngle == null) { this.waveAngle = this.master.facing; - this.velocity.x = this.velocity.length + amount * Math.cos(this.waveAngle); - this.velocity.y = this.velocity.length * Math.sin(this.waveAngle); + this.velocity.x = ((5 + this.velocity.length * (amount + 2)) * Math.cos(this.waveAngle)) / 7; + this.velocity.y = ((5 + this.velocity.length * (amount + 2)) * Math.sin(this.waveAngle)) / 7; } let waveX = this.maxSpeed * 5 * Math.cos((this.RANGE - this.range) / (args.period ?? 4) * 2); let waveY = (args.amplitude ?? 15) * Math.cos((this.RANGE - this.range) / (args.period ?? 4)) * this.waveReversed * (args.invert ? -1 : 1); this.x += Math.cos(this.waveAngle) * waveX - Math.sin(this.waveAngle) * waveY; this.y += Math.sin(this.waveAngle) * waveX + Math.cos(this.waveAngle) * waveY; break; - } this.accel.x += engine.x * this.control.power; this.accel.y += engine.y * this.control.power; @@ -2129,11 +2088,10 @@ class Entity extends EventEmitter { } } contemplationOfMortality() { - if (this.invuln || this.godmode) { + if (this.invuln) { this.damageReceived = 0; return 0; } - if (this.damageReceived > 0) { let damageInflictor = [] let damageTool = [] @@ -2227,7 +2185,6 @@ class Entity extends EventEmitter { killers = killers.filter((elem, index, self) => index == self.indexOf(elem)); this.emit('death', { body: this, killers, killTools }); killers.forEach((e) => e.emit('kill', { body: e, entity: this })); - // If there's no valid killers (you were killed by food), change the message to be more passive let killText = notJustFood ? "" : "You have been killed by ", dothISendAText = this.settings.givesKillMessage; @@ -2238,20 +2195,11 @@ class Entity extends EventEmitter { switch (this.type) { case "tank": killers.length > 1 ? instance.killCount.assists++ : instance.killCount.solo++; - if (instance.killCount.solo == 5) { - if (instance.socket) instance.socket.talk("achieve", 0); - }; - if (instance.killCount.solo == 10) { - if (instance.socket) instance.socket.talk("achieve", 1); - sockets.broadcast(instance.name + " is on a kill streak of 10!"); - }; - if (instance.socket) instance.socket.talk("killgained"); break; case "food": case "crasher": instance.killCount.polygons++; - if (instance.socket) instance.socket.talk("shapegained"); break case "miniboss": @@ -2300,6 +2248,7 @@ class Entity extends EventEmitter { } sockets.broadcast(text); } + // instead of "a Machine Gunner Bullet and a Machine Gunner Bullet and a Machine Gunner Bullet", // make it say " 3 Machine Gunner Bullets" let killCounts = {}; @@ -2312,6 +2261,7 @@ class Entity extends EventEmitter { killText += (killCounts[killCountEntries[i]] == 1) ? util.addArticle(killTools[i].label) : killCounts[killCountEntries[i]] + ' ' + killCountEntries[i] + 's'; killText += i < killCountEntries.length - 2 ? ', ' : ' and '; } + // Prepare it and clear the collision array. killText = killText.slice(0, -5); if (killText === "You have been kille") { diff --git a/server/modules/network/sockets.js b/server/modules/network/sockets.js index 7390ff54b..c1739bb8e 100644 --- a/server/modules/network/sockets.js +++ b/server/modules/network/sockets.js @@ -136,9 +136,6 @@ function incoming(message, socket) { util.log("[INFO] A socket was verified with the token: " + key); } else { util.log("[WARNING] A socket failed to verify with the token: " + key); - if (key !== "") { - socket.talk("achieve", 2); - } } socket.key = key; } @@ -151,15 +148,14 @@ function incoming(message, socket) { socket.kick("Trying to spawn while already alive."); return 1; } - if (m.length !== 4) { - socket.kick("Ill-sized spawn request." + global.playerskin + m.length); + if (m.length !== 3) { + socket.kick("Ill-sized spawn request."); return 1; } // Get data let name = m[0].replace(c.BANNED_CHARACTERS_REGEX, ""); let needsRoom = m[1]; let autoLVLup = m[2]; - global.playerskin = m[3].replace(name, ""); // Verify it if (typeof name != "string") { socket.kick("Bad spawn request name."); @@ -441,171 +437,6 @@ function incoming(message, socket) { player.body.destroy(); } break; - case "testTeleport": - if (player.body != null && socket.permissions) { - player.body.x = player.body.x + player.target.x; - player.body.y = player.body.y + player.target.y; - } - break; - case "smallerTank": - if (player.body != null && socket.permissions) { - player.body.SIZE *= 4/5; - player.body.RECOIL_MULTIPLIER *= 4/5; - } - break; - case "biggerTank": - if (player.body != null && socket.permissions) { - player.body.SIZE *= 5/4; - player.body.RECOIL_MULTIPLIER *= 5/4; - } - break; - case "smallerFOV": - if (player.body != null && socket.permissions) { - player.body.FOV *= 4/5 - } - break; - case "biggerFOV": - if (player.body != null && socket.permissions) { - player.body.FOV *= 5/4 - } - break; - case "godmodeButton": - if (player.body != null && socket.permissions) { - player.body.godmode = !player.body.godmode; - player.body.sendMessage((player.body.godmode ? "Godmode enabled." : "Godmode disabled.")); - } - break; - case "invisibility": - if (player.body != null && socket.permissions) { - player.body.alpha = !player.body.alpha; - player.body.invisible = [player.body.alpha, !player.body.alpha] - } - break; - case "canBeOnLeaderboard": - if (player.body != null && socket.permissions) { - player.body.settings.leaderboardable = !player.body.settings.leaderboardable; - player.body.sendMessage((player.body.settings.leaderboardable ? "You have been added to the leaderboard" : "You have been removed from the leaderboard.")); - } - break; - case "keyStrong"://keyStrong - if (player.body != null && socket.permissions) { - player.body.skill.raw = Array(10).fill(12); - player.body.define({ - SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], - }); - } - break; - case "drag": { // drag - if (player.body != null && socket.permissions) { - if (!player.pickedUpInterval) { - let tx = player.body.x + player.target.x; - let ty = player.body.y + player.target.y; - let pickedUp = []; - entities.forEach(e => { - if (!(e.type === "mazeWall" && e.shape === 4) && (e.x - tx) * (e.x - tx) + (e.y - ty) * (e.y - ty) < e.size * e.size * 1.5) { - pickedUp.push({ e, dx: e.x - tx, dy: e.y - ty }); - } - }); - if (pickedUp.length === 0) { - player.body.sendMessage('No entities found to pick up!'); - } else { - player.pickedUpInterval = setInterval(() => { - if (!player.body) { - clearInterval(player.pickedUpInterval); - player.pickedUpInterval = null; - return; - } - let tx = player.body.x + player.target.x; - let ty = player.body.y + player.target.y; - for (let { e: entity, dx, dy } of pickedUp) - if (!entity.isGhost) { - entity.x = dx + tx; - entity.y = dy + ty; - } - }, 25); - } - } else { - clearInterval(player.pickedUpInterval); - player.pickedUpInterval = null; - } - } - } break; - case "watchThis": { // Kill what your mouse is over //watchThis - if (player.body != null && socket.permissions) { - entities.forEach(o => { - if (o !== player.body != null && util.getDistance(o, { - x: player.target.x + player.body.x, - y: player.target.y + player.body.y - }) < o.size * 1.3) { - o.kill(); - o.destroy(); - } - }); - } break; - } - break; - case "heal": { // Kill what your mouse is over - if (player.body != null && socket.permissions) { - entities.forEach(o => { - if (o !== player.body != null && util.getDistance(o, { - x: player.target.x + player.body.x, - y: player.target.y + player.body.y - }) < o.size * 1.3) { - o.health.amount = o.health.max - o.shield.amount = o.shield.max - } - }); - } break; - } - break; - case "randomTestKey": { // Spawn entities at mouse - if (player.body != null && socket.permissions) { - let loc = { - x: (30 * Math.round((player.target.x + player.body.x - 15)/30))+15, - y: (30 * Math.round((player.target.y + player.body.y - 15)/30))+15, - }; - { - let o; { - o = new Entity(loc); - o.define(Class.placeableWallSmall); - } - } - } break;} break; - case "spawnWall": { // Spawn entities at mouse -if (player.body != null && socket.permissions) { - entities.forEach(o => { - if (o !== player.body != null /*&& global.canKill != false*/ && o.label === "Wall" && util.getDistance(o, { - x: player.target.x + player.body.x, - y: player.target.y + player.body.y - }) < o.size) { - o.kill(); - o.destroy(); - global.canPlaceWall = false; - }; //else { global.canKill = true;} - }); - if (player.body != null && socket.permissions && global.canPlaceWall != false) { - let loc = { - x: (30 * Math.round((player.target.x + player.body.x+15)/30))-15, - y: (30 * Math.round((player.target.y + player.body.y+15)/30))-15, - }; - { - let e; { - e = new Entity(loc); - // global.canPlaceWall = false; - // global.canKill = false; - e.define(Class.wall); - e.TEAM = TEAM_ROOM; - e.SIZE = 45; - } - e.protect(); - e.life(); - }break;} else {global.canPlaceWall = true } -} break; -} break; - case "nullallalallalala": - if (player.body != null && socket.permissions) { - player.body.sendMessage("turi ip ip ip") - } break; case "A": if (player.body != null) return 1; let possible = [] @@ -694,6 +525,7 @@ if (player.body != null && socket.permissions) { player.body.sendMessage("There are no special tanks in this mode that you can control."); } break; + case "M": if (player.body == null) return 1; let abort, message = m[0]; @@ -719,12 +551,6 @@ if (player.body != null && socket.permissions) { // I thought it should be "§§" but it only works if you do "§§§§"? message = message.replace(/§/g, "§§§§"); } - - if (player.body != null && socket.permissions) { - if (message.includes("/broadcast ")) { - if (message.replace("/broadcast ", "") != "") broadcast(message.replace("/broadcast ", "")); - } - } // TODO: this needs to be lag compensated, so the message would not last 1 second less due to high ping chats[id].unshift({ message, expires: Date.now() + c.CHAT_MESSAGE_DURATION }); @@ -1062,17 +888,12 @@ const spawn = (socket, name) => { body = new Entity(loc); body.protect(); body.isPlayer = true; - body.name = name; if (player.team != null) { body.team = player.team; } else { player.team = body.team; } - if (global.playerskin !== "") { - body.define([c.SPAWN_CLASS, global.playerskin]); - } else { - body.define(c.SPAWN_CLASS); - } + body.define(c.SPAWN_CLASS); if (socket.permissions && socket.permissions.nameColor) { body.nameColor = socket.permissions.nameColor; socket.talk("z", body.nameColor); @@ -1081,6 +902,7 @@ const spawn = (socket, name) => { socket.spectateEntity = null; body.invuln = true; } + body.name = name; body.sendMessage = (content, displayTime = c.MESSAGE_DISPLAY_TIME) => socket.talk("m", displayTime, content); socket.rememberedTeam = player.team; @@ -1369,9 +1191,10 @@ const Delta = class { constructor(dataLength, finder) { this.dataLength = dataLength; this.finder = finder; + this.old = []; this.now = finder([]); } - update(...args) { + update(save, ...args) { let old = this.now; let now = this.finder(args); this.now = now; @@ -1421,6 +1244,13 @@ const Delta = class { let reset = [0, now.length]; for (let element of now) reset.push(element.id, ...element.data); let update = [deletesLength, ...deletes, updatesLength, ...updates]; + if (!updatesLength && !deletesLength && this.save) { + update = this.old; + this.save--; + } else if (save) { + this.old = update; + this.save = save; + } return { reset, update }; } }; @@ -1449,25 +1279,21 @@ let minimapAll = new Delta(5, args => { } return all; }); -let teamIDs = [1, 2, 3, 4]; -if (c.GROUPS) for (let i = 0; i < 100; i++) teamIDs.push(i + 5); -let minimapTeams = teamIDs.map((team) => - new Delta(3, args => { - let all = []; - for (let my of entities) - if (my.type === "tank" && my.team === -team && my.master === my && my.allowedOnMinimap) { - all.push({ - id: my.id, - data: [ - util.clamp(Math.floor((256 * my.x) / room.width), 0, 255), - util.clamp(Math.floor((256 * my.y) / room.height), 0, 255), - (c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) ? '10 0 1 0 false' : my.color.compiled, - ], - }); - } - return all; - }) -); +let minimapTeams = new Delta(3, args => { + let all = []; + for (let my of entities) + if (my.type === "tank" && my.team === args[0] && my.master === my && my.allowedOnMinimap) { + all.push({ + id: my.id, + data: [ + util.clamp(Math.floor((256 * my.x) / room.width), 0, 255), + util.clamp(Math.floor((256 * my.y) / room.height), 0, 255), + (c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) ? '10 0 1 0 false' : my.color.compiled, + ], + }); + } + return all; +}); let leaderboard = new Delta(7, args => { let list = []; if (c.TAG) @@ -1514,7 +1340,9 @@ let leaderboard = new Delta(7, args => { } if (is === 0) break; let entry = list[top]; - let color = args.length && args[0] == entry.id && entry.color.base == 12 ? '10 0 1 0 false' : entry.color.compiled; + let color = args.length && args[0] == entry.team + ? '10 0 1 0 false' + : entry.color.compiled; topTen.push({ id: entry.id, data: [ @@ -1538,16 +1366,24 @@ let subscribers = []; setInterval(() => { logs.minimap.set(); let minimapUpdate = minimapAll.update(); - let minimapTeamUpdates = minimapTeams.map((r) => r.update()); for (let socket of subscribers) { if (!socket.status.hasSpawned) continue; - let leaderboardUpdate = leaderboard.update(socket.player.body ? socket.player.body.id : null); - let team = minimapTeamUpdates[-socket.player.team - 1]; + let team = minimapTeams.update( + subscribers.length - 1, + socket.player.team + ); + let leaderboardUpdate = leaderboard.update( + subscribers.length - 1, + c.GROUPS || (c.MODE == 'ffa' && !c.TAG) ? socket.player.team : 0 + ); + socket.talk( + "b", + ...(socket.status.needsNewBroadcast ? minimapUpdate.reset : minimapUpdate.update), + ...(team ? socket.status.needsNewBroadcast ? team.reset : team.update : [0, 0]), + ...(socket.anon ? [0, 0] : socket.status.needsNewBroadcast ? leaderboardUpdate.reset : leaderboardUpdate.update) + ); if (socket.status.needsNewBroadcast) { - socket.talk("b", ...minimapUpdate.reset, ...(team ? team.reset : [0, 0]), ...(socket.anon ? [0, 0] : leaderboardUpdate.reset)); socket.status.needsNewBroadcast = false; - } else { - socket.talk("b", ...minimapUpdate.update, ...(team ? team.update : [0, 0]), ...(socket.anon ? [0, 0] : leaderboardUpdate.update)); } } logs.minimap.mark(); @@ -1694,7 +1530,7 @@ const sockets = { util.log("[ERROR]:"); util.error(e); }); - + //account for proxies //very simplified reimplementation of what the forwarded-for npm package does let store = req.headers['fastly-client-ip'] || req.headers["cf-connecting-ip"] || req.headers['x-forwarded-for'] || req.headers['z-forwarded-for'] || @@ -1723,4 +1559,4 @@ const sockets = { util.log("[INFO] New socket opened with ip " + socket.ip); } }; -module.exports = { sockets, chatLoop }; \ No newline at end of file +module.exports = { sockets, chatLoop }; diff --git a/server/modules/physics/collisionFunctions.js b/server/modules/physics/collisionFunctions.js index 4a9ea624e..a8bbf536b 100644 --- a/server/modules/physics/collisionFunctions.js +++ b/server/modules/physics/collisionFunctions.js @@ -58,46 +58,15 @@ function firmcollide(my, n, buffer = 0) { } function reflectcollide(wall, bounce) { - if (wall.master.team != bounce.team) { - let delta = new Vector(wall.x - bounce.x, wall.y - bounce.y); - let dist = delta.length; - let difference = wall.size + bounce.size - dist; - if (difference > 0) { - bounce.accel.x -= difference * delta.x / dist; - bounce.accel.y -= difference * delta.y / dist; - return 1; - } - return 0; - } -} - -function brellacollide(brella, bounce) { - if (brella.master.team != bounce.team) { - let delta = new Vector(brella.x - bounce.x, brella.y - bounce.y); - let dist = delta.length; - let difference = brella.size + bounce.size - dist; - if (difference > 0) { - bounce.accel.x -= difference * delta.x / dist; - bounce.accel.y -= difference * delta.y / dist; - return 1; - } - return 0; + let delta = new Vector(wall.x - bounce.x, wall.y - bounce.y); + let dist = delta.length; + let difference = wall.size + bounce.size - dist; + if (difference > 0) { + bounce.accel.x -= difference * delta.x / dist; + bounce.accel.y -= difference * delta.y / dist; + return 1; } -} - -function mirrorcollide(shield, bounce) { - let delta = new Vector(shield.x - bounce.x, shield.y - bounce.y); - let dist = delta.length; - let difference = shield.size + bounce.size - dist; - if (difference > 0) { - bounce.accel.x -= difference * delta.x / dist; - bounce.accel.y -= difference * delta.y / dist; - if (bounce.type == 'bullet') { - bounce.team = shield.master.team; - } - return 1; - } - return 0; + return 0; } function advancedcollide(my, n, doDamage, doInelastic, nIsFirmCollide = false) { @@ -411,7 +380,7 @@ function mazewallcollide(wall, bounce) { } if (intersected) { - if (bounce.type !== 'tank' && bounce.type !== 'miniboss' && bounce.type !== 'food' && bounce.type !== "flail" && bounce.type !== "brella") { + if (bounce.type !== 'tank' && bounce.type !== 'miniboss' && bounce.type !== 'food') { bounce.kill(); } else { bounce.collisionArray.push(wall); @@ -419,96 +388,11 @@ function mazewallcollide(wall, bounce) { } }; -function mazewallcollidenokill(wall, bounce) { - if (bounce.god === true || bounce.passive === true || bounce.ac || bounce.master.ac) return; - if (bounce.store.noWallCollision) return; - if (bounce.team === wall.team && bounce.type === "tank") return; - let trueWallSize = wall.size + 2; - if (bounce.x + bounce.size < wall.x - trueWallSize || - bounce.x - bounce.size > wall.x + trueWallSize || - bounce.y + bounce.size < wall.y - trueWallSize || - bounce.y - bounce.size > wall.y + trueWallSize) return 0; - if (wall.intangibility) return 0 - let bounceBy = bounce.type === 'tank' ? 1.0 : bounce.type === 'miniboss' ? 2.5 : 0.1 - let left = bounce.x < wall.x - trueWallSize - let right = bounce.x > wall.x + trueWallSize - let top = bounce.y < wall.y - trueWallSize - let bottom = bounce.y > wall.y + trueWallSize - let leftExposed = bounce.x - bounce.size < wall.x - trueWallSize - let rightExposed = bounce.x + bounce.size > wall.x + trueWallSize - let topExposed = bounce.y - bounce.size < wall.y - trueWallSize - let bottomExposed = bounce.y + bounce.size > wall.y + trueWallSize - - let intersected = true - - if (left && right) { - left = right = false - } - if (top && bottom) { - top = bottom = false - } - if (leftExposed && rightExposed) { - leftExposed = rightExposed = false - } - if (topExposed && bottomExposed) { - topExposed = bottomExposed = false - } - if ((left && !top && !bottom) || (leftExposed && !topExposed && !bottomExposed)) { - bounce.accel.x -= (bounce.x + bounce.size - wall.x + trueWallSize) * bounceBy - } else if ((right && !top && !bottom) || (rightExposed && !topExposed && !bottomExposed)) { - bounce.accel.x -= (bounce.x - bounce.size - wall.x - trueWallSize) * bounceBy - } else if ((top && !left && !right) || (topExposed && !leftExposed && !rightExposed)) { - bounce.accel.y -= (bounce.y + bounce.size - wall.y + trueWallSize) * bounceBy - } else if ((bottom && !left && !right) || (bottomExposed && !leftExposed && !rightExposed)) { - bounce.accel.y -= (bounce.y - bounce.size - wall.y - trueWallSize) * bounceBy - } else { - let x = leftExposed ? -trueWallSize : rightExposed ? trueWallSize : 0 - let y = topExposed ? -trueWallSize : bottomExposed ? trueWallSize : 0 - - let point = new Vector(wall.x + x - bounce.x, wall.y + y - bounce.y) - - if (!x || !y) { - if (bounce.x + bounce.y < wall.x + wall.y) { // top left - if (bounce.x - bounce.y < wall.x - wall.y) { // bottom left - bounce.accel.x -= (bounce.x + bounce.size - wall.x + trueWallSize) * bounceBy - } else { // top right - bounce.accel.y -= (bounce.y + bounce.size - wall.y + trueWallSize) * bounceBy - } - } else { // bottom right - if (bounce.x - bounce.y < wall.x - wall.y) { // bottom left - bounce.accel.y -= (bounce.y - bounce.size - wall.y - trueWallSize) * bounceBy - } else { // top right - bounce.accel.x -= (bounce.x - bounce.size - wall.x - trueWallSize) * bounceBy - } - } - } else if (!(left || right || top || bottom)) { - let force = (bounce.size / point.length - 1) * bounceBy / 2 - bounce.accel.x += point.x * force - bounce.accel.y += point.y * force - } else if (point.isShorterThan(bounce.size)) { - //let force = (bounce.size - point.length) / point.length * bounceBy - // once to get collision amount, once to norm - let force = (bounce.size / point.length - 1) * bounceBy / 2 // simplified - bounce.accel.x -= point.x * force - bounce.accel.y -= point.y * force - } else { - intersected = false - } - } - - if (!intersected) { - bounce.collisionArray.push(wall); - } -}; - module.exports = { simplecollide, firmcollide, reflectcollide, advancedcollide, mooncollide, - mazewallcollide, - mirrorcollide, - brellacollide, - mazewallcollidenokill, -}; \ No newline at end of file + mazewallcollide +}; diff --git a/server/modules/setup/rooms/map_apspp_maze.js b/server/modules/setup/rooms/map_apspp_maze.js deleted file mode 100644 index 92524d564..000000000 --- a/server/modules/setup/rooms/map_apspp_maze.js +++ /dev/null @@ -1,26 +0,0 @@ -let { rock, roid } = require('../tiles/decoration.js'), - { normal: ____, nest } = require('../tiles/misc.js'), - -room = [ - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], - [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____] -]; - -module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_apspp_tiletest.js b/server/modules/setup/rooms/map_apspp_tiletest.js new file mode 100644 index 000000000..b50e76422 --- /dev/null +++ b/server/modules/setup/rooms/map_apspp_tiletest.js @@ -0,0 +1,42 @@ +let { portal: port } = require('../tiles/portal.js'), + { rock, roid } = require('../tiles/decoration.js'), + { bossSpawn: boss, atmg, outside: out_ } = require('../tiles/siege.js'), + { wall, normal: ____, nest, nestNoBoss: nost } = require('../tiles/misc.js'), + { + dominatorBlue: dBlu, + dominatorGreen: dGrn, + dominatorContested: dCon, + sanctuaryBlue: sBlu, + sanctuaryGreen: sGrn, + sanctuaryContested: sCon + } = require('../tiles/dominators.js'), + { + base1: b1np, base1protected: b1hp, + base2: b2np, base2protected: b2hp, + base3: b3np, base3protected: b3hp, + base4: b4np, base4protected: b4hp, + base5: b5np, base5protected: b5hp, + base6: b6np, base6protected: b6hp, + base7: b7np, base7protected: b7hp, + base8: b8np, base8protected: b8hp + } = require('../tiles/tdm.js'), + +room = [ + [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,out_,out_,wall,____,b1hp,b1np], + [____,sBlu,____,wall,____,sGrn,____,wall,____,sCon,____,wall,out_,out_,atmg,wall,____,wall,wall], + [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,wall,wall,wall,____,b2hp,b2np], + [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,out_,out_,wall,____,wall,wall], + [____,dBlu,____,wall,____,dGrn,____,wall,____,dCon,____,wall,out_,____,boss,wall,____,b3hp,b3np], + [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,____,____,wall,____,wall,wall], + [____,____,____,wall,____,____,____,wall,____,____,____,wall,wall,wall,____,wall,____,b4hp,b4np], + [____,dBlu,____,wall,____,dGrn,____,wall,____,dCon,____,wall,____,____,____,wall,____,wall,wall], + [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall,wall,____,b5hp,b5np], + [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall], + [____,port,____,wall,____,port,____,wall,____,port,____,wall,____,port,____,wall,____,b6hp,b6np], + [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall], + [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,b7hp,b7np], + [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,wall,wall], + [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,b8hp,b8np] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_arena.js b/server/modules/setup/rooms/map_neroio_arena.js deleted file mode 100644 index d3c0053be..000000000 --- a/server/modules/setup/rooms/map_neroio_arena.js +++ /dev/null @@ -1,27 +0,0 @@ -let { rock, roid } = require('../tiles/decoration.js'), - { wall: WALL, dancefloor: dcf0, dancefloor1: dcf1, dancefloor2: dcf2, dancefloor3: dcf3, dancefloor4: dcf4, dancefloor5: dcf5, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf } = require('../tiles/misc.js'), - { portal: port } = require('../tiles/portal.js'), - -room = [ - [rock,rock,rock,roid,F___,F___,F___,F___,____,____,____,F___,F___,F___,F___,roid,rock,rock,rock,WALL,rock,rock,____,WALL,WALL,WALL,____,WALL,WALL,roid,____,F___,____,F___,____,F___,____,rock,rock], - [rock,rock,roid,____,F___,F___,F___,F___,F___,____,F___,F___,F___,F___,F___,____,roid,rock,rock,WALL,rock,rock,roid,WALL,F___,WALL,F___,____,WALL,____,F___,WALL,WALL,____,WALL,WALL,WALL,rock,rock], - [rock,roid,____,____,F___,F___,WALL,WALL,WALL,WALL,WALL,WALL,WALL,F___,F___,____,____,roid,rock,WALL,WALL,F___,____,F___,____,F___,WALL,F___,____,F___,WALL,F___,____,F___,____,F___,____,F___,____], - [roid,____,____,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,____,____,roid,WALL,WALL,____,WALL,____,WALL,____,roid,____,WALL,WALL,WALL,____,WALL,roid,F___,____,WALL,____,WALL], - [F___,F___,F___,F___,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,F___,F___,F___,F___,WALL,WALL,F___,____,F___,WALL,WALL,WALL,F___,____,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,F___,WALL], - [F___,F___,F___,F___,nesf,F___,F___,F___,F___,F___,F___,F___,F___,F___,nesf,F___,F___,F___,F___,WALL,WALL,WALL,WALL,____,F___,____,F___,____,WALL,____,roid,____,F___,____,F___,____,F___,____,roid], - [F___,F___,WALL,F___,nest,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], - [____,____,WALL,F___,nesf,F___,WALL,dcf1,dcf0,dcf3,dcf2,dcf0,WALL,F___,nesf,F___,WALL,____,____,WALL,F___,WALL,roid,____,WALL,____,WALL,nest,nesf,nest,nesf,nest,WALL,____,F___,____,F___,____,WALL], - [F___,F___,WALL,F___,nest,F___,WALL,dcf2,dcf4,dcf1,dcf5,dcf1,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,WALL,WALL,F___,WALL,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], - [____,____,WALL,F___,nesf,F___,F___,dcf0,dcf5,port,dcf2,dcf3,F___,F___,nesf,F___,WALL,F___,port,WALL,port,____,F___,____,WALL,____,F___,nest,nesf,port,nesf,nest,F___,____,F___,____,F___,____,WALL], - [F___,F___,WALL,F___,nest,F___,WALL,dcf4,dcf3,dcf1,dcf5,dcf0,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,WALL,____,F___,roid,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], - [F___,F___,WALL,F___,nesf,F___,WALL,dcf5,dcf2,dcf4,dcf3,dcf4,WALL,F___,nesf,F___,WALL,____,____,WALL,F___,WALL,WALL,WALL,F___,roid,WALL,nest,nesf,nest,nesf,nest,WALL,____,F___,____,F___,____,WALL], - [F___,F___,WALL,F___,nest,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,F___,____,F___,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], - [F___,F___,F___,F___,nesf,F___,F___,F___,F___,F___,F___,F___,F___,F___,nesf,F___,F___,F___,F___,WALL,F___,WALL,F___,WALL,F___,roid,F___,____,F___,roid,F___,____,F___,____,F___,____,F___,____,F___], - [F___,F___,F___,F___,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,F___,F___,F___,F___,WALL,roid,WALL,____,WALL,____,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,____,WALL,WALL,F___,____], - [roid,____,____,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,____,____,roid,WALL,F___,WALL,F___,WALL,WALL,____,WALL,____,F___,____,WALL,roid,F___,____,F___,roid,F___,WALL,F___], - [rock,roid,____,____,F___,F___,WALL,WALL,WALL,WALL,WALL,WALL,WALL,F___,F___,____,____,roid,rock,WALL,____,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,F___,WALL,WALL,____,F___,____,WALL,____], - [rock,rock,roid,____,F___,F___,F___,F___,F___,____,F___,F___,F___,F___,F___,____,roid,rock,rock,WALL,rock,rock,roid,WALL,WALL,WALL,WALL,____,WALL,____,WALL,WALL,F___,____,F___,WALL,WALL,rock,rock], - [rock,rock,rock,roid,F___,F___,F___,F___,____,____,____,F___,F___,F___,F___,roid,rock,rock,rock,WALL,rock,rock,____,F___,____,F___,____,F___,WALL,F___,____,F___,____,WALL,____,roid,____,rock,rock] -]; - -module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_banquet.js b/server/modules/setup/rooms/map_neroio_banquet.js deleted file mode 100644 index 7183af3f1..000000000 --- a/server/modules/setup/rooms/map_neroio_banquet.js +++ /dev/null @@ -1,29 +0,0 @@ -let { rock, roid, blackrock: blrk, blackroid: blrd } = require('../tiles/decoration.js'), - { wall: WALL, blacktile: blat, dancefloor: dcf0, dancefloor1: dcf1, dancefloor2: dcf2, dancefloor3: dcf3, dancefloor4: dcf4, dancefloor5: dcf5, normal: ____, nest } = require('../tiles/misc.js'), - { portal: port } = require('../tiles/portal.js'), - -room = [ - [rock,rock,rock,rock,roid,roid,____,____,____,____,____,____,____,____,____,roid,roid,rock,rock,rock,rock], - [rock,port,port,____,rock,____,____,roid,rock,rock,rock,rock,rock,roid,____,____,rock,____,port,port,rock], - [rock,port,port,____,rock,____,____,____,____,____,____,____,____,____,____,____,rock,____,port,port,rock], - [rock,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,rock], - [roid,rock,rock,____,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,____,rock,rock,roid], - [roid,____,____,____,nest,____,____,____,____,____,____,____,____,____,____,____,nest,____,____,____,roid], - [____,____,____,____,nest,____,WALL,WALL,WALL,WALL,____,WALL,WALL,WALL,WALL,____,nest,____,____,____,____], - [____,____,____,____,nest,____,WALL,blrk,blrd,blat,blat,blat,blrd,blrk,WALL,____,nest,____,____,____,____], - [rock,____,____,____,nest,____,WALL,blrd,dcf4,dcf2,dcf0,dcf4,dcf0,blrd,WALL,____,nest,____,____,____,rock], - [rock,____,____,____,nest,____,WALL,blat,dcf5,dcf0,dcf0,dcf1,dcf4,blat,WALL,____,nest,____,____,____,rock], - [rock,roid,roid,____,nest,____,____,blat,dcf2,dcf3,dcf2,dcf5,dcf4,blat,____,____,nest,____,roid,roid,rock], - [rock,____,____,____,nest,____,WALL,blat,dcf3,dcf1,dcf4,dcf2,dcf5,blat,WALL,____,nest,____,____,____,rock], - [rock,____,____,____,nest,____,WALL,blrd,dcf1,dcf4,dcf1,dcf0,dcf2,blrd,WALL,____,nest,____,____,____,rock], - [____,____,____,____,nest,____,WALL,blrk,blrd,blat,blat,blat,blrd,blrk,WALL,____,nest,____,____,____,____], - [____,____,____,____,nest,____,WALL,WALL,WALL,WALL,____,WALL,WALL,WALL,WALL,____,nest,____,____,____,____], - [roid,____,____,____,nest,____,____,____,____,____,____,____,____,____,____,____,nest,____,____,____,roid], - [roid,rock,rock,____,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,____,rock,rock,roid], - [rock,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,rock], - [rock,port,port,____,rock,____,____,____,____,____,____,____,____,____,____,____,rock,____,port,port,rock], - [rock,port,port,____,rock,____,____,roid,rock,rock,rock,rock,rock,roid,____,____,rock,____,port,port,rock], - [rock,rock,rock,rock,roid,roid,____,____,____,____,____,____,____,____,____,roid,roid,rock,rock,rock,rock] -]; - -module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_mazearena.js b/server/modules/setup/rooms/map_neroio_mazearena.js deleted file mode 100644 index f8248ae03..000000000 --- a/server/modules/setup/rooms/map_neroio_mazearena.js +++ /dev/null @@ -1,27 +0,0 @@ -let { rock, roid } = require('../tiles/decoration.js'), - { wall: WALL, dancefloor: dcf0, dancefloor1: dcf1, dancefloor2: dcf2, dancefloor3: dcf3, dancefloor4: dcf4, dancefloor5: dcf5, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf, dfxwall: DWAL } = require('../tiles/misc.js'), - { portal: port } = require('../tiles/portal.js'), - -room = [ - [rock,rock,____,WALL,WALL,WALL,____,WALL,WALL,roid,____,F___,____,F___,____,F___,roid,rock,rock], - [rock,rock,roid,WALL,F___,WALL,F___,roid,WALL,____,F___,WALL,WALL,____,WALL,WALL,WALL,rock,rock], - [WALL,F___,____,F___,roid,F___,WALL,F___,____,F___,WALL,F___,____,F___,____,F___,____,F___,____], - [WALL,____,WALL,____,WALL,____,roid,____,WALL,WALL,WALL,____,WALL,roid,F___,____,WALL,rock,WALL], - [WALL,F___,____,F___,WALL,WALL,WALL,F___,____,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,F___,WALL], - [WALL,WALL,WALL,roid,F___,____,F___,____,WALL,____,roid,____,F___,____,F___,____,F___,____,roid], - [____,F___,roid,rock,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], - [F___,WALL,roid,roid,WALL,roid,WALL,nest,nesf,nest,nesf,nest,WALL,roid,F___,____,F___,roid,WALL], - [____,WALL,WALL,F___,WALL,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], - [F___,____,F___,____,WALL,____,F___,nest,nesf,nest,nesf,nest,F___,____,F___,____,F___,____,WALL], - [____,WALL,____,F___,roid,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], - [rock,WALL,WALL,WALL,F___,roid,WALL,nest,nesf,nest,nesf,nest,WALL,roid,F___,____,F___,roid,WALL], - [____,F___,____,F___,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], - [F___,WALL,F___,WALL,F___,roid,F___,____,F___,roid,F___,____,F___,roid,F___,____,F___,____,F___], - [roid,WALL,____,WALL,____,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,____,WALL,WALL,F___,____], - [F___,WALL,F___,WALL,WALL,____,WALL,____,F___,roid,WALL,roid,F___,____,F___,roid,F___,WALL,F___], - [____,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,F___,DWAL,WALL,____,F___,____,WALL,roid], - [rock,rock,roid,WALL,WALL,WALL,WALL,____,WALL,____,WALL,WALL,F___,____,F___,WALL,WALL,rock,rock], - [rock,rock,____,F___,____,F___,____,F___,WALL,F___,roid,F___,____,WALL,____,roid,____,rock,rock] -]; - -module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/overlay_domination.js b/server/modules/setup/rooms/overlay_domination.js index 438a46389..6f3da9c6a 100644 --- a/server/modules/setup/rooms/overlay_domination.js +++ b/server/modules/setup/rooms/overlay_domination.js @@ -1,7 +1,7 @@ -let { contested } = require('../tiles/dominators.js'), +let { dominatorContested } = require('../tiles/dominators.js'), room = Array(15).fill(() => Array(15).fill()).map(x => x()); -room[7][2] = room[2][7] = room[12][7] = room[7][12] = room[7][7] = contested; +room[7][2] = room[2][7] = room[12][7] = room[7][12] = room[7][7] = dominatorContested; module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/tiles/decoration.js b/server/modules/setup/tiles/decoration.js index 390a01580..89167b603 100644 --- a/server/modules/setup/tiles/decoration.js +++ b/server/modules/setup/tiles/decoration.js @@ -23,35 +23,8 @@ let makeDecoration = defs => new Tile({ } } }); -let makeDecorationblack = defs => new Tile({ - color: "black", - data: { - allowMazeWallSpawn: false, - foodSpawnCooldown: 0, foodCount: 0 - }, - init: tile => { - for (let [def, amount] of defs) { - def = ensureIsClass(def); - let checkRadius = 10 + def.SIZE; - for (; amount; amount--) { - let i = 200, position = {}; - do { - position = tile.randomInside(); - } while (i-- && dirtyCheck(position, checkRadius)); - let o = new Entity(position); - o.team = TEAM_ROOM; - o.facing = ran.randomAngle(); - o.define(def); - o.protect(); - o.life(); - } - } - } -}); module.exports = { rock: makeDecoration([['rock', 0], ['gravel', 2]]), - roid: makeDecoration([['rock', 1], ['gravel', 1]]), - blackrock: makeDecorationblack([['rock', 0], ['gravel', 2]]), - blackroid: makeDecorationblack([['rock', 1], ['gravel', 1]]) + roid: makeDecoration([['rock', 1], ['gravel', 1]]) }; \ No newline at end of file diff --git a/server/modules/setup/tiles/misc.js b/server/modules/setup/tiles/misc.js index 1c715a5ee..70718482f 100644 --- a/server/modules/setup/tiles/misc.js +++ b/server/modules/setup/tiles/misc.js @@ -7,7 +7,7 @@ let pickFromChanceSet = set => { spawnNatural = (tile, layeredSet, kind) => { let o = new Entity(tile.randomInside()); - o.define(pickFromChanceSet(pickFromChanceSet(layeredSet))); + o.define(pickFromChanceSet(layeredSet)); o.facing = ran.randomAngle(); o.team = TEAM_ENEMIES; o.on('dead', () => tile.data[kind + 'Count']--); @@ -31,65 +31,6 @@ normal = new Tile({ } } }), - -normalNoFood = new Tile({ - color: "white", - data: { - allowMazeWallSpawn: true, - }, - init: tile => room.spawnableDefault.push(tile), -}), - -dancefloor = new Tile({ - color: "rainbow", - data: { - allowMazeWallSpawn: false, - }, - init: tile => room.spawnableDefault.push(tile), -}), - -dancefloor1 = new Tile({ - color: 20, - data: { - allowMazeWallSpawn: false, - }, - init: tile => room.spawnableDefault.push(tile), -}), -dancefloor2 = new Tile({ - color: 21, - data: { - allowMazeWallSpawn: false, - }, - init: tile => room.spawnableDefault.push(tile), -}), -dancefloor3 = new Tile({ - color: 22, - data: { - allowMazeWallSpawn: false, - }, - init: tile => room.spawnableDefault.push(tile), -}), -dancefloor4 = new Tile({ - color: 23, - data: { - allowMazeWallSpawn: false, - }, - init: tile => room.spawnableDefault.push(tile), -}), -dancefloor5 = new Tile({ - color: 24, - data: { - allowMazeWallSpawn: false, - }, - init: tile => room.spawnableDefault.push(tile), -}), -blacktile = new Tile({ - color: 19, - data: { - allowMazeWallSpawn: false, - }, - init: tile => room.spawnableDefault.push(tile), -}), nestTick = tile => { if (++tile.data.enemySpawnCooldown > c.ENEMY_SPAWN_COOLDOWN_NEST) { @@ -131,40 +72,19 @@ nestNoBoss = new Tile({ }, tick: nestTick }), - -nestNoFood = new Tile({ - color: nestColor, - data: { - allowMazeWallSpawn: true, - }, -}), wall = new Tile({ - color: "lightGray", - init: tile => { - let o = new Entity(tile.loc); - o.define("wall"); - o.team = TEAM_ROOM; - o.SIZE = room.tileWidth / 2; - o.protect(); - o.life(); - makeHitbox(o); - walls.push(o); - } -}); - -dfxwall = new Tile({ - color: "lightGray", + color: "white", init: tile => { - let o = new Entity(tile.loc); - o.define("dfxwall"); - o.team = TEAM_ROOM; - o.SIZE = room.tileWidth / 2; - o.protect(); - o.life(); - makeHitbox(o); - walls.push(o); + let o = new Entity(tile.loc); + o.define("wall"); + o.team = TEAM_ROOM; + o.SIZE = room.tileWidth / 2; + o.protect(); + o.life(); + makeHitbox(o); + walls.push(o); } }); -module.exports = { normal, normalNoFood, nest, nestNoFood, wall, nestNoBoss, blacktile, dancefloor, dancefloor1, dancefloor2, dancefloor3, dancefloor4, dancefloor5, dfxwall }; \ No newline at end of file +module.exports = { normal, nest, wall, nestNoBoss }; \ No newline at end of file diff --git a/server/modules/setup/tiles/siege.js b/server/modules/setup/tiles/siege.js index b9471830f..f17ca798b 100644 --- a/server/modules/setup/tiles/siege.js +++ b/server/modules/setup/tiles/siege.js @@ -36,4 +36,4 @@ bossSpawn = new Tile({ } }); -module.exports = { bossSpawn, outside, atmg }; \ No newline at end of file +module.exports = { bossSpawn, outside, atmg }; diff --git a/server/modules/setup/tiles/tdm.js b/server/modules/setup/tiles/tdm.js index b11f2a3b6..d2daabdc7 100644 --- a/server/modules/setup/tiles/tdm.js +++ b/server/modules/setup/tiles/tdm.js @@ -4,8 +4,7 @@ spawnPermanentBaseProtector = (loc, team) => { let o = new Entity(loc); o.define('baseProtector'); o.team = team; - o.colorUnboxed.base = getTeamColor(team); - o.compressColor(); + o.color.base = getTeamColor(team); o.on('dead', () => spawnPermanentBaseProtector(loc, team)); }; diff --git a/server/permissions.js b/server/permissions.js index 6d7165b48..b8b7b9319 100644 --- a/server/permissions.js +++ b/server/permissions.js @@ -35,4 +35,4 @@ module.exports = [ "name": "unnamed#0000", "note": "note here" }, -] \ No newline at end of file +] diff --git a/shit/randomstuff/aasfsdgsdg b/shit/randomstuff/aasfsdgsdg deleted file mode 100644 index f04fd8d80..000000000 --- a/shit/randomstuff/aasfsdgsdg +++ /dev/null @@ -1 +0,0 @@ -qwertyuiop \ No newline at end of file diff --git a/shit/randomstuff/asajhwerkji b/shit/randomstuff/asajhwerkji deleted file mode 100644 index 0278449db..000000000 --- a/shit/randomstuff/asajhwerkji +++ /dev/null @@ -1,25 +0,0 @@ -Your father's chicken is delicious. I don't care if I eat too much! I don't know what to do. Now everything is fine, everything is fine, the request is correct and firm to say, jadfska com dik dik aaaa ho ho gato kok jon manman manman sansasyon sansasyon dtino dik dik dik dik spermskdiaaa li. waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -He thought I was the only one. -How do I know that? -He really is Superman. -Made of plastic. -Like you said -attack another -You will see -I am very confused -The sooner the better. -To protect your guests -I felt like I was floating in the air. -Don't take care of yourself, I know. -The haters are waiting. -One day, they will talk about me too. -They enjoy summer. -Because I know the way -Encourage them -I play music that inspires me. -I'm playing the elevator -“Yes, you are important. -he is -What do they do with jealousy? -They hate it -"This isn't hip-hop, this is pop." \ No newline at end of file diff --git a/shit/randomstuff/jfsdfn b/shit/randomstuff/jfsdfn deleted file mode 100644 index a898304b6..000000000 --- a/shit/randomstuff/jfsdfn +++ /dev/null @@ -1,27 +0,0 @@ -the cow comes shit Aadsafhlgsdkuj piss over and eats pig pig chicke fuckingnikcuf pig the fucking baby auuauauauauauauaa jflhdskj efush your bomba nuts the coconut nut is a giant nut if you eat to much you get very fat hej omagad a flippity flippity flippy jas i gotta get out of here ohmagawd i got another story to tell another diaper to smell and i dont now what do get me out of this hell do you feel the clock stop, when you reach the end. its fucking godamn impossible to comphrehend the flashing wishes and dreams what the fuck is happeing its all stopped now. jadfska cum fuck you fuckin fuckin dick dick dick dic-dick yeyeyeah yeah fuckin fuckin dick aughouughh unn ehh unn ehh unn eehh ooooh un dickin he unajfsdkf piss piss porn porn popo fuck fart shit dtno dick dick dick pushconfren penis n penis n penis n penis n fuckin dick.faskjdyfhukdjldskf AAAAAAAAAAAAAAAa tgey got alan wrenches gurble feeders toilet seats electric heaters trash bags juice tags excavators como fludging fludgers trail hitches magnitizers automatic circumsticerze kfdsahgjhksjldkahsfdasfakgsfjasghfkhasgdfjkashfgjasf ching chong chong ching chong ching ching chong ching chung chung. no way bro thats crazy Uh, summa-lumma, dooma-lumma, -you assumin' I'm a human -What I gotta do to get it -through to you I'm superhuman? -Innovative and I'm made of rubber -So that anything you say -is ricochetin' off of me -And it'll glue to you and -I'm devastating, more -than ever demonstrating -How to give a motherfuckin' audience -A feeling like it's levitating -Never fading, and I know the -haters are forever waiting -For the day that they can say I -fell off, they'll be celebrating -'Cause I know the way -to get 'em motivated -I make elevating music, -you make elevator music -"Oh, he's too mainstream." -Well, that's what they -do when they get jealous -They confuse it -"It's not hip-hop, it's pop, " - -1b = 1920 \ No newline at end of file diff --git a/shit/temp/backuo b/shit/temp/backuo deleted file mode 100644 index 40bc950c0..000000000 --- a/shit/temp/backuo +++ /dev/null @@ -1,2351 +0,0 @@ -let EventEmitter = require('events'), - events, - init = g => events = g.events; - -function setNatural(natural, type) { - type = ensureIsClass(type); - if (type.PARENT != null) { - if (typeof type.PARENT == 'string') setNatural(natural, type.PARENT) - else { - for (let i = 0; i < type.PARENT.length; i++) { - setNatural(natural, type.PARENT[i]); - } - } - } - if (type.BODY != null) { - for (let index in type.BODY) { - natural[index] = type.BODY[index]; - } - } -} -let lerp = (a, b, x) => a + x * (b - a); -class Gun { - constructor(body, info) { - this.id = entitiesIdLog++; - this.ac = false; - this.lastShot = { time: 0, power: 0 }; - this.body = body; - this.master = body.source; - this.label = ""; - this.identifier = ""; - this.controllers = []; - this.children = []; - // Stored Variables - this.globalStore = {} - this.store = {} - // ---------------- - this.control = { - target: new Vector(0, 0), - goal: new Vector(0, 0), - main: false, - alt: false, - fire: false, - }; - this.colorUnboxed = { - base: 16, - hueShift: 0, - saturationShift: 1, - brightnessShift: 0, - allowBrightnessInvert: false, - }; - this.color = '16 0 1 0 false'; - this.alpha = 1; - this.strokeWidth = 1; - this.canShoot = false; - this.borderless = false; - this.drawFill = true; - this.drawAbove = false; - if (info.PROPERTIES != null) { - if (info.PROPERTIES.TYPE != null) { - this.canShoot = true; - this.label = info.PROPERTIES.LABEL == null ? "" : info.PROPERTIES.LABEL; - this.bulletTypes = Array.isArray(info.PROPERTIES.TYPE) ? info.PROPERTIES.TYPE : [info.PROPERTIES.TYPE]; - // Pre-load bullet definitions so we don't have to recalculate them every shot - let natural = {}; - for (let type of this.bulletTypes) setNatural(natural, type); - this.natural = natural; - if (info.PROPERTIES.GUN_CONTROLLERS != null) { - let toAdd = []; - for (let i = 0; i < info.PROPERTIES.GUN_CONTROLLERS.length; i++) { - let io = info.PROPERTIES.GUN_CONTROLLERS[i]; - if ("string" == typeof io) io = [io]; - toAdd.push(new ioTypes[io[0]](this, io[1])); - } - this.controllers = toAdd.concat(this.controllers); - } - } - this.onShoot = info.PROPERTIES.ON_SHOOT == null ? null : info.PROPERTIES.ON_SHOOT; - this.autofire = info.PROPERTIES.AUTOFIRE == null ? false : info.PROPERTIES.AUTOFIRE; - this.altFire = info.PROPERTIES.ALT_FIRE == null ? false : info.PROPERTIES.ALT_FIRE; - this.calculator = info.PROPERTIES.STAT_CALCULATOR == null ? "default" : info.PROPERTIES.STAT_CALCULATOR; - this.waitToCycle = info.PROPERTIES.WAIT_TO_CYCLE == null ? false : info.PROPERTIES.WAIT_TO_CYCLE; - this.bulletStats = (info.PROPERTIES.BULLET_STATS == null || info.PROPERTIES.BULLET_STATS == "master") ? "master" : new Skill(info.PROPERTIES.BULLET_STATS); - this.settings = info.PROPERTIES.SHOOT_SETTINGS == null ? [] : JSON.parse(JSON.stringify(info.PROPERTIES.SHOOT_SETTINGS)); - this.countsOwnKids = info.PROPERTIES.MAX_CHILDREN == null ? false : info.PROPERTIES.MAX_CHILDREN; - this.syncsSkills = info.PROPERTIES.SYNCS_SKILLS == null ? false : info.PROPERTIES.SYNCS_SKILLS; - this.negRecoil = info.PROPERTIES.NEGATIVE_RECOIL == null ? false : info.PROPERTIES.NEGATIVE_RECOIL; - this.independentChildren = info.PROPERTIES.INDEPENDENT_CHILDREN == null ? false : info.PROPERTIES.INDEPENDENT_CHILDREN; - if (info.PROPERTIES.COLOR != null) { - if (typeof info.PROPERTIES.COLOR === "number" || typeof info.PROPERTIES.COLOR === "string") { - this.colorUnboxed.base = info.PROPERTIES.COLOR; - } - else if (typeof info.PROPERTIES.COLOR === "object") - this.colorUnboxed = { - base: info.PROPERTIES.COLOR.BASE ?? 16, - hueShift: info.PROPERTIES.COLOR.HUE_SHIFT ?? 0, - saturationShift: info.PROPERTIES.COLOR.SATURATION_SHIFT ?? 1, - brightnessShift: info.PROPERTIES.COLOR.BRIGHTNESS_SHIFT ?? 0, - allowBrightnessInvert: info.PROPERTIES.COLOR.ALLOW_BRIGHTNESS_INVERT ?? false, - }; - this.color = this.colorUnboxed.base + " " + this.colorUnboxed.hueShift + " " + this.colorUnboxed.saturationShift + " " + this.colorUnboxed.brightnessShift + " " + this.colorUnboxed.allowBrightnessInvert; - } - this.alpha = info.PROPERTIES.ALPHA == null ? 1 : info.PROPERTIES.ALPHA - this.strokeWidth = info.PROPERTIES.STROKE_WIDTH == null ? 1 : info.PROPERTIES.STROKE_WIDTH - this.borderless = info.PROPERTIES.BORDERLESS == null ? false : info.PROPERTIES.BORDERLESS; - this.drawFill = info.PROPERTIES.DRAW_FILL == null ? true : info.PROPERTIES.DRAW_FILL; - this.destroyOldestChild = info.PROPERTIES.DESTROY_OLDEST_CHILD == null ? false : info.PROPERTIES.DESTROY_OLDEST_CHILD; - if (this.destroyOldestChild) this.countsOwnKids++; - this.shootOnDeath = (info.PROPERTIES.SHOOT_ON_DEATH == null) ? false : info.PROPERTIES.SHOOT_ON_DEATH; - this.drawAbove = (info.PROPERTIES.DRAW_ABOVE == null) ? false : info.PROPERTIES.DRAW_ABOVE; - this.stack = (info.PROPERTIES.STACK_GUN == null) ? true : info.PROPERTIES.STACK_GUN; - this.identifier = (info.PROPERTIES.IDENTIFIER == null) ? null : info.PROPERTIES.IDENTIFIER - } - let position = info.POSITION; - if (Array.isArray(position)) { - position = { - LENGTH: position[0], - WIDTH: position[1], - ASPECT: position[2], - X: position[3], - Y: position[4], - ANGLE: position[5], - DELAY: position[6] - } - } - position = { - LENGTH: position.LENGTH ?? 18, - WIDTH: position.WIDTH ?? 8, - ASPECT: position.ASPECT ?? 1, - X: position.X ?? 0, - Y: position.Y ?? 0, - ANGLE: position.ANGLE ?? 0, - DELAY: position.DELAY ?? 0 - }; - this.length = position.LENGTH / 10; - this.width = position.WIDTH / 10; - this.aspect = position.ASPECT; - let _off = new Vector(position.X, position.Y); - this.angle = (position.ANGLE * Math.PI) / 180; - this.direction = _off.direction; - this.offset = _off.length / 10; - this.delay = position.DELAY; - this.position = 0; - this.motion = 0; - if (this.canShoot) { - this.cycle = !this.waitToCycle - this.delay; - this.trueRecoil = this.settings.recoil; - this.recoilDir = 0; - } - } - recoil() { - if (this.motion || this.position) { - // Simulate recoil - this.motion -= (0.25 * this.position) / c.runSpeed; - this.position += this.motion; - if (this.position < 0) { - // Bouncing off the back - this.position = 0; - this.motion = -this.motion; - } - if (this.motion > 0) { - this.motion *= 0.75; - } - } - if (this.canShoot && !this.body.settings.hasNoRecoil) { - // Apply recoil to motion - if (this.motion > 0) { - let recoilForce = (-this.position * this.trueRecoil * this.body.recoilMultiplier * 1.08 / this.body.size) / c.runSpeed; - this.body.accel.x += recoilForce * Math.cos(this.recoilDir); - this.body.accel.y += recoilForce * Math.sin(this.recoilDir); - } - } - } - getSkillRaw() { - if (this.bulletStats === "master") { - return [ - this.body.skill.raw[0], - this.body.skill.raw[1], - this.body.skill.raw[2], - this.body.skill.raw[3], - this.body.skill.raw[4], - 0, - 0, - 0, - 0, - 0, - ]; - } - return this.bulletStats.raw; - } - getPhotoInfo() { - return { - ...this.lastShot, - color: this.color, - alpha: this.alpha, - strokeWidth: this.strokeWidth, - borderless: this.borderless, - drawFill: this.drawFill, - drawAbove: this.drawAbove, - length: this.length, - width: this.width, - aspect: this.aspect, - angle: this.angle, - direction: this.direction, - offset: this.offset, - }; - } - spawnBullets(useWhile, shootPermission) { - // Find out some intermediate values - let angle1 = this.direction + this.angle + this.body.facing, - angle2 = this.angle + this.body.facing, - gunlength = this.length - this.width * this.settings.size / 2, - - // Calculate offsets based on lengths and directions - offsetBaseX = this.offset * Math.cos(angle1), - offsetBaseY = this.offset * Math.sin(angle1), - offsetEndX = gunlength * Math.cos(angle2), - offsetEndY = gunlength * Math.sin(angle2), - - // Finally get the final bullet offset - offsetFinalX = offsetBaseX + offsetEndX, - offsetFinalY = offsetBaseY + offsetEndY, - skill = this.bulletStats === "master" ? this.body.skill : this.bulletStats; - - // Shoot, multiple times in a tick if needed - do { - this.fire(offsetFinalX, offsetFinalY, skill); - this.cycle--; - shootPermission = - this.countsOwnKids ? this.countsOwnKids > this.children.length - : this.body.maxChildren ? this.body.maxChildren > this.body.children.length - : true; - - } while (useWhile && shootPermission && this.cycle-1 >= 1); - } - live() { - this.recoil(); - - if (!this.canShoot) return - - // Find the proper skillset for shooting - let sk = this.bulletStats === "master" ? this.body.skill : this.bulletStats; - // Decides what to do based on child-counting settings - let shootPermission = this.countsOwnKids - ? this.countsOwnKids > - this.children.length * (this.calculator == "necro" ? sk.rld : 1) - : this.body.maxChildren - ? this.body.maxChildren > - this.body.children.length * (this.calculator == "necro" ? sk.rld : 1) - : true; - if (this.destroyOldestChild) { - if (!shootPermission) { - shootPermission = true; - this.destroyOldest(); - } - } - // Override in invuln - if (this.body.master.invuln) { - shootPermission = false; - } - // Cycle up if we should - if (shootPermission || !this.waitToCycle) { - if (this.cycle < 1) { - this.cycle += 1 / (this.settings.reload * c.runSpeed * (this.calculator == "necro" || this.calculator == "fixed reload" ? 1 : sk.rld)); - } - } - // Firing routines - if (shootPermission && - (this.autofire || (this.altFire ? this.body.control.alt : this.body.control.fire)) - ) { - if (this.cycle >= 1) { - this.spawnBullets(true, shootPermission); - } // If we're not shooting, only cycle up to where we'll have the proper firing delay - } else if (this.cycle > !this.waitToCycle - this.delay) { - this.cycle = !this.waitToCycle - this.delay; - } - } - destroyOldest() { - let oldestChild, - oldestTime = Infinity; - for (let i = 0; i < this.children.length; i++) { - let child = this.children[i]; - if (child && child.creationTime < oldestTime) { - oldestTime = child.creationTime; - oldestChild = child; - } - } - if (oldestChild) oldestChild.kill(); - } - syncChildren() { - if (this.syncsSkills) { - let self = this; - for (let i = 0; i < this.children.length; i++) { - let child = this.children[i]; - child.define({ - BODY: self.interpret(), - SKILL: self.getSkillRaw(), - }); - child.refreshBodyAttributes(); - } - } - } - syncTurretSkills() { - if (this.syncTurretSkills) { - let self = this; - for (let i = 0; i < this.turret.length; i++) { - let turret = this.turrets[i]; - turret.define({ - BODY: self.interpret(), - SKILL: self.getSkillRaw(), - }); - turret.refreshBodyAttributes(); - } - } - } - fire(gx, gy, sk) { - // Recoil - this.lastShot.time = util.time(); - this.lastShot.power = 3 * Math.log(Math.sqrt(sk.spd) + this.trueRecoil + 1) + 1; - this.motion += this.lastShot.power; - // Find inaccuracy - let shudder = 0, spread = 0; - if (this.settings.shudder) { - do { - shudder = ran.gauss(0, Math.sqrt(this.settings.shudder)); - } while (Math.abs(shudder) >= this.settings.shudder * 2); - } - if (this.settings.spray) { - do { - spread = ran.gauss(0, this.settings.spray * this.settings.shudder); - } while (Math.abs(spread) >= this.settings.spray / 2); - } - spread *= Math.PI / 180; - // Find speed - let vecLength = (this.negRecoil ? -1 : 1) * this.settings.speed * c.runSpeed * sk.spd * (1 + shudder), - vecAngle = this.angle + this.body.facing + spread, - s = new Vector(vecLength * Math.cos(vecAngle), vecLength * Math.sin(vecAngle)); - // Boost it if we should - if (this.body.velocity.length) { - let extraBoost = - Math.max(0, s.x * this.body.velocity.x + s.y * this.body.velocity.y) / - this.body.velocity.length / - s.length; - if (extraBoost) { - let len = s.length; - s.x += (this.body.velocity.length * extraBoost * s.x) / len; - s.y += (this.body.velocity.length * extraBoost * s.y) / len; - } - } - - //create an independent entity - if (this.independentChildren) { - var o = new Entity({ - x: this.body.x + this.body.size * gx - s.x, - y: this.body.y + this.body.size * gy - s.y, - }); - for (let type of this.bulletTypes) { - o.define(type); - } - o.coreSize = o.SIZE; - o.team = this.body.team; - o.refreshBodyAttributes(); - o.life(); - this.master.triggerOn(undefined, this.altFire ? 'altFire' : 'fire', { gun: this, store: this.store, globalStore: this.globalStore, child: o }); - return; - } - - // Create the bullet - var o = new Entity({ - x: this.body.x + this.body.size * gx - s.x, - y: this.body.y + this.body.size * gy - s.y, - }, - this.master.master - ); - /*let jumpAhead = this.cycle - 1; - if (jumpAhead) { - o.x += s.x * this.cycle / jumpAhead; - o.y += s.y * this.cycle / jumpAhead; - }*/ - o.velocity = s; - this.bulletInit(o); - o.coreSize = o.SIZE; - - this.master.triggerOn(undefined, this.altFire ? 'altFire' : 'fire', { gun: this, store: this.store, globalStore: this.globalStore, child: o }); - } - bulletInit(o) { - // Define it by its natural properties - o.color = undefined; - for (let type of this.bulletTypes) { - o.define(type); - } - // Pass the gun attributes - o.define({ - BODY: this.interpret(), - SKILL: this.getSkillRaw(), - SIZE: (this.body.size * this.width * this.settings.size) / 2, - LABEL: this.master.label + (this.label ? " " + this.label : "") + " " + o.label - }); - if (!o.color || o.colorUnboxed.base == '-1' || o.colorUnboxed.base == 'mirror') { - o.colorUnboxed.base = this.body.master.colorUnboxed.base - o.compressColor(); - } - // Keep track of it and give it the function it needs to deutil.log itself upon death - if (this.countsOwnKids) { - o.parent = this; - this.children.push(o); - } else if (this.body.maxChildren) { - o.parent = this.body; - this.body.children.push(o); - this.children.push(o); - } - o.source = this.body; - o.facing = o.velocity.direction; - // Necromancers. - let oo = o; - o.necro = (host) => { - if (this.countsOwnKids ? - this.countsOwnKids > this.children.length * (this.bulletStats === "master" ? this.body.skill.rld : this.bulletStats.rld) - : this.body.maxChildren ? - this.body.maxChildren > this.body.children.length * (this.bulletStats === "master" ? this.body.skill.rld : this.bulletStats.rld) - : true - ) { - let save = { - facing: host.facing, - size: host.SIZE, - }; - host.define(Class.genericEntity); - this.bulletInit(host); - host.team = oo.master.master.team; - host.master = oo.master; - host.color = oo.color; - host.facing = save.facing; - host.SIZE = save.size; - host.health.amount = host.health.max; - return true; - } - return false; - }; - // Otherwise - o.refreshBodyAttributes(); - o.life(); - this.onShootFunction(); - this.recoilDir = this.body.facing + this.angle; - } - onShootHitscan() { - if (this.body.master.health.amount < 0) return; - let save = { - x: this.body.master.x, - y: this.body.master.y, - angle: this.body.master.facing + this.angle, - }; - let s = this.body.size * this.width * this.settings2.size; - let target = { - x: save.x + this.body.master.control.target.x, - y: save.y + this.body.master.control.target.y, - }; - let amount = (util.getDistance(target, save) / s) | 0; - let gun = this; - let explode = (e) => { - e.on('dead', () => { - let o = new Entity(e, gun.body); - o.accel = { - x: 3 * Math.cos(save.angle), - y: 3 * Math.sin(save.angle), - }; - o.color = gun.body.master.master.color; - o.define(Class.hitScanExplosion); - // Pass the gun attributes - o.define({ - BODY: gun.interpret(gun.settings3), - SKILL: gun.getSkillRaw(), - SIZE: (gun.body.size * gun.width * gun.settings3.size) / 2, - LABEL: gun.master.label + (gun.label ? " " + gun.label + " " : " ") + o.label, - }); - o.refreshBodyAttributes(); - o.life(); - o.source = gun.body; - }); - }; - let branchAlt = 0; - let branchLength = 0; - let branch = (e, a, b = false, g = 0, z = amount) => { - if (!b) branchAlt++; - let total = (z / 5) | 0 || 2; - let dir = (a ? Math.PI / 2 : -Math.PI / 2) + g; - for (let i = 0; i < total; i++) - setTimeout(() => { - let ss = s * 1.5; - let x = e.x + ss * Math.cos(save.angle + dir) * i; - let y = e.y + ss * Math.sin(save.angle + dir) * i; - let o = new Entity( - { - x, - y, - }, - this.body - ); - o.facing = Math.atan2(target.y - y, target.x - x) + dir; - o.color = this.body.master.master.color; - o.define(Class.hitScanBullet); - // Pass the gun attributes - o.define({ - BODY: this.interpret(this.settings3), - SKILL: this.getSkillRaw(), - SIZE: (this.body.size * this.width * this.settings2.size) / 2, - LABEL: - this.master.label + - (this.label ? " " + this.label : "") + - " " + - o.label, - }); - o.refreshBodyAttributes(); - o.life(); - o.source = this.body; - if (i === total - 1) { - if (branchLength < 3) { - branchLength++; - branch(o, a, true, dir + g, total); - } else branchLength = 0; - } - }, (500 / amount) * i); - }; - const hitScanLevel = +this.onShoot.split("hitScan").pop(); - for (let i = 0; i < amount; i++) { - setTimeout(() => { - if (this.body.master.health.amount < 0) return; - let x = save.x + s * Math.cos(save.angle) * i; - let y = save.y + s * Math.sin(save.angle) * i; - let e = new Entity({ x: x, y: y }, this.body); - e.facing = Math.atan2(target.y - y, target.x - x); - e.color = this.body.master.master.color; - e.define(Class.hitScanBullet); - // Pass the gun attributes - e.define({ - BODY: this.interpret(this.settings2), - SKILL: this.getSkillRaw(), - SIZE: (this.body.size * this.width * this.settings2.size) / 2, - LABEL: - this.master.label + - (this.label ? " " + this.label : "") + - " " + - e.label, - }); - e.refreshBodyAttributes(); - e.life(); - e.source = this.body; - switch (hitScanLevel) { - case 1: - if (i % 5 === 0) branch(e, branchAlt % 2 === 0); - break; - case 2:// Superlaser - if (i === amount - 1) explode(e); - break; - case 3:// Death Star - if (i % 3 === 0) explode(e); - break; - } - }, 10 * i); - } - } - onShootFunction() { - switch (this.onShoot) { - case "hitScan": - case "hitScan1": - case "hitScan2": - case "hitScan3": - onShootHitscan(); - break; - } - } - getTracking() { - return { - speed: c.runSpeed * (this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.maxSpeed * this.natural.SPEED, - range: Math.sqrt(this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.range * this.natural.RANGE - }; - } - interpret(alt = false) { - let sizeFactor = this.master.size / this.master.SIZE; - let shoot = alt ? alt : this.settings; - let sk = this.bulletStats == "master" ? this.body.skill : this.bulletStats; - // Defaults - let out = { - SPEED: shoot.maxSpeed * sk.spd, - HEALTH: shoot.health * sk.str, - RESIST: shoot.resist + sk.rst, - DAMAGE: shoot.damage * sk.dam, - PENETRATION: Math.max(1, shoot.pen * sk.pen), - RANGE: shoot.range / Math.sqrt(sk.spd), - DENSITY: (shoot.density * sk.pen * sk.pen) / sizeFactor, - PUSHABILITY: 1 / sk.pen, - HETERO: 3 - 2.8 * sk.ghost, - }; - // Special cases - switch (this.calculator) { - case "thruster": - this.trueRecoil = shoot.recoil * Math.sqrt(sk.rld * sk.spd); - break; - case "sustained": - out.RANGE = shoot.range; - break; - case "swarm": - out.PENETRATION = Math.max(1, shoot.pen * (0.5 * (sk.pen - 1) + 1)); - out.HEALTH /= shoot.pen * sk.pen; - break; - case "trap": - case "block": - out.PUSHABILITY = 1 / Math.pow(sk.pen, 0.5); - out.RANGE = shoot.range; - break; - case "necro": - case "drone": - out.PUSHABILITY = 1; - out.PENETRATION = Math.max(1, shoot.pen * (0.5 * (sk.pen - 1) + 1)); - out.HEALTH = (shoot.health * sk.str + sizeFactor) / Math.pow(sk.pen, 0.8); - out.DAMAGE = shoot.damage * sk.dam * Math.sqrt(sizeFactor) * shoot.pen * sk.pen; - out.RANGE = shoot.range * Math.sqrt(sizeFactor); - break; - } - // Go through and make sure we respect its natural properties - for (let property in out) { - if (this.natural[property] == null || !out.hasOwnProperty(property)) - continue; - out[property] *= this.natural[property]; - } - return out; - } -} - -class antiNaN { - constructor (me) { - this.me = me; - this.nansInARow = 0; - this.data = { x: 1, y: 1, vx: 0, vy: 0, ax: 0, ay: 0 }; - this.amNaN = me => [ me.x, me.y, me.velocity.x, me.velocity.y, me.accel.x, me.accel.y ].some(isNaN); - } - update() { - if (this.amNaN(this.me)) { - this.nansInARow++; - if (this.nansInARow > 50) { - console.log("NaN instance found. (Repeated)\nDebug:", [ - ["x" , isNaN(this.me.x)], - ["y" , isNaN(this.me.y)], - ["velocity.x", isNaN(this.me.velocity.x)], - ["velocity.y", isNaN(this.me.velocity.y)], - ["accel.x" , isNaN(this.me.accel.x)], - ["accel.y" , isNaN(this.me.accel.y)], - ].filter(entry => entry[1]).join(', ')); - } - this.me.x = this.data.x; - this.me.y = this.data.y; - this.me.velocity.x = this.data.vx; - this.me.velocity.y = this.data.vy; - this.me.accel.x = this.data.ax; - this.me.accel.y = this.data.ay; - if (this.amNaN(this.me)) console.log("NaN instance is still NaN."); - } else { - this.data.x = this.me.x; - this.data.y = this.me.y; - this.data.vx = this.me.velocity.x; - this.data.vy = this.me.velocity.y; - this.data.ax = this.me.accel.x; - this.data.ay = this.me.accel.y; - if (this.nansInARow > 0) this.nansInARow--; - } - } -} - -function getValidated(obj, prop, allowedType, from, optional = true) { - let type = typeof obj[prop]; - if (allowedType === type || (optional && 'undefined' === type)) { - return obj[prop]; - } - throw new TypeError(`${from} property ${prop} is of type ${type} instead of type ${allowedType}`); -} -let labelThing = "StatusEffect's effects argument"; -class StatusEffect extends EventEmitter { - constructor (duration = 0, multipliers = {}, tick = a=>a) { - super(); - this.duration = getValidated({duration}, 'duration', 'number', labelThing, false); - this.acceleration = getValidated(multipliers, 'acceleration', 'number', labelThing); - this.topSpeed = getValidated(multipliers, 'topSpeed', 'number', labelThing); - this.health = getValidated(multipliers, 'health', 'number', labelThing); - this.shield = getValidated(multipliers, 'shield', 'number', labelThing); - this.regen = getValidated(multipliers, 'regen', 'number', labelThing); - this.damage = getValidated(multipliers, 'damage', 'number', labelThing); - this.penetration = getValidated(multipliers, 'penetration', 'number', labelThing); - this.range = getValidated(multipliers, 'range', 'number', labelThing); - this.fov = getValidated(multipliers, 'fov', 'number', labelThing); - this.density = getValidated(multipliers, 'density', 'number', labelThing); - this.stealth = getValidated(multipliers, 'stealth', 'number', labelThing); - this.pushability = getValidated(multipliers, 'pushability', 'number', labelThing); - this.recoilReceived = getValidated(multipliers, 'recoilReceived', 'number', labelThing); - this.size = getValidated(multipliers, 'size', 'number', labelThing); - this.tick = getValidated({tick}, 'tick', 'function', "StatusEffect's argument"); - } -} - -let entitiesIdLog = 0; -const forceTwiggle = ["autospin", "turnWithSpeed", "spin", "fastspin", "veryfastspin", "withMotion", "smoothWithMotion", "looseWithMotion"]; -class Entity extends EventEmitter { - constructor(position, master) { - super(); - if (!master) master = this; - this.isGhost = false; - this.killCount = { - solo: 0, - assists: 0, - bosses: 0, - polygons: 0, - killers: [], - }; - this.creationTime = new Date().getTime(); - // Inheritance - this.skipLife = false; - this.master = master; - this.source = this; - this.parent = this; - this.control = { - target: new Vector(0, 0), - goal: new Vector(0, 0), - main: false, - alt: false, - fire: false, - power: 0, - }; - this.isInGrid = false; - this.removeFromGrid = () => { - if (this.isInGrid) { - grid.removeObject(this); - this.isInGrid = false; - } - }; - this.addToGrid = () => { - if (!mockupsLoaded) return; - if (!this.collidingBond && this.bond != null) return; - if (!this.isInGrid) { - grid.addObject(this); - this.isInGrid = true; - } - }; - this.activation = (() => { - let active = true; - let timer = ran.irandom(15); - return { - update: () => { - if (this.skipLife) { - return active = false; - } - if (this.isDead()) { - return 0; - } - if (!active) { - this.removeFromGrid(); - if (this.settings.diesAtRange) { - this.kill(); - } - if (!timer--) { - active = true; - } - } else { - this.addToGrid(); - timer = 15; - active = this.alwaysActive || this.isPlayer || this.isBot || views.some((v) => v.check(this, 0.6)); - } - }, - check: () => { - return active; - }, - }; - })(); - this.autoOverride = false; - this.healer = false; - this.controllers = []; - this.blend = { - color: "#FFFFFF", - amount: 0, - }; - this.reverseTank = 1; - // Objects - this.skill = new Skill(); - this.health = new HealthType(1, "static", 0); - this.shield = new HealthType(0, "dynamic"); - this.guns = []; - this.turrets = []; - this.upgrades = []; - this.settings = {}; - this.aiSettings = {}; - this.children = []; - this.statusEffects = []; - this.colorUnboxed = { - base: 16, - hueShift: 0, - saturationShift: 1, - brightnessShift: 0, - allowBrightnessInvert: false, - }; - this.color = '16 0 1 0 false'; - this.glow = {radius: null, color: null, alpha: 1, recursion: 1} - this.invisible = [0, 0]; - this.alphaRange = [0, 1]; - // Define it - this.SIZE = 1; - this.sizeMultiplier = 1; - this.define("genericEntity"); - // Initalize physics and collision - this.alwaysShowOnMinimap = false; - this.allowedOnMinimap = true; - this.maxSpeed = 0; - this.facingLocked = false; - this.facing = 0; - this.vfacing = 0; - this.range = 0; - this.damageRecieved = 0; - this.recoilMultiplier = 1; - this.stepRemaining = 1; - this.x = position.x; - this.y = position.y; - this.cameraOverrideX = null; - this.cameraOverrideY = null; - this.velocity = new Vector(0, 0); - this.accel = new Vector(0, 0); - this.damp = 0.05; - this.collisionArray = []; - this.perceptionAngleIndependence = 1; - this.firingArc = [0, 360]; - this.invuln = false; - this.alpha = 1; - this.strokeWidth = 1; - this.levelCap = undefined; - this.autospinBoost = 0; - this.antiNaN = new antiNaN(this); - // Get a new unique id - this.id = entitiesIdLog++; - this.team = this.id; - this.team = master.team; - this.turnAngle = 0; - // Stored Variables - this.globalStore = {}; - this.store = {}; - // This is for collisions - this.AABB_data = {}; - this.AABB_savedSize = 0; - this.collidingBond = false - this.updateAABB = (active) => { - if (!this.collidingBond && this.bond != null) return 0; - if (!active) { - this.AABB_data.active = false; - return 0; - } - if (this.isPlayer && !this.isDead()) this.refreshBodyAttributes(); - this.antiNaN.update(); - // Get bounds - let x1 = Math.min(this.x, this.x + this.velocity.x + this.accel.x) - this.realSize - 5; - let y1 = Math.min(this.y, this.y + this.velocity.y + this.accel.y) - this.realSize - 5; - let x2 = Math.max(this.x, this.x + this.velocity.x + this.accel.x) + this.realSize + 5; - let y2 = Math.max(this.y, this.y + this.velocity.y + this.accel.y) + this.realSize + 5; - let size = Math.max(Math.abs(x2 - x1), Math.abs(y2 - y1)); - let sizeDiff = this.AABB_savedSize / size; - // Update data - this.AABB_data = { - min: [x1, y1], - max: [x2, y2], - active: true, - size: size, - }; - // Update grid if needed - if (sizeDiff > Math.SQRT2 || sizeDiff < Math.SQRT1_2) { - this.removeFromGrid(); - this.addToGrid(); - this.AABB_savedSize = size; - } - }; - this.getAABB = () => this.AABB_data; - this.updateAABB(true); - entities.push(this); - for (let v of views) v.add(this); - this.activation.update(); - events.emit('spawn', this); - } - addStatusEffect(effect) { - this.emit('newStatusEffect', effect); - this.statusEffects.push({ durationLeftover: effect.duration, effect }); - this.refreshBodyAttributes(); - } - life() { - // Size - this.coreSize = this.SIZE; - // Invisibility - if (!this.damageReceived && (this.velocity.x ** 2 + this.velocity.y ** 2 <= 0.1)) { - this.alpha = Math.max(this.alphaRange[0], this.alpha - this.invisible[1]); - } else { - this.alpha = Math.min(this.alphaRange[1], this.alpha + this.invisible[0]); - } - - let lastingEffects = [], needsBodyAttribRefresh = false; - for (let i = 0; i < this.statusEffects.length; i++) { - let entry = this.statusEffects[i]; - entry.durationLeftover -= 1 / c.runSpeed; - if (entry.durationLeftover > 0) { - lastingEffects.push(entry); - } else { - needsBodyAttribRefresh = true; - this.emit('expiredStatusEffect', entry.effect); - } - if (entry.effect.tick && entry.effect.tick(this, entry.effect, entry.durationLeftover)) { - needsBodyAttribRefresh = true; - } - } - this.statusEffects = lastingEffects; - - // Think - let faucet = this.settings.independent || this.source == null || this.source === this ? {} : this.source.control, - b = { - target: remapTarget(faucet, this.source, this), - goal: undefined, - fire: faucet.fire, - main: faucet.main, - alt: faucet.alt, - power: undefined, - }; - // Seek attention - if (this.settings.attentionCraver && !faucet.main && this.range) { - this.range -= 1; - } - // So we start with my master's thoughts and then we filter them down through our control stack - for (let i = 0; i < this.controllers.length; i++) { - let AI = this.controllers[i], - a = AI.think(b); - if (a != null) { - if (a.target != null && (b.target == null || AI.acceptsFromTop)) b.target = a.target; - if (a.goal != null && (b.goal == null || AI.acceptsFromTop)) b.goal = a.goal ; - if (a.fire != null && (b.fire == null || AI.acceptsFromTop)) b.fire = a.fire ; - if (a.main != null && (b.main == null || AI.acceptsFromTop)) b.main = a.main ; - if (a.alt != null && (b.alt == null || AI.acceptsFromTop)) b.alt = a.alt ; - if (a.power != null && (b.power == null || AI.acceptsFromTop)) b.power = a.power ; - } - } - this.control.target = b.target == null ? this.control.target : b.target; - this.control.goal = b.goal ? b.goal : { x: this.x, y: this.y }; - this.control.fire = b.fire; - this.control.main = b.main; - this.control.alt = b.alt; - this.control.power = b.power == null ? 1 : b.power; - - if (this.invuln && (this.control.goal.x !== this.x || this.control.goal.y !== this.y)) { - this.invuln = false; - } - - // React - this.move(); - this.face(); - // Handle guns and turrets if we've got them - for (let i = 0; i < this.guns.length; i++) this.guns[i].live(); - for (let i = 0; i < this.turrets.length; i++) this.turrets[i].life(); - if (this.skill.maintain()) needsBodyAttribRefresh = true; - if (needsBodyAttribRefresh) this.refreshBodyAttributes(); - } - addController(newIO) { - let listenToPlayer; - if (this.controllers && this.controllers[0] instanceof ioTypes.listenToPlayer) { - listenToPlayer = this.controllers.shift(); - } - if (!Array.isArray(newIO)) newIO = [newIO]; - for (let io of newIO) { - for (let i in this.controllers) { - let oldIO = this.controllers[i]; - if (io.constructor === oldIO.constructor) this.controllers.splice(i, 1); - } - } - this.controllers = newIO.concat(this.controllers); - if (listenToPlayer) this.controllers.unshift(listenToPlayer); - } - become(player, dom = false) { - this.addController(new ioTypes.listenToPlayer(this, { player, static: dom })); - this.sendMessage = (content, color) => player.socket.talk("m", content); - this.kick = (reason) => player.socket.kick(reason); - } - giveUp(player, name = "Mothership") { - if (!player.body.isMothership) { - player.body.controllers = [ - new ioTypes.nearestDifferentMaster(player.body), - new ioTypes.spin(player.body, { onlyWhenIdle: true }), - ]; - } else { - player.body.controllers = [ - new ioTypes.nearestDifferentMaster(player.body), - new ioTypes.wanderAroundMap(player.body, { lookAtGoal: true }), - new ioTypes.mapTargetToGoal(player.body), - ]; - } - player.body.name = player.body.label; - player.body.underControl = false; - player.body.sendMessage = () => {}; - let fakeBody = new Entity({ x: player.body.x, y: player.body.y }); - fakeBody.passive = true; - fakeBody.underControl = true; - player.body = fakeBody; - player.body.kill(); - } - compressColor() { - this.color = this.colorUnboxed.base + " " + this.colorUnboxed.hueShift + " " + this.colorUnboxed.saturationShift + " " + this.colorUnboxed.brightnessShift + " " + this.colorUnboxed.allowBrightnessInvert; - } - define(defs, emitEvent = true) { - if (!Array.isArray(defs)) defs = [defs]; - - // Define all primary stats - let set = ensureIsClass(defs[0]); - this.store = {}; - for (let gun of this.guns) gun.store = {}; - - if (set.PARENT != null) { - if (Array.isArray(set.PARENT)) { - for (let i = 0; i < set.PARENT.length; i++) { - this.define(set.PARENT[i], false); - } - } else { - this.define(set.PARENT, false); - } - } - if (set.LAYER != null) this.layerID = set.LAYER; - if (set.index != null) this.index = set.index.toString(); - if (set.NAME != null) this.name = set.NAME; - if (set.LABEL != null) this.label = set.LABEL; - if (set.ANGLE != null) this.angle = set.ANGLE; - if (set.UPGRADE_LABEL != null) this.upgradeLabel = set.UPGRADE_LABEL; - if (set.UPGRADE_TOOLTIP != null) this.upgradeTooltip = set.UPGRADE_TOOLTIP; - if (set.DISPLAY_NAME != null) this.displayName = set.DISPLAY_NAME; - if (set.TYPE != null) this.type = set.TYPE; - if (set.SHAPE != null) { - this.shape = typeof set.SHAPE === "number" ? set.SHAPE : 0; - this.shapeData = set.SHAPE; - } - this.imageInterpolation = set.IMAGE_INTERPOLATION != null ? set.IMAGE_INTERPOLATION : 'bilinear' - if (set.COLOR != null) { - if (typeof set.COLOR === "number" || typeof set.COLOR === 'string') - this.colorUnboxed.base = set.COLOR; - else if (typeof set.COLOR === "object") { - if (set.COLOR.BASE != null) this.colorUnboxed.base = set.COLOR.BASE; - if (set.COLOR.HUE_SHIFT != null) this.colorUnboxed.hueShift = set.COLOR.HUE_SHIFT; - if (set.COLOR.SATURATION_SHIFT != null) this.colorUnboxed.saturationShift = set.COLOR.SATURATION_SHIFT; - if (set.COLOR.BRIGHTNESS_SHIFT != null) this.colorUnboxed.brightnessShift = set.COLOR.BRIGHTNESS_SHIFT; - if (set.COLOR.ALLOW_BRIGHTNESS_INVERT != null) this.colorUnboxed.allowBrightnessInvert = set.COLOR.ALLOW_BRIGHTNESS_INVERT; - } - this.compressColor(); - } - this.upgradeColor = set.UPGRADE_COLOR == null ? null : set.UPGRADE_COLOR; - if (set.GLOW != null) { - this.glow = { - radius: set.GLOW.RADIUS ?? 0, - color: set.GLOW.COLOR ?? null, - alpha: set.GLOW.ALPHA ?? 1, - recursion: set.GLOW.RECURSION ?? 1 - }; - } - if (set.CONTROLLERS != null) { - let toAdd = []; - for (let i = 0; i < set.CONTROLLERS.length; i++) { - let io = set.CONTROLLERS[i]; - if ("string" == typeof io) io = [io]; - toAdd.push(new ioTypes[io[0]](this, io[1])); - } - this.addController(toAdd); - } - if (set.IGNORED_BY_AI != null) this.ignoredByAi = set.IGNORED_BY_AI; - if (set.MOTION_TYPE != null) this.motionType = set.MOTION_TYPE; - if (typeof this.motionType == "string") this.motionType = [this.motionType]; - if (set.FACING_TYPE != null) this.facingType = set.FACING_TYPE; - if (typeof this.facingType == "string") this.facingType = [this.facingType]; - if (set.MIRROR_MASTER_ANGLE != null) this.settings.mirrorMasterAngle = set.MIRROR_MASTER_ANGLE - if (set.DRAW_HEALTH != null) this.settings.drawHealth = set.DRAW_HEALTH; - if (set.DRAW_SELF != null) this.settings.drawShape = set.DRAW_SELF; - if (set.DAMAGE_EFFECTS != null) this.settings.damageEffects = set.DAMAGE_EFFECTS; - if (set.RATIO_EFFECTS != null) this.settings.ratioEffects = set.RATIO_EFFECTS; - if (set.MOTION_EFFECTS != null) this.settings.motionEffects = set.MOTION_EFFECTS; - if (set.ACCEPTS_SCORE != null) this.settings.acceptsScore = set.ACCEPTS_SCORE; - if (set.GIVE_KILL_MESSAGE != null) this.settings.givesKillMessage = set.GIVE_KILL_MESSAGE; - if (set.CAN_GO_OUTSIDE_ROOM != null) this.settings.canGoOutsideRoom = set.CAN_GO_OUTSIDE_ROOM; - if (set.HITS_OWN_TYPE != null) this.settings.hitsOwnType = set.HITS_OWN_TYPE; - if (set.DIE_AT_LOW_SPEED != null) this.settings.diesAtLowSpeed = set.DIE_AT_LOW_SPEED; - if (set.DIE_AT_RANGE != null) this.settings.diesAtRange = set.DIE_AT_RANGE; - if (set.INDEPENDENT != null) this.settings.independent = set.INDEPENDENT; - if (set.PERSISTS_AFTER_DEATH != null) this.settings.persistsAfterDeath = set.PERSISTS_AFTER_DEATH; - if (set.CLEAR_ON_MASTER_UPGRADE != null) this.settings.clearOnMasterUpgrade = set.CLEAR_ON_MASTER_UPGRADE; - if (set.HEALTH_WITH_LEVEL != null) this.settings.healthWithLevel = set.HEALTH_WITH_LEVEL; - if (set.ACCEPTS_SCORE != null) this.settings.acceptsScore = set.ACCEPTS_SCORE; - if (set.OBSTACLE != null) this.settings.obstacle = set.OBSTACLE; - if (set.NECRO != null) this.settings.necroTypes = Array.isArray(set.NECRO) ? set.NECRO : set.NECRO ? [this.shape] : []; - if (set.HAS_NO_RECOIL != null) this.settings.hasNoRecoil = set.HAS_NO_RECOIL; - if (set.CRAVES_ATTENTION != null) this.settings.attentionCraver = set.CRAVES_ATTENTION; - if (set.KILL_MESSAGE != null) this.settings.killMessage = set.KILL_MESSAGE === "" ? "Killed" : set.KILL_MESSAGE; - if (set.AUTOSPIN_MULTIPLIER != null) this.autospinBoost = set.AUTOSPIN_MULTIPLIER; - if (set.BROADCAST_MESSAGE != null) this.settings.broadcastMessage = set.BROADCAST_MESSAGE === "" ? undefined : set.BROADCAST_MESSAGE; - if (set.DEFEAT_MESSAGE) this.settings.defeatMessage = true; - if (set.HEALER) this.healer = true; - if (set.DAMAGE_CLASS != null) this.settings.damageClass = set.DAMAGE_CLASS; - if (set.BUFF_VS_FOOD != null) this.settings.buffVsFood = set.BUFF_VS_FOOD; - if (set.CAN_BE_ON_LEADERBOARD != null) this.settings.leaderboardable = set.CAN_BE_ON_LEADERBOARD; - if (set.INTANGIBLE != null) this.intangibility = set.INTANGIBLE; - if (set.IS_SMASHER != null) this.settings.reloadToAcceleration = set.IS_SMASHER; - if (set.STAT_NAMES != null) this.settings.skillNames = { - body_damage: set.STAT_NAMES?.BODY_DAMAGE ?? 'Body Damage', - max_health: set.STAT_NAMES?.MAX_HEALTH ?? 'Max Health', - bullet_speed: set.STAT_NAMES?.BULLET_SPEED ?? 'Bullet Speed', - bullet_health: set.STAT_NAMES?.BULLET_HEALTH ?? 'Bullet Health', - bullet_pen: set.STAT_NAMES?.BULLET_PEN ?? 'Bullet Penetration', - bullet_damage: set.STAT_NAMES?.BULLET_DAMAGE ?? 'Bullet Damage', - reload: set.STAT_NAMES?.RELOAD ?? 'Reload', - move_speed: set.STAT_NAMES?.MOVE_SPEED ?? 'Movement Speed', - shield_regen: set.STAT_NAMES?.SHIELD_REGEN ?? 'Shield Regeneration', - shield_cap: set.STAT_NAMES?.SHIELD_CAP ?? 'Shield Capacity', - }; - if (set.AI != null) this.aiSettings = set.AI; - if (set.INVISIBLE != null) this.invisible = set.INVISIBLE; - if (set.ALPHA != null) { - this.alpha = ("number" === typeof set.ALPHA) ? set.ALPHA : set.ALPHA[1]; - this.alphaRange = [ - set.ALPHA[0] || 0, - set.ALPHA[1] || 1 - ]; - } - if (set.STROKE_WIDTH != null) this.strokeWidth = set.STROKE_WIDTH - if (set.DANGER != null) this.dangerValue = set.DANGER; - if (set.SHOOT_ON_DEATH != null) this.shootOnDeath = set.SHOOT_ON_DEATH; - if (set.BORDERLESS != null) this.borderless = set.BORDERLESS; - if (set.DRAW_FILL != null) this.drawFill = set.DRAW_FILL; - if (set.TEAM != null) { - this.team = set.TEAM; - if (!sockets.players.length) { - const _entity = this; - for (let i = 0; i < sockets.players.length; i++) { - if (sockets.players[i].body.id == _entity.id) { - sockets.players[i].team = -_entity.team; - } - } - } - for (let child of this.children) child.team = set.TEAM - } - if (set.SYNC_TURRET_SKILLS != null) this.syncTurretSkills = set.SYNC_TURRET_SKILLS; - if (set.VARIES_IN_SIZE != null) { - this.settings.variesInSize = set.VARIES_IN_SIZE; - this.squiggle = this.settings.variesInSize ? ran.randomRange(0.8, 1.2) : 1; - } - if (set.RESET_UPGRADES || set.RESET_STATS) { - let caps = this.skill.caps.map(x=>x); - this.skill.setCaps(Array(10).fill(0)); - this.skill.setCaps(caps); - this.upgrades = []; - this.isArenaCloser = false; - this.ac = false; - this.alpha = 1; - this.reset(); - } - if (set.RESET_UPGRADE_MENU) this.upgrades = [] - if (set.ARENA_CLOSER != null) { - this.isArenaCloser = set.ARENA_CLOSER; - this.ac = set.ARENA_CLOSER; - } - if (set.BRANCH_LABEL != null) this.branchLabel = set.BRANCH_LABEL; - if (set.BATCH_UPGRADES != null) this.batchUpgrades = set.BATCH_UPGRADES; - for (let i = 0; i < c.MAX_UPGRADE_TIER; i++) { - let tierProp = 'UPGRADES_TIER_' + i; - if (set[tierProp] != null && emitEvent) { - for (let j = 0; j < set[tierProp].length; j++) { - let upgrades = set[tierProp][j]; - let index = ""; - if (!Array.isArray(upgrades)) upgrades = [upgrades]; - let redefineAll = upgrades.includes(true); - let trueUpgrades = upgrades.slice(0, upgrades.length - redefineAll); // Ignore last element if it's true - for (let k of trueUpgrades) { - let e = ensureIsClass(k); - index += e.index + "-"; - } - this.upgrades.push({ - class: trueUpgrades, - level: c.TIER_MULTIPLIER * i, - index: index.substring(0, index.length-1), - tier: i, - branch: 0, - branchLabel: this.branchLabel, - redefineAll, - }); - } - } - } - if (set.SIZE != null) { - this.SIZE = set.SIZE * this.squiggle; - if (this.coreSize == null) this.coreSize = this.SIZE; - } - if (set.LEVEL_CAP != null) { - this.levelCap = set.LEVEL_CAP; - } - if (set.LEVEL != null) { - this.skill.reset(); - while (this.skill.level < set.LEVEL) { - this.skill.score += this.skill.levelScore; - this.skill.maintain(); - } - this.refreshBodyAttributes(); - } - if (set.SKILL_CAP != null && set.SKILL_CAP != []) { - if (set.SKILL_CAP.length != 10) throw "Inappropiate skill cap amount."; - this.skill.setCaps(set.SKILL_CAP); - } - if (set.SKILL != null && set.SKILL != []) { - if (set.SKILL.length != 10) throw "Inappropiate skill raws."; - this.skill.set(set.SKILL); - } - if (set.VALUE != null) this.skill.score = Math.max(this.skill.score, set.VALUE * this.squiggle); - if (set.ALT_ABILITIES != null) this.abilities = set.ALT_ABILITIES; - if (set.GUNS != null) { - let newGuns = []; - for (let i = 0; i < set.GUNS.length; i++) { - newGuns.push(new Gun(this, set.GUNS[i])); - } - this.guns = newGuns; - } - if (set.MAX_CHILDREN != null) this.maxChildren = set.MAX_CHILDREN; - if (set.RESET_CHILDREN) this.destroyAllChildren(); - if ("function" === typeof set.LEVEL_SKILL_POINT_FUNCTION) { - this.skill.LSPF = set.LEVEL_SKILL_POINT_FUNCTION; - } - if (set.RECALC_SKILL != null) { - let score = this.skill.score; - this.skill.reset(); - this.skill.score = score; - while (this.skill.maintain()) {} - } - if (set.EXTRA_SKILL != null) { - this.skill.points += set.EXTRA_SKILL; - } - if (set.BODY != null) { - if (set.BODY.ACCELERATION != null) this.ACCELERATION = set.BODY.ACCELERATION; - if (set.BODY.SPEED != null) this.SPEED = set.BODY.SPEED; - if (set.BODY.HEALTH != null) this.HEALTH = set.BODY.HEALTH; - if (set.BODY.RESIST != null) this.RESIST = set.BODY.RESIST; - if (set.BODY.SHIELD != null) this.SHIELD = set.BODY.SHIELD; - if (set.BODY.REGEN != null) this.REGEN = set.BODY.REGEN; - if (set.BODY.DAMAGE != null) this.DAMAGE = set.BODY.DAMAGE; - if (set.BODY.PENETRATION != null) this.PENETRATION = set.BODY.PENETRATION; - if (set.BODY.RANGE != null) this.RANGE = set.BODY.RANGE; - if (set.BODY.FOV != null) this.FOV = set.BODY.FOV; - if (set.BODY.SHOCK_ABSORB != null) this.SHOCK_ABSORB = set.BODY.SHOCK_ABSORB; - if (set.BODY.RECOIL_MULTIPLIER != null) this.RECOIL_MULTIPLIER = set.BODY.RECOIL_MULTIPLIER; - if (set.BODY.DENSITY != null) this.DENSITY = set.BODY.DENSITY; - if (set.BODY.STEALTH != null) this.STEALTH = set.BODY.STEALTH; - if (set.BODY.PUSHABILITY != null) this.PUSHABILITY = set.BODY.PUSHABILITY; - if (set.BODY.HETERO != null) this.heteroMultiplier = set.BODY.HETERO; - this.refreshBodyAttributes(); - } - if (set.SPAWN_ON_DEATH) this.spawnOnDeath = set.SPAWN_ON_DEATH; - if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; - if (Array.isArray(this.rerootUpgradeTree)) { - let finalRoot = ""; - for (let root of this.rerootUpgradeTree) finalRoot += root + "\\/"; - this.rerootUpgradeTree = finalRoot.substring(0, finalRoot.length - 2); - } - if (set.ON_MINIMAP != null) this.allowedOnMinimap = set.ON_MINIMAP; - if (set.TURRETS != null) { - for (let i = 0; i < this.turrets.length; i++) { - this.turrets[i].destroy(); - } - this.turrets = []; - for (let i = 0; i < set.TURRETS.length; i++) { - let def = set.TURRETS[i], - o = new Entity(this, this.master), - turretDanger = false, - type = Array.isArray(def.TYPE) ? def.TYPE : [def.TYPE]; - for (let j = 0; j < type.length; j++) { - o.define(type[j]); - if (type.TURRET_DANGER) turretDanger = true; - } - if (!turretDanger) o.define({ DANGER: 0 }); - o.collidingBond = def.VULNERABLE - o.bindToMaster(def.POSITION, this, def.VULNERABLE); - } - } - if (set.ON != null) this.onDef = set.ON; - this.reverseTargetWithTank = set.REVERSE_TARGET_WITH_TANK ?? false; - if (set.mockup != null) { - this.mockup = set.mockup; - } - - if (emitEvent) { - this.emit('define', set); - } - - if (this.onDef != null) { - this.triggerOn(this.onDef, 'define') - } - - this.defs = []; - for (let def of defs) this.defs.push(def); - - // Define additional stats for other split upgrades - for (let branch = 1; branch < defs.length; branch++) { - set = ensureIsClass(defs[branch]); - - if (set.index != null) this.index += "-" + set.index; - if (set.PARENT != null) { - if (Array.isArray(set.PARENT)) { - for (let i = 0; i < set.PARENT.length; i++) { - this.branchLabel = ensureIsClass(set.PARENT[i]).BRANCH_LABEL; - } - } else { - this.branchLabel = ensureIsClass(set.PARENT).BRANCH_LABEL; - } - } - if (set.LABEL != null && set.LABEL.length > 0) this.label = this.label + "-" + set.LABEL; - if (set.MAX_CHILDREN != null) this.maxChildren += set.MAX_CHILDREN; - else this.maxChildren = null; // For bullet and drone combos so all parts remain functional - if (set.BODY != null) { - if (set.BODY.ACCELERATION != null) this.ACCELERATION *= set.BODY.ACCELERATION; - if (set.BODY.SPEED != null) this.SPEED *= set.BODY.SPEED; - if (set.BODY.HEALTH != null) this.HEALTH *= set.BODY.HEALTH; - if (set.BODY.RESIST != null) this.RESIST *= set.BODY.RESIST; - if (set.BODY.SHIELD != null) this.SHIELD *= set.BODY.SHIELD; - if (set.BODY.REGEN != null) this.REGEN *= set.BODY.REGEN; - if (set.BODY.DAMAGE != null) this.DAMAGE *= set.BODY.DAMAGE; - if (set.BODY.PENETRATION != null) this.PENETRATION *= set.BODY.PENETRATION; - if (set.BODY.RANGE != null) this.RANGE *= set.BODY.RANGE; - if (set.BODY.FOV != null) this.FOV *= set.BODY.FOV; - if (set.BODY.SHOCK_ABSORB != null) this.SHOCK_ABSORB *= set.BODY.SHOCK_ABSORB; - if (set.BODY.RECOIL_MULTIPLIER != null) this.RECOIL_MULTIPLIER *= set.BODY.RECOIL_MULTIPLIER; - if (set.BODY.DENSITY != null) this.DENSITY *= set.BODY.DENSITY; - if (set.BODY.STEALTH != null) this.STEALTH *= set.BODY.STEALTH; - if (set.BODY.PUSHABILITY != null) this.PUSHABILITY *= set.BODY.PUSHABILITY; - if (set.BODY.HETERO != null) this.heteroMultiplier *= set.BODY.HETERO; - this.refreshBodyAttributes(); - } - if (set.GUNS != null) { - let newGuns = []; - for (let i = 0; i < set.GUNS.length; i++) { - newGuns.push(new Gun(this, set.GUNS[i])); - } - this.guns.push(...newGuns); - } - if (set.TURRETS != null) { - for (let i = 0; i < set.TURRETS.length; i++) { - let def = set.TURRETS[i], - o = new Entity(this, this.master), - turretDanger = false, - type = Array.isArray(def.TYPE) ? def.TYPE : [def.TYPE]; - for (let j = 0; j < type.length; j++) { - o.define(type[j]); - if (type.TURRET_DANGER) turretDanger = true; - } - if (!turretDanger) o.define({ DANGER: 0 }); - o.bindToMaster(def.POSITION, this); - } - } - if (set.SIZE != null) { - this.SIZE *= set.SIZE * this.squiggle; - if (this.coreSize == null) this.coreSize = this.SIZE; - } - if (set.BATCH_UPGRADES != null) this.batchUpgrades = set.BATCH_UPGRADES; - for (let i = 0; i < c.MAX_UPGRADE_TIER; i++) { - let tierProp = 'UPGRADES_TIER_' + i; - if (set[tierProp] != null && emitEvent) { - for (let j = 0; j < set[tierProp].length; j++) { - let upgrades = set[tierProp][j]; - let index = ""; - if (!Array.isArray(upgrades)) upgrades = [upgrades]; - let redefineAll = upgrades.includes(true); - let trueUpgrades = upgrades.slice(0, upgrades.length - redefineAll); // Ignore last element if it's true - for (let k of trueUpgrades) { - let e = ensureIsClass(k); - index += e.index + "-"; - } - this.upgrades.push({ - class: trueUpgrades, - level: c.TIER_MULTIPLIER * i, - index: index.substring(0, index.length-1), - tier: i, - branch, - branchLabel: this.branchLabel, - redefineAll, - }); - } - } - } - if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; - if (Array.isArray(this.rerootUpgradeTree)) { - let finalRoot = ""; - for (let root of this.rerootUpgradeTree) finalRoot += root + "\\/"; - this.rerootUpgradeTree += finalRoot.substring(0, finalRoot.length - 2); - } - } - // Turret layer ordering - this.turrets.sort(this.turretSort); - - // Batch upgrades - if (this.batchUpgrades && emitEvent) { - this.tempUpgrades = []; - let numBranches = this.defs.length; - for (let i = 0; i < numBranches; i++) { // Create a 2d array for the upgrades (1st index is branch index) - this.tempUpgrades.push([]); - } - for (let upgrade of this.upgrades) { - let upgradeBranch = upgrade.branch; - this.tempUpgrades[upgradeBranch].push(upgrade); - } - - this.upgrades = []; - this.selection = JSON.parse(JSON.stringify(this.defs)); - this.chooseUpgradeFromBranch(numBranches); // Recursively build upgrade options - } - } - turretSort(a, b) { - return a.bound.layer - b.bound.layer; - } - chooseUpgradeFromBranch(remaining) { - if (remaining > 0) { // If there's more to select - let branchUgrades = this.tempUpgrades[this.defs.length - remaining]; - for (let i = 0; i < branchUgrades.length; i++) { // Pick all possible options and continue selecting - this.selection[this.defs.length - remaining] = branchUgrades[i]; - this.chooseUpgradeFromBranch(remaining - 1); - } - if (branchUgrades.length == 0) // For when the branch has no upgrades - this.chooseUpgradeFromBranch(remaining - 1); - } else { // If there's nothing more to select - let upgradeClass = [], - upgradeTier = 0, - upgradeIndex = ""; - for (let u of this.selection) { - upgradeClass.push(u.class); - upgradeIndex += u.index + '-'; - upgradeTier = Math.max(upgradeTier, u.tier); - } - this.upgrades.push({ - class: upgradeClass, - level: c.TIER_MULTIPLIER * upgradeTier, - index: upgradeIndex.substring(0, upgradeIndex.length-1), - tier: upgradeTier, - branch: 0, - branchLabel: "", - redefineAll: true, - }); - } - } - triggerOn(onDef = this.onDef, eventTriggered, value) { - if (onDef == null) return - const commonValues = { - body: this, - masterStore: this.store, - globalMasterStore: this.globalStore, - gunStore: value.store, - globalGunStore: value.globalStore - } - for (let onPairs of onDef) { - switch (onPairs.event) { - case 'fire': - if (eventTriggered == 'fire') onPairs.handler({ - ...commonValues, - gun: value.gun, - child: value.child, - }) - break; - case 'altFire': - if (eventTriggered == 'altFire') onPairs.handler({ - ...commonValues, - gun: value.gun, - child: value.child, - }) - case 'death': - if (eventTriggered == 'death') onPairs.handler({ - ...commonValues, - killers: value.killers, - killTools: value.killTools - }) - break; - case 'collide': - if (eventTriggered == 'collide') onPairs.handler({ - ...commonValues, - instance: value.instance, - other: value.other - }) - break; - case 'damage': - if (eventTriggered == 'damage') onPairs.handler({ - ...commonValues, - damageInflictor: value.damageInflictor, - damageTool: value.damageTool - }) - break; - case 'upgrade': - if (eventTriggered == 'upgrade') onPairs.handler({ - ...commonValues, - oldEntity: value.oldEntity - }) - break; - case 'tick': - if (eventTriggered == 'tick') onPairs.handler({ - ...commonValues - }) - break; - case 'define': - if (eventTriggered == 'define') onPairs.handler({ - ...commonValues - }) - break; - case 'trigger': - if (eventTriggered == 'trigger') onPairs.handler({ - ...commonValues, - info: value.info - }) - break; - case 'animationStart': - if (eventTriggered == 'animationStart') onPairs.handler({ - ...commonValues, - animationName: value.animationName, - time: value.time - }) - break; - case 'animationIteration': - if (eventTriggered == 'animationStart') onPairs.handler({ - ...commonValues, - animationName: value.animationName, - time: value.time - }) - break; - case 'animationEnd': - if (eventTriggered == 'animationStart') onPairs.handler({ - ...commonValues, - animationName: value.animationName, - time: value.time - }) - break; - } - } - } - refreshBodyAttributes() { - let accelerationMultiplier = 1, - topSpeedMultiplier = 1, - healthMultiplier = 1, - shieldMultiplier = 1, - regenMultiplier = 1, - damageMultiplier = 1, - penetrationMultiplier = 1, - rangeMultiplier = 1, - fovMultiplier = 1, - densityMultiplier = 1, - stealthMultiplier = 1, - pushabilityMultiplier = 1, - sizeMultiplier = 1, - recoilReceivedMultiplier = 1; - for (let i = 0; i < this.statusEffects.length; i++) { - let effect = this.statusEffects[i].effect; - if (effect.acceleration != null) accelerationMultiplier *= effect.acceleration; - if (effect.topSpeed != null) topSpeedMultiplier *= effect.topSpeed; - if (effect.health != null) healthMultiplier *= effect.health; - if (effect.shield != null) shieldMultiplier *= effect.shield; - if (effect.regen != null) regenMultiplier *= effect.regen; - if (effect.damage != null) damageMultiplier *= effect.damage; - if (effect.penetration != null) penetrationMultiplier *= effect.penetration; - if (effect.range != null) rangeMultiplier *= effect.range; - if (effect.fov != null) fovMultiplier *= effect.fov; - if (effect.density != null) densityMultiplier *= effect.density; - if (effect.stealth != null) stealthMultiplier *= effect.stealth; - if (effect.pushability != null) pushabilityMultiplier *= effect.pushability; - if (effect.recoilReceived != null) recoilReceivedMultiplier *= effect.recoilReceived; - if (effect.size != null) sizeMultiplier *= effect.size; - } - - let speedReduce = Math.pow(this.size / (this.coreSize || this.SIZE), 1); - this.acceleration = (accelerationMultiplier * c.runSpeed * this.ACCELERATION) / speedReduce; - if (this.settings.reloadToAcceleration) this.acceleration *= this.skill.acl; - this.topSpeed = (topSpeedMultiplier * c.runSpeed * this.SPEED * this.skill.mob) / speedReduce; - if (this.settings.reloadToAcceleration) this.topSpeed /= Math.sqrt(this.skill.acl); - this.health.set(((this.settings.healthWithLevel ? 2 * this.level : 0) + this.HEALTH) * this.skill.hlt * healthMultiplier); - this.health.resist = 1 - 1 / Math.max(1, this.RESIST + this.skill.brst); - this.shield.set(((this.settings.healthWithLevel ? 0.6 * this.level : 0) + this.SHIELD) * this.skill.shi, Math.max(0, ((this.settings.healthWithLevel ? 0.006 * this.level : 0) + 1) * this.REGEN * this.skill.rgn * regenMultiplier)); - this.damage = damageMultiplier * this.DAMAGE * this.skill.atk * !this.pacify; - this.penetration = penetrationMultiplier * (this.PENETRATION + 1.5 * (this.skill.brst + 0.8 * (this.skill.atk - 1))); - if (!this.settings.dieAtRange || !this.range) this.range = rangeMultiplier * this.RANGE; - this.fov = fovMultiplier * this.FOV * 275 * Math.sqrt(this.size); - this.density = densityMultiplier * (1 + 0.08 * this.level) * this.DENSITY; - this.stealth = stealthMultiplier * this.STEALTH; - this.pushability = pushabilityMultiplier * this.PUSHABILITY; - this.sizeMultiplier = sizeMultiplier; - this.recoilMultiplier = this.RECOIL_MULTIPLIER * recoilReceivedMultiplier; - } - bindToMaster(position, bond, isInvulnerable) { - this.bond = bond; - this.source = bond; - this.bond.turrets.push(this); - this.skill = this.bond.skill; - this.label = this.label.length ? this.bond.label + " " + this.label : this.bond.label; - // It will not be in collision calculations any more nor shall it be seen or continue to run independently. - if (!isInvulnerable) { - this.removeFromGrid(); - this.skipLife = true; - } - // TODO: FIX CLIENT MAKING EVERYTHING FLASH WHEN A VULN TURRET DIES, and display health - if (isInvulnerable) this.on('dead', () => {util.remove(this.master.turrets, this.master.turrets.indexOf(this))}) - this.settings.drawShape = false; - // Get my position. - if (Array.isArray(position)) { - position = { - SIZE: position[0], - X: position[1], - Y: position[2], - ANGLE: position[3], - ARC: position[4], - LAYER: position[5] - }; - } - position.SIZE ??= 10; - position.X ??= 0; - position.Y ??= 0; - position.ANGLE ??= 0; - position.ARC ??= 360; - position.LAYER ??= 0; - let _off = new Vector(position.X, position.Y); - this.bound = { - size: position.SIZE / 20, - angle: position.ANGLE * Math.PI / 180, - direction: _off.direction, - offset: _off.length / 10, - arc: position.ARC * Math.PI / 180, - layer: position.LAYER - }; - // Initalize. - this.activation.update(); - this.facing = this.bond.facing + this.bound.angle; - this.facingType = ["bound"]; - this.motionType = ["bound"]; - this.move(); - } - get level() { - return Math.min(this.levelCap ?? c.LEVEL_CAP, this.skill.level); - } - get size() { - return this.bond == null ? (this.coreSize || this.SIZE) * this.sizeMultiplier * (1 + this.level / 45) : this.bond.size * this.bound.size; - } - get mass() { - return this.density * (this.size ** 2 + 1); - } - get realSize() { - return this.size * lazyRealSizes[Math.floor(Math.abs(this.shape))]; - } - get xMotion() { - return (this.velocity.x + this.accel.x) / c.runSpeed; - } - get yMotion() { - return (this.velocity.y + this.accel.y) / c.runSpeed; - } - camera(tur = false) { - return { - type: 0 + tur * 0x01 + this.settings.drawHealth * 0x02 + (this.type === "tank" && this.displayName) * 0x04, - invuln: this.invuln, - id: this.id, - index: this.index, - label: this.label, - x: this.x, - y: this.y, - vx: this.velocity.x, - vy: this.velocity.y, - size: this.size, - realSize: this.realSize, - status: 1, - health: this.health.display(), - shield: this.shield.display(), - alpha: this.alpha, - facing: this.facing, - direction: this.bound ? this.bound.direction : 0, - angle: this.bound ? this.bound.angle : 0, - offset: this.bound ? this.bound.offset : 0, - sizeFactor: this.bound ? this.bound.size : 1, - mirrorMasterAngle: this.settings.mirrorMasterAngle ?? false, - perceptionAngleIndependence: this.perceptionAngleIndependence, //vfacing: this.vfacing, - defaultAngle: this.firingArc[0], - twiggle: forceTwiggle.includes(this.facingType[0]) || (this.facingType[0] === "locksFacing" && this.control.alt), - layer: this.layerID ? this.layerID : this.bond != null ? this.bound.layer : this.type === "wall" ? 11 : this.type === "food" ? 10 : this.type === "tank" ? 5 : this.type === "crasher" ? 1 : 0, - color: this.color, - strokeWidth: this.strokeWidth, - borderless: this.borderless, - drawFill: this.drawFill, - name: (this.nameColor || "#FFFFFF") + this.name, - score: this.skill.score, - guns: this.guns.map((gun) => gun.getPhotoInfo()), - turrets: this.turrets.map((turret) => turret.camera(true)), - glow: this.glow, - }; - } - syncTurrets() { - for (let i = 0; i < this.guns.length; i++) this.guns[i].syncChildren(); - for (let i = 0; i < this.turrets.length; i++) { - this.turrets[i].skill = this.skill; - this.turrets[i].refreshBodyAttributes(); - this.turrets[i].syncTurrets(); - } - } - skillUp(stat) { - let suc = this.skill.upgrade(stat); - if (suc) { - this.refreshBodyAttributes(); - for (let i = 0; i < this.guns.length; i++) this.guns[i].syncChildren(); - for (let i = 0; i < this.turrets.length; i++) this.turrets[i].syncTurrets(); - } - return suc; - } - upgrade(number) { - let old = this; - if ( - number < this.upgrades.length && - this.skill.level >= this.upgrades[number].level - ) { - let upgrade = this.upgrades[number], - upgradeClass = upgrade.class, - upgradeBranch = upgrade.branch, - redefineAll = upgrade.redefineAll; - if (redefineAll) { - for (let i = 0; i < upgradeClass.length; i++){ - upgradeClass[i] = ensureIsClass(...upgradeClass[i]); - } - this.upgrades = []; - this.define(upgradeClass); - this.triggerOn(this.onDef, "upgrade", { oldEntity: old }) - } else { - this.defs.splice(upgradeBranch, 1, ...upgradeClass); - this.upgrades = []; - this.define(this.defs); - this.triggerOn(this.onDef, "upgrade", { oldEntity: old }) - } - if (this.colorUnboxed.base == '-1' || this.colorUnboxed.base == 'mirror') { - this.colorUnboxed.base = getTeamColor((c.MODE == 'ffa' || c.GROUPS) ? TEAM_RED : this.team); - this.compressColor(); - } - this.sendMessage("You have upgraded to " + this.label + "."); - for (let def of this.defs) { - def = ensureIsClass(def); - if (typeof def.TOOLTIP == 'string' && def.TOOLTIP.length > 0) { - let tooltips = Array.isArray(def.TOOLTIP) ? def.TOOLTIP : [def.TOOLTIP]; - for (let i = tooltips.length; i--;) this.sendMessage(tooltips[i]); - } - } - this.destroyAllChildren(); - this.skill.update(); - this.syncTurrets(); - this.refreshBodyAttributes(); - } - } - destroyAllChildren() { - for (let instance of entities) { - if ( - instance.settings.clearOnMasterUpgrade && - instance.master.id === this.id - ) { - instance.kill(); - } - } - } - damageMultiplier() { - switch (this.type) { - case "swarm": - return 0.25 + 1.5 * util.clamp(this.range / (this.RANGE + 1), 0, 1); - default: - return 1; - } - } - move() { - let g = { - x: this.control.goal.x - this.x, - y: this.control.goal.y - this.y, - }, - gactive = g.x !== 0 || g.y !== 0, - engine = { - x: 0, - y: 0, - }, - a = this.acceleration / c.runSpeed; - if (c.SPACE_PHYSICS) { - this.maxSpeed = this.topSpeed; - this.damp = 100; - } - let type = this.motionType[0], - args = this.motionType[1] ?? {}; - switch (type) { - case "grow": - this.SIZE += args.growSpeed ?? 1; - break; - case "fastgrow": - this.SIZE += args.growSpeed ?? 5; - break; - case "fuckingnuclearbomb": - this.SIZE += args.growSpeed ?? 10; - break; - case "trappershockwave": - this.SIZE += args.growSpeed ?? 20; - break; - case "glide": - this.maxSpeed = this.topSpeed; - this.damp = args.damp ?? 0.05; - break; - case "motor": - this.maxSpeed = 0; - if (this.topSpeed) { - this.damp = Math.abs(a) / this.topSpeed; - } - if (gactive) { - let len = Math.sqrt(g.x * g.x + g.y * g.y); - engine = { - x: (a * g.x) / len, - y: (a * g.y) / len, - }; - } - break; - case "spgw": - this.SIZE += args.growSpeed ?? 0.75; - this.maxSpeed = this.topSpeed; - this.damp = args.damp ?? -0.025; - break; - case "chonk": - this.SIZE += args.growSpeed ?? 50; - this.maxSpeed = this.topSpeed; - this.damp = args.damo ?? -0.025; - break; - case "swarm": - this.maxSpeed = this.topSpeed; - let l = - util.getDistance( - { - x: 0, - y: 0, - }, - g - ) + 1; - if (gactive && l > this.size) { - let XvelDesired = (this.topSpeed * g.x) / l, - YvelDesired = (this.topSpeed * g.y) / l, - turning = Math.sqrt( - (this.topSpeed * Math.max(1, this.range) + 1) / a - ); - engine = { - x: (XvelDesired - this.velocity.x) / Math.max(5, turning), - y: (YvelDesired - this.velocity.y) / Math.max(5, turning), - }; - } else { - if (this.velocity.length < this.topSpeed) { - engine = { - x: (this.velocity.x * a) / 20, - y: (this.velocity.y * a) / 20, - }; - } - } - break; - case "chase": - if (gactive) { - let l = util.getDistance({ x: 0, y: 0, }, g); - if (l > this.size * 2) { - this.maxSpeed = this.topSpeed; - let XvelDesired = (this.topSpeed * g.x) / l, - YvelDesired = (this.topSpeed * g.y) / l; - engine = { - x: (XvelDesired - this.velocity.x) * a, - y: (YvelDesired - this.velocity.y) * a, - }; - } else { - this.maxSpeed = 0; - } - } else { - this.maxSpeed = 0; - } - break; - case "aimassist": - this.x = this.source.x + this.master.control.target.x; - this.y = this.source.y + this.master.control.target.y; - this.velocity.x = this.source.velocity.x; - this.velocity.y = this.source.velocity.y; - break; - case "aimassistlock": - if (!this.control.alt) { - this.x = this.source.x + this.master.control.target.x; - this.y = this.source.y + this.master.control.target.y; - this.velocity.x = this.source.velocity.x; - this.velocity.y = this.source.velocity.y; - }; - break; - case "drift": - this.maxSpeed = 0; - engine = { - x: g.x * a, - y: g.y * a, - }; - break; - case "bound": - let bound = this.bound, - ref = this.bond; - this.x = ref.x + ref.size * bound.offset * Math.cos(bound.direction + bound.angle + ref.facing); - this.y = ref.y + ref.size * bound.offset * Math.sin(bound.direction + bound.angle + ref.facing); - ref.velocity.x += bound.size * this.accel.x * ref.recoilMultiplier; - ref.velocity.y += bound.size * this.accel.y * ref.recoilMultiplier; - this.velocity = ref.velocity; - this.firingArc = [ref.facing + bound.angle, bound.arc / 2]; - this.accel.null(); - this.blend = ref.blend; - break; - case "withMaster": - this.x = this.source.x; - this.y = this.source.y; - this.velocity.x = this.source.velocity.x; - this.velocity.y = this.source.velocity.y; - break; - case 'assembler': - this.alpha -= 0.02; - this.SIZE += 0.17; - if (this.alpha <= 0) { - this.kill(); - if (this.SIZE > 50) { - this.destroy(); - } - } - break; - case "desmos": - this.damp = 0; - if (this.waveReversed == null) this.waveReversed = this.master.control.alt ? -1 : 1; - if (this.waveAngle == null) { - this.waveAngle = this.master.facing; - this.velocity.x = this.velocity.length * Math.cos(this.waveAngle); - this.velocity.y = this.velocity.length * Math.sin(this.waveAngle);; - } - let waveX = this.maxSpeed * 5 * Math.cos((this.RANGE - this.range) / (args.period ?? 4) * 2); - let waveY = (args.amplitude ?? 15) * Math.cos((this.RANGE - this.range) / (args.period ?? 4)) * this.waveReversed * (args.invert ? -1 : 1); - this.x += Math.cos(this.waveAngle) * waveX - Math.sin(this.waveAngle) * waveY; - this.y += Math.sin(this.waveAngle) * waveX + Math.cos(this.waveAngle) * waveY; - break; - - } - this.accel.x += engine.x * this.control.power; - this.accel.y += engine.y * this.control.power; - } - reset(keepPlayerController = true) { - this.controllers = keepPlayerController ? [this.controllers.filter(con => con instanceof ioTypes.listenToPlayer)[0]] : []; - } - face() { - let t = this.control.target, - tactive = t.x !== 0 || t.y !== 0, - oldFacing = this.facing, - oldVFacing = this.vfacing; - let type = this.facingType[0], - args = this.facingType[1] ?? {}; - switch (type) { - case "autospin": - this.facing += (args.speed ?? 0.02) / c.runSpeed; - break; - case "turnWithSpeed": - this.facing += ((this.velocity.length / 90) * Math.PI) / c.runSpeed; - break; - case "spin": - this.facing += (args.speed ?? 0.05) / c.runSpeed; - break; - case "fastspin": - this.facing += (args.speed ?? 0.1) / c.runSpeed; - break; - case "veryfastspin": - this.facing += (args.speed ?? 1) / c.runSpeed; - break; - case "withMotion": - this.facing = this.velocity.direction; - break; - case "smoothWithMotion": - case "looseWithMotion": - this.facing += util.loopSmooth(this.facing, this.velocity.direction, (args.speed ?? 4) / c.runSpeed); - break; - case "withTarget": - case "toTarget": - let reverse = this.reverseTargetWithTank ? 1 : this.reverseTank; - this.facing = Math.atan2(t.y * reverse, t.x * reverse); - break; - case "locksFacing": - if (!this.control.alt) this.facing = Math.atan2(t.y, t.x); - break; - case "looseWithTarget": - case "looseToTarget": - case "smoothToTarget": - this.facing += util.loopSmooth(this.facing, Math.atan2(t.y, t.x), (args.speed ?? 4) / c.runSpeed); - break; - case "noFacing": - this.facing = args.angle ?? 0; - break; - case "bound": - let givenangle, - reduceIndependence = false, - slowness = this.settings.mirrorMasterAngle ? 1 : (args.slowness ?? 4) / c.runSpeed; - if (this.control.main) { - givenangle = Math.atan2(t.y, t.x); - let diff = util.angleDifference(givenangle, this.firingArc[0]); - if (Math.abs(diff) >= this.firingArc[1]) { - givenangle = this.firingArc[0]; - reduceIndependence = true; - } - } else { - givenangle = this.firingArc[0]; - reduceIndependence = true; - } - if (reduceIndependence) { - this.perceptionAngleIndependence -= 0.3 / c.runSpeed; - if (this.perceptionAngleIndependence < 0) { - this.perceptionAngleIndependence = 0; - } - } else { - this.perceptionAngleIndependence += 0.3 / c.runSpeed; - if (this.perceptionAngleIndependence > 1) { - this.perceptionAngleIndependence = 1; - } - } - this.facing += util.loopSmooth(this.facing, givenangle, slowness); - if (this.bond.syncTurretSkills) this.skill.set(this.bond.skill.raw); - break; - } - this.facing += this.turnAngle; - // Loop - const TAU = 2 * Math.PI; - if (this.facingLocked) { - this.facing = oldFacing; - this.vfacing = oldVFacing; - } else { - this.facing = ((this.facing % TAU) + TAU) % TAU; - this.vfacing = util.angleDifference(oldFacing, this.facing) * c.runSpeed; - } - } - - takeSelfie() { - this.flattenedPhoto = null; - this.photo = this.settings.drawShape - ? this.camera() - : (this.photo = undefined); - } - physics() { - if (this.accel.x == null || this.velocity.x == null) { - util.error("Void Error!"); - util.error(this.collisionArray); - util.error(this.label); - util.error(this); - this.accel.null(); - this.velocity.null(); - } - // Apply acceleration - this.velocity.x += this.accel.x; - this.velocity.y += this.accel.y; - // Reset acceleration - this.accel.null(); - // Apply motion - this.stepRemaining = 1; - if (c.SPACE_PHYSICS) this.stepRemaining = 2; - this.x += (this.stepRemaining * this.velocity.x) / c.runSpeed; - this.y += (this.stepRemaining * this.velocity.y) / c.runSpeed; - } - friction() { - var motion = this.velocity.length, - excess = motion - this.maxSpeed; - if (excess > 0 && this.damp) { - var k = this.damp / c.runSpeed, - drag = excess / (k + 1), - finalvelocity = this.maxSpeed + drag; - if (c.SPACE_PHYSICS) - finalvelocity *= this.type === "bullet" ? 1.005 : 1.1; - this.velocity.x = (finalvelocity * this.velocity.x) / motion; - this.velocity.y = (finalvelocity * this.velocity.y) / motion; - } - } - confinementToTheseEarthlyShackles() { - if (this.x == null || this.x == null) { - util.error("Void Error!"); - util.error(this.collisionArray); - util.error(this.label); - util.error(this); - this.accel.null(); - this.velocity.null(); - return 0; - } - if (!this.settings.canGoOutsideRoom) { - if (c.ARENA_TYPE === "circle") { - let centerPoint = { - x: room.width / 2, - y: room.height / 2, - }, dist = util.getDistance(this, centerPoint); - if (dist > room.width / 2) { - let strength = (dist - room.width / 2) * c.ROOM_BOUND_FORCE / (c.runSpeed * 750); - this.x = lerp(this.x, centerPoint.x, strength); - this.y = lerp(this.y, centerPoint.y, strength); - } - } else { - let padding = this.realSize - 50; - this.accel.x -= Math.max(this.x + padding - room.width, Math.min(this.x - padding, 0)) * c.ROOM_BOUND_FORCE / c.runSpeed; - this.accel.y -= Math.max(this.y + padding - room.height, Math.min(this.y - padding, 0)) * c.ROOM_BOUND_FORCE / c.runSpeed; - } - } - } - contemplationOfMortality() { - if (this.invuln || this.godmode) { - this.damageRecieved = 0; - return 0; - } - - if (this.damageRecieved > 0) { - let damageInflictor = [] - let damageTool = [] - - for (let i = 0; i < this.collisionArray.length; i++) { - let instance = this.collisionArray[i]; - if (instance.type === 'wall' || !instance.damage) continue; - damageInflictor.push(instance.master) - damageTool.push(instance) - } - this.onDef != null ? this.triggerOn(undefined, 'damage', { damageInflictor, damageTool }) : null - // TODO: find out how to fix 'collide' and 'damage' - } - // Life-limiting effects - if (this.settings.diesAtRange) { - this.range -= 1 / c.runSpeed; - if (this.range < 0) { - this.kill(); - } - } - if (this.settings.diesAtLowSpeed) { - if ( - !this.collisionArray.length && - this.velocity.length < this.topSpeed / 2 - ) { - this.health.amount -= this.health.getDamage(1 / c.runSpeed); - } - } - // Shield regen and damage - if (this.shield.max) { - if (this.damageRecieved) { - let shieldDamage = this.shield.getDamage(this.damageRecieved); - this.damageRecieved -= shieldDamage; - this.shield.amount -= shieldDamage; - } - } - // Health damage - if (this.damageRecieved) { - let healthDamage = this.health.getDamage(this.damageRecieved); - this.blend.amount = 1; - this.health.amount -= healthDamage; - } - this.damageRecieved = 0; - // Check for death - if (this.isDead()) { - - this.emit('dead'); - - //Shoot on death - for (let i = 0; i < this.guns.length; i++) { - let gun = this.guns[i]; - if (gun.shootOnDeath && gun.body != null) { - gun.spawnBullets(); - } - } - - // MEMORY LEAKS ARE BAD!!!! - for (let i = 0; i < this.turrets.length; i++) { - this.turrets[i].kill(); - } - - // Initalize message arrays - let killers = [], - killTools = [], - notJustFood = false; - // If I'm a tank, call me a nameless player - let name = this.master.name == "" - ? this.master.type === "tank" - ? "an unnamed " + this.label : this.master.type === "miniboss" - ? "a visiting " + this.label : this.label.substring(0, 3) == 'The' - ? this.label : util.addArticle(this.label) - : this.master.name + "'s " + this.label; - // Calculate the jackpot - let jackpot = util.getJackpot(this.skill.score) / this.collisionArray.length; - // Now for each of the things that kill me... - for (let i = 0; i < this.collisionArray.length; i++) { - let instance = this.collisionArray[i]; - if (instance.type === 'wall' || !instance.damage) continue; - if (instance.master.settings.acceptsScore) { - // If it's not food, give its master the score - if (instance.master.type === "tank" || instance.master.type === "miniboss") { - notJustFood = true; - } - instance.master.skill.score += jackpot; - killers.push(instance.master); // And keep track of who killed me - } else if (instance.settings.acceptsScore) { - instance.skill.score += jackpot; - } - killTools.push(instance); // Keep track of what actually killed me - } - // Remove duplicates - killers = killers.filter((elem, index, self) => index == self.indexOf(elem)); - this.onDef != null ? this.triggerOn(this.onDef, 'death', { killers, killTools }) : null - // If there's no valid killers (you were killed by food), change the message to be more passive - let killText = notJustFood ? "" : "You have been killed by ", - dothISendAText = this.settings.givesKillMessage; - - for (let i = 0; i < killers.length; i++) { - let instance = killers[i]; - - switch (this.type) { - case "tank": - killers.length > 1 ? instance.killCount.assists++ : instance.killCount.solo++; - if (instance.killCount.solo == 5) { - if (instance.socket) instance.socket.talk("achieve"); - }; - if (instance.killCount.solo == 10) { - if (instance.socket) instance.socket.talk("achieve2"); - sockets.broadcast(instance.name + "is on a kill streak of 10!"); - }; - if (instance.socket) instance.socket.talk("killgained"); - break; - - case "food": - case "crasher": - instance.killCount.polygons++; - break - - case "miniboss": - instance.killCount.bosses++; - break; - } - - this.killCount.killers.push(instance.index); - }; - // Add the killers to our death message, also send them a message - if (notJustFood) { - for (let i = 0; i < killers.length; i++) { - let instance = killers[i]; - if (instance.master.type !== "food" && instance.master.type !== "crasher") { - killText += instance.name == "" ? killText == "" ? "An unnamed player" : "an unnamed player" : instance.name; - killText += " and "; - } - // Only if we give messages - if (dothISendAText) { - instance.sendMessage("You killed " + name + (killers.length > 1 ? " (with some help)." : ".")); - } - if (this.settings.killMessage) { - instance.sendMessage("You " + this.settings.killMessage + " " + name + (killers.length > 1 ? " (with some help)." : ".")); - } - } - // Prepare the next part of the next - killText = killText.slice(0, -4) + "killed you with "; - } - // Broadcast - if (this.settings.broadcastMessage) { - sockets.broadcast(this.settings.broadcastMessage); - } - if (this.settings.defeatMessage) { - let text = util.addArticle(this.label, true); - if (notJustFood) { - text += " has been defeated by"; - for (let { name } of killers) { - text += " "; - text += name === "" ? "an unnamed player" : name; - text += " and"; - } - text = text.slice(0, -4); - text += "!"; - } else { - text += " fought a polygon... and the polygon won."; - } - sockets.broadcast(text); - } - // Add the implements to the message - for (let i = 0; i < killTools.length; i++) { - killText += util.addArticle(killTools[i].label) + " and "; - } - // Prepare it and clear the collision array. - killText = killText.slice(0, -5); - if (killText === "You have been kille") { - killText = "You have died a stupid death"; - } - this.sendMessage(killText + "."); - // If I'm the leader, broadcast it: - if (this.id === room.topPlayerID) { - let usurptText = this.name === "" ? "The leader" : this.name; - if (notJustFood) { - usurptText += " has been usurped by"; - for (let i = 0; i < killers.length; i++) { - usurptText += " "; - usurptText += killers[i].name === "" ? "an unnamed player" : killers[i].name; - usurptText += " and"; - } - usurptText = usurptText.slice(0, -4) + "!"; - } else { - usurptText += " fought a polygon... and the polygon won."; - } - sockets.broadcast(usurptText); - } - this.setKillers(killers); - // Kill it - return 1; - } - return 0; - } - protect() { - entitiesToAvoid.push(this); - this.isProtected = true; - } - say(message, duration = c.CHAT_MESSAGE_DURATION) { - if (!chats[this.id]) { - chats[this.id] = []; - } - chats[this.id].unshift({ message, expires: Date.now() + duration }); - } - sendMessage(message) {} // Dummy - setKillers(killers) {} // Dummy - kill() { - this.invuln = false; - this.health.amount = -100; - } - destroy() { - // Remove from the protected entities list - if (this.isProtected) { - util.remove(entitiesToAvoid, entitiesToAvoid.indexOf(this)); - } - // Remove from minimap - let i = minimap.findIndex(entry => entry[0] === this.id); - if (i != -1) { - util.remove(minimap, i); - } - // Remove this from views - for (let view of views) { - view.remove(this); - } - // Remove from parent lists if needed - if (this.parent != null) - util.remove(this.parent.children, this.parent.children.indexOf(this)); - // Kill all of its children - for (let instance of entities) { - if (instance.source.id === this.id) { - if (instance.settings.persistsAfterDeath) { - instance.source = instance; - } else { - instance.kill(); - } - } - if (instance.parent && instance.parent.id === this.id) { - instance.parent = null; - } - if (instance.master.id === this.id) { - instance.kill(); - instance.master = instance; - } - } - // Remove everything bound to it - for (let i = 0; i < this.turrets.length; i++) this.turrets[i].destroy(); - // Remove from the collision grid - this.removeFromGrid(); - this.isGhost = true; - } - isDead() { - return this.health.amount <= 0; - } -} -module.exports = { init, StatusEffect, Gun, Entity }; \ No newline at end of file diff --git a/shit/temp/changelog template b/shit/temp/changelog template deleted file mode 100644 index 66f07ac46..000000000 --- a/shit/temp/changelog template +++ /dev/null @@ -1,26 +0,0 @@ -
    -

    Update

    - [20] -
      -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    • Placeholder
    • -
    -
    \ No newline at end of file diff --git a/shit/temp/changes b/shit/temp/changes deleted file mode 100644 index 42472a1d5..000000000 --- a/shit/temp/changes +++ /dev/null @@ -1,512 +0,0 @@ -exports.laser = { - PARENT: ["bullet"], - SHAPE: -1, - BODY: { - PENETRATION: 0.7, - SPEED: 5.2, - RANGE: 100, - DENSITY: 0.85, - HEALTH: 0.1, - DAMAGE: 4.65, - } -} -exports.revolutionist = { - PARENT: ["genericTank"], - LABEL: "Revolutionist", - DANGER: 6, - GUNS: [{ - POSITION: [20, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flank]), - TYPE: "bullet", - }, - }, - ], - TURRETS: [{ - POSITION: [34, 0, 0, 0, 360, 0], - TYPE: "turretBase", - }, - ], -}; -exports.revoception = makeCeption(exports.revolutionist, "revoception"); -exports.hivemind = { - PARENT: ["genericTank"], - LABEL: "Hivemind", - //CONTROLLERS: ['nearestDifferentMaster'], - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet" - } - }, - { - POSITION: [0, 20, 1, 0, 0, 90, 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow]), - TYPE: "hiveprobe", - MAX_CHILDREN: 1 - } - }, - { - POSITION: [0, 20, 1, 0, 0, 270, 3.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow]), - TYPE: "hiveprobe", - MAX_CHILDREN: 1 - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [25, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -}; -exports.cloner = { - PARENT: ["genericTank"], - LABEL: "Cloner", - //CONTROLLERS: ['nearestDifferentMaster'], - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet" - } - }, - { - POSITION: [0, 20, 1, 0, 0, 180, 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.slow]), - TYPE: "clonerprobe", - MAX_CHILDREN: 1 - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [22, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -}; - - - -exports.hiveprobe = { - PARENT: ["genericTank"], - LABEL: "Probe", - TYPE: "drone", - HITS_OWN_TYPE: "hardWithBuffer", - DRAW_HEALTH: true, - BODY: { - FOV: 0.5, - SPEED: 3, - ACCELERATION: 0.4, - HEALTH: 2.5, - SHIELD: 0, - DAMAGE: 1.2, - RESIST: 1, - PENETRATION: 1, - DENSITY: 0.4 - }, - AI: { - BLIND: true - }, - CLEAR_ON_MASTER_UPGRADE: true, - GIVE_KILL_MESSAGE: false, - ACCEPTS_SCORE: false, - CONTROLLERS: [ - "nearestDifferentMaster", - "mapAltToFire", - "minion", - "canRepel", - "hangOutNearMaster" - ], - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lowpower]), - TYPE: "bullet" - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [25, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -}; -exports.clonerprobe = { - PARENT: ["hiveprobe"], - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.lowpower]), - TYPE: "bullet" - } - } - ], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [22, 0, 0, 0, 360, 0], - TYPE: "mindindicator" - } - ] -} - -//wait whats stuff -exports.placeableWall = { - PARENT: ["rock"], - LABEL: "Wall", - SIZE: 30, - SHAPE: 4, - CLEAR_ON_MASTER_UPGRADE: true, - TEAM: TEAM_ENEMIES, - VARIES_IN_SIZE: false, -}; -exports.placeableWallSmall = { - PARENT: ["rock"], - LABEL: "Wall", - SIZE: 15, - SHAPE: 4, - CLEAR_ON_MASTER_UPGRADE: true, - TEAM: TEAM_ENEMIES, - VARIES_IN_SIZE: false, -}; -exports.wallPlacerThing = { - PARENT: ["genericTank"], - SHAPE:0, - MIRROR_MASTER_ANGLE: true, - INTANGIBLE: true, - DRAW_SELF:false, - COLOR: 16, - CLEAR_ON_MASTER_UPGRADE: true, - BODY: { - ACCELERATION: 0.1, - SPEED: true, - HEALTH: 340282366920938463463374607431768211455, - RESIST: 1, - SHIELD: 340282366920938463463374607431768211455, - REGEN: 340282366920938463463374607431768211455, - DAMAGE: false, - PENETRATION: true, - RANGE: true, - FOV: true, - SHOCK_ABSORB: 340282366920938463463374607431768211455, - RECOIL_MULTIPLIER: false, - DENSITY: 340282366920938463463374607431768211455, - STEALTH: true, - PUSHABILITY: false, - HETERO: false, - }, - MOTION_TYPE: "withMouse", - GUNS: [ - { - POSITION: [0, 20, 1, 10, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([{reload:10, speed:0, maxSpeed:0, shudder:0.0001, spray:0.0001}]), - TYPE: "placeableWall", - COLOR: 16, - LABEL: "", - STAT_CALCULATOR: 0, - WAIT_TO_CYCLE: false, - AUTOFIRE: false, - SYNCS_SKILLS: false, - MAX_CHILDREN: 0, - ALT_FIRE: false, - NEGATIVE_RECOIL: false, - DRAW_FILL:false, - BORDERLESS:true, - }, - }, - ], - -}; -exports.wallPlacer = { - PARENT: ["genericTank"], - LABEL: "Messin' Around", - BODY: { - ACCELERATION: base.ACCEL * 1, - SPEED: base.SPEED * 1, - HEALTH: base.HEALTH * 1, - DAMAGE: base.DAMAGE * 1, - PENETRATION: base.PENETRATION * 1, - SHIELD: base.SHIELD * 1, - REGEN: base.REGEN * 1, - FOV: base.FOV * 1, - DENSITY: base.DENSITY * 1, - PUSHABILITY: 1, - HETERO: 3, - }, - GUNS: [ - { - POSITION: [16, 20, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic,{reload:1/8}]), - TYPE: "wallPlacerThing", - COLOR: 16, - LABEL: "", - STAT_CALCULATOR: 0, - WAIT_TO_CYCLE: false, - AUTOFIRE: false, - SYNCS_SKILLS: false, - MAX_CHILDREN: 1, - ALT_FIRE: false, - NEGATIVE_RECOIL: false, - }, - }, - ], -}; - -// TANK UPGRADE PATHS -exports.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "autoBasic"/*, "desmos"*/]; - exports.basic.UPGRADES_TIER_2 = ["smasher", "cloner"]; - exports.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "autoSmasher", "landmine"]; - exports.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] - - exports.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "autoTwin"]; - exports.twin.UPGRADES_TIER_3 = ["dual", "bulwark", "musket"]; - exports.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble"]; - exports.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentHybrid", "bentDouble", "triplet", "autoTripleShot"]; - - exports.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "autoSniper"]; - exports.sniper.UPGRADES_TIER_3 = ["bushwhacker"]; - exports.assassin.UPGRADES_TIER_3 = ["ranger", "falcon", "stalker", "autoAssassin", "single"]; - exports.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "dual","autoHunter"]; - exports.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman", "autoRifle"]; - - exports.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "autoMach"]; - exports.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture", "autoMini"]; - exports.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner"]; - exports.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "autoSprayer"]; - - exports.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank"]; - exports.flankGuard.UPGRADES_TIER_3 = ["tripleTwin"]; - exports.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper", "autoHexaTank"]; - exports.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "surfer", "eagle", "phoenix", "vulture"]; - exports.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee", "autoAuto3"]; - - exports.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "spawner", "autoDirector"]; - exports.director.UPGRADES_TIER_3 = ["manager", "bigCheese"]; - exports.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "overdrive", "commander"]; - exports.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "autoCruiser", "commander"]; - exports.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor", "autoUnderseer"]; - exports.spawner.UPGRADES_TIER_3 = ["factory", "autoSpawner"]; - - exports.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher", "autoPound"/*, "volute"*/]; - exports.pounder.UPGRADES_TIER_3 = ["shotgun", "eagle"]; - exports.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct", "autoDestroy"]; - exports.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun", "autoArtillery"]; - exports.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "sidewinder", "fieldGun", "autoLaunch"]; - - exports.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "autoTrap"]; - exports.trapper.UPGRADES_TIER_3 = ["barricade", "overtrapper"]; - exports.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror"]; - exports.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "autoTriTrapper"]; - exports.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "autoTrapGuard"]; - - exports.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "revolutionist", "basicCeption"]; - exports.autoBasic.UPGRADES_TIER_3 = ["autoSmasher", "autoCloner"]; - exports.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "twinCeption"]; - exports.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "snipeCeption"]; - exports.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "machCeption"]; - exports.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "autoTriTrapper", "flankCeption"]; - exports.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoSpawner", "directCeption"]; - exports.autoPound.UPGRADES_TIER_3 = ["autoDestroy", "autoBuilder", "autoArtillery", "autoLaunch", "poundCeption"]; - exports.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "autoTriTrapper", "autoTrapGuard", "trapCeption"]; - exports.revolutionist.UPGRADES_TIER_3 = ["autoRevolutionist"]; - exports.basicCeption.UPGRADES_TIER_3 = ["twinCeption", "snipeCeption", "machCeption", "flankCeption", "directCeption", "poundCeption", "trapCeption"]; - - - exports.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner"]; - - exports.desmos.UPGRADES_TIER_2 = ["helix", "volute"]; - exports.helix.UPGRADES_TIER_3 = ["triplex"]; - exports.volute.UPGRADES_TIER_3 = ["sidewinder"]; - -exports.minilaser = { - PARENT: ["genericTank"], - LABEL: "Plasma SMG", - DANGER: 6, - BODY: { - FOV: 1.2, - }, - GUNS: [ - { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [21, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.mini, g.doublereload, g.one_third_reload]), - TYPE: "laser", - }, - }, - { - POSITION: [19, 8, 1, 0, 0, 0, 1 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.mini, g.doublereload, g.one_third_reload]), - TYPE: "laser", - }, - }, - { - POSITION: [17, 8, 1, 0, 0, 0, 2 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.mini, g.doublereload, g.one_third_reload]), - TYPE: "laser", - }, - }, - ], -}; -exports.autoBasic = makeAuto(exports.basic, "Auto-Basic"); -exports.autoRevolutionist = makeAuto(exports.revolutionist, "Auto-Revolutionist"); - -exports.autoTwin = makeAuto(exports.twin, "Auto-Twin"); -exports.autoMach = makeAuto(exports.machineGun, "Auto-Mach"); -exports.autoSniper = makeAuto(exports.sniper, "Auto-Sniper"); -exports.autoFlank = makeAuto(exports.flankGuard, "Auto-Flank"); -exports.autoDirector = makeAuto(exports.director, "Auto-Director"); -exports.autoPound = makeAuto(exports.pounder, "Auto-Pounder"); -exports.autoTrap = makeAuto(exports.trapper, "Auto-Trapper"); -exports.autoCloner = makeAuto(exports.cloner, "Auto-Cloner"); - -exports.autoTripleShot = makeAuto(exports.tripleShot, "Auto-Triple Shot"); - -exports.autoHunter = makeAuto(exports.hunter, "Auto-Hunter"); -exports.autoRifle = makeAuto(exports.rifle, "Auto-Rifle"); - -exports.autoMini = makeAuto(exports.minigun, "Auto-Minigun"); -exports.autoSprayer = makeAuto(exports.sprayer, "Auto-Sprayer"); - -exports.autoHexaTank = makeAuto(exports.hexaTank, "Auto-HexaTank"); -exports.autoAuto3 = makeAuto(exports.auto3, "Auto-Auto3"); - -exports.autoUnderseer = makeAuto(exports.underseer, "Auto-Underseer"); - -exports.autoDestroy = makeAuto(exports.destroyer, "Auto-Destroyer"); -exports.autoArtillery = makeAuto(exports.artillery, "Auto-Artillery"); -exports.autoLaunch = makeAuto(exports.launcher, "Auto-Launcher"); - -exports.autoTriTrapper = makeAuto(exports.triTrapper, "Auto-Tri Trapper"); -exports.autoTrapGuard = makeAuto(exports.trapGuard, "Auto-TrapGuard"); - - -exports.basicCeption = makeCeptionNerf(exports.basic, "Basic-Ception"); - -exports.twinCeption = makeCeptionNerf(exports.twin, "Twin-Ception"); -exports.twinCeption.BODY = { SPEED: base.SPEED }; -exports.snipeCeption = makeCeptionNerf(exports.sniper, "Snipe-Ception"); -exports.machCeption = makeCeptionNerf(exports.machineGun, "Mach-Ception"); -exports.flankCeption = makeCeptionNerf(exports.flankGuard, "Flank-Ception"); -exports.directCeption = makeCeptionNerf(exports.director, "Drone-Ception"); -exports.poundCeption = makeCeptionNerf(exports.pounder, "Pound-Ception"); -exports.trapCeption = makeCeptionNerf(exports.trapper, "Trap-Ception"); - -// ??? it still dont spin i think lol -exports.turretBase = { - LABEL: "Base", - SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', - COLOR: 9, - CONTROLLERS: [["spin", { independent: true }]], - INDEPENDENT: true, - TURRETS: [{ - POSITION: [4.65, 9.85, 0, 90, 220, 1], - TYPE: "autoTurret", - }, { - POSITION: [4.65, 9.85, 0, 270, 220, 1], - TYPE: "autoTurret", - }] -}; - - if (gui.class === "Winsor") { - PlaySound169(); - } - //just some code to make the sound work - var playbuttonsound = new Audio(); - playbuttonsound.src = - "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/op1.wav?v=1675463613542"; - function PlaySound69() { - playbuttonsound.play(); - } - var clicked = false; - - var slap = new Audio(); - slap.src = - "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/(Audio)%20videoplayback.m4a?v=1675999054321"; - function PlaySound68() { - slap.play(); - } - var clicked = false; - - var clicksound = new Audio(); - clicksound.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/sysse_ok.ogg"; - function PlaySound210() { - clicksound.play(); - } - var clicked = false; - - function doSomething() { - if (clicked) { - var optionclicksound = new Audio(); - optionclicksound.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/cancel.wav"; - optionclicksound.load(); - optionclicksound.play(); - } else { - clicksound.load(); - clicksound.play(); - } - clicked = !clicked; - } - var smallaudio2 = new Audio(); - smallaudio2.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/error.ogg"; - function PlaySound211() { - smallaudio2.play(); - } - var smallaudio3 = new Audio( - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/socket.wav" - ); - smallaudio3.loop = false; - function PlaySound212() { - smallaudio3.loop = false; - smallaudio3.play(); - } - var grubhub = new Audio(); -grubhub.src = ("https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/d318bd1e-5162-4fae-a757-5c350b16ccc9.mp3?v=1700153738394"); -function PlaySound169() { - grubhub.load(); - grubhub.play(); -} - var smallaudio5 = new Audio(); - smallaudio5.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/poka.wav"; - function PlaySound214() { - smallaudio5.play(); - } - var smallaudio6 = new Audio(); - smallaudio6.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/finish.wav"; - function PlaySound215() { - smallaudio6.play(); - } - var camerasound = new Audio(); - camerasound.src = - "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/camera.wav"; - function PlaySound213() { - camerasound.play(); - }; \ No newline at end of file diff --git a/shit/temp/gifbackround b/shit/temp/gifbackround deleted file mode 100644 index 0211166f5..000000000 --- a/shit/temp/gifbackround +++ /dev/null @@ -1,33 +0,0 @@ - \ No newline at end of file diff --git a/shit/temp/music b/shit/temp/music deleted file mode 100644 index 46fe5ec52..000000000 --- a/shit/temp/music +++ /dev/null @@ -1,20 +0,0 @@ - - \ No newline at end of file diff --git a/shit/temp/mytankcount b/shit/temp/mytankcount deleted file mode 100644 index ae2963ea7..000000000 --- a/shit/temp/mytankcount +++ /dev/null @@ -1,13 +0,0 @@ -auto branch - -railgun -hivemind -cloner -plasma smg -scanner -dictator -revolutionist -revo -bacrid -auto -ception \ No newline at end of file diff --git a/shit/temp/stuff b/shit/temp/stuff deleted file mode 100644 index 520100d43..000000000 --- a/shit/temp/stuff +++ /dev/null @@ -1,137 +0,0 @@ - //Class.unfinishedtesting.UPGRADES_TIER_0 = ["testing", "aimassisttest", "toxic", "autoboosttest"] -Class.toxic = { - PARENT: "genericTank", - LABEL: "Intoxicator", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "poisonbullet", - } - }, - { - POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] - } - ] -}; -Class.poisonbullet = { - PARENT: "bullet", - LABEL: "posonio", - TURRETS: [ - { - POSITION: [0, 0, 0, 0, 360, 1], - TYPE: "recangluhitbox" - } - ] -}; -Class.aimassistbullet = { - PARENT: "bullet", - LABEL: "Bullet", - SHAPE: "M 1 1 l -2 0 L -1 -1 L 1 -1 L -1 -1 L -1 1 L 1 1 L 1 -1 L 1 1", - CONTROLLERS: ["nearestDifferentMaster"], - ACCEPTS_SCORE: false, - BODY: { - PENETRATION: 0.1, - SPEED: 99999, - DENSITY: 0.1, - HEALTH: 5, - DAMAGE: 0, - PUSHABILITY: 0.1, - SIZE: 18, - }, - MOTION_TYPE: "aimassistlock", - CAN_GO_OUTSIDE_ROOM: true, - HITS_OWN_TYPE: "never", - DIE_AT_RANGE: true, - TURRETS: [ - { - POSITION: [25, 0, 0, 0, 360, 1], - TYPE: "crosshair1" - } - ] -}; -Class.aimassisttest = { - PARENT: "genericTank", - LABEL: "Aim Assist", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet", - HAS_NO_RECOIL: true - } - }, - { - POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "aimassistbullet", - HAS_NO_RECOIL: true - } - }, - ], - TURRETS: [ - { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: "autoTankGunLock" - } - ] -} -Class.autoboosttest = { - PARENT: "genericTank", - LABEL: "Aim Assist", - DANGER: 7, - GUNS: [ - { - POSITION: [19, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.single]), - TYPE: "bullet", - } - }, - ], - TURRETS: [ - { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: "autoTankGunLockRecoil" - } - ] -} -Class.autoTankGunLock = { - PARENT: "autoTankGun", - MOTION_TYPE: "aimassistlock", - BODY: { - FOV: 1 - }, - CONTROLLERS: ["nearestDifferentMasterAltAlt", "AimAssistLock"], - AI: { - FARMER: true, - BLIND: true, - }, -} -Class.autoTankGunLockRecoil = { - PARENT: "autoTankGun", - MOTION_TYPE: "aimassistlock", - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.tonsmorerecoil, g.tonsmorerecoil, g.halfreload, g.halfreload, g.halfreload, g.fakewithrecoil]), - TYPE: "bullet", - }, - }, - ], - CONTROLLERS: ["nearestDifferentMasterAlt", "AimAssistLock"], - AI: { - FARMER: true, - }, -} - -Class.unfinishedtesting = { - PARENT: ["menu"], - LABEL: "Unfinished tanks", -}; \ No newline at end of file diff --git a/shit/temp/woomycolorname b/shit/temp/woomycolorname deleted file mode 100644 index 2b674856a..000000000 --- a/shit/temp/woomycolorname +++ /dev/null @@ -1,3 +0,0 @@ -yeah no, -anyways so basically what im gonna say is -2019/april/24/11/45/32 \ No newline at end of file From 9aa1e627a273dcbeef56c890febd84827d89474a Mon Sep 17 00:00:00 2001 From: "Glitch (purring-rhetorical-drink)" Date: Thu, 2 May 2024 13:28:21 +0000 Subject: [PATCH 04/15] Fixed Desmos' static Velocity & Nerfed Quadruplex From 253f59dec65087ba8a74b26427bdb58ec65d4534 Mon Sep 17 00:00:00 2001 From: "Glitch (purring-rhetorical-drink)" Date: Thu, 2 May 2024 13:38:25 +0000 Subject: [PATCH 05/15] =?UTF-8?q?=F0=9F=8F=9B=EF=B8=8F=F0=9F=9B=8B?= =?UTF-8?q?=EF=B8=8F=20Updated=20with=20Glitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From d5ab1927c77a3c0dd72a4359d7bee39f05b76e5d Mon Sep 17 00:00:00 2001 From: "Glitch (purring-rhetorical-drink)" Date: Thu, 2 May 2024 13:44:29 +0000 Subject: [PATCH 06/15] =?UTF-8?q?=F0=9F=90=AA=F0=9F=A5=BE=20Updated=20with?= =?UTF-8?q?=20Glitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/modules/definitions/groups/tanks.js | 10 +++++----- server/modules/live/entity.js | 14 ++------------ 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 49ccee8bd..448f47b3c 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -3025,7 +3025,7 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, 45, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25}]}] } }, @@ -3038,7 +3038,7 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, -45, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25, invert: true}]}] } }, @@ -3051,8 +3051,8 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, 135, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 12.5}]}] + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10}]}] } }, { @@ -3064,7 +3064,7 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, -135, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10, invert: true}]}] } }, diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index 9452360c6..162b5237b 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -1908,21 +1908,11 @@ class Entity extends EventEmitter { break; case "desmos": this.damp = 0; - let save = { - x: this.master.x, - y: this.master.y, - }; - let target = { - x: this.master.x + this.master.control.target.x, - y: this.master.y + this.master.control.target.y, - }; - let amount = (util.getDistance(target, save) / 100) | 0; - //sockets.broadcast(this.velocity.x.toString()) if (this.waveReversed == null) this.waveReversed = this.master.control.alt ? -1 : 1; if (this.waveAngle == null) { this.waveAngle = this.master.facing; - this.velocity.x = ((5 + this.velocity.length * (amount + 2)) * Math.cos(this.waveAngle)) / 7; - this.velocity.y = ((5 + this.velocity.length * (amount + 2)) * Math.sin(this.waveAngle)) / 7; + this.velocity.x = this.velocity.length * Math.cos(this.waveAngle); + this.velocity.y = this.velocity.length * Math.sin(this.waveAngle);; } let waveX = this.maxSpeed * 5 * Math.cos((this.RANGE - this.range) / (args.period ?? 4) * 2); let waveY = (args.amplitude ?? 15) * Math.cos((this.RANGE - this.range) / (args.period ?? 4)) * this.waveReversed * (args.invert ? -1 : 1); From 56138d101241a81cda6babd29322ad0dacce687a Mon Sep 17 00:00:00 2001 From: "Glitch (purring-rhetorical-drink)" Date: Thu, 2 May 2024 13:50:26 +0000 Subject: [PATCH 07/15] Fixed Desmos' static Velocity & Nerfed Quadruplex. --- server/modules/definitions/groups/tanks.js | 10 +++++----- server/modules/live/entity.js | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 448f47b3c..49ccee8bd 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -3025,7 +3025,7 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, 45, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25}]}] } }, @@ -3038,7 +3038,7 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, -45, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {amplitude: 25, invert: true}]}] } }, @@ -3051,8 +3051,8 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, 135, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10}]}] + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 12.5}]}] } }, { @@ -3064,7 +3064,7 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, -135, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos]), + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10, invert: true}]}] } }, diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index 162b5237b..9452360c6 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -1908,11 +1908,21 @@ class Entity extends EventEmitter { break; case "desmos": this.damp = 0; + let save = { + x: this.master.x, + y: this.master.y, + }; + let target = { + x: this.master.x + this.master.control.target.x, + y: this.master.y + this.master.control.target.y, + }; + let amount = (util.getDistance(target, save) / 100) | 0; + //sockets.broadcast(this.velocity.x.toString()) if (this.waveReversed == null) this.waveReversed = this.master.control.alt ? -1 : 1; if (this.waveAngle == null) { this.waveAngle = this.master.facing; - this.velocity.x = this.velocity.length * Math.cos(this.waveAngle); - this.velocity.y = this.velocity.length * Math.sin(this.waveAngle);; + this.velocity.x = ((5 + this.velocity.length * (amount + 2)) * Math.cos(this.waveAngle)) / 7; + this.velocity.y = ((5 + this.velocity.length * (amount + 2)) * Math.sin(this.waveAngle)) / 7; } let waveX = this.maxSpeed * 5 * Math.cos((this.RANGE - this.range) / (args.period ?? 4) * 2); let waveY = (args.amplitude ?? 15) * Math.cos((this.RANGE - this.range) / (args.period ?? 4)) * this.waveReversed * (args.invert ? -1 : 1); From d573cf147dd39861060ee29046609e0d8233ed89 Mon Sep 17 00:00:00 2001 From: "Glitch (neroio2)" Date: Fri, 21 Jun 2024 01:09:29 +0000 Subject: [PATCH 08/15] =?UTF-8?q?=E2=9B=84=F0=9F=8F=A2=20Updated=20with=20?= =?UTF-8?q?Glitch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .glitch-assets | 222 + LICENSE | 29 +- README.md | 5 +- changelog preview | 533 ++ features.md | 4 +- install.sh | 2 +- neroplayer/script.js | 86 + neroplayer/stylesheet.css | 14 + neroplayer/visual.html | 15 + package.json | 7 +- public/app.js | 1705 ++++- public/changelog.html | 534 +- public/credits.html | 104 + public/favicon.ico | Bin 21654 -> 225726 bytes public/favicon.png | Bin 0 -> 81775 bytes public/google777bc33c0347b790.html | 1 + public/icon32x32.png | Bin 1898 -> 0 bytes public/index.html | 581 +- public/index.js | 49 + public/lib/canvas.js | 114 +- public/lib/color.js | 60 +- public/lib/gameDraw.js | 51 +- public/lib/global.js | 138 +- public/lib/json/color.json | 58 + public/lib/json/manifest.json | 10 +- public/lib/settings.js | 5 +- public/lib/socketInit.js | 43 +- public/lib/tankdesc.js | 549 ++ public/lib/util.js | 29 +- public/main.css | 1262 +++- public/osa_background_tile.png | Bin 748 -> 0 bytes public/round.png | Bin 25179 -> 0 bytes run.bat => public/run.bat | 0 public/servers.json | 4 + server/config.js | 84 +- server/index.js | 88 +- server/lib/hshg.js | 2 +- server/lib/util.js | 2 + server/modules/debug/speedLoop.js | 9 +- server/modules/definitions/addons/amongus.js | 108 + .../definitions/addons/basicChatModeration.js | 7 +- server/modules/definitions/addons/cooper.js | 30 + .../modules/definitions/addons/dailyTanks.js | 1347 ++++ server/modules/definitions/addons/dreadv1.js | 33 +- server/modules/definitions/addons/dreadv2.js | 2160 +++---- .../definitions/addons/exampleAddon.js | 2 +- .../definitions/addons/geometryDashDart.js | 72 + server/modules/definitions/addons/labyFood.js | 4 +- .../modules/definitions/addons/playerskins.js | 175 + server/modules/definitions/addons/solario.js | 573 ++ server/modules/definitions/combined.js | 6 +- server/modules/definitions/constants.js | 6 + server/modules/definitions/facilitators.js | 335 +- server/modules/definitions/groups/bosses.js | 5721 ++++++++--------- server/modules/definitions/groups/dev.js | 1507 ++++- server/modules/definitions/groups/food.js | 183 +- server/modules/definitions/groups/generics.js | 18 +- server/modules/definitions/groups/misc.js | 211 +- .../modules/definitions/groups/projectiles.js | 615 +- server/modules/definitions/groups/tanks.js | 2815 +++++++- server/modules/definitions/groups/turrets.js | 629 +- server/modules/definitions/gunvals.js | 62 +- server/modules/gamemodes/bossRush.js | 66 +- server/modules/gamemodes/gamemodeLoop.js | 28 +- server/modules/gamemodes/groups.js | 2 +- server/modules/gamemodes/maze.js | 2 +- server/modules/gamemodes/moon.js | 2 +- server/modules/gamemodes/mothership.js | 34 +- server/modules/gamemodes/risk.js | 80 + server/modules/gamemodes/tag.js | 4 +- server/modules/global.js | 20 +- server/modules/live/controllers.js | 146 +- server/modules/live/entity.js | 202 +- server/modules/live/entitySubFunctions.js | 18 +- server/modules/network/sockets.js | 327 +- server/modules/network/webServer.js | 71 +- server/modules/physics/collisionFunctions.js | 146 +- server/modules/setup/gamemodeconfigs/risk.js | 9 + server/modules/setup/gamemodeconfigs/siege.js | 2 +- server/modules/setup/mockups.js | 7 +- server/modules/setup/room.js | 18 +- server/modules/setup/rooms/map_apspp_maze.js | 26 + .../modules/setup/rooms/map_apspp_tiletest.js | 42 - .../modules/setup/rooms/map_neroio_arena.js | 27 + .../modules/setup/rooms/map_neroio_banquet.js | 29 + .../modules/setup/rooms/map_neroio_blank.js | 26 + .../setup/rooms/map_neroio_mazearena.js | 27 + .../modules/setup/rooms/map_neroio_zerolag.js | 14 + .../modules/setup/rooms/map_nexus_trplnr.js | 36 +- .../modules/setup/rooms/map_risk_default.js | 17 + .../modules/setup/rooms/overlay_domination.js | 4 +- server/modules/setup/tiles/decoration.js | 29 +- server/modules/setup/tiles/dominators.js | 56 +- server/modules/setup/tiles/misc.js | 128 +- server/modules/setup/tiles/portal.js | 8 +- server/modules/setup/tiles/siege.js | 2 +- server/modules/setup/tiles/tdm.js | 5 +- server/permissions.js | 2 +- shit/js/main.js | 82 + shit/popup.html | 15 + shit/randomstuff/aasfsdgsdg | 1 + shit/randomstuff/asajhwerkji | 25 + shit/randomstuff/jfsdfn | 27 + shit/temp/backuo | 2409 +++++++ shit/temp/changelog template | 26 + shit/temp/gifbackround | 33 + shit/temp/music | 20 + shit/temp/mytankcount | 13 + shit/temp/stuff | 137 + shit/temp/woomycolorname | 3 + 110 files changed, 21571 insertions(+), 5900 deletions(-) create mode 100644 .glitch-assets create mode 100644 changelog preview mode change 100755 => 100644 install.sh create mode 100644 neroplayer/script.js create mode 100644 neroplayer/stylesheet.css create mode 100644 neroplayer/visual.html create mode 100644 public/credits.html create mode 100644 public/favicon.png create mode 100644 public/google777bc33c0347b790.html delete mode 100644 public/icon32x32.png create mode 100644 public/index.js create mode 100644 public/lib/tankdesc.js delete mode 100644 public/osa_background_tile.png delete mode 100644 public/round.png rename run.bat => public/run.bat (100%) create mode 100644 public/servers.json create mode 100644 server/modules/definitions/addons/amongus.js create mode 100644 server/modules/definitions/addons/cooper.js create mode 100644 server/modules/definitions/addons/dailyTanks.js create mode 100644 server/modules/definitions/addons/geometryDashDart.js create mode 100644 server/modules/definitions/addons/playerskins.js create mode 100644 server/modules/definitions/addons/solario.js create mode 100644 server/modules/gamemodes/risk.js create mode 100644 server/modules/setup/gamemodeconfigs/risk.js create mode 100644 server/modules/setup/rooms/map_apspp_maze.js delete mode 100644 server/modules/setup/rooms/map_apspp_tiletest.js create mode 100644 server/modules/setup/rooms/map_neroio_arena.js create mode 100644 server/modules/setup/rooms/map_neroio_banquet.js create mode 100644 server/modules/setup/rooms/map_neroio_blank.js create mode 100644 server/modules/setup/rooms/map_neroio_mazearena.js create mode 100644 server/modules/setup/rooms/map_neroio_zerolag.js create mode 100644 server/modules/setup/rooms/map_risk_default.js create mode 100644 shit/js/main.js create mode 100644 shit/popup.html create mode 100644 shit/randomstuff/aasfsdgsdg create mode 100644 shit/randomstuff/asajhwerkji create mode 100644 shit/randomstuff/jfsdfn create mode 100644 shit/temp/backuo create mode 100644 shit/temp/changelog template create mode 100644 shit/temp/gifbackround create mode 100644 shit/temp/music create mode 100644 shit/temp/mytankcount create mode 100644 shit/temp/stuff create mode 100644 shit/temp/woomycolorname diff --git a/.glitch-assets b/.glitch-assets new file mode 100644 index 000000000..ce69671a1 --- /dev/null +++ b/.glitch-assets @@ -0,0 +1,222 @@ +{"name":"2023_10_10_0rf_Kleki.png","date":"2023-10-10T18:58:08.611Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_10_0rf_Kleki.png","type":"image/png","size":30464,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_10_0rf_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"UP44Oex8WvGywkCD"} +{"name":"6avWH55.jpg","date":"2023-10-25T12:45:16.390Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6avWH55.jpg","type":"image/jpeg","size":327303,"imageWidth":2500,"imageHeight":1667,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6avWH55.jpg","thumbnailWidth":330,"thumbnailHeight":221,"uuid":"o6pEXEUSnOPqm4bg"} +{"name":"4073e372df1399336a01c51052a1bbd8.jpg","date":"2023-10-25T13:01:09.623Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4073e372df1399336a01c51052a1bbd8.jpg","type":"image/jpeg","size":48408,"imageWidth":960,"imageHeight":649,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4073e372df1399336a01c51052a1bbd8.jpg","thumbnailWidth":330,"thumbnailHeight":224,"uuid":"w9ZO2wxV83aWhelI"} +{"name":"58563194-553c-49ae-95db-441b06bf9bef.image.png","date":"2023-10-25T13:19:20.463Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/58563194-553c-49ae-95db-441b06bf9bef.image.png","type":"image/png","size":76850,"imageWidth":360,"imageHeight":240,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F58563194-553c-49ae-95db-441b06bf9bef.image.png","thumbnailWidth":330,"thumbnailHeight":220,"uuid":"RsOUyfm1cBYSqbw0"} +{"uuid":"o6pEXEUSnOPqm4bg","deleted":true} +{"name":"girb.jpg","date":"2023-10-25T12:45:16.390Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/girb.jpg","type":"image/jpeg","size":327303,"imageWidth":2500,"imageHeight":1667,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6avWH55.jpg","thumbnailWidth":330,"thumbnailHeight":221,"uuid":"o6pEXEUSnOPqm4bg"} +{"uuid":"w9ZO2wxV83aWhelI","deleted":true} +{"name":"othergirb.jpg","date":"2023-10-25T13:01:09.623Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/othergirb.jpg","type":"image/jpeg","size":48408,"imageWidth":960,"imageHeight":649,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4073e372df1399336a01c51052a1bbd8.jpg","thumbnailWidth":330,"thumbnailHeight":224,"uuid":"w9ZO2wxV83aWhelI"} +{"name":"131107152744-mona-lisa.jpg","date":"2023-10-26T11:10:16.817Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/131107152744-mona-lisa.jpg","type":"image/jpeg","size":747095,"imageWidth":2000,"imageHeight":3000,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F131107152744-mona-lisa.jpg","thumbnailWidth":220,"thumbnailHeight":330,"uuid":"YM7ULs8ieFPfkHTh"} +{"name":"2022_06_23_11e_Kleki.png","date":"2023-10-26T11:10:22.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2022_06_23_11e_Kleki.png","type":"image/png","size":66360,"imageWidth":1009,"imageHeight":601,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2022_06_23_11e_Kleki.png","thumbnailWidth":330,"thumbnailHeight":197,"uuid":"CKrqEXVr9r1fWHQ6"} +{"name":"84812d435b246f4edffe887c5f755008.jpg","date":"2023-10-26T11:10:27.584Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/84812d435b246f4edffe887c5f755008.jpg","type":"image/jpeg","size":111067,"imageWidth":924,"imageHeight":1000,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F84812d435b246f4edffe887c5f755008.jpg","thumbnailWidth":305,"thumbnailHeight":330,"uuid":"iKniUyyIl8sambKK"} +{"name":"videoplayback.mp4","date":"2023-10-26T11:10:49.863Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp4","type":"video/mp4","size":2106277,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"txSk7RsRJ33ZgL0R"} +{"name":"IMG_0316.webp","date":"2023-10-26T11:20:34.628Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_0316.webp","type":"image/webp","size":12986,"imageWidth":640,"imageHeight":494,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_0316.webp","thumbnailWidth":330,"thumbnailHeight":255,"uuid":"ULDBE338jPz5CztZ"} +{"name":"devil vortex.jpg","date":"2023-10-26T11:23:31.448Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/devil%20vortex.jpg","type":"image/jpeg","size":70977,"imageWidth":2048,"imageHeight":1070,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdevil%20vortex.jpg","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"rwxaYBQQ3Vdh4GOB"} +{"uuid":"CKrqEXVr9r1fWHQ6","deleted":true} +{"name":"lratio","date":"2023-10-26T11:10:22.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/lratio","type":"image/png","size":66360,"imageWidth":1009,"imageHeight":601,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2022_06_23_11e_Kleki.png","thumbnailWidth":330,"thumbnailHeight":197,"uuid":"CKrqEXVr9r1fWHQ6"} +{"name":"mqdefault.jpg","date":"2023-10-26T15:51:05.241Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/mqdefault.jpg","type":"image/jpeg","size":8165,"imageWidth":320,"imageHeight":180,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/mqdefault.jpg","thumbnailWidth":320,"thumbnailHeight":180,"uuid":"vUoqYUUmAaCJlbFE"} +{"name":"e4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","date":"2023-10-26T15:52:48.829Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","type":"image/png","size":667529,"imageWidth":970,"imageHeight":750,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fe4b3f8d2-72dd-4995-87ad-633e8c5e5754.image.png","thumbnailWidth":330,"thumbnailHeight":256,"uuid":"2TdCgTp1qJy5VpQF"} +{"name":"4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","date":"2023-10-26T15:56:52.346Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","type":"image/png","size":13711,"imageWidth":295,"imageHeight":247,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4703606e-9aeb-4893-aad3-b9788cccfc9b.image.png","thumbnailWidth":295,"thumbnailHeight":247,"uuid":"vB57dbf5e3LDGNTc"} +{"name":"9fbac25f-6710-4a95-b963-502275ff8728.image.png","date":"2023-10-26T16:03:48.998Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/9fbac25f-6710-4a95-b963-502275ff8728.image.png","type":"image/png","size":5638,"imageWidth":218,"imageHeight":157,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/9fbac25f-6710-4a95-b963-502275ff8728.image.png","thumbnailWidth":218,"thumbnailHeight":157,"uuid":"AUYt8QpAyhIjzDDo"} +{"uuid":"AUYt8QpAyhIjzDDo","deleted":true} +{"name":"2023_10_26_0ml_Kleki.png","date":"2023-10-26T16:04:27.088Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_26_0ml_Kleki.png","type":"image/png","size":6063,"imageWidth":218,"imageHeight":157,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_10_26_0ml_Kleki.png","thumbnailWidth":218,"thumbnailHeight":157,"uuid":"XrOWUvHhmVrkljWG"} +{"name":"b6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","date":"2023-10-26T16:06:40.232Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/b6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","type":"image/png","size":155677,"imageWidth":480,"imageHeight":480,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fb6b06d98-c722-433b-b100-0fb0d0d0915c.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"ctTmChYwrALlsYSY"} +{"name":"asda.gif","date":"2023-10-26T16:07:13.205Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/asda.gif","type":"image/gif","size":2414319,"imageWidth":1160,"imageHeight":653,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fasda.gif","thumbnailWidth":330,"thumbnailHeight":186,"uuid":"DrNyvjoahVRfPqfc"} +{"name":"freddy.gif","date":"2023-10-26T16:07:33.397Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/freddy.gif","type":"image/gif","size":3807320,"imageWidth":480,"imageHeight":480,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffreddy.gif","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"JZgBnLYoTvZmoiEm"} +{"name":"poop-emoji.jpg","date":"2023-11-27T16:55:26.682Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/poop-emoji.jpg","type":"image/jpeg","size":277135,"imageWidth":1200,"imageHeight":1200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fpoop-emoji.jpg","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"Cb4D9nc5184NLZWn"} +{"name":"Screen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","date":"2023-11-27T16:55:33.660Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","type":"image/webp","size":34994,"imageWidth":1400,"imageHeight":788,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreen_Shot_2021-06-25_at_8.06.28_PM_1400x.webp","thumbnailWidth":330,"thumbnailHeight":186,"uuid":"ZVERuCeCDI11tY8f"} +{"name":"videoplayback (5).mp4","date":"2023-11-30T20:09:06.159Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(5).mp4","type":"video/mp4","size":5225498,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(5).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"x22blklePMGQRwIA"} +{"name":"afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","date":"2023-12-01T17:04:48.242Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","type":"image/jpeg","size":673888,"imageWidth":2048,"imageHeight":1365,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fafg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg","thumbnailWidth":330,"thumbnailHeight":220,"uuid":"DjbeeYPv58kWZxGT"} +{"name":"Papyrus.webp","date":"2023-12-01T17:04:54.185Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp","type":"image/webp","size":22528,"imageWidth":400,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FPapyrus.webp","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"1oCUTGTCUHSm6Rht"} +{"name":"videoplayback (6).mp4","date":"2023-12-04T12:01:19.895Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(6).mp4","type":"video/mp4","size":107238,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(6).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sKgj926hemecxf1z"} +{"name":"nerd-emoji.gif","date":"2023-12-04T12:10:45.734Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nerd-emoji.gif","type":"image/gif","size":58415,"imageWidth":200,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nerd-emoji.gif","thumbnailWidth":200,"thumbnailHeight":200,"uuid":"IEWg3jT2scnmIEBa"} +{"name":"IMG_20231204_144411762_LAYER.jpg","date":"2023-12-04T18:20:34.323Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144411762_LAYER.jpg","type":"image/jpeg","size":4291465,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144411762_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"kHofB34sB8zK8ghc"} +{"name":"IMG_20231204_144409218_LAYER.jpg","date":"2023-12-04T18:20:37.274Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144409218_LAYER.jpg","type":"image/jpeg","size":4649997,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144409218_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"wy3sATUDmtO4UKav"} +{"name":"IMG_20231204_144406913_LAYER.jpg","date":"2023-12-04T18:20:40.278Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144406913_LAYER.jpg","type":"image/jpeg","size":4663414,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144406913_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"VVnb7tpycOZ96wIM"} +{"name":"IMG_20231204_144358408_LAYER.jpg","date":"2023-12-04T18:20:43.765Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144358408_LAYER.jpg","type":"image/jpeg","size":4910430,"imageWidth":3072,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20231204_144358408_LAYER.jpg","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"298PzLlhaFIqxxcq"} +{"name":"2023_12_05_0sn_Kleki.png","date":"2023-12-05T20:41:21.532Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_05_0sn_Kleki.png","type":"image/png","size":9872,"imageWidth":91,"imageHeight":93,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_05_0sn_Kleki.png","thumbnailWidth":91,"thumbnailHeight":93,"uuid":"lzgyLwxKAAQT4aRa"} +{"name":"2023_12_06_0yp_Kleki.png","date":"2023-12-07T00:24:27.560Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yp_Kleki.png","type":"image/png","size":70691,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yp_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"lq8MCR84TekmbueY"} +{"name":"2023_12_06_0yt_Kleki.png","date":"2023-12-07T00:24:47.196Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yt_Kleki.png","type":"image/png","size":81775,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yt_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"ggXSa8BNzRjqSBnD"} +{"name":"2023_12_06_0yl_Kleki.png","date":"2023-12-07T00:25:10.293Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png","type":"image/png","size":84439,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"YAFhahkJBvHvomAo"} +{"name":"2023_12_06_0yi_Kleki.png","date":"2023-12-07T00:30:14.507Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yi_Kleki.png","type":"image/png","size":87010,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yi_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"dvm2XAnEJNmrlaoJ"} +{"name":"2023_12_06_0yh_Kleki.png","date":"2023-12-07T00:30:19.835Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yh_Kleki.png","type":"image/png","size":87060,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yh_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"RakITIBsTZAoxn6J"} +{"name":"2023_12_06_0yb_Kleki.png","date":"2023-12-07T00:30:29.284Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yb_Kleki.png","type":"image/png","size":75357,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yb_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"EvxT6uRiwx18Z2e8"} +{"name":"2023_12_06_0za_Kleki.png","date":"2023-12-07T00:49:05.704Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png","type":"image/png","size":72696,"imageWidth":296,"imageHeight":296,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png","thumbnailWidth":296,"thumbnailHeight":296,"uuid":"aoroY4SW6zapPfOE"} +{"name":"2023_12_08_0g8_Kleki.png","date":"2023-12-08T13:15:13.341Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_08_0g8_Kleki.png","type":"image/png","size":142882,"imageWidth":1117,"imageHeight":607,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2023_12_08_0g8_Kleki.png","thumbnailWidth":330,"thumbnailHeight":180,"uuid":"iRH2k0fN1Gx4DUk1"} +{"name":"MOSHED-2023-11-2-9-15-39.gif","date":"2023-12-12T12:59:58.261Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-15-39.gif","type":"image/gif","size":9742202,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-15-39.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"52P1expoZSM3Z2bZ"} +{"name":"MOSHED-2023-11-2-9-16-18.jpg","date":"2023-12-12T13:00:04.817Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-16-18.jpg","type":"image/jpeg","size":122406,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-16-18.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"VyBWbHyBZeQDkCqK"} +{"name":"MOSHED-2023-11-2-9-16-30.jpg","date":"2023-12-12T13:00:12.253Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-16-30.jpg","type":"image/jpeg","size":194318,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-16-30.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"ccSREI092qAxPu6K"} +{"name":"MOSHED-2023-11-2-9-17-44.gif","date":"2023-12-12T13:00:21.674Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-17-44.gif","type":"image/gif","size":8254208,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-17-44.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"vThvLihG3U4Tva8u"} +{"name":"MOSHED-2023-11-2-9-18-42.gif","date":"2023-12-12T13:00:29.800Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-18-42.gif","type":"image/gif","size":22820370,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-18-42.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"Aei1r7CUxV9JTPGZ"} +{"name":"MOSHED-2023-11-2-9-19-19.jpg","date":"2023-12-12T13:00:34.450Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-19-19.jpg","type":"image/jpeg","size":102760,"imageWidth":1568,"imageHeight":980,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-19-19.jpg","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"lp7GBZ7NYag3ZEM5"} +{"name":"MOSHED-2023-11-2-9-22-40.gif","date":"2023-12-12T13:00:45.756Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-22-40.gif","type":"image/gif","size":13789663,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-22-40.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"b3XRVsDg7Qv5QFYZ"} +{"name":"MOSHED-2023-11-2-9-24-47.gif","date":"2023-12-12T13:00:51.248Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-24-47.gif","type":"image/gif","size":6092682,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-24-47.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"9TjxQT7jJYwEwQZb"} +{"uuid":"Aei1r7CUxV9JTPGZ","deleted":true} +{"name":"MOSHED-2023-11-2-9-18-42.gif","date":"2023-12-12T13:07:15.262Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-11-2-9-18-42.gif","type":"image/gif","size":22820370,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-11-2-9-18-42.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"mFh1JnSydzXR12gh"} +{"uuid":"mFh1JnSydzXR12gh","deleted":true} +{"name":"MOSHED-2023-12-12-10-47-6.gif","date":"2023-12-12T14:17:22.498Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-47-6.gif","type":"image/gif","size":11089695,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-47-6.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"kEzXuIpHEELcAuHJ"} +{"name":"MOSHED-2023-12-12-10-46-41.gif","date":"2023-12-12T14:17:26.360Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-46-41.gif","type":"image/gif","size":12491342,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-46-41.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"MjoGdc3z87JYHYl4"} +{"name":"MOSHED-2023-12-12-10-42-0.gif","date":"2023-12-12T14:17:29.599Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-42-0.gif","type":"image/gif","size":8559279,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-42-0.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"orEDVirkk7HGAjwX"} +{"name":"MOSHED-2023-12-12-10-39-41.gif","date":"2023-12-12T14:17:33.878Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-39-41.gif","type":"image/gif","size":6042203,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-39-41.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"soSGGxLRe87PpUyB"} +{"name":"MOSHED-2023-12-12-10-37-55.gif","date":"2023-12-12T14:17:36.549Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-12-10-37-55.gif","type":"image/gif","size":1825419,"imageWidth":640,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMOSHED-2023-12-12-10-37-55.gif","thumbnailWidth":330,"thumbnailHeight":207,"uuid":"suIcEXpXCuqgBnhb"} +{"uuid":"suIcEXpXCuqgBnhb","deleted":true} +{"uuid":"soSGGxLRe87PpUyB","deleted":true} +{"uuid":"orEDVirkk7HGAjwX","deleted":true} +{"uuid":"MjoGdc3z87JYHYl4","deleted":true} +{"uuid":"kEzXuIpHEELcAuHJ","deleted":true} +{"uuid":"9TjxQT7jJYwEwQZb","deleted":true} +{"uuid":"b3XRVsDg7Qv5QFYZ","deleted":true} +{"uuid":"lp7GBZ7NYag3ZEM5","deleted":true} +{"uuid":"vThvLihG3U4Tva8u","deleted":true} +{"uuid":"ccSREI092qAxPu6K","deleted":true} +{"uuid":"VyBWbHyBZeQDkCqK","deleted":true} +{"uuid":"52P1expoZSM3Z2bZ","deleted":true} +{"name":"fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","date":"2024-01-14T21:10:07.867Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","type":"image/png","size":2376,"imageWidth":96,"imageHeight":96,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fb286e65-331c-42ff-b226-ac5bfc7418b7.image.png","thumbnailWidth":96,"thumbnailHeight":96,"uuid":"uuaOAwjEVYE8UjTl"} +{"name":"oioioi.mp3","date":"2024-01-15T02:47:10.033Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3","type":"audio/mpeg","size":7221396,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Foioioi.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"TLbSQQprOSopfHoY"} +{"name":"Depredation.mp3","date":"2024-01-15T02:47:46.890Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation.mp3","type":"audio/mpeg","size":8288129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"XfFWeHV5t1gcuE4J"} +{"name":"World's End.wav","date":"2024-01-15T02:48:09.038Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav","type":"audio/wav","size":33800236,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FWorld's%20End.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"nFvYO1N5f6xH8PgY"} +{"name":"4Miklipi (Dejected) Preview.mp3","date":"2024-01-15T02:50:22.417Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3","type":"audio/mpeg","size":4125377,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4Miklipi%20(Dejected)%20Preview.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"b0959XaAUwrm5DBm"} +{"name":"nero shitpost.png","date":"2024-01-15T03:46:10.363Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nero%20shitpost.png","type":"image/png","size":192370,"imageWidth":500,"imageHeight":400,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fnero%20shitpost.png","thumbnailWidth":330,"thumbnailHeight":264,"uuid":"27bMMsSzzePzc4gx"} +{"name":"6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","date":"2024-01-15T04:04:38.159Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","type":"image/png","size":151618,"imageWidth":498,"imageHeight":498,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"BS5SvNlFUKcj0C0u"} +{"name":"look_closely.mp3","date":"2024-01-15T04:09:46.778Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/look_closely.mp3","type":"audio/mpeg","size":20922,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flook_closely.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"VlbLJHd2YrAkE8oQ"} +{"name":"e304fc26-480b-47b5-8270-949f7df44d92.image.png","date":"2024-01-15T04:58:22.951Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png","type":"image/png","size":85814,"imageWidth":298,"imageHeight":397,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fe304fc26-480b-47b5-8270-949f7df44d92.image.png","thumbnailWidth":248,"thumbnailHeight":330,"uuid":"JndrzAvoYpyDCqAG"} +{"name":"toilet_flush.mp3","date":"2024-01-15T05:28:22.578Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/toilet_flush.mp3","type":"audio/mpeg","size":94293,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftoilet_flush.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"8EtOGgdbXaVQRsG2"} +{"name":"y2mate_HOnnyD0.mp3","date":"2024-01-15T05:28:25.126Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/y2mate_HOnnyD0.mp3","type":"audio/mpeg","size":50684,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fy2mate_HOnnyD0.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"gZIE2RUndOaeOkpY"} +{"name":"flowing-water-sound-effect.mp3","date":"2024-01-15T06:24:21.150Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/flowing-water-sound-effect.mp3","type":"audio/mpeg","size":164603,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fflowing-water-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"lFzb954crqkjqSxU"} +{"name":"pew_pew-dknight556-1379997159.mp3","date":"2024-01-15T06:26:15.747Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/pew_pew-dknight556-1379997159.mp3","type":"audio/mpeg","size":7551,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fpew_pew-dknight556-1379997159.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"wbsUbQ176JelACja"} +{"name":"2024_01_15_05q_Kleki.png","date":"2024-01-15T06:57:08.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png","type":"image/png","size":20218,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_15_05q_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"FSqPDlLinpE8Loxx"} +{"name":"chipi-chipi-chapa-chapa.mp3","date":"2024-01-15T07:13:52.837Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chipi-chipi-chapa-chapa.mp3","type":"audio/mpeg","size":192826,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchipi-chipi-chapa-chapa.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"yz3SmgjTHe6LnBrF"} +{"name":"neko-arc.mp3","date":"2024-01-15T07:13:55.953Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/neko-arc.mp3","type":"audio/mpeg","size":17901,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fneko-arc.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"u3PHWM6bxDbQa4Z4"} +{"name":"bwomp.mp3","date":"2024-01-15T07:13:59.344Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bwomp.mp3","type":"audio/mpeg","size":6765,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fbwomp.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ORPQeX8y3fWoNeC1"} +{"name":"nfl.mp3","date":"2024-01-15T07:14:03.389Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nfl.mp3","type":"audio/mpeg","size":300347,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fnfl.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ll5dGpaMX1dkzUAc"} +{"name":"Gear-icon-transparent-background.png","date":"2024-01-18T11:59:38.381Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png","type":"image/png","size":14537,"imageWidth":512,"imageHeight":512,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FGear-icon-transparent-background.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"kK6xzuT7nN8es5J9"} +{"name":"Untitled979_20240120123618.png","date":"2024-01-20T17:38:31.845Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled979_20240120123618.png","type":"image/png","size":14246,"imageWidth":350,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FUntitled979_20240120123618.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"izP72RmZ8nLYsSdc"} +{"name":"74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","date":"2024-01-20T17:39:19.444Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","type":"image/png","size":17060,"imageWidth":215,"imageHeight":196,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png","thumbnailWidth":215,"thumbnailHeight":196,"uuid":"bJt3vCO1iQJAcPkv"} +{"name":"videoplayback.mp3","date":"2024-01-21T03:17:37.028Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3","type":"audio/mpeg","size":3451436,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"hFAccqiGuKtlcJVr"} +{"name":"jake-chudnow-edited_y1t8j5q.mp3","date":"2024-01-23T13:54:17.534Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jake-chudnow-edited_y1t8j5q.mp3","type":"audio/mpeg","size":340823,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fjake-chudnow-edited_y1t8j5q.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"KsmNUXrjFBTR9nnt"} +{"name":"MemeFeedBot_5.mp4","date":"2024-01-30T20:25:51.474Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MemeFeedBot_5.mp4","type":"video/mp4","size":1311719,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FMemeFeedBot_5.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"reUPECkwcraGwOc3"} +{"name":"4 2.wav","date":"2024-01-31T15:49:21.860Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4%202.wav","type":"audio/wav","size":248118,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4%202.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"1E7gld9pLGXWDUC8"} +{"name":"Screen recording 2024-01-23 9.38.41 AM.webm","date":"2024-02-02T01:45:08.442Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screen%20recording%202024-01-23%209.38.41%20AM.webm","type":"video/webm","size":1616860,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreen%20recording%202024-01-23%209.38.41%20AM.webm","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"Lp97bNs9HjhFIlKp"} +{"name":"2024_02_01_112_Kleki.png","date":"2024-02-02T01:45:11.256Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_112_Kleki.png","type":"image/png","size":84804,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_112_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"QZfJ4aPwLpj3gxD9"} +{"name":"2024_02_01_10z_Kleki.png","date":"2024-02-02T01:45:15.168Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_10z_Kleki.png","type":"image/png","size":84316,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_01_10z_Kleki.png","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"nDK0YapB9Y94CjO7"} +{"name":"2024_02_09_11n_Kleki.png","date":"2024-02-10T02:06:04.886Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_09_11n_Kleki.png","type":"image/png","size":53374,"imageWidth":218,"imageHeight":143,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_09_11n_Kleki.png","thumbnailWidth":218,"thumbnailHeight":143,"uuid":"KkGODJKzVOA9trS5"} +{"name":"2024_02_15_0qs_Kleki.png","date":"2024-02-15T19:34:53.434Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","type":"image/png","size":2051,"imageWidth":100,"imageHeight":100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","thumbnailWidth":100,"thumbnailHeight":100,"uuid":"b7U68EwE9UUNAsv8"} +{"uuid":"b7U68EwE9UUNAsv8","deleted":true} +{"name":"Trophy.png","date":"2024-02-15T19:34:53.434Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png","type":"image/png","size":2051,"imageWidth":100,"imageHeight":100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_02_15_0qs_Kleki.png","thumbnailWidth":100,"thumbnailHeight":100,"uuid":"b7U68EwE9UUNAsv8"} +{"name":"download.mp3","date":"2024-02-18T01:07:44.295Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download.mp3","type":"audio/mpeg","size":9263777,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdownload.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"cCo9wkdNbXgR9VRm"} +{"name":"download (1).mp3","date":"2024-02-18T01:07:55.743Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/download%20(1).mp3","type":"audio/mpeg","size":6227366,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdownload%20(1).mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"GUN6DCqlRr6SCsv0"} +{"name":"Untitled Project (22).jpg","date":"2024-02-19T15:27:04.097Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg","type":"image/jpeg","size":34686,"imageWidth":159,"imageHeight":159,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg","thumbnailWidth":159,"thumbnailHeight":159,"uuid":"QzQilm4F3P6jalgR"} +{"uuid":"x22blklePMGQRwIA","deleted":true} +{"name":"videoplayback (5).mp4","date":"2024-02-21T15:51:31.894Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(5).mp4","type":"video/mp4","size":2213386,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(5).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"q6L0WZWbnI2dyDzS"} +{"name":"arrow.png","date":"2024-02-21T17:00:37.425Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/arrow.png","type":"image/png","size":20446,"imageWidth":500,"imageHeight":500,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Farrow.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"ZUGJVJXduGCYUybX"} +{"name":"arrow2.png","date":"2024-02-21T17:00:40.066Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/arrow2.png","type":"image/png","size":20272,"imageWidth":500,"imageHeight":500,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Farrow2.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"vTxD8Cdq5AZzpZHG"} +{"name":"2024_01_29_0rx_Kleki.png","date":"2024-02-21T17:30:37.147Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0rx_Kleki.png","type":"image/png","size":44308,"imageWidth":512,"imageHeight":362,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0rx_Kleki.png","thumbnailWidth":330,"thumbnailHeight":234,"uuid":"RyxRk17SDpdmFzRs"} +{"uuid":"RyxRk17SDpdmFzRs","deleted":true} +{"name":"2024_01_29_0ry_Kleki.png","date":"2024-02-21T17:30:52.978Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png","type":"image/png","size":78166,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0ry_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"02ssJF2Tzrmn3sTQ"} +{"uuid":"02ssJF2Tzrmn3sTQ","deleted":true} +{"name":"2024_01_29_0rs_Kleki.png","date":"2024-02-21T17:31:06.919Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0rs_Kleki.png","type":"image/png","size":49959,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0rs_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"HqLijl5c1PuEAXz6"} +{"uuid":"HqLijl5c1PuEAXz6","deleted":true} +{"name":"2024_01_29_0ry_Kleki.png","date":"2024-02-21T17:31:20.813Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png","type":"image/png","size":78166,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2024_01_29_0ry_Kleki.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"teEHfjowTA5oXZNX"} +{"uuid":"ULDBE338jPz5CztZ","deleted":true} +{"name":"onetransparentsingulardamnfuckingpixel.png","date":"2024-02-22T02:16:19.353Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png","type":"image/png","size":81,"imageWidth":1,"imageHeight":1,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png","thumbnailWidth":1,"thumbnailHeight":1,"uuid":"ckPJEBh7eEJWdxnK"} +{"name":"primal.webp","date":"2024-02-22T11:52:43.032Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp","type":"image/webp","size":56824,"imageWidth":350,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fprimal.webp","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"cfHcvjVbbDfZh8xc"} +{"name":"image.webp","date":"2024-02-22T11:52:45.689Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","type":"image/webp","size":59336,"imageWidth":281,"imageHeight":350,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fimage.webp","thumbnailWidth":265,"thumbnailHeight":330,"uuid":"9yXl5YIjYKceliFg"} +{"uuid":"ctTmChYwrALlsYSY","deleted":true} +{"name":"locked.png","date":"2024-02-22T11:55:29.342Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked.png","type":"image/png","size":18202,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"n8yNyvfqwb7DnXAi"} +{"name":"tv.png","date":"2024-02-22T15:17:55.011Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png","type":"image/png","size":106896,"imageWidth":600,"imageHeight":600,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftv.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"IZOWYASNX0WOguf8"} +{"name":"MOSHED-2023-12-14-17-8-14.gif","date":"2024-02-22T16:22:04.966Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif","type":"image/gif","size":710884,"imageWidth":182,"imageHeight":182,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif","thumbnailWidth":182,"thumbnailHeight":182,"uuid":"zoDYKbRylm4uPSua"} +{"name":"skype.png","date":"2024-02-22T16:23:57.464Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png","type":"image/png","size":135963,"imageWidth":2400,"imageHeight":2435,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fskype.png","thumbnailWidth":326,"thumbnailHeight":330,"uuid":"H8TxN9mqnMgaTfLw"} +{"name":"2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","date":"2024-02-22T16:25:46.196Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","type":"image/png","size":163198,"imageWidth":1200,"imageHeight":1200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"BETXanMl4Oa3nyk2"} +{"uuid":"9yXl5YIjYKceliFg","deleted":true} +{"uuid":"H8TxN9mqnMgaTfLw","deleted":true} +{"name":"skype.png","date":"2024-02-22T17:39:54.494Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png","type":"image/png","size":37427,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fskype.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"f8Ge23pxSgxIHP3y"} +{"name":"image.webp","date":"2024-02-22T17:39:56.560Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","type":"image/webp","size":76573,"imageWidth":300,"imageHeight":300,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp","thumbnailWidth":300,"thumbnailHeight":300,"uuid":"T4mvFRGVmo7ZSS3r"} +{"name":"locked2.png","date":"2024-02-23T18:43:14.287Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked2.png","type":"image/png","size":17278,"imageWidth":612,"imageHeight":612,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked2.png","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"M9o7ylMUafge5ugm"} +{"name":"select.png","date":"2024-02-23T19:54:31.992Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png","type":"image/png","size":8705,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fselect.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"VUgg69AS6qvPYYm2"} +{"name":"locked!.png","date":"2024-02-23T19:54:35.601Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png","type":"image/png","size":9307,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Flocked!.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"9TbrgbxQ4qWp7wo8"} +{"name":"selected.png","date":"2024-02-23T19:57:48.075Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png","type":"image/png","size":10342,"imageWidth":382,"imageHeight":200,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fselected.png","thumbnailWidth":330,"thumbnailHeight":173,"uuid":"FOpbj7lZQ46siJhg"} +{"name":"Coca_Cola_Espuma.mp4","date":"2024-02-25T21:05:14.047Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Coca_Cola_Espuma.mp4","type":"video/mp4","size":104064,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FCoca_Cola_Espuma.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"FGE2VR7615Lfujp8"} +{"name":"channels4_profile.jpg","date":"2024-03-01T20:16:47.088Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/channels4_profile.jpg","type":"image/jpeg","size":99589,"imageWidth":900,"imageHeight":900,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchannels4_profile.jpg","thumbnailWidth":330,"thumbnailHeight":330,"uuid":"jd7joNLFJLt9pfED"} +{"name":"2024_03_02_0yw_Kleki.png","date":"2024-03-03T00:26:41.538Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki.png","type":"image/png","size":2141,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"th3bRPzSTorKXKDi"} +{"name":"2024_03_02_0yw_Kleki (1).png","date":"2024-03-03T00:26:52.528Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki%20(1).png","type":"image/png","size":7139,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_02_0yw_Kleki%20(1).png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"p9YoKuARaRk3B841"} +{"uuid":"txSk7RsRJ33ZgL0R","deleted":true} +{"name":"videoplayback.mp4","date":"2024-03-03T01:45:53.601Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp4","type":"video/mp4","size":2796319,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"NKyN5jkpsVkhg3Yl"} +{"uuid":"q6L0WZWbnI2dyDzS","deleted":true} +{"name":"undertakers-bell_2UwFCIe.mp3","date":"2024-03-12T18:42:39.839Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/undertakers-bell_2UwFCIe.mp3","type":"audio/mpeg","size":68055,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fundertakers-bell_2UwFCIe.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"u6xFAcMANHBQhPTB"} +{"name":"aaaaaaaa-online-audio-converter_r9waVUO.mp3","date":"2024-03-12T19:17:49.219Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/aaaaaaaa-online-audio-converter_r9waVUO.mp3","type":"audio/mpeg","size":17807,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Faaaaaaaa-online-audio-converter_r9waVUO.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"aNcuRqu2nQzZStT2"} +{"name":"metal-pipe-clang.mp3","date":"2024-03-12T19:17:53.637Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/metal-pipe-clang.mp3","type":"audio/mpeg","size":45694,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fmetal-pipe-clang.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ro1Gfn5NPJDSpUUK"} +{"name":"vine-boom.mp3","date":"2024-03-12T22:02:49.499Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/vine-boom.mp3","type":"audio/mpeg","size":21230,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvine-boom.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ebMorJE4l2U0t6ec"} +{"name":"tmp_7901-951678082.mp3","date":"2024-03-12T22:02:54.624Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tmp_7901-951678082.mp3","type":"audio/mpeg","size":16425,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftmp_7901-951678082.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ApoIUl7SyuyEaopN"} +{"name":"emotional-damage-meme.mp3","date":"2024-03-12T22:02:59.660Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/emotional-damage-meme.mp3","type":"audio/mpeg","size":54262,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Femotional-damage-meme.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"UNGgdWN3md0VrWpz"} +{"name":"discord-notification.mp3","date":"2024-03-12T22:03:03.356Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/discord-notification.mp3","type":"audio/mpeg","size":8301,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdiscord-notification.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"NCiDWuamdHpEV71a"} +{"name":"wrong-answer-sound-effect.mp3","date":"2024-03-12T22:03:15.813Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/wrong-answer-sound-effect.mp3","type":"audio/mpeg","size":19479,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fwrong-answer-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"cvaZ88hmjymDoYyl"} +{"name":"clash-royale-hog-rider.mp3","date":"2024-03-12T22:03:19.656Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/clash-royale-hog-rider.mp3","type":"audio/mpeg","size":70145,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fclash-royale-hog-rider.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"58kvJm1P0eAgy2zu"} +{"name":"goofy-ahh-car-horn-sound-effect.mp3","date":"2024-03-12T22:03:24.188Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/goofy-ahh-car-horn-sound-effect.mp3","type":"audio/mpeg","size":49456,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fgoofy-ahh-car-horn-sound-effect.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sqlTlpMYSaoC5Ibw"} +{"name":"tf_nemesis.mp3","date":"2024-03-12T22:03:29.502Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tf_nemesis.mp3","type":"audio/mpeg","size":73813,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftf_nemesis.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"pQcX3TfMLczzdXm0"} +{"name":"chinese-rap-song.mp3","date":"2024-03-12T22:03:35.151Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chinese-rap-song.mp3","type":"audio/mpeg","size":160451,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fchinese-rap-song.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"UG4BHOkrbtySjMoI"} +{"name":"fire-in-the-hole-geometry-dash.mp3","date":"2024-03-12T22:03:40.367Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fire-in-the-hole-geometry-dash.mp3","type":"audio/mpeg","size":31680,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffire-in-the-hole-geometry-dash.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"RxWARK12ebQVuh9e"} +{"name":"water-on-the-hill.mp3","date":"2024-03-12T22:03:47.326Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/water-on-the-hill.mp3","type":"audio/mpeg","size":13100,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fwater-on-the-hill.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"6lJLNPCsgJCtbgrd"} +{"name":"taco-bell-bong-sfx.mp3","date":"2024-03-12T22:03:52.201Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/taco-bell-bong-sfx.mp3","type":"audio/mpeg","size":31599,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ftaco-bell-bong-sfx.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"wdvpWAE7Px1X3Z6R"} +{"name":"dun_dun_1.mp3","date":"2024-03-14T15:54:39.063Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/dun_dun_1.mp3","type":"audio/mpeg","size":21607,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdun_dun_1.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"RukfNSPWQfBw87v2"} +{"name":"holy-moly-emoji.mp3","date":"2024-03-14T15:54:42.780Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/holy-moly-emoji.mp3","type":"audio/mpeg","size":22567,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fholy-moly-emoji.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"B3qwwfOmo4IqDjky"} +{"name":"spongebob-boowomp.mp3","date":"2024-03-14T15:54:49.245Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spongebob-boowomp.mp3","type":"audio/mpeg","size":23751,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fspongebob-boowomp.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"WKAEtNX56P5Yjl6G"} +{"name":"bad-to-the-bone-meme.mp3","date":"2024-03-14T15:54:54.343Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bad-to-the-bone-meme.mp3","type":"audio/mpeg","size":41346,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fbad-to-the-bone-meme.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"GE5BxezBXE6OeL3d"} +{"name":"feet-gd.mp3","date":"2024-03-14T15:54:59.794Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/feet-gd.mp3","type":"audio/mpeg","size":8352,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Ffeet-gd.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"8mtGRsAwmu5czOoy"} +{"name":"5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","date":"2024-03-20T22:15:57.366Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","type":"image/png","size":66868,"imageWidth":1536,"imageHeight":951,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F5c6d635f-a352-4145-9002-2d0a4e16824d.image.png","thumbnailWidth":330,"thumbnailHeight":205,"uuid":"XP09HX2tGTiXNXFs"} +{"name":"2024_03_26_0zp_Kleki.png","date":"2024-03-26T23:55:49.798Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_26_0zp_Kleki.png","type":"image/png","size":8852,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_03_26_0zp_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"xFkrHKnI6qOjWIB7"} +{"name":"image_2024-04-11_161031965.ico","date":"2024-04-11T18:41:32.273Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image_2024-04-11_161031965.ico","type":"image/x-icon","size":225726,"imageWidth":256,"imageHeight":256,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image_2024-04-11_161031965.ico","thumbnailWidth":256,"thumbnailHeight":256,"uuid":"b73O6MpXAdhV1Rur"} +{"uuid":"XfFWeHV5t1gcuE4J","deleted":true} +{"name":"Action Agenda - Killa DFX Edit.mp3","date":"2024-04-17T11:10:44.240Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3","type":"audio/mpeg","size":7596960,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FAction%20Agenda%20-%20Killa%20DFX%20Edit.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"goq6Nz3Otdd2T6CZ"} +{"uuid":"RsOUyfm1cBYSqbw0","deleted":true} +{"name":"Apotheosis.wav","date":"2024-04-17T11:13:48.783Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.wav","type":"audio/wav","size":33796140,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FApotheosis.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"sdKc4c16V8kOoffG"} +{"name":"Depredation.wav","date":"2024-04-17T11:51:30.584Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation.wav","type":"audio/wav","size":39784492,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"vMjHBJ94XqKWFz9b"} +{"name":"2024_04_17_0gh_Kleki.png","date":"2024-04-17T12:23:56.170Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png","type":"image/png","size":2144,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"dAHNcl4YUXtrnYNr"} +{"uuid":"sdKc4c16V8kOoffG","deleted":true} +{"uuid":"vMjHBJ94XqKWFz9b","deleted":true} +{"name":"8mb.video-tQi-0UoaHVvl.mp4","date":"2024-04-18T22:14:20.996Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/8mb.video-tQi-0UoaHVvl.mp4","type":"video/mp4","size":18092799,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F8mb.video-tQi-0UoaHVvl.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"qbGOtBvcJcjg37V9"} +{"uuid":"qbGOtBvcJcjg37V9","deleted":true} +{"name":"Screenshot_2024-04-12_at_2.52.02_PM.png","date":"2024-04-19T10:54:45.626Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Screenshot_2024-04-12_at_2.52.02_PM.png","type":"image/png","size":72691,"imageWidth":272,"imageHeight":366,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FScreenshot_2024-04-12_at_2.52.02_PM.png","thumbnailWidth":246,"thumbnailHeight":330,"uuid":"UmCvpyaMKwvJtjI9"} +{"name":"videoplayback (4).mp4","date":"2024-04-19T10:56:39.084Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback%20(4).mp4","type":"video/mp4","size":258165,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback%20(4).mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"DGrL98ImDItr7mJG"} +{"name":"Depredation V2.mp3","date":"2024-04-19T11:12:12.474Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3","type":"audio/mpeg","size":8288129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FDepredation%20V2.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"6LtgWCgUdzzqE3hr"} +{"name":"Apotheosis (1).mp3","date":"2024-04-19T11:16:59.376Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis%20(1).mp3","type":"audio/mpeg","size":7040129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FApotheosis%20(1).mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ku50xwnoZ8ABjNcJ"} +{"name":"2024_04_22_0ep_Kleki.png","date":"2024-04-22T11:40:03.892Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0ep_Kleki.png","type":"image/png","size":2169,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0ep_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"KtLhCRh5D7z40ufq"} +{"uuid":"KtLhCRh5D7z40ufq","deleted":true} +{"name":"2024_04_22_0fb_Kleki.png","date":"2024-04-22T11:43:54.204Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0fb_Kleki.png","type":"image/png","size":2165,"imageWidth":128,"imageHeight":128,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_22_0fb_Kleki.png","thumbnailWidth":128,"thumbnailHeight":128,"uuid":"Zq5aBpo0JAKsFPSd"} +{"name":"Voicy_Slap Battles Killstreak Kill.mp3","date":"2024-04-25T11:47:23.190Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Voicy_Slap%20Battles%20Killstreak%20Kill.mp3","type":"audio/mpeg","size":45171,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FVoicy_Slap%20Battles%20Killstreak%20Kill.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"YE7Wbxb7eY4uN03N"} +{"name":"1165825970528325682.webp","date":"2024-04-26T18:39:24.280Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp","type":"image/webp","size":1098,"imageWidth":45,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp","thumbnailWidth":45,"thumbnailHeight":48,"uuid":"bAX0kJLTMphe3F8v"} +{"name":"1165934432608321546.webp","date":"2024-04-26T18:39:28.932Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp","type":"image/webp","size":968,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"Ci3JnJpEDmg4VF1c"} +{"name":"1165934167280848969.webp","date":"2024-04-26T18:39:33.284Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp","type":"image/webp","size":1582,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"HTqsPOJz4I9rlBGh"} +{"name":"1165826077843796018.webp","date":"2024-04-26T18:39:38.841Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp","type":"image/webp","size":950,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"eV1sBWslSmqgAf1m"} +{"name":"1165825970528325682l.webp","date":"2024-04-26T18:40:07.621Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp","type":"image/webp","size":864,"imageWidth":48,"imageHeight":48,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp","thumbnailWidth":48,"thumbnailHeight":48,"uuid":"neN7tKpXt8DS0TpV"} +{"uuid":"nFvYO1N5f6xH8PgY","deleted":true} +{"uuid":"b0959XaAUwrm5DBm","deleted":true} +{"name":"Dejected.mp3","date":"2024-01-15T02:50:22.417Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3","type":"audio/mpeg","size":4125377,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F4Miklipi%20(Dejected)%20Preview.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"b0959XaAUwrm5DBm"} +{"uuid":"ku50xwnoZ8ABjNcJ","deleted":true} +{"name":"Apotheosis.mp3","date":"2024-04-19T11:16:59.376Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3","type":"audio/mpeg","size":7040129,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FApotheosis%20(1).mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ku50xwnoZ8ABjNcJ"} +{"uuid":"cCo9wkdNbXgR9VRm","deleted":true} +{"name":"longing.mp3","date":"2024-02-18T01:07:44.295Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3","type":"audio/mpeg","size":9263777,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdownload.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"cCo9wkdNbXgR9VRm"} +{"uuid":"GUN6DCqlRr6SCsv0","deleted":true} +{"name":"resurgam.mp3","date":"2024-02-18T01:07:55.743Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3","type":"audio/mpeg","size":6227366,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdownload%20(1).mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"GUN6DCqlRr6SCsv0"} +{"uuid":"hFAccqiGuKtlcJVr","deleted":true} +{"name":"anybody.mp3","date":"2024-01-21T03:17:37.028Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3","type":"audio/mpeg","size":3451436,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fvideoplayback.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"hFAccqiGuKtlcJVr"} +{"name":"World's End.wav","date":"2024-04-29T13:56:37.026Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav","type":"audio/wav","size":33800236,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FWorld's%20End.wav","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"ifIYobcrMaJ5CVvw"} +{"uuid":"ifIYobcrMaJ5CVvw","deleted":true} +{"name":"World's End but mp4.mp3","date":"2024-04-29T13:58:52.177Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End%20but%20mp4.mp3","type":"audio/mpeg","size":7041141,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FWorld's%20End%20but%20mp4.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"OzD5VXdumCGeEqDb"} +{"uuid":"OzD5VXdumCGeEqDb","deleted":true} +{"name":"WorldsEnd.mp3","date":"2024-04-29T13:58:52.177Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3","type":"audio/mpeg","size":7041141,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FWorld's%20End%20but%20mp4.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"OzD5VXdumCGeEqDb"} +{"name":"(Audio) 2024-04-22 15-59-27.m4a","date":"2024-04-29T17:56:37.185Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/(Audio)%202024-04-22%2015-59-27.m4a","type":"audio/x-m4a","size":469042,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F(Audio)%202024-04-22%2015-59-27.m4a","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"BL7o4FYSsr2Xtdab"} +{"uuid":"BL7o4FYSsr2Xtdab","deleted":true} +{"name":"ultimate laughter.mp4","date":"2024-04-29T17:57:21.289Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/ultimate%20laughter.mp4","type":"video/mp4","size":12731065,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fultimate%20laughter.mp4","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"qKxRKzwie2uwOD1P"} +{"name":"demol1sh.mp3","date":"2024-04-29T18:15:57.787Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3","type":"audio/mpeg","size":4167680,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdemol1sh.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"J2BTiSehE6If7Hxe"} +{"name":"routin3s.mp3","date":"2024-04-29T18:18:00.054Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3","type":"audio/mpeg","size":3073485,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Froutin3s.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"n1p45IKty7rhEB3C"} +{"name":"souven1r.mp3","date":"2024-04-29T18:18:04.036Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/souven1r.mp3","type":"audio/mpeg","size":3815868,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fsouven1r.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"gT7k6nINNGIZi3N3"} +{"name":"jitt3rs.mp3","date":"2024-04-29T18:18:04.287Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3","type":"audio/mpeg","size":4775267,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fjitt3rs.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"Be3hu6iiO23cqEY0"} +{"name":"2ouvenir.mp3","date":"2024-04-29T18:18:20.719Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2ouvenir.mp3","type":"audio/mpeg","size":4318545,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F2ouvenir.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"1XBSkO00yeI1Yi2Y"} +{"name":"d3molish.mp3","date":"2024-04-29T18:18:26.958Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3","type":"audio/mpeg","size":3902041,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fd3molish.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"zW0KIBTt4lgumW6g"} +{"name":"demoli2h.mp3","date":"2024-04-29T18:18:34.759Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3","type":"audio/mpeg","size":3995734,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Fdemoli2h.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"lVqeyaHXOOHA3aZa"} +{"uuid":"n1p45IKty7rhEB3C","deleted":true} +{"name":"routin3s.mp3","date":"2024-04-29T18:20:50.230Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3","type":"audio/mpeg","size":3073485,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Froutin3s.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"TFRBBNfrVJUyspgF"} +{"name":"routine2.mp3","date":"2024-04-29T18:21:29.291Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3","type":"audio/mpeg","size":3457701,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2Froutine2.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"YFI91wH7W4ImAspG"} +{"uuid":"Lp97bNs9HjhFIlKp","deleted":true} +{"uuid":"1E7gld9pLGXWDUC8","deleted":true} +{"name":"IMG_20240528_183451141.jpg","date":"2024-05-28T21:05:24.675Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20240528_183451141.jpg","type":"image/jpeg","size":1297815,"imageWidth":1842,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20240528_183451141.jpg","thumbnailWidth":149,"thumbnailHeight":330,"uuid":"DOggN020wevkaQxc"} diff --git a/LICENSE b/LICENSE index 791d0c458..3c577b03e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,13 +1,24 @@ - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 +This is free and unencumbered software released into the public domain. -Copyright (C) 2004 Sam Hocevar +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. -Everyone is permitted to copy and distribute verbatim or modified -copies of this license document, and changing it is allowed as long -as the name is changed. +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. -0. You just DO WHAT THE FUCK YOU WANT TO. +For more information, please refer to \ No newline at end of file diff --git a/README.md b/README.md index fa25247ae..2b6481f00 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Open Source Arras -Logo ![GitHub Release](https://img.shields.io/github/v/release/Taureon/aps-plus-plus) ![Discord](https://img.shields.io/discord/1004907608018264094) @@ -32,7 +31,7 @@ Create a new project and choose to import one from GitHub. When prompted for the Navigate to `server/config.js` and replace `localhost:26301` with the URL for your project. (For Glitch users, it's `your-project.glitch.me` (replace `your-project` with the actual name of your project, it should be above settings)). -**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"` and change your port to something more generic like 3000 or 8080.** +**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"`. Glitch doesn't currently support Node 18.** After doing that, your server should be ready! @@ -45,4 +44,4 @@ After doing that, your server should be ready! ## Other Links - [Our Discord server](https://discord.gg/kvCAZfUCjy) -*p.s. if something goes terribly wrong it's not our fault* +*p.s. if something goes terribly wrong it's not our fault* \ No newline at end of file diff --git a/changelog preview b/changelog preview new file mode 100644 index 000000000..f0a94ebd6 --- /dev/null +++ b/changelog preview @@ -0,0 +1,533 @@ +
    +

    Update 3.2

    + [2024] +
      +
    • Fixed Undertow
    • +
    • Added Surge
    • +
    • Moved Music Checkbox
    • +
    • Bugfixes
    • +
    • Added Katana
    • +
    • Addded Risk Gamemode
    • +
    • Changed look of Revolutionist branch
    • +
    • Skin Issue Fix
    • +
    • Added Mini Defender
    • +
    • Integrated Lancer into Main & Added More Lancer Things
    • +
    • buffed kiva
    • +

      Holay Molay

      +
    +
    +
    +

    Update 3.1

    + [2024] +
      +
    • Fixed date since counter
    • +
    • Added BackShield & Mirror Shield
    • +
    • Fixed Tag Gamemode
    • +
    • Removed Stats Temporarily
    • +
    • Changed Bot Leveling
    • +
    • Nerfs & Buffs
    • +
    • Reorganized Entities
    • +
    • Added New Color System
    • +
    • Fixed Color System
    • +
    • New DFX Maze Map
    • +
    • Added Apotheosis V2 & Depredation Remastered V2 By Deltafyrex and Killa By Action Agenda (DFX Edit) To OST
    • +
    • Fixed Siege
    • +
    • Fixed Movement System
    • +
    • Fixed Death Sounds
    • +
    • Revamped Menu Popups
    • +
    • Added TwinSniper Branch And More to Acid And Chiller Branch
    • +
    • Fixed Music Bug, And Added Aura Basic, Jump Smasher And Whirlwind To The Main game
    • +
    • Fixed Shields
    • +
    • Moved Aura From Tier 3 To Tier 2 And Added Aura Branch
    • +
    • Added Flail & Buffed Auras
    • +
    • Added Firecracker, Douverie & Auto-2 Branch
    • +
    • Added Brella (upgrades from backshield) And Lancer Branch
    • +
    • Added More Options For Quality Of Life Features
    • +
    • Added New Achievements & Skins
    • +
    • Fixed Player Skin Bug
    • +
    • Fixed Color System Again And Added Glow + Nerfs/Buffs And other Bug Fixes
    • +

      Update 3.11 [2024]

      +
    • Fixed Desmos + 8 New OST Tracks
    • +
    • Added Music Selector And Fixed Music Bugs
    • +
    • Added In Game Audio Visualizer
    • +
    • Fixed Server Selector
    • +
    • Added A Beta Cocci
    • +
    • Small Menu & Ui Updates
    • +
    • Fixed Desmos AI Bug & Undertow
    • +
    • Nerfed Some Things
    • +

      Holay Molay

      +
    +
    +
    +

    Update 3.0

    + [2024] +
      +
    • Added Clubbin
    • +
    • Testing Achievements
    • +
    • Added Reset Achievements Button
    • +
    • Added Start Achievement
    • +
    • Added and Fixed Achievement Details
    • +
    • Added Disconnect, Lag, And Killstreak Achievement
    • +
    • Removed Kill Achievement cuz it dont work
    • +
    • Added New Special Achievement Type
    • +
    • Added Special Piss.io Achievement And Funny Skype Achievement
    • +
    • Re-Added And Fixed 5 Killstreak Achievement Again
    • +
    • Added Server to Client Functions
    • +
    • Added 10 Killstreak Achievement
    • +
    • Changed Debug Menu
    • +
    • Added Kill Amount In Debug
    • +
    • Added Audio Visualizer in the title screen
    • +
    • Fixed Embed Not Working Properly
    • +
    • Fixed Bug Where Audio Visualizer Appears In Game
    • +
    • Added Token And Discord Achievement
    • +
    • Added Achievements Tab
    • +
    • Removed Ach Testing
    • +
    • Added Credits Button
    • +
    • fixed credits interfering with changelog
    • +
    • added credits-changelog animation transition
    • +
    • moved credits button (its 1:08 am im soooooo tired)
    • +
    • Fixed Game Breaking Bug
    • +
    • Added Contagion Branch To Subduer & Trapper
    • +
    • Added Longing And Resurgam By Amaryllis To The OST
    • +
    • added credits ach
    • +
    • Added 2 New Branches For Desmos
    • +
    • Testing Skins
    • +
    • Added Beta Skin Menu
    • +
    • Fixed Skin Bug
    • +
    • Fixed Crashing On Respawn
    • +
    • Added More Detail To Skin Menu
    • +
    • Added Cat Code and Chickensandwhichman Skin
    • +
    • Added Daily Tanks
    • +
    • Added Plenty New Skins, New Achievements And Made Achievements Unlockable
    • +
    • Added Skater & Hitman
    • +
    • Added New "Duality" Map
    • +

      Update 2.93 [2024]

      +
    • David Goggins Event
    • +
    • Updated Menu
    • +
    • Added Marksman Branch To Sniper And Car Branch To
    • +
    • Added Trollface Emote (add --troll to the end of a chat message)
    • +
    • Added Waterfall, Acid, Cooler, Rainmaker And New Options Layout
    • +
    • Added Notes Tab + Live Counter
    • +
    • Added More Customization, Graphics, Helecopter And Fixed Music Bug
    • +
    • Added Reverie Branch And Injector
    • +
    • Added Debugger Menu
    • +
    • You Can Now Color Messages With §
    • +

      Niners fucking lost Again Bruh...Fuck Taylor Swift

      +
    +
    +
    +

    Update 2.9

    + [2024] +
      +
    • Added Motor
    • +
    • Added Kivaaharatedas (i did not spell that right)
    • +
    • Added Equilibrium, Revobrid, Subverter
    • +
    • shrapnel testing
    • +
    • removed unfinished aimbot/boosting testing
    • +
    • Added Basic Hybrid Tier 3 branch
    • +
    • Bug Fixed Colors
    • +
    • Added Tanks of my friends and tank soundboard support
    • +
    • Added the rest of the Basic Hybrid branch (tier 4)
    • +
    • Fixed changelog not appearing
    • +
    • Added beta music support including 5 songs
    • +
    • changed start button look to not shade out and actually work like a button
    • +
    • fixed debug key (again)
    • +
    • fixed screen tearing
    • +
    • worked bullet spawn position
    • +
    • Better organized dev menu and changed the way utilities looks
    • +
    • Added music recognition in the debug key to see the song name & artist
    • +
    • Added new song (Anybody can find Love (except You) by hkmori
    • +
    • fixed debug not recognizing a song and not updating after a song is finished
    • +
    • Testing wall colors/effects
    • +
    • Added Shield Turrets
    • +
    • Added new tiles (dance floor+black)
    • +
    • added new "banquet" map
    • +
    • Finished Revolutionist Branch
    • +
    • Added Inception & Albuquerque
    • +
    • im a fucking moron
    • +
    • Added Machceptioner & Tailgator
    • +
    • Added Interceptor, Twinceptioner, Inceptionist branch, hybrid/auto ver of inception branch
    • +
    • Added Desmos/Inception/Bascrid Ception
    • +
    • fixed the ceptionist turrets/autobullet turrets
    • +
    • nerfed shit
    • +
    • fixed some upgrades not appearing
    • +
    • no players (dead game and nobody plays is sadly)
    • +
    • so it turns out i forgot to give twinceptionist the right bullets so i fixed that :/
    • +
    • fixed flankcept branch turrets
    • +

      Update 2.91 [2024]

      +
    • Added the subduer branch
    • +
    • Fixed The Rest of the menu buttons and fixed sound effects
    • +
    • Added flankduer
    • +
    • Added Binary branch, Pathogen branch, mitochondrion branch, Subduer-Hybrid branch and Auto-Subduer Branch
    • +
    • fixed missing upgrades
    • +

      Hey! vsauce, Michael here. the game is stable and non buggy...or is it?

      +
    +
    +
    +

    Update 2.8

    + [2023] +
      +
    • Tank Adding Wave Two (ex. hadron, dictator, railgun + more)
    • +
    • Debug Key Bug Fix (how ironic)
    • +
    • Fixed Rng Images Bugging Out
    • +
    • Testing Whirlwind Branch
    • +
    • Fixed Maze Gamemode
    • +
    • Added Tooltips (beta)
    • +
    • Added Status Effects (beta+devevent)
    • +
    • Added Addon Support
    • +
    • Fixed button Shadows
    • +
    • Upgraded APS++ Updating Speed
    • +
    • New Mouse Controller
    • +
    • Keybind Fix
    • +
    • Enter can cancel a chat message being sent
    • +
    • CoNgReGaTiOn JuMpScArEs
    • +
    • Images on Tanks/Sound Effects For Tanks (dev)
    • +
    • Blackhole (dont ask just roll with it)
    • +
    • P A P Y R U S
    • +
    • Fixed Some Lag Holding Down Server Speed
    • +
    • 109.43.21.5.14
    • +
    • Added Desmos Branch
    • +
    • Theres Prob More But I Forgor
    • +

      wahhh... (i forgor why im crying)

      +
    +
    +
    +

    Update 2.7

    + [2023] +
      +
    • Debuffed Many Tanks
    • +
    • Migrated to new host
    • +
    • Removed all Nero Exclusive Tanks From The Game (for now anyway, dont worry)
    • +
    • Added "revolutionist" to testbed"
    • +
    • Massive Testbed overhaul
    • +
    • Added a funny randomly generated image on the start screen
    • +
    • Readded Sounds, design and other previous widgets
    • +
    • Hired new devs
    • +
    • did some tweaks to bots
    • +
    • got rid of the "nero" theme and the server list
    • +
    • added easter eggs
    • +
    • added random funny image
    • +

      Update 2.71 [2023]

      +
    • Tank Adding Wave One (ex. auto branch, revolutionist, cloner + more)
    • +
    • plenty of new dev features
    • +
    • added gamemode polls (once theres enough people)
    • +

      There are Easter Eggs All Over The Main Menu, You Might Find Something...

      +
    +
    +
    +

    Update 2.6

    + [2023] +
      +
    • replaced smashers origional upgrade path with the "armoury" tree -added lancer and smasher upgrades to armoury tree
    • +
    • added "Sword", "Injector" and "Fencer" to lancer upgrades
    • +
    • buffed drone tanks, twin tanks & tank health
    • +
    • added "Dictator" -added "Tripwire"
    • +
    • added "Barricade", "Twister", "Cyclone" and "Architect" -added "Tri-Trapper" tree -added "auto tritrapper", "auto armour" and "autolancer"
    • +
    • added "eagle" and "bulwark"
    • +
    • updated debug menu
    • +
    • removed hivemind from basic
    • +
    • added cloner upgrade
    • +
    • added hivemind and "splitter" to cloner upgrade
    • +
    • added "auto cloner", "auto flamethrower", "flamethrower hybrid" and "lancer hybrid"
    • +
    • updated colorscheme and other color related things
    • +
    • updated teams on 2tdm after 3 team bug -added all new Rock Maze gamemode
    • +

      Ryerson Loves Burger King

      +
    +
    +
    +

    Update 2.5

    + [2023] +
      +
    • added new tanks into beta for further testing
    • +
    • hired new devs
    • +
    • neroio discord is up
    • +
    • added new mascallenus tank and section
    • +
    • hired new beta testers
    • +
    • added new easter eggs
    • +
    • tested 2nd server opening
    • +
    • added "Scanner" and "hadoken"
    • +
    • nerfed Hahaugobrr
    • +
    • promoted lucas medieros to co-owner of the game
    • +
    • demoted a few staff
    • +
    • added 2TDM game mode
    • +
    • woomy event is back! now with free access to testbed
    • +
    • added "flankdrive", "twindrive" and "machinedrive"
    • +
    • fixed trapper look
    • +
    • added "infantry", "musket", "Traprid", "Auto Traprid", "Snigrav", "AsWdragafora", "Assasolak", "Builifacate", "Rifagiulus", "Auto Snigrav"
    • +
    • added "flamethrower", "Baker", "Wildfire" and "Equinox"
    • +
    • new nero.io default theme instead of using arras's
    • +
    • added insane af tanks to testbed
    • +
    • added "lancer"
    • +

      Open Na Noor

      +
    +
    +
    +

    Update 2.4

    + [2023] +
      +
    • added 2 new admin commands
    • +
    • added homing auto Basic
    • +
    • added bosses tab to AIT
    • +
    • bwomp AA $$ €€
    • +
    • added easter egg name colors
    • +
    • added the tanks "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", and "neptune"
    • +
    • added a new boss
    • +
    • added more natural spawning bosses
    • +
    • added "SpawnTrap"
    • +
    • updated bot names
    • +
    • ended woomy event
    • +

      Oh great red Text of the Changelog, What is your Wisdom?

      +
    +
    +
    +

    Update 2.3

    + [2023] +
      +
    • added "maleficator", "stalker", "landmine", "jumpsmash", "speedbent", "heavy3", and re-added "twindrive", "interceptioner", the "drive" subtree to autobasic, plus increased map size
    • +
    • fixed and debuffed jumpsmash
    • +
    • debuffed speedbent
    • +
    • added a public changelog (the one your looking at now)
    • +
    • added the red text
    • +
    • updated sounds and styles
    • +
    • added the "corrupted" button
    • +

      So Hows Ur Day?

      + +
    +
    +
    +

    Update 2.2

    + [2023] +
      +
    • added more tanks into beta
    • +
    • added sounds and updated client backround
    • +
    • Decoration finished
    • +
    • started decoration on migration host
    • +
    • added chat feature
    • +
    • migration big fixes
    • +
    • WE DID IT! MIGRATION COMPLETE!
    • +
    • during migration found multiple small bugs that was fixed
    • +
    • 2nd failed migrating attempt, starting yet another
    • +
    • fixed crashing bug
    • +
    • 2nd attempt at migrating
    • +
    • added random bot and skill classes
    • +
    • made bots more op
    • +
    • fixed a bot bug
    • +
    • downgraded bots
    • +
    • added tank visualizers
    • +
    • buffed bots a tiny bit more
    • +
    • fixed visualizer bug
    • +
    • added "rifle"
    • +
    • fixed "lilfact" upgrade path
    • +
    • added auto "lilfact"
    • +
    • renamed "lilfact" to "spawner"
    • +
    • added secret tanks for update 2.3
    • +
    • minor crash bug fixes
    • +
    • removed "rifle" and "autospawner" from beta
    • +
    • fixed smasher bug
    • +
    • failed "lancer" class attempt
    • +
    • secret tank updates
    • +
    • major bug fixes
    • +
    • rainbow color old client fix
    • +
    • last patches before big update
    • +
    • fixed tiny bug
    • +

      I Know Where You Live

      +
    +
    +
    +

    Update 2.1

    + [2022] +
      +
    • fixed the 2 game crashing bugs
    • +
    • tried to migrate to another server host but yet failed due to unknown reasons
    • +
    • added "speedbent" to beta
    • +
    • updated messages
    • +

      tbh im sad the 49ers missed the super bowl :/

      +
    +
    +
    +

    Update 2.0

    + [2021] +
      +
    • brought the ception tree into beta tanks
    • +
    • figured out that the "ceptions" arent really ceptions
    • +
    • forgot to add the actual way to access it LOL, also added a REAL machine ceptionist as a test
    • +
    • removed ceptionist and drive tanks as they are too overpowered
    • +
    • added lazer guns
    • +
    • stole code from someone elses server
    • +
    • added beta shock and burn
    • +
    • added some secret really stupid tanks
    • +
    • fixed a tank
    • +
    • removed revolutionist for being too buggy
    • +
    • added new auto class branch
    • +
    • added hivemind
    • +
    • bug fixes
    • +
    • major bug that caused no tanks to be added or bugs fixed causing confusion
    • +
    • crashing bug made game unplayable for large amount of time (like a whole 9 months)
    • +

      Whats Up Guys Quandale Dingle Here

      +
    +
    +
    +

    Update 1.9

    + [2021] +
      +
    • testing in progress
    • +
    • approved multiple tanks into the game
    • +
    • did some stupidity and added random stuff and figured out that there is indeed, 12882 lines of code in this project
    • +
    • added some dumb tanks like "mInIfLyInGfAsTeRtHiNgY"
    • +
    • added some cool colored objects on the "AsWdWsA" branch
    • +
    • added a secret tank
    • +
    • messed with some things like homing bullets
    • +
    • removed the homing stuff due to bugs
    • +
    • tried to recreate the "revolutionist" tank from woomy arras
    • +
    • more tests
    • +
    • added auto bullets
    • +
    • added drive tanks into beta testing phase
    • +
    • moved where the secret tank is
    • +
    • debuffed "single"
    • +
    • added "Cascal", "Gunto", "Catalyst", And "Cescav" to beta tanks
    • +
    • added a beta version of the drive tree into the game after some testing
    • +

      What A Dumb Fucking Game!

      +
    +
    +
    +

    Update 1.8

    + [2021] +
      +
    • completed and put the poison function into the game
    • +
    • completed and put the freeze function into the game
    • +
    • created a seprate freeze and poison bullets
    • +
    • added a stun function
    • +
    • added a healing and speed function
    • +
    • added a stun, healing and speed bullet shooting tanks
    • +
    • added the "AsWdWsA" branch
    • +
    • fixed poison cannon
    • +
    • renamed the bullets to respected name
    • +
    • renamed the cannons to a respected name
    • +
    • created a page 2 for the mascallenus
    • +
    • put multitanks into testbed
    • +
    • put multitanks into testbed
    • +
    • organized the tanks
    • +
    • removed public testbed
    • +

      :skull:

      +
    +
    +
    +

    Update 1.7

    + [2020] +
      +
    • added an admin logger
    • +
    • changed the AI color to pink
    • +
    • changed AI to have twin upgrade instead of basic
    • +
    • expanded the map
    • +
    • changed the colors of the spawning player to be random instead of always red or blue
    • +
    • added the tanks "oof" and "oof2" to mascallenus
    • +
    • added the tank "minibee" to testbed
    • +
    • added the tank "hexa trapper" into the game
    • +
    • added the tank "Paint Brush" into the crayon tree
    • +
    • added the tank "brutalizer"
    • +
    • added "sidewinder"
    • +

      Share with your friends!

      +
    +
    +
    +

    Update 1.6

    + [2020] +
      +
    • added the tank "tower mech"
    • +
    • added the "AIT" category into testbed
    • +
    • added a way to get back to a basic tank after becoming testbed
    • +
    • added the tank "crayon"
    • +
    • added the two tanks "marker" and "pastel"
    • +
    • added the tank "pen"
    • +
    • added a kill button to testbed
    • +
    • added the tank "highlighter"
    • +
    • added a way to immediatly upgrade into a basic trapper
    • +
    • invited some friends to help code my game
    • +

      Yo shout out to Lucas Medeiros

      +
    +
    +
    +

    Update 1.5

    + [2020] +
      +
    • removed jesus donut
    • +
    • removed DeltaCannon
    • +
    • fixed some bugs with AI's
    • +
    • fixed some bugs with crashers and bosses
    • +
    • added a bunch of testbed tanks into the real thing
    • +
    • removed fairsquare
    • +
    • added flame killa to testbed
    • +
    • removed access to the recently added tanks from testbed to save space
    • +
    • added Boxer to testbed
    • +
    • removed every testbed tank
    • +
    • added categories to test bed like "beta" and "mascallenus"
    • +

      come down today and try some corn, or we will sacrifice your newborn

      +
    +
    +
    +

    Update 1.4

    + [2020] +
      +
    • added Lottery to testbed
    • +
    • added hellblazer and Rocketer to testbed
    • +
    • added Nautilus to testbed
    • +
    • added jesus donut to testbed
    • +
    • experimented with bullet effects
    • +
    • added SleamShot
    • +
    • added TrapHard into testbed
    • +

      LMFAO WHAT A BOZO

      +
    +
    +
    +

    Update 1.3

    + [2020] +
      +
    • added master
    • +
    • added lilfact
    • +
    • fixed bug with bots
    • +
    • fixed bug with lilfact
    • +
    • ADDED PUBLIC TESTBED
    • +
    • fixed some bugs
    • +
    • fixed testbed problems
    • +
    • fixed testbed key errors regarding platform
    • +
    • added helltank to testbed
    • +
    • added DeltaCannon to testbed
    • +

      DrUgS aRe BaD fOr YoU1!1!

      +
    +
    +
    +

    Update 1.2

    + [2020] +
      +
    • server shutdown due to server problems
    • +
    • fixed problem
    • +
    • fixed some more bugs
    • +
    • fixed bug with the upgrades
    • +
    • added 3 pre-made extra tanks (hive shooter, auto assassin, auto cruiser)
    • +
    • added Unlocked
    • +
    • added more ways to get hive shooter
    • +
    • added more ways to get unlocked
    • +
    • added bots
    • +
    • fixed bad bug with Unlocked
    • +

      tbh play a better game than this

      +
    +
    +
    +

    Update 1.1

    + [2019] +
      +
    • added revix
    • +
    • added DeltaGunner
    • +

      OH BABY A TRIPLE

      +
    +
    +
    +

    Update 1.0

    + [2019] +
      +
    • just opened server
    • +
    • testing new tanks
    • +

      Bwomp

      +
    +
    +You've Reached The End ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file diff --git a/features.md b/features.md index 0ffa3a086..cbd7d12bc 100644 --- a/features.md +++ b/features.md @@ -174,7 +174,7 @@ It includes all features up to the latest release version. * Definitions Management * Split up into numerous other files, all located in `server/modules/definitions`. * Entity definitions are in `/groups`. - * "Facilitators" (makeAuto, combineStats, etc.), constants and gun values are in their own files. + * "Facilitators" (makeHybrid, combineStats, etc.), constants and gun values are in their own files. * As a requirement, you can now put `"strings"` as references instead of `Class.entity` references. * Added definition flattening, which would improve performance a bit by applying `PARENT`'s definitions directly to the definition. * Definition flattening also checks for entities that do not exist. @@ -275,4 +275,4 @@ It includes all features up to the latest release version. * Dominator Game Mode. * Doesn't kick for invalid tokens, instead just does not give any perms. * Level Bar now shows max level if you have exactly enough score to reach that level. -* Large `SHAPE`s now work. +* Large `SHAPE`s now work. \ No newline at end of file diff --git a/install.sh b/install.sh old mode 100755 new mode 100644 index b4847ba0a..ceab25054 --- a/install.sh +++ b/install.sh @@ -15,4 +15,4 @@ else else echo "Error occurred during installation." fi -fi +fi \ No newline at end of file diff --git a/neroplayer/script.js b/neroplayer/script.js new file mode 100644 index 000000000..f947ac1ff --- /dev/null +++ b/neroplayer/script.js @@ -0,0 +1,86 @@ +window.onload = function() { + + //Music functions: + //decide the music + var music2 = new Audio(); + const pmusic = ["https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/4Miklipi%20(Dejected)%20Preview.mp3?v=1705287022417", "https://cdn.glitch.me/5fc7dcb6-aada-495b-828e-66901a470a29/World's%20End.wav?v=1705286889038", "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/Meloncholy.mp3?v=1675465750213","https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation.mp3?v=1705286866890", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/videoplayback.mp3?v=1705807057028"]; + var randmusic = pmusic[~~(Math.random() * pmusic.length)]; + music2.src = (randmusic); + //load the play functions for itasdasf meow + function PlayMusic() { + music2.load(); + music2.play(); +} + +//actually play the audio when the checkbox is clicked on (checked) and stop it when unchecked +/* document.getElementById("optSound").onclick = () => { + if (document.getElementById("optSound").checked === true) { + global.music2.play() + global.music2.addEventListener('ended', function() {this.currentTime = 0; global.music2.src = pmusic[~~(Math.random() * pmusic.length)]; this.play();}, false); + } else if (document.getElementById("optSound").checked === false) { + global.music2.pause() + global.music2.songname = "Not Playing"; + } + return; };*/ + + var checkbox = document.getElementById("optSound"); + var audio = document.getElementById("audio"); + +checkbox.onclick = function() { + audio.src = randmusic; + audio.load(); + audio.play(); + var context = new AudioContext(); + var src = context.createMediaElementSource(audio); + var analyser = context.createAnalyser(); + + var canvas = document.getElementById("canvas"); + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + var ctx = canvas.getContext("2d"); + + src.connect(analyser); + analyser.connect(context.destination); + + analyser.fftSize = 256; + + var bufferLength = analyser.frequencyBinCount; + console.log(bufferLength); + + var dataArray = new Uint8Array(bufferLength); + + var WIDTH = canvas.width; + var HEIGHT = canvas.height; + + var barWidth = (WIDTH / bufferLength) * 2.5; + var barHeight; + var x = 0; + + function renderFrame() { + requestAnimationFrame(renderFrame); + + x = 0; + + analyser.getByteFrequencyData(dataArray); + + ctx.fillStyle = "#000"; + ctx.fillRect(0, 0, WIDTH, HEIGHT); + + for (var i = 0; i < bufferLength; i++) { + barHeight = dataArray[i]; + + var r = barHeight + (25 * (i/bufferLength)); + var g = 250 * (i/bufferLength); + var b = 50; + + ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; + ctx.fillRect(x, HEIGHT - barHeight, barWidth, barHeight); + + x += barWidth + 1; + } + } + + audio.play(); + renderFrame(); + }; +}; \ No newline at end of file diff --git a/neroplayer/stylesheet.css b/neroplayer/stylesheet.css new file mode 100644 index 000000000..c6218fa18 --- /dev/null +++ b/neroplayer/stylesheet.css @@ -0,0 +1,14 @@ +#canvas { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +audio { + position: fixed; + left: 10px; + bottom: 10px; + width: calc(100% - 20px); +} \ No newline at end of file diff --git a/neroplayer/visual.html b/neroplayer/visual.html new file mode 100644 index 000000000..658530558 --- /dev/null +++ b/neroplayer/visual.html @@ -0,0 +1,15 @@ + + + + + Audio Visualizer + + +
    + + +
    +
    + + + \ No newline at end of file diff --git a/package.json b/package.json index 68119883e..2987dcd79 100644 --- a/package.json +++ b/package.json @@ -6,15 +6,16 @@ "startOptimized": "node --optimize-for-size --no-lazy --gc_interval=120 server/index", "restartOnSaveOptimized": "node --optimize-for-size --no-lazy --gc_interval=120 --watch server/index", "start": "node server/index", + "startClient": "node public/index", "restartOnSave": "node --watch server/index", "host": "node standaloneClient/index", "build": "node standaloneClient/build minify" }, "dependencies": { - "ws": "^8.13.0" + "ws": "^8.16.0" }, "engines": { - "node": "18.x" + "node": "16.x" }, "license": "GPL-3.0" -} +} \ No newline at end of file diff --git a/public/app.js b/public/app.js index af49506b8..15c19ac94 100644 --- a/public/app.js +++ b/public/app.js @@ -6,6 +6,7 @@ import { settings } from "./lib/settings.js"; import { Canvas } from "./lib/canvas.js"; import { color } from "./lib/color.js"; import { gameDraw } from "./lib/gameDraw.js"; +import { tankdescs } from "./lib/tankdesc.js"; import * as socketStuff from "./lib/socketInit.js"; (async function (util, global, settings, Canvas, color, gameDraw, socketStuff) { @@ -19,7 +20,795 @@ let { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow } = s // document.getElementById("patchNotes").innerHTML += `
    ${changelog[0][0].slice(1).trim()}: ${changelog[0].slice(1).join(":") || "Update lol"}
      ${changelog.slice(1).map((line) => `
    • ${line.slice(1).trim()}
    • `).join("")}

    `; // } // }); + var playbuttonsound = new Audio(); + playbuttonsound.src = + "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/op1.wav?v=1675463613542"; + function PlaySound69() { + playbuttonsound.play(); + } + var clicked = false; + + var slap = new Audio(); + slap.src = + "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/(Audio)%20videoplayback.m4a?v=1675999054321"; + function PlaySound68() { + slap.play(); + } + + var vsau = new Audio(); + vsau.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jake-chudnow-edited_y1t8j5q.mp3?v=1706018057534" + function PlaySound99() { + vsau.play(); + } + + var clicksound = new Audio(); + clicksound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/sysse_ok.ogg"; + function PlaySound210() { + clicksound.play(); + } + + var trapperclosely = new Audio(); + trapperclosely.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/look_closely.mp3?v=1705291786778"); + function PlaySoundtrap() { + trapperclosely.play(); + } + + var waterflush = new Audio(); + waterflush.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/toilet_flush.mp3?v=1705296502578"); + function PlaySoundwater() { + waterflush.play(); + } + + var undadewatuh = new Audio(); + undadewatuh.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/y2mate_HOnnyD0.mp3?v=1705296505126"); + function PlaySoundwatuh() { + undadewatuh.play(); + } + + var piss = new Audio(); + piss.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/flowing-water-sound-effect.mp3?v=1705299861150"); + function PlaySoundpiss() { + piss.play(); + } + + var pew = new Audio(); + pew.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/pew_pew-dknight556-1379997159.mp3?v=1705299975747"); + function PlaySoundpew() { + pew.play(); + } + var chipi = new Audio(); + chipi.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chipi-chipi-chapa-chapa.mp3?v=1705302832837"); + function PlaySoundchipi() { + chipi.play(); + } + var neko = new Audio(); + neko.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/neko-arc.mp3?v=1705302835953"); + function PlaySoundneko() { + neko.play(); + } + var bwomp = new Audio(); + bwomp.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bwomp.mp3?v=1705302839344"); + function PlaySoundbwomp() { + bwomp.play(); + } + var nfl = new Audio(); + nfl.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/nfl.mp3?v=1705302843389"); + function PlaySoundnfl() { + nfl.play(); + } + + function doSomething() { + if (clicked) { + var optionclicksound = new Audio(); + optionclicksound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/cancel.wav"; + optionclicksound.load(); + optionclicksound.play(); + } else { + clicksound.load(); + clicksound.play(); + } + clicked = !clicked; + } + + var smallaudio2 = new Audio(); + smallaudio2.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/error.ogg"; + function PlaySound211() { + smallaudio2.play(); + } + + var smallaudio3 = new Audio( + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/socket.wav" + ); + smallaudio3.loop = false; + function PlaySound212() { + smallaudio3.loop = false; + smallaudio3.play(); + } +var killvariablenamething = true; +let metalpipe = new Audio(); +metalpipe.loop = false; +var randomdeathsound = ["https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/metal-pipe-clang.mp3?v=1710271073637", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/undertakers-bell_2UwFCIe.mp3?v=1710268959839", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/aaaaaaaa-online-audio-converter_r9waVUO.mp3?v=1710271069219", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/vine-boom.mp3?v=1710280969499", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tmp_7901-951678082.mp3?v=1710280974624", + "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/emotional-damage-meme.mp3?v=1710280979660", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/discord-notification.mp3?v=1710280983356", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/wrong-answer-sound-effect.mp3?v=1710280995813", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/clash-royale-hog-rider.mp3?v=1710280999656", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/goofy-ahh-car-horn-sound-effect.mp3?v=1710281004188", + "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tf_nemesis.mp3?v=1710281009502", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/chinese-rap-song.mp3?v=1710281015151", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/fire-in-the-hole-geometry-dash.mp3?v=1710281020367", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/water-on-the-hill.mp3?v=1710281027326", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/taco-bell-bong-sfx.mp3?v=1710281032201", + "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/download.mp3?v=1699142486910", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/spongebob-fail.mp3?v=1699146799125", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/62640b13-df2b-47d8-a06e-fb63b7fbb06e.mp3?v=1699272890577", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/f93f6d33-9dab-4e9d-aebb-917fe2d22982.mp3?v=1700153956047", "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/c647ea60-edf9-4bde-a0af-c49353593c7f.mp3?v=1700153959194", + "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/feet-gd.mp3?v=1710431699794", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/bad-to-the-bone-meme.mp3?v=1710431694343", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/spongebob-boowomp.mp3?v=1710431689245", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/holy-moly-emoji.mp3?v=1710431682780", "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/dun_dun_1.mp3?v=1710431679063"]; +function PlaySound420() { + if (global.killsoundready) { + killvariablenamething = true; + getksound(); + } +} +function getksound() { + if (global.killsoundready) { + if (killvariablenamething) { + metalpipe.src = randomdeathsound[Math.floor(Math.random() * randomdeathsound.length)]; + metalpipe.play(); + global.killsoundready = false; + } + } +} + var grubhub = new Audio(); +grubhub.src = ("https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/d318bd1e-5162-4fae-a757-5c350b16ccc9.mp3?v=1700153738394"); +function PlaySound169() { + grubhub.play(); +} + var smallaudio5 = new Audio(); + smallaudio5.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/poka.wav"; + function PlaySound214() { + smallaudio5.play(); + } + var smallaudio6 = new Audio(); + smallaudio6.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/finish.wav"; + function PlaySound215() { + smallaudio6.play(); + } + var camerasound = new Audio(); + camerasound.src = + "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/camera.wav"; + function PlaySound213() { + camerasound.play(); + } +var checkList = document.getElementById('list1'); +checkList.getElementsByClassName('anchor')[0].onclick = function(evt) { + if (checkList.classList.contains('visible')) + checkList.classList.remove('visible'); + else + checkList.classList.add('visible'); +} + +var pmusic = new Array(); +if (localStorage.getItem("oioioi" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033"); +if (localStorage.getItem("dejected" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417"); +if (localStorage.getItem("worldsend" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3?v=1714399132177"); +if (localStorage.getItem("depredation" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474"); +if (localStorage.getItem("anybody" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028"); +if (localStorage.getItem("resurgam" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3?v=1708218475743"); +if (localStorage.getItem("longing" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295"); +if (localStorage.getItem("apotheosis" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3?v=1713525419376"); +if (localStorage.getItem("killa" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"); +//if (localStorage.getItem("melancholy" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Meloncholy.mp3?v=1675465750213"); +if (localStorage.getItem("demol1sh" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787"); +if (localStorage.getItem("demoli2h" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3?v=1714414714759"); +if (localStorage.getItem("d3molish" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3?v=1714414706958"); +if (localStorage.getItem("souven1r" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/souven1r.mp3?v=1714414684036"); +if (localStorage.getItem("2ouvenir" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2ouvenir.mp3?v=1714414700719"); +if (localStorage.getItem("routine2" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3?v=1714414889291"); +if (localStorage.getItem("routin3s" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3?v=1714414850230"); +if (localStorage.getItem("jitt3rs" + 'Checked')) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287"); + +//Music functions: + //decide the music + global.music2 = document.getElementById("audio"); + var randmusic = pmusic[~~(Math.random() * pmusic.length)]; + global.music2.src = (randmusic); + //load the play functions for itasdasf meow + function PlayMusic() { + global.music2.load(); + global.music2.play(); +} + let musicvolume = 0; + var analyser; + +//actually play the audio when the checkbox is clicked on (checked) and stop it when unchecked + $("#optSound").on("click", function() { + if (document.getElementById("optSound").checked === true) { + songrecog() + global.music2.play() + //if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { + document.getElementById("content").style.opacity = 0.5 + //audio.src = randmusic; + //audio.load(); + //audio.play(); + var musiccontext = new AudioContext(); + var musicsrc = musiccontext.createMediaElementSource(global.music2); + var analyser = musiccontext.createAnalyser(); + + let musiccanvas = document.getElementById("canvas"); + musiccanvas.width = window.innerWidth * 1.3; + musiccanvas.height = window.innerHeight; + var ctx3 = musiccanvas.getContext("2d"); + ctx3.clearRect(0, 0, WIDTHOFBAR, global.screenHeight); + + musicsrc.connect(analyser); + analyser.connect(musiccontext.destination); + + analyser.fftSize = 1024; + + var bufferLength = analyser.frequencyBinCount; + console.log(bufferLength); + + var WIDTHOFBAR = musiccanvas.width; + var HEIGHTOFBAR = musiccanvas.height; + + var dataArray = new Uint8Array(bufferLength); + + var musicbarWidth = (WIDTHOFBAR / bufferLength); + var musicbarHeight; + var barstuffx = 0; + + function renderFrame() { + + if (global.gameStart) { + analyser.fftSize = 32; + musiccanvas.width = window.innerWidth; + WIDTHOFBAR = musiccanvas.width; + musicbarWidth = (WIDTHOFBAR / bufferLength); + musiccanvas.height = window.innerHeight; + bufferLength = analyser.frequencyBinCount; + document.getElementById("canvas").style.border = "solid 7px #000000" + } + + let deviscale = window.devicePixelRatio + + requestAnimationFrame(renderFrame); + + barstuffx = 0; + + analyser.getByteFrequencyData(dataArray); + + ctx3.fillStyle = "rgba(0,0,0,0.12)"; + ctx3.fillRect(0, 0, WIDTHOFBAR, global.screenHeight); + + for (var i = 0; i < bufferLength; i++) { + musicbarHeight = dataArray[i] * 2; + musicvolume = musicbarHeight; + + var b = musicbarHeight + (18 * (i/bufferLength)); + var r = 250 * (i/bufferLength); + var g = 50; + + ctx3.fillStyle = "rgb(" + r + "," + g + "," + b + ")"; + ctx3.fillRect(barstuffx, global.screenHeight - musicbarHeight * deviscale, musicbarWidth, musicbarHeight); + + barstuffx += musicbarWidth; + } + } + //audio.play(); + renderFrame(); + //} + global.music2.addEventListener('ended', function() {this.currentTime = 0; global.music2.src = pmusic[~~(Math.random() * pmusic.length)]; this.play(); songrecog();}, false); + } else if (document.getElementById("optSound").checked === false) { + document.getElementById("content").style.opacity = 0 + global.music2.pause() + global.music2.songname = "Not Playing"; + } + return; }); + + let counterthing = document.querySelector(".displaytest"); + let skinnamedisplay = document.querySelector(".displayskinname"); + let myImg = document.querySelector("#skinpreview"); + let lock = document.querySelector("#lockedskin"); + let selectimage = document.querySelector("#selectskin"); + + $("#rightarrowbutton").on("click", function() { + if (global.skinpage === 16) { + global.skinpage = 0; + } else { + global.skinpage += 1; + }; + changeskinpreview(); + }); + $("#leftarrowbutton").on("click", function() { + if (global.skinpage === 0) { + global.skinpage = 16; + } else { + global.skinpage -= 1; + }; + changeskinpreview(); + }); + + $("#selectskin").on("click", function() { + if (global.lockedornot === 0) { + global.skin = global.selectedskin; + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; + } else { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; + } + }) + + + function checkifachieve(ach, lockcolor) { + if (global.selectedskin !== "") { + if (localStorage.getItem(ach) === "YOUDIDIT:D!!!") { + global.lockedornot = 0; + lock.style.display = 'none'; + myImg.style.filter = 'brightness(1)'; + updateskinselectbutton(); + } else { + global.lockedornot = 1; + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; + lock.style.display = 'inline-block'; + myImg.style.filter = 'brightness(0.5)'; + if (lockcolor === "white") { + lock.style.filter = 'invert(1)'; + } else if (lockcolor === "grey") { + lock.style.filter = 'invert(0.7)'; + } else if (lockcolor === "dgrey") { + lock.style.filter = 'invert(0.3)'; + } else { + lock.style.filter = 'invert(0)'; + } + } + } else { + lock.style.display = 'none'; + if (global.skin === global.selectedskin) { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; + } else { + global.skin === global.selectedskin + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png?v=1708718071992"; + }; + } +} + + function updateskinselectbutton() { + if (global.lockedornot === 0) { + if (global.skin === global.selectedskin) { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/selected.png?v=1708718268075"; + } else { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/select.png?v=1708718071992"; + } + } else { + selectimage.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/locked!.png?v=1708718075601"; + } + } + + function changeskinpreview() { + if (global.skinpage === 0) { + counterthing.textContent = "◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = ""; + skinnamedisplay.textContent = "Default"; + checkifachieve("", ""); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/onetransparentsingulardamnfuckingpixel.png?v=1708568179353"; + } + if (global.skinpage === 1) { + counterthing.textContent = "○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "bsignalskin"; + skinnamedisplay.textContent = "Broken Signal"; + checkifachieve("disconnectachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png?v=1708615075011" + } + if (global.skinpage === 2) { + counterthing.textContent = "○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "tankcharmskin"; + skinnamedisplay.textContent = "Tank Charm"; + checkifachieve("25killsachievement", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png?v=1708536680813"; + } + if (global.skinpage === 3) { + counterthing.textContent = "○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "dfxskin"; + skinnamedisplay.textContent = "Deltafyrex"; + checkifachieve("50killsachievement", "grey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif?v=1708618924966"; + } + if (global.skinpage === 4) { + counterthing.textContent = "○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "primalskin"; + skinnamedisplay.textContent = "Ultimate Primal"; + checkifachieve("100killsachievement", "white"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp?v=1708602763032"; + } + if (global.skinpage === 5) { + counterthing.textContent = "○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "kangarooskin"; + skinnamedisplay.textContent = "Kangaroo"; + checkifachieve("killachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp?v=1708623596560"; + } + if (global.skinpage === 6) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "cswmskin"; + skinnamedisplay.textContent = "ChickenSandwhichMan"; + checkifachieve("killachievement2", "grey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg?v=1708356424097" + } + if (global.skinpage === 7) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "cogskin"; + skinnamedisplay.textContent = "Cogwheel"; + checkifachieve("lagachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381"; + } + if (global.skinpage === 8) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "eggskin"; + skinnamedisplay.textContent = "Eggbert"; + checkifachieve("100shapesachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp?v=1714156807621"; + } + if (global.skinpage === 9) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "squareskin"; + skinnamedisplay.textContent = "Squarey"; + checkifachieve("250shapesachievement", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp?v=1714156773284"; + } + if (global.skinpage === 10) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○ ○"; + global.selectedskin = "triangleskin"; + skinnamedisplay.textContent = "Triangleton"; + checkifachieve("500shapesachievement", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp?v=1714156768932"; + } + if (global.skinpage === 11) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○ ○"; + global.selectedskin = "pentagonskin"; + skinnamedisplay.textContent = "Pentogan"; + checkifachieve("750shapesachievement", "white"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp?v=1714156764280"; + } + if (global.skinpage === 12) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○ ○"; + global.selectedskin = "gemskin"; + skinnamedisplay.textContent = "Gemy"; + checkifachieve("1000shapesachievement", "grey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp?v=1714156778841"; + } + if (global.skinpage === 13) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○ ○"; + global.selectedskin = "coinskin"; + skinnamedisplay.textContent = "Coined"; + checkifachieve("tokenachievement", "black"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png?v=1708619146196"; + } + if (global.skinpage === 14) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○ ○"; + global.selectedskin = "discordskin"; + skinnamedisplay.textContent = "Sex Update"; + checkifachieve("Getbacktowoooak", "dgrey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png?v=1701908710293"; + } + if (global.skinpage === 15) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉ ○"; + global.selectedskin = "deltaDecoskin"; + skinnamedisplay.textContent = "Cat-Code"; + checkifachieve("creditsachievement", "grey"); + myImg.src = "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png?v=1705301828958"; + } + if (global.skinpage === 16) { + counterthing.textContent = "○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ◉"; + global.selectedskin = "incomskin"; + skinnamedisplay.textContent = "Very Much Incommodiousness"; + checkifachieve("pissio", "grey"); + myImg.style.filter = 'blur(10px)'; + myImg.src = "https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/1200px-Icon-round-Question_mark.svg.png?v=1699273933044"; + } + }; + let tanktype = "unfinished", + tankdesc = "unfinished", + tanktier = "???", + tankweap = "???", + tankabil = "???", + tankweak = "unfinished", + tankupto = ["Tier 2: ???", "Tier 3: ???", "Tier 4: ???", "Misc: ???"], + tankupfr = "unfinished", + tankorgn = "???", + tankupad = "???"; + let tabappearance = document.querySelector(".tabappearance"); + let taboptions = document.querySelector(".taboptions"); + let tabcontrols = document.querySelector(".tabcontrols"); + let tablinks = document.querySelector(".tablinks"); + let tabappearancebutton = document.querySelector(".tabappearancebutton"); + let taboptionsbutton = document.querySelector(".taboptionsbutton"); + let tabcontrolsbutton = document.querySelector(".tabcontrolsbutton"); + let tablinksbutton = document.querySelector(".tablinksbutton"); + + function changetab(vroomvroomimaracecarreeeroweaweerrrm) { + switch(vroomvroomimaracecarreeeroweaweerrrm) { + case 0: + tabappearance.style.display = 'block'; + taboptions.style.display = 'none'; + tabcontrols.style.display = 'none'; + tablinks.style.display = 'none'; + tabappearancebutton.classList.add("active"); + taboptionsbutton.classList.remove("active"); + tabcontrolsbutton.classList.remove("active"); + tablinksbutton.classList.remove("active"); + break; + case 1: + tabappearance.style.display = 'none'; + taboptions.style.display = 'block'; + tabcontrols.style.display = 'none'; + tablinks.style.display = 'none'; + tabappearancebutton.classList.remove("active"); + taboptionsbutton.classList.add("active"); + tabcontrolsbutton.classList.remove("active"); + tablinksbutton.classList.remove("active"); + break; + case 2: + tabappearance.style.display = 'none'; + taboptions.style.display = 'none'; + tabcontrols.style.display = 'block'; + tablinks.style.display = 'none'; + tabappearancebutton.classList.remove("active"); + taboptionsbutton.classList.remove("active"); + tabcontrolsbutton.classList.add("active"); + tablinksbutton.classList.remove("active"); + break; + case 3: + tabappearance.style.display = 'none'; + taboptions.style.display = 'none'; + tabcontrols.style.display = 'none'; + tablinks.style.display = 'block'; + tabappearancebutton.classList.remove("active"); + taboptionsbutton.classList.remove("active"); + tabcontrolsbutton.classList.remove("active"); + tablinksbutton.classList.add("active"); + break; + } + } + + if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { + + $(".tabappearancebutton").on("click", function() { + changetab(0); + }); + $(".taboptionsbutton").on("click", function() { + changetab(1); + }); + $(".tabcontrolsbutton").on("click", function() { + changetab(2); + }); + $(".tablinksbutton").on("click", function() { + changetab(3); + }); + +} + +let trollface = null; +function songrecog() { +//song names for display in the debug menu (may move it to a different place later) +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033") { + global.music2.songname = "OI OI OI --- Action Agenda"; +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417") { + global.music2.songname = "Dejected --- Deltafyrex"; +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3?v=1714399132177") { + global.music2.songname = "World's End --- Deltafyrex"; +} +if (global.music2.src === "https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/Meloncholy.mp3?v=1675465750213") { + global.music2.songname = "Melancholy --- Deltafyrex"; +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474") { + global.music2.songname = "Depredation Remastered V2--- Deltafyrex"; +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028") { + global.music2.songname = "Anybody can find Love (except You.) --- hkmori" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3?v=1708218475743") { + global.music2.songname = "Resurgam --- Amaryllis" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295") { + global.music2.songname = "Longing --- Amaryllis" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240") { + global.music2.songname = "Killa --- Action Agenda (DFX EDIT)" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3?v=1713525419376") { + global.music2.songname = "Apotheosis V2 --- Deltafyrex" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787") { + global.music2.songname = "Demol1sh --- Nintendo" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3?v=1714414714759") { + global.music2.songname = "Demoli2h --- Nintendo" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3?v=1714414706958") { + global.music2.songname = "D3molish --- Nintendo" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/souven1r.mp3?v=1714414684036") { + global.music2.songname = "Souven1r --- Nintendo" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2ouvenir.mp3?v=1714414700719") { + global.music2.songname = "2ouvenir --- Nintendo" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3?v=1714414889291") { + global.music2.songname = "Routine2 --- Nintendo" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3?v=1714414850230") { + global.music2.songname = "Routin3s --- Nintendo" +} +if (global.music2.src === "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287") { + global.music2.songname = "Jitt3rs --- Nintendo" +} +} +function lagachloop() { + if (global.metrics.rendertime <= 45 && global.metrics.rendertime >= 15) { + util.submitAchievementToLocalStorage("lagachievement"); + } + if (global.savedkillcount >= 100) { + util.submitAchievementToLocalStorage("100killsachievement"); + } + if (global.savedkillcount >= 50) { + util.submitAchievementToLocalStorage("50killsachievement"); + } + if (global.savedkillcount >= 25) { + util.submitAchievementToLocalStorage("25killsachievement"); + } + if (global.savedshapecount >= 100) { + util.submitAchievementToLocalStorage("100shapesachievement"); + } + if (global.savedshapecount >= 250) { + util.submitAchievementToLocalStorage("250shapesachievement"); + } + if (global.savedshapecount >= 500) { + util.submitAchievementToLocalStorage("500shapesachievement"); + } + if (global.savedshapecount >= 750) { + util.submitAchievementToLocalStorage("750shapesachievement"); + } + if (global.savedshapecount >= 1000) { + util.submitAchievementToLocalStorage("1000shapesachievement"); + } +} +/*if (localStorage.getItem("killachievement") !== "YOUDIDIT:D!!!") { + if (global.achievements.kills >= 4) { + util.submitAchievementToLocalStorage("killachievement"); + } +}*/ +if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { +if (localStorage.getItem("startachievement") !== "YOUDIDIT:D!!!") { +localStorage.setItem("savedkills", 0); +} +} +function resetAllAchievements() { + var zeroyeah = 0; + util.resetAchievementFromLocalStorage("killachievement"); +} + let nIntervId; + if (!nIntervId) { + nIntervId = setInterval(gettimesince, 1000); + } + function gettimesince() { + const date = new Date() + var sec = 0; + var min = 0; + var hour = 0; + var day = 0; + var month = 0; + var year = 0; + var nerosec = ''; + var neromin = ''; + var nerohour = ''; + var neroday = ''; + var neromonth = ''; + var daysinm = 0; + if (date.getMonth() == 8 || 10 || 3 || 5) { + daysinm = 30 + } else { + if (date.getMonth() == 1) { + if (date.getFullYear() == 2024 || 2028 || 2032 || 2036 || 2040 || 2044 || 2048 || 2042) { + daysinm = 29 + } else { + daysinm = 28 + } + } else { + daysinm = 31 + } + } + if (date.getSeconds() + 28 > 59) { + sec = (date.getSeconds() + 60) - 92 + } else { + sec = (date.getSeconds() + 60) - 32 + }; + if (date.getMinutes() < 45) { + if (date.getSeconds() > 31) { + min = (date.getMinutes() + 60) - 44 + } else { + min = (date.getMinutes() + 60) - 45 + } + } else { + if (date.getSeconds() > 31) { + min = (date.getMinutes() + 60) - 104 + } else { + min = (date.getMinutes() + 60) - 105 + } + } + if (date.getHours() < 11) { + if (date.getMinutes() > 44) { + hour = ((date.getHours() + 24) - 10) + } else { + hour = ((date.getHours() + 24) - 11) + } + } else { + if (date.getMinutes() > 44) { + hour = ((date.getHours() + 24) - 34) + } else { + hour = ((date.getHours() + 24) - 35) + } + } + if (date.getDate() < 24) { + if (date.getHours() > 10) { + day = (date.getDate() + daysinm) - 23 + } else { + day = (date.getDate() + daysinm) - 24 + } + } else { + if (date.getHours() > 10) { + day = (date.getDate() + daysinm) - (23 + daysinm) + } else { + day = (date.getDate() + daysinm) - (24 + daysinm) + } + }; + if (date.getMonth() < 4) { + if (date.getDate() > 23) { + if (date.getMonth() == 3) { + month = (date.getMonth() + 11) - 14 + } else { + month = (date.getMonth() + 11) - 2 + } + } else { + month = (date.getMonth() + 11) - 3 + } + } else { + if (date.getDate() > 23) { + month = (date.getMonth() + 11) - 14 + } else { + month = (date.getMonth() + 11) - 15 + } + }; + if (date.getMonth() > 2) { + year = ' | Years: ' + (date.getFullYear() - 2019) + } else { + year = ' | Years: ' + (date.getFullYear() - 2020) + } + if (sec !== 0) { + nerosec = ', Seconds: ' + sec + } else { + nerosec = '' + } + if (min !== 0) { + neromin = ', Minutes: ' + min + } else { + neromin = '' + } + if (hour !== 0) { + nerohour = ', Hours: ' + hour + } else { + nerohour = '' + } + if (day !== 0) { + neroday = ', Days: ' + day + } else { + neroday = '' + } + if (month !== 0) { + neromonth = ', Months: ' + month + } else { + neromonth = '' + } + //const currentdate = ' / Current Year: ' + date.getFullYear() + ' / Current Month: ' + date.getMonth() + ' / Current Day: ' + date.getDate() + ' / Current Hour: ' + date.getHours() + ' / Current Minute: ' + date.getMinutes() + ' / Current Second: ' + date.getSeconds() + ' /' + const nerodate = year + ' ' + neromonth + ' ' + neroday + ' ' + nerohour + ' ' + neromin + ' ' + nerosec + ' |' + $(document.getElementById("updatetime")).html("

    " + nerodate + "

    "); + //$(document.getElementById("updatetime2")).html("

    " + currentdate + "

    "); + } fetch("changelog.html", { cache: "no-cache" }) .then(async ChangelogsHTMLFile => { let patchNotes = document.querySelector("#patchNotes"); @@ -39,6 +828,25 @@ fetch("changelog.html", { cache: "no-cache" }) } }); +fetch("credits.html", { cache: "no-cache" }) +.then(async CreditsHTMLFile => { + let patchNotes = document.querySelector("#credits"); + try { + let parser = new DOMParser(), + RawHTMLString = await CreditsHTMLFile.text(), + ParsedHTML = parser.parseFromString(RawHTMLString, "text/html"), + titles = ParsedHTML.documentElement.getElementsByTagName('h1'); + for (const title of titles) { + title.classList.add('title'); + } + + patchNotes.innerHTML += ParsedHTML.documentElement.innerHTML; + } catch (error) { + patchNotes.innerHTML = `

    An error occured while trying to fetch 'credits.html'

    ${error}

    `; + console.error(error); + } +}); + class Animation { constructor(start, to, smoothness = 0.05) { this.start = start; @@ -121,57 +929,107 @@ function getMockups() { util.pullJSON("mockups").then(data => { global.mockups = data; console.log('Mockups loading complete.'); + console.log("%cWhy are you here Lmfao", "color: #FFFFFF; font-size: 45px; background: #333333; text-shadow: #FFF 0px 0px 5px, #FFF 0px 0px 10px, #FFF 0px 0px 15px, #FF2D95 0px 0px 20px, #FF2D95 0px 0px 30px, #FF2D95 0px 0px 40px, #FF2D95 0px 0px 50px, #FF2D95 0px 0px 75px;"); Resolve(); }); }); } window.onload = async () => { - window.serverAdd = (await (await fetch("/serverData.json")).json()).ip; - if (Array.isArray(window.serverAdd)) { - window.isMultiserver = true; - const servers = window.serverAdd; - let serverSelector = document.getElementById("serverSelector"), - tbody = document.createElement("tbody"); - serverSelector.style.display = "block"; - document.getElementById("startMenuSlidingContent").removeChild(document.getElementById("serverName")); - serverSelector.classList.add("serverSelector"); - serverSelector.classList.add("shadowscroll"); - serverSelector.appendChild(tbody); - let myServer = { + let serverSelector = document.getElementById("serverSelector"), + tbody = document.createElement("tbody"), + servers = [], + myServer = { classList: { - contains: () => false, + contains: () => "selected", }, }; - for (let server of servers) { - try { - const tr = document.createElement("tr"); - const td = document.createElement("td"); - td.textContent = `${server.gameMode} | ${server.players} Players`; - td.onclick = () => { - if (myServer.classList.contains("selected")) { - myServer.classList.remove("selected"); - } - tr.classList.add("selected"); - myServer = tr; - window.serverAdd = server.ip; - getMockups(); - }; - tr.appendChild(td); - tbody.appendChild(tr); - myServer = tr; - } catch (e) { - console.log(e); + + const serverNames = await (await fetch("/servers.json")).json(); + for (let i = 0; i < serverNames.length; i++) { + serverName = serverNames[i]; + try { + if (typeof serverName != "string") throw 0; + + let now = Date.now(); + await fetch(`${serverName}/serverData.json`).then(x => x.json()).then(fetchedServer => { + servers.push({ server: fetchedServer, ping: Date.now() - now }); + }); + } catch (e) { + switch (e) { + case 0: + console.log(`${serverName} is not a string`); + break; + default: + console.log(`Failed to fetch ${serverName}/serverData.json`); } } - if (Array.from(myServer.children)[0].onclick) { - Array.from(myServer.children)[0].onclick(); - } + } + + window.isMultiserver = true; + + if (servers.length) { + document.getElementById("serverName").remove(); + + window.serverAdd = servers[0].server.ip; + serverSelector.style.display = "block"; + serverSelector.classList.add("serverSelector"); + serverSelector.classList.add("shadowscroll"); + serverSelector.appendChild(tbody); } else { + document.getElementById("serverName").innerHTML = "

    No servers found

    "; + } + + let _ping = Number.MAX_SAFE_INTEGER; + const select = (tr, ip) => { + if (myServer.classList.contains("selected")) { + myServer.classList.remove("selected"); + } + tr.classList.add("selected"); + window.serverAdd = ip; getMockups(); - util.pullJSON("gamemodeData").then((json) => { - document.getElementById("serverName").innerHTML = `

    ${json.gameMode} | ${json.players} Players

    `; - }); + }; + for (let { server, ping } of servers) { + try { + let tr = document.createElement("tr"), + td1 = document.createElement("td"), + td2 = document.createElement("td"), + td3 = document.createElement("td"), + td4 = document.createElement("td"); + + td1.style.width = "25%"; + td2.style.width = "25%"; + td1.textContent = `${server.name}`; + td2.textContent = `${server.region}`; + td3.textContent = `${server.gameMode}`; + td4.textContent = `${server.players}`; + + tr.appendChild(td1); + tr.appendChild(td2); + tr.appendChild(td3); + tr.appendChild(td4); + tr.title = server.ip; + + tr.onclick = () => { + select(tr, server.ip); + myServer = tr; + }; + + if (_ping > ping) { + myServer = tr; + select(tr, server.ip); + _ping = ping; + } + + tbody.appendChild(tr); + myServer = tr; + } catch (e) { + console.log(e); + } } + + // Save forms + util.retrieveFromLocalStorage("playerNameInput"); + // Save forms util.retrieveFromLocalStorage("playerNameInput"); util.retrieveFromLocalStorage("playerKeyInput"); @@ -184,15 +1042,42 @@ window.onload = async () => { util.retrieveFromLocalStorage("optCustom"); util.retrieveFromLocalStorage("optNoPointy"); util.retrieveFromLocalStorage("optBorders"); + util.retrieveFromLocalStorage("optResolution"); util.retrieveFromLocalStorage("seperatedHealthbars"); + util.retrieveFromLocalStorage("optOgIcon"); + util.retrieveFromLocalStorage("disableDeathSounds"); + util.retrieveFromLocalStorage("optNoEmojis"); util.retrieveFromLocalStorage("autoLevelUp"); + util.retrieveFromLocalStorageCheckDefault("oioioi"); + util.retrieveFromLocalStorageCheckDefault("dejected"); + util.retrieveFromLocalStorageCheckDefault("worldsend"); + util.retrieveFromLocalStorageCheckDefault("depredation"); + util.retrieveFromLocalStorage("anybody"); + util.retrieveFromLocalStorageCheckDefault("resurgam"); + util.retrieveFromLocalStorageCheckDefault("longing"); + util.retrieveFromLocalStorageCheckDefault("apotheosis"); + util.retrieveFromLocalStorageCheckDefault("killa"); + util.retrieveFromLocalStorageCheckDefault("melancholy"); + util.retrieveFromLocalStorageCheckDefault("demol1sh"); + util.retrieveFromLocalStorageCheckDefault("demoli2h"); + util.retrieveFromLocalStorage("d3molish"); + util.retrieveFromLocalStorageCheckDefault("souven1r"); + util.retrieveFromLocalStorageCheckDefault("2ouvenir"); + util.retrieveFromLocalStorage("routine2"); + util.retrieveFromLocalStorage("routin3s"); + util.retrieveFromLocalStorage("jitt3rs"); // Set default theme if (document.getElementById("optColors").value === "") { - document.getElementById("optColors").value = "normal"; + document.getElementById("optColors").value = "nero"; } if (document.getElementById("optBorders").value === "") { - document.getElementById("optBorders").value = "normal"; + document.getElementById("optBorders").value = "nero"; + } + if (document.getElementById("optResolution").value === "") { + document.getElementById("optResolution").value = "normal"; } + // Achievement Shit + document.getElementById("resetachievementsbutton").onclick = () => resetAllAchievements(); // Game start stuff document.getElementById("startButton").onclick = () => startGame(); document.onkeydown = (e) => { @@ -204,13 +1089,36 @@ window.onload = async () => { window.addEventListener("resize", resizeEvent); resizeEvent(); }; +var callofduty = ""; function resizeEvent() { + if (settings.graphical.quality === undefined) { + settings.graphical.quality = 1; + }; let scale = window.devicePixelRatio; if (!settings.graphical.fancyAnimations) { scale *= 0.5; } + if (typeof settings.graphical.quality === 'string' || settings.graphical.quality instanceof String) { + callofduty = new Image(); // Create new img element + if (settings.graphical.quality == "cod") { + callofduty.src = "https://image.api.playstation.com/cdn/EP0002/CUSA12443_00/VgKYOxWoNSp4mNJ2KvzEFVBWN0idCM5I.png?w=440" + } + } else { + scale *= settings.graphical.quality + } + if (settings.graphical.quality == "1dim") { + global.screenWidth = window.innerWidth * scale; + global.screenHeight = 1 * scale; + } else if (settings.graphical.quality == "d1dim") { + global.screenWidth = 1 * scale; + global.screenHeight = window.innerHeight * scale; + } else if (settings.graphical.quality == "1pix") { + global.screenWidth = 1 * scale; + global.screenHeight = 1 * scale; + } else { global.screenWidth = window.innerWidth * scale; global.screenHeight = window.innerHeight * scale; + } c.resize(global.screenWidth, global.screenHeight); global.ratio = scale; global.screenSize = Math.min(1920, Math.max(window.innerWidth, 1280)); @@ -239,7 +1147,7 @@ function Smoothbar(value, speed, sharpness = 3, lerpValue = 0.025) { display = util.lerp(display, value, lerpValue); if (Math.abs(value - display) < 0.1 && round) display = value; return display; - }, + }, force: (val) => { display = value = val; }, @@ -284,7 +1192,7 @@ function parseTheme(string){ stripped += '='; let data = atob(stripped); - let name = 'Unknown Theme', + let name = 'Unknown Theme', author = ''; let index = data.indexOf('\x00'); if (index === -1) return null; @@ -334,7 +1242,6 @@ function parseTheme(string){ } return { name, author, content }; } catch (e) {} - // Decode from JSON try { let output = JSON.parse(string); @@ -379,27 +1286,79 @@ function parseTheme(string){ } // This starts the game and sets up the websocket function startGame() { + PlaySound69(); + clearInterval(nIntervId); + // release our intervalID from the variable + nIntervId = null; // Set flag global.gameLoading = true; console.log('Started connecting.') + //set start achievement + util.submitAchievementToLocalStorage("startachievement"); // Get options util.submitToLocalStorage("optFancy"); util.submitToLocalStorage("centerTank"); util.submitToLocalStorage("optBorders"); + util.submitToLocalStorage("optResolution"); util.submitToLocalStorage("optNoPointy"); + util.submitToLocalStorage("optOgIcon"); + util.submitToLocalStorage("disableDeathSounds"); + util.submitToLocalStorage("optNoEmojis"); util.submitToLocalStorage("autoLevelUp"); util.submitToLocalStorage("optPredictive"); util.submitToLocalStorage("optScreenshotMode"); util.submitToLocalStorage("coloredHealthbars"); util.submitToLocalStorage("seperatedHealthbars"); + util.submitToLocalStorage("oioioi"); + util.submitToLocalStorage("dejected"); + util.submitToLocalStorage("worldsend"); + util.submitToLocalStorage("depredation"); + util.submitToLocalStorage("anybody"); + util.submitToLocalStorage("resurgam"); + util.submitToLocalStorage("longing"); + util.submitToLocalStorage("apotheosis"); + util.submitToLocalStorage("killa"); + util.submitToLocalStorage("melancholy"); + util.submitToLocalStorage("demol1sh"); + util.submitToLocalStorage("demoli2h"); + util.submitToLocalStorage("d3molish"); + util.submitToLocalStorage("souven1r"); + util.submitToLocalStorage("2ouvenir"); + util.submitToLocalStorage("routine2"); + util.submitToLocalStorage("routin3s"); + util.submitToLocalStorage("jitt3rs"); + global.ISTHEGODAMNFUCKINGGAMEON = "yeah"; settings.graphical.fancyAnimations = !document.getElementById("optFancy").checked; settings.graphical.centerTank = document.getElementById("centerTank").checked; settings.graphical.pointy = !document.getElementById("optNoPointy").checked; - settings.game.autoLevelUp = document.getElementById("autoLevelUp").checked; + settings.game.optOgIcon = !document.getElementById("optOgIcon").checked; + settings.game.disableDeathSounds = !document.getElementById("disableDeathSounds").checked; + settings.game.optNoEmojis = !document.getElementById("optNoEmojis").checked; + settings.game.autoLevelUp = !document.getElementById("autoLevelUp").checked; settings.lag.unresponsive = document.getElementById("optPredictive").checked; settings.graphical.screenshotMode = document.getElementById("optScreenshotMode").checked; settings.graphical.coloredHealthbars = document.getElementById("coloredHealthbars").checked; settings.graphical.seperatedHealthbars = document.getElementById("seperatedHealthbars").checked; + const pmusic = []; + if (document.getElementById("oioioi").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033"); + if (document.getElementById("dejected").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417"); + if (document.getElementById("worldsend").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/WorldsEnd.mp3?v=1714399132177"); + if (document.getElementById("depredation").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Depredation%20V2.mp3?v=1713525132474"); + if (document.getElementById("anybody").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/anybody.mp3?v=1705807057028"); + if (document.getElementById("resurgam").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/resurgam.mp3?v=1708218475743"); + if (document.getElementById("longing").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/longing.mp3?v=1708218464295"); + if (document.getElementById("apotheosis").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Apotheosis.mp3?v=1713525419376"); + if (document.getElementById("killa").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Action%20Agenda%20-%20Killa%20DFX%20Edit.mp3?v=1713352244240"); + if (document.getElementById("melancholy").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Meloncholy.mp3?v=1675465750213"); + if (document.getElementById("demol1sh").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demol1sh.mp3?v=1714414557787"); + if (document.getElementById("demoli2h").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/demoli2h.mp3?v=1714414714759"); + if (document.getElementById("d3molish").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/d3molish.mp3?v=1714414706958"); + if (document.getElementById("souven1r").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/souven1r.mp3?v=1714414684036"); + if (document.getElementById("2ouvenir").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2ouvenir.mp3?v=1714414700719"); + if (document.getElementById("routine2").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routine2.mp3?v=1714414889291"); + if (document.getElementById("routin3s").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/routin3s.mp3?v=1714414850230"); + if (document.getElementById("jitt3rs").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/jitt3rs.mp3?v=1714414684287"); + switch (document.getElementById("optBorders").value) { case "normal": settings.graphical.darkBorders = settings.graphical.neon = false; @@ -416,9 +1375,50 @@ function startGame() { settings.graphical.darkBorders = settings.graphical.neon = true; break; } + switch (document.getElementById("optResolution").value) { + case "normal": + settings.graphical.quality = 1; + break; + case "low": + settings.graphical.quality = 0.75; + break; + case "high": + settings.graphical.quality = 1.5; + break; + case "higher": + settings.graphical.quality = 2; + break; + case "rtx": + settings.graphical.quality = 4; + break; + case "really low": + settings.graphical.quality = 0.5; + break; + case "really really low": + settings.graphical.quality = 0.25; + break; + case "unplayable": + settings.graphical.quality = 0.1; + break; + case "1d": + settings.graphical.quality = "1dim"; + break; + case "d1": + settings.graphical.quality = "d1dim"; + break; + case "onepixel": + settings.graphical.quality = "1pix"; + break; + case "codbo4": + settings.graphical.quality = "cod"; + break; + case "drugs": + settings.graphical.quality = "trippy"; + break; + } util.submitToLocalStorage("optColors"); let a = document.getElementById("optColors").value; - color = color[a === "" ? "normal" : a]; + color = color[a === "" ? "nero" : a]; if (a == "custom") { let customTheme = document.getElementById("optCustom").value; color = parseTheme(customTheme).content; @@ -438,6 +1438,13 @@ function startGame() { global.screenHeight = window.innerHeight; document.getElementById("startMenuWrapper").style.maxHeight = "0px"; document.getElementById("gameAreaWrapper").style.opacity = 1; + + document.getElementById("hideongamestart").style.zIndex = "-3"; + document.getElementById("canvas").style.width = "120px"; + document.getElementById("canvas").style.height = "72px"; + document.getElementById("content").style.zIndex = "6"; + document.getElementById("canvas").style.top = "90%"; + document.getElementById("canvas").style.position = "relative"; // Set up the socket if (!global.socket) { global.socket = socketInit(26301); @@ -449,6 +1456,9 @@ function startGame() { setInterval(() => moveCompensation.iterate(global.socket.cmd.getMotion()), 1000 / 30); document.getElementById("gameCanvas").focus(); window.onbeforeunload = () => true; + if (settings.game.optNoEmojis) { + trollface = new Image(); // Create new img element + } } // Background clearing function clearScreen(clearColor, alpha) { @@ -463,7 +1473,7 @@ function arrayifyText(rawText) { // string with double § txt col txt txt // "...§text§§text§..." => [..., "text", "", "text", ...] => [..., "text§text", ...] // this code is balanced on tight threads, holy shit - let textArrayRaw = rawText.split('§'), + let textArrayRaw = rawText.split(/§|;;/), textArray = []; if (!(textArrayRaw.length & 1)) { textArrayRaw.unshift(''); @@ -561,6 +1571,162 @@ function drawText(rawText, x, y, size, defaultFillStyle, align = "left", center } context.restore(); } + +// Library: mltext.js +// Desciption: Extends the CanvasRenderingContext2D that adds two functions: mlFillText and mlStrokeText. +// +// The prototypes are: +// +// function mlFillText(text,x,y,w,h,vAlign,hAlign,lineheight); +// function mlStrokeText(text,x,y,w,h,vAlign,hAlign,lineheight); +// +// Where vAlign can be: "top", "center" or "button" +// And hAlign can be: "left", "center", "right" or "justify" +// Author: Jordi Baylina. (baylina at uniclau.com) +// License: GPL +// Date: 2013-02-21 + +function mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, defaultFillStyle = color.guiwhite, fn = "strokeText") { + textsize += settings.graphical.fontSizeBoost; + // Get text dimensions and resize/reset the canvas + let offset = textsize / 5, + ratio = 1; + if (ctx.getTransform) { + ratio = ctx.getTransform().d; + offset *= ratio; + } + if (ratio !== 1) { + textsize *= ratio; + } + ctx.font = "bold " + textsize + "px Ubuntu"; + text = text.replace(/[\n]/g, " \n "); + text = text.replace(/\r/g, ""); + lineheight += settings.graphical.fontSizeBoost; + var words = text.split(/[ ]+/); + var sp = ctx.measureText(' ').width; + var lines = []; + var actualline = 0; + var actualsize = 0; + var wo; + lines[actualline] = {}; + lines[actualline].Words = []; + let i = 0; + while (i < words.length) { + var word = words[i]; + if (word == "\n") { + lines[actualline].EndParagraph = true; + actualline++; + actualsize = 0; + lines[actualline] = {}; + lines[actualline].Words = []; + i++; + } else { + wo = {}; + wo.l = ctx.measureText(word).width; + if (actualsize === 0) { + while (wo.l > w) { + word = word.slice(0, word.length - 1); + wo.l = ctx.measureText(word).width; + } + if (word === "") return; // I can't fill a single character + wo.word = word; + lines[actualline].Words.push(wo); + actualsize = wo.l; + if (word != words[i]) { + words[i] = words[i].slice(word.length, words[i].length); + } else { + i++; + } + } else { + if (actualsize + sp + wo.l > w) { + lines[actualline].EndParagraph = false; + actualline++; + actualsize = 0; + lines[actualline] = {}; + lines[actualline].Words = []; + } else { + wo.word = word; + lines[actualline].Words.push(wo); + actualsize += sp + wo.l; + i++; + } + } + } + } + if (actualsize === 0) lines[actualline].pop(); + lines[actualline].EndParagraph = true; + + var totalH = lineheight * lines.length; + while (totalH > h) { + lines.pop(); + totalH = lineheight * lines.length; + } + + var yy; + if (vAlign == "bottom") { + yy = y + h - totalH + lineheight; + } else if (vAlign == "center") { + yy = y + h / 2 - totalH / 2 + lineheight; + } else { + yy = y + lineheight; + } + + var oldTextAlign = ctx.textAlign; + ctx.textAlign = "left"; + ctx.strokeStyle = color.black; + ctx.fillStyle = defaultFillStyle; + ctx.lineWidth = (textsize + 1) / settings.graphical.fontStrokeRatio; + + for (var li in lines) { + var totallen = 0; + var xx, usp; + for (wo in lines[li].Words) totallen += lines[li].Words[wo].l; + if (hAlign == "center") { + usp = sp; + xx = x + w / 2 - (totallen + sp * (lines[li].Words.length - 1)) / 2; + } else if ((hAlign == "justify") && (!lines[li].EndParagraph)) { + xx = x; + usp = (w - totallen) / (lines[li].Words.length - 1); + } else if (hAlign == "right") { + xx = x + w - (totallen + sp * (lines[li].Words.length - 1)); + usp = sp; + } else { // left + xx = x; + usp = sp; + } + for (wo in lines[li].Words) { + if (fn == "fillText") { + ctx.fillText(lines[li].Words[wo].word, xx, yy); + } else if (fn == "strokeText") { + ctx.strokeText(lines[li].Words[wo].word, xx, yy); + let textArray = lines[li].Words[wo].word; + var Xoffset = 0; + for (let i = 0; i < textArray.length; i++) { + let str = textArray[i]; + if (i) { + Xoffset += ctx.measureText(textArray[i - 1] + str).width - ctx.measureText(str).width; + } + ctx.fillText(str, xx + Xoffset, yy); + } + } + xx += lines[li].Words[wo].l + usp; + } + yy += lineheight; + } + ctx.textAlign = oldTextAlign; +} + +(function mlInit() { + CanvasRenderingContext2D.prototype.mlFunction = mlFunction; + + CanvasRenderingContext2D.prototype.mlFillText = function (text, x, y, w, h, vAlign, hAlign, lineheight, textsize, defaultFillStyle) { + ctx.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, "fillText"); + }; + + CanvasRenderingContext2D.prototype.mlStrokeText = function (text, x, y, w, h, vAlign, hAlign, lineheight, textsize, defaultFillStyle) { + ctx.mlFunction(text, x, y, w, h, hAlign, vAlign, lineheight, textsize, "strokeText"); + } + })(); // Gui drawing functions function drawGuiRect(x, y, length, height, stroke = false) { switch (stroke) { @@ -570,6 +1736,43 @@ function drawGuiRect(x, y, length, height, stroke = false) { case false: ctx.fillRect(x, y, length, height); break; + case 0: + ctx.beginPath(); + ctx.lineTo(x, y); + ctx.lineTo(x + length, y); + ctx.lineTo(x, y + height); + ctx.lineTo(x + length, y + height); + ctx.closePath(); + ctx.stroke(); + break; + case 1: + ctx.beginPath(); + ctx.roundRect(x, y, length, height, 5); + ctx.stroke(); + break; + case 2: + ctx.beginPath(); + ctx.roundRect(x, y, length, height, 5); + ctx.stroke(); + ctx.fill(); + break; + case 3: + ctx.beginPath(); + ctx.roundRect(x, y, length, height, [5,5,0,0]); + ctx.stroke(); + ctx.fill(); + break; + case 4: + ctx.beginPath(); + ctx.lineTo(x, y); + ctx.lineTo(x + length, y); + ctx.lineTo(x + length, y + height); + ctx.lineTo(x, y + height); + //ctx.lineWidth = strokeWidth; + //ctx.strokeStyle = color; + ctx.closePath(); + ctx.stroke(); + break; } } @@ -600,6 +1803,22 @@ function drawBar(x1, x2, y, width, color) { ctx.closePath(); ctx.stroke(); } + +//checking for images in the shape so we can draw them +function isImageURL(url) { + try { + const parsedUrl = new URL(url); + const path = parsedUrl.pathname; + const ext = path.split('.').pop().toLowerCase(); // Get the lowercase file extension + + // List of common image file extensions + const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']; + + return imageExtensions.includes(ext) || parsedUrl.protocol == 'data:'; + } catch (error) { + return false; // URL parsing failed, or it's not an image URL. + } +} // Sub-drawing functions const drawPolyImgs = []; function drawPoly(context, centerX, centerY, radius, sides, angle = 0, borderless, fill, imageInterpolation) { @@ -615,17 +1834,57 @@ function drawPoly(context, centerX, centerY, radius, sides, angle = 0, borderles ); } else { if ("string" === typeof sides) { - //ideally we'd preload images when mockups are loaded but im too lazy for that atm - if (!drawPolyImgs[sides]) { - drawPolyImgs[sides] = new Image(); - drawPolyImgs[sides].src = sides; - drawPolyImgs[sides].isBroken = false; - drawPolyImgs[sides].onerror = function() { - this.isBroken = true; - }; - } - let img = drawPolyImgs[sides]; - if (img.isBroken || !img.complete) { // check if img is broken and draw as path2d if so + if (isImageURL(sides)) { + //ideally we'd preload images when mockups are loaded but im too lazy for that atm + if (!drawPolyImgs[sides]) { + drawPolyImgs[sides] = new Image(); + drawPolyImgs[sides].src = sides; + drawPolyImgs[sides].isBroken = false; + drawPolyImgs[sides].onerror = function() { + console.log('Failed to load image!\nURL:', sides); + this.isBroken = true; + }; + } + let img = drawPolyImgs[sides]; + if (img.isBroken || !img.complete) { // check if img is broken and draw placeholder if so + //this is probably the worst way to draw a missing texture checkerboard but im too lazy to do a better one + context.translate(centerX, centerY); + context.rotate(angle); + context.beginPath(); + context.fillStyle = '#ff00ff'; + context.lineTo(-radius,-radius); + context.lineTo(radius,-radius); + context.lineTo(radius,radius); + context.lineTo(-radius,radius); + context.lineTo(-radius,-radius); + context.fill(); + context.closePath(); + context.beginPath(); + context.fillStyle = '#000000'; + context.lineTo(-radius,-radius); + context.lineTo(0,-radius); + context.lineTo(0,0); + context.lineTo(0, radius); + context.lineTo(radius, radius); + context.lineTo(radius, 0); + context.lineTo(0, 0); + context.lineTo(-radius, 0); + context.lineTo(-radius,-radius); + context.fill(); + context.closePath(); + context.rotate(-angle); + context.translate(-centerX, -centerY); + return; + } + context.translate(centerX, centerY); + context.rotate(angle); + context.imageSmoothingEnabled = imageInterpolation; + context.drawImage(img, -radius, -radius, radius*2, radius*2); + context.imageSmoothingEnabled = true; + context.rotate(-angle); + context.translate(-centerX, -centerY); + return; + } else { let path = new Path2D(sides); context.save(); context.translate(centerX, centerY); @@ -638,14 +1897,6 @@ function drawPoly(context, centerX, centerY, radius, sides, angle = 0, borderles context.restore(); return; } - context.translate(centerX, centerY); - context.rotate(angle); - context.imageSmoothingEnabled = imageInterpolation; - context.drawImage(img, -radius, -radius, radius*2, radius*2); - context.imageSmoothingEnabled = true; - context.rotate(-angle); - context.translate(-centerX, -centerY); - return; } angle += sides % 2 ? 0 : Math.PI / sides; } @@ -783,6 +2034,27 @@ const drawEntity = (baseColor, x, y, instance, ratio, alpha = 1, scale = 1, line } drawEntity(baseColor, xx + len * Math.cos(ang), yy + len * Math.sin(ang), t, ratio, 1, (drawSize / ratio / t.size) * t.sizeFactor, lineWidthMult, facing, turretsObeyRot, context, t, render); } + + //just so you know, the glow implimentation is REALLY bad and subject to change in the future + context.shadowColor = m.glow.color!=null ? gameDraw.modifyColor(m.glow.color) : gameDraw.mixColors( + gameDraw.modifyColor(instance.color), + render.status.getColor(), + render.status.getBlend() + ); + if (m.glow.radius && m.glow.radius>0){ + context.shadowBlur = m.glow.radius * ((drawSize / m.size) * m.realSize); + context.shadowOffsetX = 0; + context.shadowOffsetY = 0; + context.globalAlpha = m.glow.alpha; + for (var i = 0; i < m.glow.recursion; i++) { + drawPoly(context, xx, yy, (drawSize / m.size) * m.realSize, m.shape, rot, true, m.drawFill); + } + context.globalAlpha = 1; + } + context.shadowBlur = 0; + context.shadowOffsetX = 0; + context.shadowOffsetY = 0; + // Draw guns below us let positions = source.guns.getPositions(), gunConfig = source.guns.getConfig(); @@ -805,26 +2077,6 @@ const drawEntity = (baseColor, x, y, instance, ratio, alpha = 1, scale = 1, line context.globalAlpha = 1; context.lineWidth = initStrokeWidth * m.strokeWidth gameDraw.setColor(context, gameDraw.mixColors(gameDraw.modifyColor(instance.color, baseColor), render.status.getColor(), blend)); - - //just so you know, the glow implimentation is REALLY bad and subject to change in the future - context.shadowColor = m.glow.color!=null ? gameDraw.modifyColor(m.glow.color) : gameDraw.mixColors( - gameDraw.modifyColor(instance.color), - render.status.getColor(), - render.status.getBlend() - ); - if (m.glow.radius && m.glow.radius>0){ - context.shadowBlur = m.glow.radius * ((drawSize / m.size) * m.realSize); - context.shadowOffsetX = 0; - context.shadowOffsetY = 0; - context.globalAlpha = m.glow.alpha; - for (var i = 0; i < m.glow.recursion; i++) { - drawPoly(context, xx, yy, (drawSize / m.size) * m.realSize, m.shape, rot, true, m.drawFill); - } - context.globalAlpha = 1; - } - context.shadowBlur = 0; - context.shadowOffsetX = 0; - context.shadowOffsetY = 0; drawPoly(context, xx, yy, (drawSize / m.size) * m.realSize, m.shape, rot, instance.borderless, instance.drawFill, m.imageInterpolation); @@ -882,7 +2134,7 @@ function drawHealth(x, y, instance, ratio, alpha) { let health = instance.render.health.get(), shield = instance.render.shield.get(); if (health < 0.99 || shield < 0.99) { - let col = settings.graphical.coloredHealthbars ? gameDraw.mixColors(gameDraw.modifyColor(instance.color), color.guiwhite, 0.5) : color.lgreen; + let col = settings.graphical.coloredHealthbars ? gameDraw.mixColors(gameDraw.modifyColor(instance.color), color.guiwhite, 0.5) : color.blue; let yy = y + realSize + 15 * ratio; let barWidth = 3 * ratio; ctx.globalAlpha = fade * (alpha ** 2); @@ -912,10 +2164,10 @@ function drawHealth(x, y, instance, ratio, alpha) { ctx.globalAlpha = 1; } } - + const iconColorOrder = [10, 11, 12, 15, 13, 2, 14, 4, 5, 1, 0, 3]; function getIconColor(colorIndex) { - return iconColorOrder[colorIndex % 12].toString(); + return iconColorOrder[colorIndex % 12].toString(); // 12% } function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, colorIndex, upgradeKey, hover = false) { @@ -925,13 +2177,55 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c entityX = x + 0.5 * len, entityY = y + 0.5 * height, baseColor = picture.color; - - // Find x and y shift for the entity image - let xShift = position.middle.x * Math.cos(angle) - position.middle.y * Math.sin(angle), + // Find x and y shift for the entity image + let xShift = position.middle.x * Math.cos(angle) - position.middle.y * Math.sin(angle), yShift = position.middle.x * Math.sin(angle) + position.middle.y * Math.cos(angle); - entityX -= scale * xShift; - entityY -= scale * yShift; + entityX -= scale * xShift; + entityY -= scale * yShift; + + if (settings.game.optOgIcon) { + // Draw box + ctx.strokeStyle = color.black; + ctx.fillStyle = color.black; + ctx.lineWidth = 3 * lineWidthMult; + ctx.globalAlpha = 0.4 + drawGuiRect(x + 8, y + 8, len, height, 2); + ctx.globalAlpha = alpha; + ctx.fillStyle = picture.upgradeColor != null + ? gameDraw.modifyColor(picture.upgradeColor) + : gameDraw.getColor(getIconColor(colorIndex)); + //drawGuiRect(x + 25, y + 25, len - 50, height - 50, 2); + drawGuiRect(x, y, len, height, 2); + ctx.globalAlpha = 0.1; + drawGuiRect(x, y, len, height * 0.6, 3); + ctx.globalAlpha = 0.25 * alpha; + ctx.fillStyle = color.black; + drawGuiRect(x, y + height * 0.6, len, height * 0.4); + // Shading for hover + if (hover) { + ctx.globalAlpha = 0.15 * alpha; + ctx.fillStyle = color.guiwhite; + drawGuiRect(x, y, len, height, 3); + } + ctx.globalAlpha = 1; + if (settings.graphical.quality == "cod") { + ctx.drawImage(callofduty, x, y, len, height); + } + // Draw Tank + drawEntity(baseColor, entityX, entityY, picture, 1, 1, scale / picture.size, lineWidthMult, angle, true); + + // Tank name + drawText(picture.upgradeName ?? picture.name, x + (upgradeKey ? 0.9 * len : len) / 2, y + height * 0.94, height / 10, color.guiwhite, "center"); + + // Upgrade key + if (upgradeKey) { + drawText("[" + upgradeKey + "]", x + len - 4, y + height - 6, height / 8 - 5, color.guiwhite, "right"); + } + ctx.strokeStyle = color.black; + ctx.lineWidth = 3 * lineWidthMult; + drawGuiRect(x, y, len, height, 1); // Border + } else { // Draw box ctx.globalAlpha = alpha; ctx.fillStyle = picture.upgradeColor != null @@ -948,6 +2242,9 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c drawGuiRect(x, y, len, height); } ctx.globalAlpha = 1; + if (settings.graphical.quality == "cod") { + ctx.drawImage(callofduty, x, y, len, height); + } // Draw Tank drawEntity(baseColor, entityX, entityY, picture, 1, 1, scale / picture.size, lineWidthMult, angle, true); @@ -962,6 +2259,7 @@ function drawEntityIcon(model, x, y, len, height, lineWidthMult, angle, alpha, c ctx.strokeStyle = color.black; ctx.lineWidth = 3 * lineWidthMult; drawGuiRect(x, y, len, height, true); // Border + } } // Start animation @@ -1182,8 +2480,15 @@ function drawFloor(px, py, ratio) { ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : color.white; ctx.fillRect(left, top, right - left, bottom - top); ctx.globalAlpha = 0.3; - ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : gameDraw.modifyColor(tile); + if (settings.graphical.quality === "trippy") { + ctx.fillStyle = gameDraw.getColor("animatedepilepsy") + } else { + ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : gameDraw.modifyColor(tile); + } ctx.fillRect(left, top, right - left, bottom - top); + if (settings.graphical.quality == "cod") { + ctx.drawImage(callofduty, left, top, right - left, bottom - top); + } } } ctx.lineWidth = 1.25; @@ -1265,11 +2570,26 @@ function drawEntities(px, py, ratio) { text = chat.text, msgLengthHalf = measureText(text, 15 * ratioForChat) / 2, alpha = Math.max(0, Math.min(1000, chat.expires - now) / 1000); - ctx.globalAlpha = 0.5 * alpha; + if (settings.game.optNoEmojis) { + if (text.includes("--troll")) { + trollface.addEventListener("load", () => { + global.emojiloaded = true; + }); + trollface.src = "https://upload.wikimedia.org/wikipedia/en/thumb/9/9a/Trollface_non-free.png/220px-Trollface_non-free.png"; // Set source path + msgLengthHalf = (measureText(text, 15 * ratioForChat) / 2) - 23; + } + }; drawBar(x - msgLengthHalf, x + msgLengthHalf, y, 30 * ratioForChat, gameDraw.modifyColor(instance.color)); ctx.globalAlpha = alpha; settings.graphical.fontStrokeRatio *= 1.2; + if (settings.game.optNoEmojis) { + if (global.emojiloaded && text.includes("--troll")) { + let wheretrollfaceis = (ratioForChat) - msgLengthHalf; + text = text.replace("--troll", ""); + ctx.drawImage(trollface, x - wheretrollfaceis, y + -1 * ratioForChat, 18 * ratioForChat, 18 * ratioForChat); + } + } drawText(text, x, y + 7 * ratioForChat, 15 * ratioForChat, color.guiwhite, "center"); settings.graphical.fontStrokeRatio /= 1.2; y -= 35 * ratioForChat; @@ -1501,19 +2821,67 @@ function drawSelfInfo(spacing, alcoveSize, max) { ctx.lineWidth = 1; // Draw the exp bar + //ctx.fillStyle = color.black; + //drawGuiRect(x - 13, y - 3, len + 26, (height + 1) + settings.graphical.barChunk); + //ctx.fillStyle = color.grey; + //drawGuiRect(x - 10, y, len + 20, height - settings.graphical.barChunk / 4); + //ctx.fillStyle = color.blue; + //drawGuiRect(x - 10, y, (len + 20) * gui.__s.getProgress(), height - settings.graphical.barChunk / 4); drawBar(x, x + len, y + height / 2, height + settings.graphical.barChunk, color.black); drawBar(x, x + len, y + height / 2, height - settings.graphical.barChunk / 4, color.grey); - drawBar(x, x + len * gui.__s.getProgress(), y + height / 2, height - 2, color.gold); + drawBar(x, x + len * gui.__s.getProgress(), y + height / 2, height - 2, color.blue); // Draw the class type drawText("Level " + gui.__s.getLevel() + " " + gui.class, x + len / 2, y + height / 2 + 1, height - 2.5, color.guiwhite, "center", true); height = 16; y -= height + vspacing; + + if (gui.class === "Winsor") { + PlaySound169(); + } + document.onkeydown = (e) => { + var key = e.which || e.keyCode; + if (gui.class === "Trapper_guy" & key === global.KEY_SHIFT) { + PlaySoundtrap(); + } else { + if (gui.class === "Waduh" & key === global.KEY_SHIFT) { + PlaySoundwater(); + } else { + if (gui.class === "Waduh" & key === global.KEY_CHOOSE_5) { + PlaySoundwatuh(); + } else { + if (gui.class === "Pissliner" & key === global.KEY_SHIFT) { + PlaySoundpiss(); + } else { + if (gui.class === "Pissliner" & key === global.KEY_SPLIT) { + PlaySoundpew(); + } else { + if (gui.class === "Delta Congregation" & key === global.KEY_SPLIT) { + PlaySoundchipi(); + } else { + if (gui.class === "Delta" & key === global.KEY_CHOOSE_5) { + PlaySoundneko(); + } else { + if (gui.class === "Delta" & key === global.KEY_CHOOSE_4) { + PlaySoundbwomp(); + } else { + if (gui.class === "Delta" & key === global.KEY_CHOOSE_3) { + PlaySoundnfl(); + } + } + } + } + } + } + } + } + } + } // Draw the %-of-leader bar drawBar(x + len * 0.1, x + len * 0.9, y + height / 2, height - 3 + settings.graphical.barChunk, color.black); drawBar(x + len * 0.1, x + len * 0.9, y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.grey); - drawBar(x + len * 0.1, x + len * (0.1 + 0.8 * (max ? Math.min(1, gui.__s.getScore() / max) : 1)), y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.green); + drawBar(x + len * 0.1, x + len * (0.1 + 0.8 * (max ? Math.min(1, gui.__s.getScore() / max) : 1)), y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.teal); //write the score and name drawText("Score: " + util.formatLargeNumber(Math.floor(gui.__s.getScore())), x + len / 2, y + height / 2 + 1, height - 3.5, color.guiwhite, "center", true); @@ -1567,13 +2935,13 @@ function drawMinimapAndDebug(spacing, alcoveSize) { ctx.globalAlpha = 1; ctx.lineWidth = 3; ctx.fillStyle = color.black; - drawGuiRect(x, y, len, height, true); // Border for (let entity of minimap.get()) { ctx.fillStyle = gameDraw.mixColors(gameDraw.modifyColor(entity.color), color.black, 0.3); ctx.globalAlpha = entity.alpha; switch (entity.type) { case 2: - drawGuiRect(x + ((entity.x - entity.size) / global.gameWidth) * len - 0.4, y + ((entity.y - entity.size) / global.gameHeight) * height - 1, ((2 * entity.size) / global.gameWidth) * len + 0.2, ((2 * entity.size) / global.gameWidth) * len + 0.2); + let trueSize = (entity.size + 2) / 1.1283791671; // lazyRealSizes[4] / sqrt(2) + drawGuiRect(x + ((entity.x - trueSize) / global.gameWidth) * len - 0.4, y + ((entity.y - trueSize) / global.gameHeight) * height - 1, ((2 * trueSize) / global.gameWidth) * len + 0.2, ((2 * trueSize) / global.gameWidth) * len + 0.2); break; case 1: drawGuiCircle(x + (entity.x / global.gameWidth) * len, y + (entity.y / global.gameHeight) * height, (entity.size / global.gameWidth) * len + 0.2); @@ -1584,6 +2952,13 @@ function drawMinimapAndDebug(spacing, alcoveSize) { } } ctx.globalAlpha = 1; + ctx.lineWidth = 3; + ctx.fillStyle = color.black; + if (settings.game.optOgIcon) { + drawGuiRect(x, y, len, height, 1); // Border ctx.lineWidth = 1; + } else { + drawGuiRect(x, y, len, height, true); // Border ctx.lineWidth = 1; + } ctx.lineWidth = 1; ctx.strokeStyle = color.guiblack; ctx.fillStyle = color.guiblack; @@ -1592,23 +2967,29 @@ function drawMinimapAndDebug(spacing, alcoveSize) { drawGuiRect(x, y - 40, len, 30); lagGraph(lag.get(), x, y - 40, len, 30, color.teal); gapGraph(global.metrics.rendergap, x, y - 40, len, 30, color.pink); - timingGraph(GRAPHDATA, x, y - 40, len, 30, color.yellow); + //timingGraph(GRAPHDATA, x, y - 40, len, 30, color.yellow); } //minimap stuff ends here //debug stuff if (!global.showDebug) y += 14 * 3; // Text if (global.showDebug) { - drawText("Open Source Arras", x + len, y - 50 - 5 * 14 - 2, 15, "#B6E57C", "right"); - drawText("Prediction: " + Math.round(GRAPHDATA) + "ms", x + len, y - 50 - 4 * 14, 10, color.guiwhite, "right"); - drawText(`Bandwidth: ${gui.bandwidth.in} in, ${gui.bandwidth.out} out`, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); - drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); - drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); - drawText(global.metrics.latency + " ms - " + global.serverName, x + len, y - 50, 10, color.guiwhite, "right"); + drawText("Nero Engine v3.1", x + len, y - 50 - 7 * 14 - 2, 15, "#6a36e3", "right"); + //drawText("Prediction: " + Math.round(GRAPHDATA) + "ms", x + len, y - 50 - 4 * 14, 10, color.guiwhite, "right"); + drawText("Update Version: " + "v3.112", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); + drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 5 * 14, 10, color.guiwhite, "right"); + drawText("Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 4 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); + drawText("Server Speed: " + ((global.metrics.updatetime * global.metrics.rendergap-global.metrics.lag) / 10).toFixed(2) + "%", x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); + drawText("Kills: " + global.metrics.killcount + " Shapes: " + global.metrics.shapecount, x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); + drawText("Song: " + global.music2.songname, x + len, y - 50 - 1 * 14, 10, color.guiwhite, "right"); + drawText(global.metrics.latency + " ms - neroio2 :FFA:", x + len, y - 50, 10, color.guiwhite, "right"); + document.getElementById("content").style.opacity = 1; } else { - drawText("Open Source Arras", x + len, y - 50 - 2 * 14 - 2, 15, "#B6E57C", "right"); + drawText("Nero.io v3.1", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); drawText(global.metrics.latency + " ms : " + global.metrics.updatetime + "Hz", x + len, y - 50, 10, color.guiwhite, "right"); + document.getElementById("content").style.opacity = 0; + document.getElementById("content").style.left = x - spacing - 120 } global.fps = global.metrics.rendertime; } @@ -1642,16 +3023,16 @@ function drawLeaderboard(spacing, alcoveSize, max) { y += vspacing + height; } } - function drawAvailableUpgrades(spacing, alcoveSize) { // Draw upgrade menu if (gui.upgrades.length > 0) { let internalSpacing = 15; let len = alcoveSize / 2; let height = len; - + // Animation processing - let columnCount = Math.max(3, Math.floor(gui.upgrades.length ** 0.55)); +// let columnCount = Math.max(Math.ceil(gui.upgrades.length / 5), 3); + let columnCount = Math.max(3, Math.ceil(gui.upgrades.length / 3)); upgradeMenu.set(0); if (!global.canUpgrade) { upgradeMenu.force(-columnCount * 3) @@ -1672,7 +3053,7 @@ function drawAvailableUpgrades(spacing, alcoveSize) { let lastBranch = -1; let upgradeHoverIndex = global.clickables.upgrade.check({x: global.mouse.x, y: global.mouse.y}); upgradeSpin += 0.01; - + for (let i = 0; i < gui.upgrades.length; i++) { let upgrade = gui.upgrades[i]; let upgradeBranch = upgrade[0]; @@ -1699,10 +3080,12 @@ function drawAvailableUpgrades(spacing, alcoveSize) { if (y > initialY) initialY = y; rowWidth = x; - - global.clickables.upgrade.place(i, x * clickableRatio, y * clickableRatio, len * clickableRatio, height * clickableRatio); - let upgradeKey = getClassUpgradeKey(upgradeNum); - + +// global.clickables.upgrade.place(i, y * clickableRatio, x * clickableRatio, len * clickableRatio, height * clickableRatio); + global.clickables.upgrade.place(i, x * clickableRatio, y * clickableRatio, len * clickableRatio, height * clickableRatio); + let upgradeKey = getClassUpgradeKey(upgradeNum); + +// drawEntityIcon(model, y, x, len, height, 1, upgradeSpin, 0.5, colorIndex++, upgradeKey); drawEntityIcon(model, x, y, len, height, 1, upgradeSpin, 0.6, colorIndex++, upgradeKey, upgradeNum == upgradeHoverIndex); ticker++; @@ -1865,17 +3248,80 @@ const gameDrawDead = () => { drawText("(press enter to respawn)", x, y + 125, 16, color.guiwhite, "center"); ctx.translate(0, shift * global.screenHeight); }; +const gameDrawWiki = () => { + clearScreen(color.black, 0.5); + let ratio = util.getScreenRatio(); + scaleScreenRatio(ratio, true); + let shift = animations.deathScreen.get(); + ctx.translate(0, -shift * global.screenHeight); + let x = global.screenWidth / 2 - 215, + y = global.screenHeight / 2 - 50; + let len = 140, + position = global.mockups[parseInt(gui.type.split("-")[0])].position, + scale = len / position.axis, + xx = global.screenWidth / 2 - scale * position.middle.x * 0.707 - 215, + yy = global.screenHeight / 2 - 35 + scale * position.middle.y * 0.707, + picture = util.getEntityImageFromMockup(global.wikidisplaytank.toString(), color.blue), + baseColor = picture.color; + if (eval(`tankdescs.${picture.className}`) !== undefined) { + tanktype = eval(`tankdescs.${picture.className}.type`); + tankdesc = eval(`tankdescs.${picture.className}.desc`); + tanktier = eval(`tankdescs.${picture.className}.tier`); + tankweap = eval(`tankdescs.${picture.className}.weapons`); + tankabil = eval(`tankdescs.${picture.className}.abilities`); + tankweak = eval(`tankdescs.${picture.className}.weak`); + tankupto = eval(`tankdescs.${picture.className}.upgradesto`); + tankupfr = eval(`tankdescs.${picture.className}.upgradesfrom`); + tankorgn = eval(`tankdescs.${picture.className}.origin`); + tankupad = eval(`tankdescs.${picture.className}.updateadded`); + } else { + tanktype = "???"; + tankdesc = "???"; + tanktier = "???"; + tankweap = "???"; + tankabil = "???"; + tankweak = "???"; + tankupto = ["Tier 2: ???", "Tier 3: ???", "Tier 4: ???", "Misc: ???"]; + tankupad = "???"; + tankupfr = "???"; + tankorgn = "???"; + }; + drawEntity(baseColor, (xx - 190 - len / 2 + 0.5) | 0, (yy - 10 + 0.5) | 0, picture, 1.5, 1, (0.6 * scale) / picture.realSize, 1, -Math.PI / 4, true); + drawText(picture.name, (xx - 190 - len / 2 + 0.5) | 0, (yy + 78.5 + 0.5) | 0, 18, color.guiwhite, "center"); + drawText("Class." + picture.className, (xx - 190 - len / 2 + 0.5) | 0, (yy - 80 + 0.5) | 0, 14, color.guiwhite, "center"); + drawText(global.wikidisplaytank.toString(), (xx - 190 - len / 2 + 0.5) | 0, (yy - 100 + 0.5) | 0, 16, color.guiwhite, "center"); + drawText("Description:", x - 185, y - 70, 17, color.guiwhite, "left"); + ctx.mlStrokeText(tankdesc, x - 185, y - 70, 215, 200, 'top', 'left', 20, 14); + drawText("Do yall think this will work?", x + 100, y + 130, 16, color.guiwhite, "center"); + drawText("[Esc] Exit Entity Debugger", 10, global.screenHeight - 56, 12, color.guiwhite, "left"); + drawText("[Enter] Search Entity ID", 10, global.screenHeight - 33, 12, color.guiwhite, "left"); + drawText("[A] Cycle Left || [D] Cycle Right", 10, global.screenHeight - 10, 12, color.guiwhite, "left"); + drawGuiLine(x + 40, y - 90, x + 40, (yy + 58 + 0.5)); + drawText("Tier: " + tanktier, x + 60, y - 75, 14, color.guiwhite, "left"); + drawText("Weapons: " + tankweap, x + 60, y - 52, 14, color.guiwhite, "left"); + drawText("Abilities: " + tankabil, x + 60, y - 29, 14, color.guiwhite, "left"); + drawText("Upgrades From: " + tankupfr, x + 60, y - 6, 14, color.guiwhite, "left"); + drawText("Weak To: " + tankweak, x + 60, y + 17, 14, color.guiwhite, "left"); + drawText("Type: " + tanktype, x + 60, y + 40, 14, color.guiwhite, "left"); + drawText("Update: " + tankupad, x + 60, y + 63, 14, color.guiwhite, "left"); + drawText("Origin: " + tankorgn, x + 60, y + 86, 14, color.guiwhite, "left"); + drawGuiLine(x + 300, y - 90, x + 300, (yy + 58 + 0.5)); + drawText("Upgrades To: ", x + 320, y - 75, 14, color.guiwhite, "left"); + ctx.mlStrokeText(tankupto[0] + " \n " + tankupto[1] + " \n " + tankupto[2] + " \n " + tankupto[3], x + 320, y - 75, 350, 200, 'top', 'left', 16, 11); + ctx.translate(0, shift * global.screenHeight); +}; const gameDrawBeforeStart = () => { let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); - clearScreen(color.white, 0.5); + clearScreen(color.white, 1); let shift = animations.connecting.get(); ctx.translate(0, -shift * global.screenHeight); drawText("Connecting...", global.screenWidth / 2, global.screenHeight / 2, 30, color.guiwhite, "center"); - drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.lgreen, "center"); + drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.blue, "center"); ctx.translate(0, shift * global.screenHeight); }; const gameDrawDisconnected = () => { + util.submitAchievementToLocalStorage("disconnectachievement"); let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(gameDraw.mixColors(color.red, color.guiblack, 0.3), 0.25); @@ -1886,13 +3332,14 @@ const gameDrawDisconnected = () => { ctx.translate(0, shift * global.screenHeight); }; const gameDrawError = () => { + util.submitAchievementToLocalStorage("disconnectachievement"); let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(gameDraw.mixColors(color.red, color.guiblack, 0.2), 0.35); let shift = animations.error.get(); ctx.translate(0, -shift * global.screenHeight); drawText("There has been an error!", global.screenWidth / 2, global.screenHeight / 2 - 50, 50, color.guiwhite, "center"); - drawText("Check the browser console for details.", global.screenWidth / 2, global.screenHeight / 2, 30, color.guiwhite, "center"); + drawText("(This means The Dev is A Moron and The Game is Bugged)", global.screenWidth / 2, global.screenHeight / 1.8, 20, color.blue, "center"); drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.orange, "center"); ctx.translate(0, shift * global.screenHeight); }; @@ -1907,6 +3354,7 @@ function animloop() { ctx.lineJoin = "round"; // Draw the game if (global.gameStart && !global.disconnected) { + lagachloop(); global.time = getNow(); if (global.time - lastPing > 1000) { // Latency @@ -1931,22 +3379,35 @@ function animloop() { } if (global.died) { gameDrawDead(); + if (settings.game.disableDeathSounds) { + PlaySound420(); + } + global.metrics.killcount = 0; + } else { + if (global.stopthefuckingkillsoundyouprick) { + metalpipe.pause(); + metalpipe.currentTime = 0; + global.stopthefuckingkillsoundyouprick = false; + } } if (global.disconnected) { gameDrawDisconnected(); } + if (global.wiki) { + gameDrawWiki(); + } ctx.translate(-0.5, -0.5); - //oh no we need to throw an error! } catch (e) { - + //hold on.... gameDrawError(); ctx.translate(-0.5, -0.5); - + //okay, NOW throw the error! throw e; + } } -})(util, global, settings, Canvas, color, gameDraw, socketStuff); +})(util, global, settings, Canvas, color, gameDraw, socketStuff); \ No newline at end of file diff --git a/public/changelog.html b/public/changelog.html index 0d2f173ba..584eb87cb 100644 --- a/public/changelog.html +++ b/public/changelog.html @@ -1,18 +1,516 @@ -
    -

    Title 1: optional description

    - optional date -
      -
    • Change 1
    • -
    • Lorem ipsum dolor sit amet consectetur adipisicing elit. Accusantium, excepturi.
    • -
    • Change 3
    • -
    -
    -
    -

    Title 2: optional description

    - optional date -
      -
    • Change 1
    • -
    • Change 2
    • -
    • Change 3
    • -
    -
    \ No newline at end of file +
    +

    Update 3.1

    + [2024] +
      +
    • Fixed date since counter
    • +
    • Added BackShield & Mirror Shield
    • +
    • Fixed Tag Gamemode
    • +
    • Removed Stats Temporarily
    • +
    • Changed Bot Leveling
    • +
    • Nerfs & Buffs
    • +
    • Reorganized Entities
    • +
    • Added New Color System
    • +
    • Fixed Color System
    • +
    • New DFX Maze Map
    • +
    • Added Apotheosis V2 & Depredation Remastered V2 By Deltafyrex and Killa By Action Agenda (DFX Edit) To OST
    • +
    • Fixed Siege
    • +
    • Fixed Movement System
    • +
    • Fixed Death Sounds
    • +
    • Revamped Menu Popups
    • +
    • Added TwinSniper Branch And More to Acid And Chiller Branch
    • +
    • Fixed Music Bug, And Added Aura Basic, Jump Smasher And Whirlwind To The Main game
    • +
    • Fixed Shields
    • +
    • Moved Aura From Tier 3 To Tier 2 And Added Aura Branch
    • +
    • Added Flail & Buffed Auras
    • +
    • Added Firecracker, Douverie & Auto-2 Branch
    • +
    • Added Brella (upgrades from backshield) And Lancer Branch
    • +
    • Added More Options For Quality Of Life Features
    • +
    • Added New Achievements & Skins
    • +
    • Fixed Player Skin Bug
    • +
    • Fixed Color System Again And Added Glow + Nerfs/Buffs And other Bug Fixes
    • +

      Update 3.11 [2024]

      +
    • Fixed Desmos + 8 New OST Tracks
    • +
    • Added Music Selector And Fixed Music Bugs
    • +
    • Added In Game Audio Visualizer
    • +
    • Fixed Server Selector
    • +
    • Added A Beta Cocci
    • +
    • Small Menu & Ui Updates
    • +
    • Fixed Desmos AI Bug & Undertow
    • +
    • Nerfed Some Things and buffed poison damage
    • +
    • Made Leveling Up Automatic Without Setting Needed
    • +

      Holay Molay

      +
    +
    +
    +

    Update 3.0

    + [2024] +
      +
    • Added Clubbin
    • +
    • Testing Achievements
    • +
    • Added Reset Achievements Button
    • +
    • Added Start Achievement
    • +
    • Added and Fixed Achievement Details
    • +
    • Added Disconnect, Lag, And Killstreak Achievement
    • +
    • Removed Kill Achievement cuz it dont work
    • +
    • Added New Special Achievement Type
    • +
    • Added Special Piss.io Achievement And Funny Skype Achievement
    • +
    • Re-Added And Fixed 5 Killstreak Achievement Again
    • +
    • Added Server to Client Functions
    • +
    • Added 10 Killstreak Achievement
    • +
    • Changed Debug Menu
    • +
    • Added Kill Amount In Debug
    • +
    • Added Audio Visualizer in the title screen
    • +
    • Fixed Embed Not Working Properly
    • +
    • Fixed Bug Where Audio Visualizer Appears In Game
    • +
    • Added Token And Discord Achievement
    • +
    • Added Achievements Tab
    • +
    • Removed Ach Testing
    • +
    • Added Credits Button
    • +
    • fixed credits interfering with changelog
    • +
    • added credits-changelog animation transition
    • +
    • moved credits button (its 1:08 am im soooooo tired)
    • +
    • Fixed Game Breaking Bug
    • +
    • Added Contagion Branch To Subduer & Trapper
    • +
    • Added Longing And Resurgam By Amaryllis To The OST
    • +
    • added credits ach
    • +
    • Added 2 New Branches For Desmos
    • +
    • Testing Skins
    • +
    • Added Beta Skin Menu
    • +
    • Fixed Skin Bug
    • +
    • Fixed Crashing On Respawn
    • +
    • Added More Detail To Skin Menu
    • +
    • Added Cat Code and Chickensandwhichman Skin
    • +
    • Added Daily Tanks
    • +
    • Added Plenty New Skins, New Achievements And Made Achievements Unlockable
    • +
    • Added Skater & Hitman
    • +
    • Added New "Duality" Map
    • +

      Update 2.93 [2024]

      +
    • David Goggins Event
    • +
    • Updated Menu
    • +
    • Added Marksman Branch To Sniper And Car Branch To
    • +
    • Added Trollface Emote (add --troll to the end of a chat message)
    • +
    • Added Waterfall, Acid, Cooler, Rainmaker And New Options Layout
    • +
    • Added Notes Tab + Live Counter
    • +
    • Added More Customization, Graphics, Helecopter And Fixed Music Bug
    • +
    • Added Reverie Branch And Injector
    • +
    • Added Debugger Menu
    • +
    • You Can Now Color Messages With §
    • +

      Niners fucking lost Again Bruh...Fuck Taylor Swift

      +
    +
    +
    +

    Update 2.9

    + [2024] +
      +
    • Added Motor
    • +
    • Added Kivaaharatedas (i did not spell that right)
    • +
    • Added Equilibrium, Revobrid, Subverter
    • +
    • shrapnel testing
    • +
    • removed unfinished aimbot/boosting testing
    • +
    • Added Basic Hybrid Tier 3 branch
    • +
    • Bug Fixed Colors
    • +
    • Added Tanks of my friends and tank soundboard support
    • +
    • Added the rest of the Basic Hybrid branch (tier 4)
    • +
    • Fixed changelog not appearing
    • +
    • Added beta music support including 5 songs
    • +
    • changed start button look to not shade out and actually work like a button
    • +
    • fixed debug key (again)
    • +
    • fixed screen tearing
    • +
    • worked bullet spawn position
    • +
    • Better organized dev menu and changed the way utilities looks
    • +
    • Added music recognition in the debug key to see the song name & artist
    • +
    • Added new song (Anybody can find Love (except You) by hkmori
    • +
    • fixed debug not recognizing a song and not updating after a song is finished
    • +
    • Testing wall colors/effects
    • +
    • Added Shield Turrets
    • +
    • Added new tiles (dance floor+black)
    • +
    • added new "banquet" map
    • +
    • Finished Revolutionist Branch
    • +
    • Added Inception & Albuquerque
    • +
    • im a fucking moron
    • +
    • Added Machceptioner & Tailgator
    • +
    • Added Interceptor, Twinceptioner, Inceptionist branch, hybrid/auto ver of inception branch
    • +
    • Added Desmos/Inception/Bascrid Ception
    • +
    • fixed the ceptionist turrets/autobullet turrets
    • +
    • nerfed shit
    • +
    • fixed some upgrades not appearing
    • +
    • no players (dead game and nobody plays is sadly)
    • +
    • so it turns out i forgot to give twinceptionist the right bullets so i fixed that :/
    • +
    • fixed flankcept branch turrets
    • +

      Update 2.91 [2024]

      +
    • Added the subduer branch
    • +
    • Fixed The Rest of the menu buttons and fixed sound effects
    • +
    • Added flankduer
    • +
    • Added Binary branch, Pathogen branch, mitochondrion branch, Subduer-Hybrid branch and Auto-Subduer Branch
    • +
    • fixed missing upgrades
    • +

      Hey! vsauce, Michael here. the game is stable and non buggy...or is it?

      +
    +
    +
    +

    Update 2.8

    + [2023] +
      +
    • Tank Adding Wave Two (ex. hadron, dictator, railgun + more)
    • +
    • Debug Key Bug Fix (how ironic)
    • +
    • Fixed Rng Images Bugging Out
    • +
    • Testing Whirlwind Branch
    • +
    • Fixed Maze Gamemode
    • +
    • Added Tooltips (beta)
    • +
    • Added Status Effects (beta+devevent)
    • +
    • Added Addon Support
    • +
    • Fixed button Shadows
    • +
    • Upgraded APS++ Updating Speed
    • +
    • New Mouse Controller
    • +
    • Keybind Fix
    • +
    • Enter can cancel a chat message being sent
    • +
    • CoNgReGaTiOn JuMpScArEs
    • +
    • Images on Tanks/Sound Effects For Tanks (dev)
    • +
    • Blackhole (dont ask just roll with it)
    • +
    • P A P Y R U S
    • +
    • Fixed Some Lag Holding Down Server Speed
    • +
    • 109.43.21.5.14
    • +
    • Added Desmos Branch
    • +
    • Theres Prob More But I Forgor
    • +

      wahhh... (i forgor why im crying)

      +
    +
    +
    +

    Update 2.7

    + [2023] +
      +
    • Debuffed Many Tanks
    • +
    • Migrated to new host
    • +
    • Removed all Nero Exclusive Tanks From The Game (for now anyway, dont worry)
    • +
    • Added "revolutionist" to testbed"
    • +
    • Massive Testbed overhaul
    • +
    • Added a funny randomly generated image on the start screen
    • +
    • Readded Sounds, design and other previous widgets
    • +
    • Hired new devs
    • +
    • did some tweaks to bots
    • +
    • got rid of the "nero" theme and the server list
    • +
    • added easter eggs
    • +
    • added random funny image
    • +

      Update 2.71 [2023]

      +
    • Tank Adding Wave One (ex. auto branch, revolutionist, cloner + more)
    • +
    • plenty of new dev features
    • +
    • added gamemode polls (once theres enough people)
    • +

      There are Easter Eggs All Over The Main Menu, You Might Find Something...

      +
    +
    +
    +

    Update 2.6

    + [2023] +
      +
    • replaced smashers origional upgrade path with the "armoury" tree -added lancer and smasher upgrades to armoury tree
    • +
    • added "Sword", "Injector" and "Fencer" to lancer upgrades
    • +
    • buffed drone tanks, twin tanks & tank health
    • +
    • added "Dictator" -added "Tripwire"
    • +
    • added "Barricade", "Twister", "Cyclone" and "Architect" -added "Tri-Trapper" tree -added "auto tritrapper", "auto armour" and "autolancer"
    • +
    • added "eagle" and "bulwark"
    • +
    • updated debug menu
    • +
    • removed hivemind from basic
    • +
    • added cloner upgrade
    • +
    • added hivemind and "splitter" to cloner upgrade
    • +
    • added "auto cloner", "auto flamethrower", "flamethrower hybrid" and "lancer hybrid"
    • +
    • updated colorscheme and other color related things
    • +
    • updated teams on 2tdm after 3 team bug -added all new Rock Maze gamemode
    • +

      Ryerson Loves Burger King

      +
    +
    +
    +

    Update 2.5

    + [2023] +
      +
    • added new tanks into beta for further testing
    • +
    • hired new devs
    • +
    • neroio discord is up
    • +
    • added new mascallenus tank and section
    • +
    • hired new beta testers
    • +
    • added new easter eggs
    • +
    • tested 2nd server opening
    • +
    • added "Scanner" and "hadoken"
    • +
    • nerfed Hahaugobrr
    • +
    • promoted lucas medieros to co-owner of the game
    • +
    • demoted a few staff
    • +
    • added 2TDM game mode
    • +
    • woomy event is back! now with free access to testbed
    • +
    • added "flankdrive", "twindrive" and "machinedrive"
    • +
    • fixed trapper look
    • +
    • added "infantry", "musket", "Traprid", "Auto Traprid", "Snigrav", "AsWdragafora", "Assasolak", "Builifacate", "Rifagiulus", "Auto Snigrav"
    • +
    • added "flamethrower", "Baker", "Wildfire" and "Equinox"
    • +
    • new nero.io default theme instead of using arras's
    • +
    • added insane af tanks to testbed
    • +
    • added "lancer"
    • +

      Open Na Noor

      +
    +
    +
    +

    Update 2.4

    + [2023] +
      +
    • added 2 new admin commands
    • +
    • added homing auto Basic
    • +
    • added bosses tab to AIT
    • +
    • bwomp AA $$ €€
    • +
    • added easter egg name colors
    • +
    • added the tanks "mercury", "venus", "earth", "mars", "jupiter", "saturn", "uranus", and "neptune"
    • +
    • added a new boss
    • +
    • added more natural spawning bosses
    • +
    • added "SpawnTrap"
    • +
    • updated bot names
    • +
    • ended woomy event
    • +

      Oh great red Text of the Changelog, What is your Wisdom?

      +
    +
    +
    +

    Update 2.3

    + [2023] +
      +
    • added "maleficator", "stalker", "landmine", "jumpsmash", "speedbent", "heavy3", and re-added "twindrive", "interceptioner", the "drive" subtree to autobasic, plus increased map size
    • +
    • fixed and debuffed jumpsmash
    • +
    • debuffed speedbent
    • +
    • added a public changelog (the one your looking at now)
    • +
    • added the red text
    • +
    • updated sounds and styles
    • +
    • added the "corrupted" button
    • +

      So Hows Ur Day?

      + +
    +
    +
    +

    Update 2.2

    + [2023] +
      +
    • added more tanks into beta
    • +
    • added sounds and updated client backround
    • +
    • Decoration finished
    • +
    • started decoration on migration host
    • +
    • added chat feature
    • +
    • migration big fixes
    • +
    • WE DID IT! MIGRATION COMPLETE!
    • +
    • during migration found multiple small bugs that was fixed
    • +
    • 2nd failed migrating attempt, starting yet another
    • +
    • fixed crashing bug
    • +
    • 2nd attempt at migrating
    • +
    • added random bot and skill classes
    • +
    • made bots more op
    • +
    • fixed a bot bug
    • +
    • downgraded bots
    • +
    • added tank visualizers
    • +
    • buffed bots a tiny bit more
    • +
    • fixed visualizer bug
    • +
    • added "rifle"
    • +
    • fixed "lilfact" upgrade path
    • +
    • added auto "lilfact"
    • +
    • renamed "lilfact" to "spawner"
    • +
    • added secret tanks for update 2.3
    • +
    • minor crash bug fixes
    • +
    • removed "rifle" and "autospawner" from beta
    • +
    • fixed smasher bug
    • +
    • failed "lancer" class attempt
    • +
    • secret tank updates
    • +
    • major bug fixes
    • +
    • rainbow color old client fix
    • +
    • last patches before big update
    • +
    • fixed tiny bug
    • +

      I Know Where You Live

      +
    +
    +
    +

    Update 2.1

    + [2022] +
      +
    • fixed the 2 game crashing bugs
    • +
    • tried to migrate to another server host but yet failed due to unknown reasons
    • +
    • added "speedbent" to beta
    • +
    • updated messages
    • +

      tbh im sad the 49ers missed the super bowl :/

      +
    +
    +
    +

    Update 2.0

    + [2021] +
      +
    • brought the ception tree into beta tanks
    • +
    • figured out that the "ceptions" arent really ceptions
    • +
    • forgot to add the actual way to access it LOL, also added a REAL machine ceptionist as a test
    • +
    • removed ceptionist and drive tanks as they are too overpowered
    • +
    • added lazer guns
    • +
    • stole code from someone elses server
    • +
    • added beta shock and burn
    • +
    • added some secret really stupid tanks
    • +
    • fixed a tank
    • +
    • removed revolutionist for being too buggy
    • +
    • added new auto class branch
    • +
    • added hivemind
    • +
    • bug fixes
    • +
    • major bug that caused no tanks to be added or bugs fixed causing confusion
    • +
    • crashing bug made game unplayable for large amount of time (like a whole 9 months)
    • +

      Whats Up Guys Quandale Dingle Here

      +
    +
    +
    +

    Update 1.9

    + [2021] +
      +
    • testing in progress
    • +
    • approved multiple tanks into the game
    • +
    • did some stupidity and added random stuff and figured out that there is indeed, 12882 lines of code in this project
    • +
    • added some dumb tanks like "mInIfLyInGfAsTeRtHiNgY"
    • +
    • added some cool colored objects on the "AsWdWsA" branch
    • +
    • added a secret tank
    • +
    • messed with some things like homing bullets
    • +
    • removed the homing stuff due to bugs
    • +
    • tried to recreate the "revolutionist" tank from woomy arras
    • +
    • more tests
    • +
    • added auto bullets
    • +
    • added drive tanks into beta testing phase
    • +
    • moved where the secret tank is
    • +
    • debuffed "single"
    • +
    • added "Cascal", "Gunto", "Catalyst", And "Cescav" to beta tanks
    • +
    • added a beta version of the drive tree into the game after some testing
    • +

      What A Dumb Fucking Game!

      +
    +
    +
    +

    Update 1.8

    + [2021] +
      +
    • completed and put the poison function into the game
    • +
    • completed and put the freeze function into the game
    • +
    • created a seprate freeze and poison bullets
    • +
    • added a stun function
    • +
    • added a healing and speed function
    • +
    • added a stun, healing and speed bullet shooting tanks
    • +
    • added the "AsWdWsA" branch
    • +
    • fixed poison cannon
    • +
    • renamed the bullets to respected name
    • +
    • renamed the cannons to a respected name
    • +
    • created a page 2 for the mascallenus
    • +
    • put multitanks into testbed
    • +
    • put multitanks into testbed
    • +
    • organized the tanks
    • +
    • removed public testbed
    • +

      :skull:

      +
    +
    +
    +

    Update 1.7

    + [2020] +
      +
    • added an admin logger
    • +
    • changed the AI color to pink
    • +
    • changed AI to have twin upgrade instead of basic
    • +
    • expanded the map
    • +
    • changed the colors of the spawning player to be random instead of always red or blue
    • +
    • added the tanks "oof" and "oof2" to mascallenus
    • +
    • added the tank "minibee" to testbed
    • +
    • added the tank "hexa trapper" into the game
    • +
    • added the tank "Paint Brush" into the crayon tree
    • +
    • added the tank "brutalizer"
    • +
    • added "sidewinder"
    • +

      Share with your friends!

      +
    +
    +
    +

    Update 1.6

    + [2020] +
      +
    • added the tank "tower mech"
    • +
    • added the "AIT" category into testbed
    • +
    • added a way to get back to a basic tank after becoming testbed
    • +
    • added the tank "crayon"
    • +
    • added the two tanks "marker" and "pastel"
    • +
    • added the tank "pen"
    • +
    • added a kill button to testbed
    • +
    • added the tank "highlighter"
    • +
    • added a way to immediatly upgrade into a basic trapper
    • +
    • invited some friends to help code my game
    • +

      Yo shout out to Lucas Medeiros

      +
    +
    +
    +

    Update 1.5

    + [2020] +
      +
    • removed jesus donut
    • +
    • removed DeltaCannon
    • +
    • fixed some bugs with AI's
    • +
    • fixed some bugs with crashers and bosses
    • +
    • added a bunch of testbed tanks into the real thing
    • +
    • removed fairsquare
    • +
    • added flame killa to testbed
    • +
    • removed access to the recently added tanks from testbed to save space
    • +
    • added Boxer to testbed
    • +
    • removed every testbed tank
    • +
    • added categories to test bed like "beta" and "mascallenus"
    • +

      come down today and try some corn, or we will sacrifice your newborn

      +
    +
    +
    +

    Update 1.4

    + [2020] +
      +
    • added Lottery to testbed
    • +
    • added hellblazer and Rocketer to testbed
    • +
    • added Nautilus to testbed
    • +
    • added jesus donut to testbed
    • +
    • experimented with bullet effects
    • +
    • added SleamShot
    • +
    • added TrapHard into testbed
    • +

      LMFAO WHAT A BOZO

      +
    +
    +
    +

    Update 1.3

    + [2020] +
      +
    • added master
    • +
    • added lilfact
    • +
    • fixed bug with bots
    • +
    • fixed bug with lilfact
    • +
    • ADDED PUBLIC TESTBED
    • +
    • fixed some bugs
    • +
    • fixed testbed problems
    • +
    • fixed testbed key errors regarding platform
    • +
    • added helltank to testbed
    • +
    • added DeltaCannon to testbed
    • +

      DrUgS aRe BaD fOr YoU1!1!

      +
    +
    +
    +

    Update 1.2

    + [2020] +
      +
    • server shutdown due to server problems
    • +
    • fixed problem
    • +
    • fixed some more bugs
    • +
    • fixed bug with the upgrades
    • +
    • added 3 pre-made extra tanks (hive shooter, auto assassin, auto cruiser)
    • +
    • added Unlocked
    • +
    • added more ways to get hive shooter
    • +
    • added more ways to get unlocked
    • +
    • added bots
    • +
    • fixed bad bug with Unlocked
    • +

      tbh play a better game than this

      +
    +
    +
    +

    Update 1.1

    + [2019] +
      +
    • added revix
    • +
    • added DeltaGunner
    • +

      OH BABY A TRIPLE

      +
    +
    +
    +

    Update 1.0

    + [2019] +
      +
    • just opened server
    • +
    • testing new tanks
    • +

      Bwomp

      +
    +
    +You've Reached The End ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ \ No newline at end of file diff --git a/public/credits.html b/public/credits.html new file mode 100644 index 000000000..ecb93e106 --- /dev/null +++ b/public/credits.html @@ -0,0 +1,104 @@ +
    +

    Deltafyrex

    + [Lead Dev, Game Owner and Discord Owner] +
      +
    • certified moron
    • +
    • pissass
    • +
    • favorite colors are cyan, white and black
    • +
    • does everything in this game
    • +
    • the reason you get disconnected often while in game lol
    • +
    • game founder
    • +
    • working on nero since 2019
    • +
    +
    +
    +

    Can Karaman

    + [Site Manager, Co-Lead Dev] +
      +
    • second most helpful person here
    • +
    • sets up the whole domain and security section of the site
    • +
    • absolutely just an all around amazing person
    • +
    • nero would be nowhere without him
    • +
    • bill nye the server guy
    • +
    • pulling nero out of the glitch rabbit hole
    • +
    • Scares the fuck out of me when he takes such an authoritarian position
    • +
    +
    +
    +

    Eguy

    + [Lead Beta Tester] +
      +
    • third most helpful person here
    • +
    • helps deltafyrex all the time
    • +
    • cool guy 😎
    • +
    • nero would fr be not as cool as it is without eguy
    • +
    • helps test and balance tanks
    • +
    +
    +
    +

    Ultimate primal

    + [Beta Tester and Discord Server Admin] +
      +
    • actually cares about nero.io
    • +
    • Pretty fun to have around
    • +
    • quite a chill fellow
    • +
    • will definitely destroy you
    • +
    +
    +
    +

    "Wait What!?"

    + [Helper] +
      +
    • quite wise
    • +
    • owner of phoearras
    • +
    • gives Deltafyrex wisdom and pieces of code sometimes (very nice)
    • +
    +
    +
    +

    MGLIFEYT

    + [Fucking Dipshit (only still on the team because he made the damn discord bot)] +
      +
    • SeX uPdAtE wHeN!/!?11/
    • +
    • RoBlOx NeRo BeTtEr!!!!! (spoiler alert: it doesn't even fucking exist)
    • +
    • useless asshole who has bad taste in imagery
    • +
    • Discord Bot maker
    • +
    • owner of vehicle wars on roblox
    • +
    +
    +
    +

    "C"

    + [Dev In Training (i have a good feeling about him)] +
      +
    • Deltafyrex's Best Friend irl
    • +
    • bro looks like a fucking mexican border crosser in yearbook photos ☠☠☠
    • +
    • Hair that could mop a floor lol
    • +
    • O U R P l E
    • +
    • severe alastor enthusiast
    • +
    • ChickenSandwhichMan
    • +
    +
    +
    +

    Special Thanks:

    + [Other Special Thank-you's] +
      +
    • Meta (sip!)
    • +
    • Maeka09 (Also Deltafyrex's best friend)
    • +
    • Darkfrost (No need to Specify >:3)
    • +
    • "D" (I AM THE GREENMAN I SPEAK FOR THE TREES)
    • +
    • O_S (YIPPEE)
    • +
    • SafariSE (helped delta start out on creating nero all those years ago)
    • +
    • Lucas Medeiros (Fellow Faithful Member)
    • +
    • Fruitmelon (gave delta some tips awhile back)
    • +
    • The Piss Cult (yeah you know who you are)
    • +
    • Maaxxi3114 Yesus' Pet Roblox Nero Endorser
    • +
    • Galaxy Dash (David Goggins, "I cant even count that high")
    • +
    • NoahPlays (Funny Nero Hater Lol)
    • +
    • Tokay Dragon (Furry)
    • +
    • Deltas Youtube Subscribers (Thanks!)
    • +
    • Deltas Body (worked on nero through countless hours of sleep deprivation HOLY SHIT ITS 12:00 AM)
    • +
    • APS++ Developers (very nice)
    • +
    • Arras Mayhem (this is here cuz some dude got mad at me for not crediting mayhem bc i used 2 of their sounds like boohoo)
    • +
    • im not putting any other license than the "do whatever the fuck you want" license
    • +
    +
    +You've Reached The End OwO ?̵̛̤̱̯͕̠̘̬̦̟̼̏͆̍̋̀̃͋͑̈́̂̎̉͒́̇̋͗̆͗̿́́̃́͗̉̈́̓̓͒̑̌͊̎͗̕̚̕͜͠͠͝͠͠?̵̧̢̨͉̹̥̩͕͙̦̞̹͙̣̱̪̫͚͚̋͐̒͐̈́͠?̶̡̢͈̮͉͕̩̣̘͚̳̳̺̹̜̺̹͙̼̤̼̱̣̭̪̘̖̊̅̽̃̎͋̽̇͂͆̽̃̇̏͒͋͗̾̀̉̐͘͜͠?̷̧̧̨̡̛̛̪̠̝̖̪̖͓̝̖̣͖͚̖̗̼̬̯̦̹̯͖̮̥͚͓̙͇̥̼͍̠̟̙̫̫̞̆̔́̊̆̓̿́̑̇̅̄̀̑̄̇̆̀̓͐̾̄̽̒̃͝͝ͅ?̶̢̧̢̢̧̧̛̣̳̮̝̳̞̞̙̟͓̝̬̤͎̂͛͆̓͑̌͌̂̽ diff --git a/public/favicon.ico b/public/favicon.ico index 263db474e5caa9ef7a67202982a0bbf6d98f2ac4..23a67e49d6cba160f4370dbeb97260b1bcfa0641 100644 GIT binary patch literal 225726 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 z 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¥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 literal 21654 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 diff --git a/public/index.html b/public/index.html index 602027ceb..2b82b9a79 100644 --- a/public/index.html +++ b/public/index.html @@ -3,63 +3,290 @@ - + - + + + + - Open Source Arras + + Nero.io 3.1 - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    diff --git a/package.json b/package.json index 2987dcd79..f6d8d3e47 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "build": "node standaloneClient/build minify" }, "dependencies": { - "ws": "^8.16.0" + "ws": "^8.17.1" }, "engines": { "node": "16.x" diff --git a/public/app.js b/public/app.js index 15c19ac94..84a30f11a 100644 --- a/public/app.js +++ b/public/app.js @@ -509,76 +509,6 @@ if (localStorage.getItem("jitt3rs" + 'Checked')) pmusic.push("https://cdn.glitch tankupfr = "unfinished", tankorgn = "???", tankupad = "???"; - let tabappearance = document.querySelector(".tabappearance"); - let taboptions = document.querySelector(".taboptions"); - let tabcontrols = document.querySelector(".tabcontrols"); - let tablinks = document.querySelector(".tablinks"); - let tabappearancebutton = document.querySelector(".tabappearancebutton"); - let taboptionsbutton = document.querySelector(".taboptionsbutton"); - let tabcontrolsbutton = document.querySelector(".tabcontrolsbutton"); - let tablinksbutton = document.querySelector(".tablinksbutton"); - - function changetab(vroomvroomimaracecarreeeroweaweerrrm) { - switch(vroomvroomimaracecarreeeroweaweerrrm) { - case 0: - tabappearance.style.display = 'block'; - taboptions.style.display = 'none'; - tabcontrols.style.display = 'none'; - tablinks.style.display = 'none'; - tabappearancebutton.classList.add("active"); - taboptionsbutton.classList.remove("active"); - tabcontrolsbutton.classList.remove("active"); - tablinksbutton.classList.remove("active"); - break; - case 1: - tabappearance.style.display = 'none'; - taboptions.style.display = 'block'; - tabcontrols.style.display = 'none'; - tablinks.style.display = 'none'; - tabappearancebutton.classList.remove("active"); - taboptionsbutton.classList.add("active"); - tabcontrolsbutton.classList.remove("active"); - tablinksbutton.classList.remove("active"); - break; - case 2: - tabappearance.style.display = 'none'; - taboptions.style.display = 'none'; - tabcontrols.style.display = 'block'; - tablinks.style.display = 'none'; - tabappearancebutton.classList.remove("active"); - taboptionsbutton.classList.remove("active"); - tabcontrolsbutton.classList.add("active"); - tablinksbutton.classList.remove("active"); - break; - case 3: - tabappearance.style.display = 'none'; - taboptions.style.display = 'none'; - tabcontrols.style.display = 'none'; - tablinks.style.display = 'block'; - tabappearancebutton.classList.remove("active"); - taboptionsbutton.classList.remove("active"); - tabcontrolsbutton.classList.remove("active"); - tablinksbutton.classList.add("active"); - break; - } - } - - if (global.ISTHEGODAMNFUCKINGGAMEON !== "yeah") { - - $(".tabappearancebutton").on("click", function() { - changetab(0); - }); - $(".taboptionsbutton").on("click", function() { - changetab(1); - }); - $(".tabcontrolsbutton").on("click", function() { - changetab(2); - }); - $(".tablinksbutton").on("click", function() { - changetab(3); - }); - -} let trollface = null; @@ -879,12 +809,20 @@ class Animation { return Math.abs(this.to - this.value) < val; } } -let animations = window.animations = { - connecting: new Animation(1, 0), - disconnected: new Animation(1, 0), - deathScreen: new Animation(1, 0), - error: new Animation(1, 0), -}; +let controls = document.getElementById("controlSettings"), + resetButton = document.getElementById("resetControls"), + moreControls = document.getElementById("moreControls"), + moreControlsLength = null, + selectedElement = null, + controlsArray = [], + defaultKeybinds = {}, + keybinds = {}, + animations = window.animations = { + connecting: new Animation(1, 0), + disconnected: new Animation(1, 0), + deathScreen: new Animation(1, 0), + error: new Animation(1, 0), + }; // Mockup functions // Prepare stuff @@ -920,8 +858,15 @@ global.canUpgrade = false; global.canSkill = false; global.message = ""; global.time = 0; +global.enableSlideAnimation = false; +global.mspt = "?"; +global.serverName = "neroio2.glitch.me"; +// Tips setup :D +let tips = global.tips[Math.floor(Math.random() * global.tips.length)]; +global.tips = tips[Math.floor(Math.random() * tips.length)]; // Window setup <3 global.mobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent); +global.mobile && document.body.classList.add("mobile"); var serverName = "Connected"; var provider = "Unknown"; function getMockups() { @@ -934,6 +879,73 @@ function getMockups() { }); }); } +function getKeybinds() { + let kb = localStorage.getItem("keybinds"); + keybinds = typeof kb === "string" && kb.startsWith("{") ? JSON.parse(kb) : {}; +} +function setKeybinds() { + localStorage.setItem("keybinds", JSON.stringify(keybinds)); +} +function unselectElement() { + if (window.getSelection) { + window.getSelection().removeAllRanges(); + } + selectedElement.element.parentNode.parentNode.classList.remove("editing"); + selectedElement = null; +} +function selectElement(element) { + selectedElement = element; + selectedElement.element.parentNode.parentNode.classList.add("editing"); + if (selectedElement.keyCode !== -1 && window.getSelection) { + let selection = window.getSelection(); + selection.removeAllRanges(); + let range = document.createRange(); + range.selectNodeContents(selectedElement.element); + selection.addRange(range); + } +} +function setKeybind(key, keyCode) { + selectedElement.element.parentNode.parentNode.classList.remove("editing"); + resetButton.classList.add("active"); + if (keyCode !== selectedElement.keyCode) { + let otherElement = controlsArray.find(c => c.keyCode === keyCode); + if (keyCode !== -1 && otherElement) { + otherElement.keyName = selectedElement.keyName; + otherElement.element.innerText = selectedElement.keyName; + otherElement.keyCode = selectedElement.keyCode; + global[otherElement.keyId] = selectedElement.keyCode; + keybinds[otherElement.keyId] = [selectedElement.keyName, selectedElement.keyCode]; + } + } + selectedElement.keyName = key; + selectedElement.element.innerText = key; + selectedElement.keyCode = keyCode; + global[selectedElement.keyId] = keyCode; + keybinds[selectedElement.keyId] = [key, keyCode]; + setKeybinds(); +} +function getElements(kb, storeInDefault) { + for (let row of controls.rows) { + for (let cell of row.cells) { + let element = cell.firstChild.firstChild; + if (!element) continue; + let key = element.dataset.key; + if (storeInDefault) defaultKeybinds[key] = [element.innerText, global[key]]; + if (kb[key]) { + element.innerText = kb[key][0]; + global[key] = kb[key][1]; + resetButton.classList.add("active"); + } + let obj = { + element, + keyId: key, + keyName: element.innerText, + keyCode: global[key] + }; + controlsArray.push(obj); + } + } +} window.onload = async () => { let serverSelector = document.getElementById("serverSelector"), tbody = document.createElement("tbody"), @@ -1036,13 +1048,28 @@ window.onload = async () => { util.retrieveFromLocalStorage("optScreenshotMode"); util.retrieveFromLocalStorage("optPredictive"); util.retrieveFromLocalStorage("optFancy"); + util.retrieveFromLocalStorage("optLowResolution"); util.retrieveFromLocalStorage("coloredHealthbars"); util.retrieveFromLocalStorage("centerTank"); util.retrieveFromLocalStorage("optColors"); util.retrieveFromLocalStorage("optCustom"); util.retrieveFromLocalStorage("optNoPointy"); util.retrieveFromLocalStorage("optBorders"); + util.retrieveFromLocalStorage("optNoGrid"); + util.retrieveFromLocalStorage("seperatedHealthbars"); + util.retrieveFromLocalStorage("autoLevelUp"); util.retrieveFromLocalStorage("optResolution"); + util.retrieveFromLocalStorage("optMobile"); + // GUI + util.retrieveFromLocalStorage("optRenderGui"); + util.retrieveFromLocalStorage("optRenderLeaderboard"); + util.retrieveFromLocalStorage("optRenderNames"); + util.retrieveFromLocalStorage("optRenderHealth"); + util.retrieveFromLocalStorage("optRenderScores"); + util.retrieveFromLocalStorage("optReducedInfo"); + util.retrieveFromLocalStorage("showCrosshair"); + util.retrieveFromLocalStorage("showJoystick"); + util.retrieveFromLocalStorage("seperatedHealthbars"); util.retrieveFromLocalStorage("optOgIcon"); util.retrieveFromLocalStorage("disableDeathSounds"); @@ -1069,6 +1096,15 @@ window.onload = async () => { // Set default theme if (document.getElementById("optColors").value === "") { document.getElementById("optColors").value = "nero"; + + // Also do auto check for GUI stuff. + document.getElementById("optRenderGui").checked = true; + document.getElementById("optRenderLeaderboard").checked = true; + document.getElementById("optRenderNames").checked = true; + document.getElementById("optRenderHealth").checked = true; + document.getElementById("optRenderScores").checked = true; + document.getElementById("optFancy").checked = true; + if (global.mobile) document.getElementById("showCrosshair").checked = true, document.getElementById("showJoystick").checked = true; } if (document.getElementById("optBorders").value === "") { document.getElementById("optBorders").value = "nero"; @@ -1076,26 +1112,123 @@ window.onload = async () => { if (document.getElementById("optResolution").value === "") { document.getElementById("optResolution").value = "normal"; } + + // Mobile Selection stuff. + if (document.getElementById("optMobile").value === "") { + document.getElementById("optMobile").value = "mobile"; + } + // Achievement Shit document.getElementById("resetachievementsbutton").onclick = () => resetAllAchievements(); + // Keybinds stuff + getKeybinds(); + getElements(keybinds, true); + document.addEventListener("click", event => { + if (!global.gameStart) { + if (selectedElement) { + unselectElement(); + } else { + let element = controlsArray.find(({ element }) => element === event.target); + if (element) selectElement(element); + } + } + }); + resetButton.addEventListener("click", () => { + keybinds = {}; + setKeybinds(); + controlsArray = []; + getElements(defaultKeybinds); + resetButton.classList.add("spin"); + setTimeout(() => { + resetButton.classList.remove("active"); + resetButton.classList.remove("spin"); + }, 400); + }); + moreControls.addEventListener("click", () => { + if (moreControlsLength) { + for (var b = 0; b < moreControlsLength.length; b++) moreControlsLength[b].classList.add("hidden"); + moreControlsLength = null; + moreControls.classList.remove("x"); + } else { + moreControlsLength = document.querySelectorAll("#controlSettings tr.hidden"); + for (b = 0; b < moreControlsLength.length; b++) moreControlsLength[b].classList.remove("hidden"); + moreControls.classList.add("x"); + } + }); // Game start stuff document.getElementById("startButton").onclick = () => startGame(); document.onkeydown = (e) => { - var key = e.which || e.keyCode; - if (key === global.KEY_ENTER && (global.dead || !global.gameLoading)) { - startGame(); + if (!(global.gameStart || e.shiftKey || e.ctrlKey || e.altKey)) { + let key = e.which || e.keyCode; + if (selectedElement) { + if (1 !== e.key.length || /[0-9]/.test(e.key) || 3 === e.location) { + if (!("Backspace" !== e.key && "Delete" !== e.key)) { + setKeybind("", -1); + } + } else { + setKeybind(e.key.toUpperCase(), e.keyCode); + } + } else if (key === global.KEY_ENTER) { + startGame(); + } } }; window.addEventListener("resize", resizeEvent); resizeEvent(); }; var callofduty = ""; +// Sliding between options menu. +function toggleOptionsMenu() { + let clicked = false, + a = document.getElementById("startMenuSlidingTrigger"), // Trigger ID + c = document.getElementById("optionArrow"), // Arrow + h = document.getElementById("viewOptionText"), // Text (view options) + u = document.getElementsByClassName("sliderHolder")[0], // Sliding. + y = document.getElementsByClassName("slider"), // For animations things. + toggle = () => { + c.style.transform = c.style.webkitTransform = clicked // Rotate the arrow. + ? "translate(2px, -2px) rotate(45deg)" + : "rotate(-45deg)"; + h.innerText = clicked ? "close options" : "view options"; // Change the text. + clicked ? u.classList.add("slided") : u.classList.remove("slided"); // Slide it up. + y[0].style.opacity = clicked ? 0 : 1; // Fade it away. + y[2].style.opacity = clicked ? 1 : 0; // same for this. + }; + a.onclick = () => { // When the button is triggered, This code runs. + clicked = !clicked; + toggle(); + }; + return () => { + clicked || ((clicked = !0), toggle()); + }; +}; +// Tab options +function tabOptionsMenuSwitcher() { + let buttonTabs = document.getElementById("optionMenuTabs"), + tabOptions = [ + document.getElementById("tabAppearance"), + document.getElementById("tabOptions"), + document.getElementById("tabControls"), + document.getElementById("tabAbout"), + ]; + for (let g = 1; g < tabOptions.length; g++) tabOptions[g].style.display = "none"; + let e = 0; + for (let g = 0; g < buttonTabs.children.length; g++) + buttonTabs.children[g].addEventListener("click", () => { + e !== g && + (buttonTabs.children[e].classList.remove("active"), // Remove the active class + buttonTabs.children[g].classList.add("active"), // Add the clicked active class + (tabOptions[e].style.display = "none"), // Dont display the old menu. + (tabOptions[g].style.display = "block"), // Display the menu. + (e = g)) + }); +} function resizeEvent() { if (settings.graphical.quality === undefined) { settings.graphical.quality = 1; }; let scale = window.devicePixelRatio; - if (!settings.graphical.fancyAnimations) { + if (settings.graphical.lowResolution) { scale *= 0.5; } if (typeof settings.graphical.quality === 'string' || settings.graphical.quality instanceof String) { @@ -1130,6 +1263,9 @@ var ctx = c.getContext("2d"); var c2 = document.createElement("canvas"); var ctx2 = c2.getContext("2d"); ctx2.imageSmoothingEnabled = true; +// important functions +tabOptionsMenuSwitcher(); +toggleOptionsMenu(); // Animation things function Smoothbar(value, speed, sharpness = 3, lerpValue = 0.025) { let time = Date.now(); @@ -1166,7 +1302,7 @@ global.player = { cy: 0, screenx: 0, screeny: 0, - target: calculateTarget(), + target: !global.mobile ? calculateTarget() : window.canvas.target, name: "", lastUpdate: 0, time: 0, @@ -1286,6 +1422,7 @@ function parseTheme(string){ } // This starts the game and sets up the websocket function startGame() { + if (!global.gameStart) { PlaySound69(); clearInterval(nIntervId); // release our intervalID from the variable @@ -1295,8 +1432,20 @@ function startGame() { console.log('Started connecting.') //set start achievement util.submitAchievementToLocalStorage("startachievement"); + } + + if (global.mobile) { + document.getElementById("optMobile").display = "block" + util.submitAchievementToLocalStorage("startachievement"); + var d = document.body; + d.requestFullscreen ? d.requestFullscreen() + : d.msRequestFullscreen ? d.msRequestFullscreen() + : d.mozRequestFullScreen ? d.mozRequestFullScreen() + : d.webkitRequestFullscreen && d.webkitRequestFullscreen(); + } // Get options util.submitToLocalStorage("optFancy"); + util.submitToLocalStorage("optLowResolution"); util.submitToLocalStorage("centerTank"); util.submitToLocalStorage("optBorders"); util.submitToLocalStorage("optResolution"); @@ -1305,6 +1454,7 @@ function startGame() { util.submitToLocalStorage("disableDeathSounds"); util.submitToLocalStorage("optNoEmojis"); util.submitToLocalStorage("autoLevelUp"); + util.submitToLocalStorage("optMobile"); util.submitToLocalStorage("optPredictive"); util.submitToLocalStorage("optScreenshotMode"); util.submitToLocalStorage("coloredHealthbars"); @@ -1327,18 +1477,39 @@ function startGame() { util.submitToLocalStorage("routine2"); util.submitToLocalStorage("routin3s"); util.submitToLocalStorage("jitt3rs"); + util.submitToLocalStorage("optNoGrid"); + // GUI + util.submitToLocalStorage("optRenderGui"); + util.submitToLocalStorage("optRenderLeaderboard"); + util.submitToLocalStorage("optRenderNames"); + util.submitToLocalStorage("optRenderHealth"); + util.submitToLocalStorage("optRenderScores"); + util.submitToLocalStorage("optReducedInfo"); + util.submitToLocalStorage("showCrosshair"); + util.submitToLocalStorage("showJoystick"); global.ISTHEGODAMNFUCKINGGAMEON = "yeah"; settings.graphical.fancyAnimations = !document.getElementById("optFancy").checked; settings.graphical.centerTank = document.getElementById("centerTank").checked; settings.graphical.pointy = !document.getElementById("optNoPointy").checked; settings.game.optOgIcon = !document.getElementById("optOgIcon").checked; - settings.game.disableDeathSounds = !document.getElementById("disableDeathSounds").checked; + settings.game.disableDeathSounds = document.getElementById("disableDeathSounds").checked; settings.game.optNoEmojis = !document.getElementById("optNoEmojis").checked; settings.game.autoLevelUp = !document.getElementById("autoLevelUp").checked; settings.lag.unresponsive = document.getElementById("optPredictive").checked; settings.graphical.screenshotMode = document.getElementById("optScreenshotMode").checked; settings.graphical.coloredHealthbars = document.getElementById("coloredHealthbars").checked; settings.graphical.seperatedHealthbars = document.getElementById("seperatedHealthbars").checked; + settings.graphical.lowResolution = document.getElementById("optLowResolution").checked; + settings.graphical.showGrid = !document.getElementById("optNoGrid").checked; + // GUI + global.GUIStatus.renderGUI = !document.getElementById("optRenderGui").checked; + global.GUIStatus.renderLeaderboard = !document.getElementById("optRenderLeaderboard").checked; + global.GUIStatus.renderPlayerNames = !document.getElementById("optRenderNames").checked; + global.GUIStatus.renderPlayerScores = !document.getElementById("optRenderScores").checked; + global.GUIStatus.renderhealth = !document.getElementById("optRenderHealth").checked; + global.GUIStatus.minimapReducedInfo = document.getElementById("optReducedInfo").checked; + global.mobileStatus.enableCrosshair = !document.getElementById("showCrosshair").checked; + global.mobileStatus.showJoysticks = !document.getElementById("showJoystick").checked; const pmusic = []; if (document.getElementById("oioioi").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/oioioi.mp3?v=1705286830033"); if (document.getElementById("dejected").checked) pmusic.push("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Dejected.mp3?v=1705287022417"); @@ -1416,7 +1587,16 @@ function startGame() { settings.graphical.quality = "trippy"; break; } + switch (document.getElementById("optMobile").value) { + case "desktop": + global.mobile = false; + break; + case "mobileWithBigJoysticks": + global.mobileStatus.useBigJoysticks = true; + break; + } util.submitToLocalStorage("optColors"); + if (!global.gameStart) { let a = document.getElementById("optColors").value; color = color[a === "" ? "nero" : a]; if (a == "custom") { @@ -1424,21 +1604,29 @@ function startGame() { color = parseTheme(customTheme).content; util.submitToLocalStorage("optCustom"); } + } gameDraw.color = color; // Other more important stuff let playerNameInput = document.getElementById("playerNameInput"); let playerKeyInput = document.getElementById("playerKeyInput"); + let autolevelUpInput = !document.getElementById("autoLevelUp").checked; + global.autolvlUp = autolevelUpInput; // Name and keys util.submitToLocalStorage("playerNameInput"); util.submitToLocalStorage("playerKeyInput"); + util.submitToLocalStorage("optMobile"); global.playerName = global.player.name = playerNameInput.value; global.playerKey = playerKeyInput.value.replace(/(<([^>]+)>)/gi, "").substring(0, 64); // Change the screen global.screenWidth = window.innerWidth; global.screenHeight = window.innerHeight; - document.getElementById("startMenuWrapper").style.maxHeight = "0px"; + document.getElementById("startMenuWrapper").style = "display: block; pointer-events: none; inset: 0; animation: fadezoomout 300ms forwards;"; document.getElementById("gameAreaWrapper").style.opacity = 1; + setTimeout(() => { + document.getElementById("startMenuWrapper").style = "display: none;"; + }, 1e3); + if (!global.gameStart) { document.getElementById("hideongamestart").style.zIndex = "-3"; document.getElementById("canvas").style.width = "120px"; document.getElementById("canvas").style.height = "72px"; @@ -1447,15 +1635,18 @@ function startGame() { document.getElementById("canvas").style.position = "relative"; // Set up the socket if (!global.socket) { - global.socket = socketInit(26301); + global.socket = socketInit(3000); } if (!global.animLoopHandle) { animloop(); } + // initialize canvas. window.canvas.socket = global.socket; - setInterval(() => moveCompensation.iterate(global.socket.cmd.getMotion()), 1000 / 30); + setInterval(() => moveCompensation.iterate(global.motion), 1000 / 30); + canvas.init(); + } document.getElementById("gameCanvas").focus(); - window.onbeforeunload = () => true; + if (!global.gameStart) window.onbeforeunload = () => true; if (settings.game.optNoEmojis) { trollface = new Image(); // Create new img element } @@ -1491,12 +1682,13 @@ function arrayifyText(rawText) { } return textArray; } -const measureText = (text, fontSize, withHeight = false) => { +function measureText(text, fontSize, withHeight = false) { fontSize += settings.graphical.fontSizeBoost; ctx.font = "bold " + fontSize + "px Ubuntu"; let measurement = ctx.measureText(arrayifyText(text).reduce((a, b, i) => (i & 1) ? a : a + b, '')); return withHeight ? { width: measurement.width, height: fontSize } : measurement.width; -}; +} + function drawText(rawText, x, y, size, defaultFillStyle, align = "left", center = false, fade = 1, stroke = true, context = ctx) { size += settings.graphical.fontSizeBoost; // Get text dimensions and resize/reset the canvas @@ -1804,78 +1996,32 @@ function drawBar(x1, x2, y, width, color) { ctx.stroke(); } -//checking for images in the shape so we can draw them -function isImageURL(url) { - try { - const parsedUrl = new URL(url); - const path = parsedUrl.pathname; - const ext = path.split('.').pop().toLowerCase(); // Get the lowercase file extension - - // List of common image file extensions - const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg']; - - return imageExtensions.includes(ext) || parsedUrl.protocol == 'data:'; - } catch (error) { - return false; // URL parsing failed, or it's not an image URL. - } -} // Sub-drawing functions const drawPolyImgs = []; function drawPoly(context, centerX, centerY, radius, sides, angle = 0, borderless, fill, imageInterpolation) { - // Start drawing - context.beginPath(); - if (sides instanceof Array) { - let dx = Math.cos(angle); - let dy = Math.sin(angle); - for (let [x, y] of sides) - context.lineTo( - centerX + radius * (x * dx - y * dy), - centerY + radius * (y * dx + x * dy) - ); - } else { - if ("string" === typeof sides) { - if (isImageURL(sides)) { + try { + // Start drawing + context.beginPath(); + if (sides instanceof Array) { + let dx = Math.cos(angle); + let dy = Math.sin(angle); + for (let [x, y] of sides) + context.lineTo( + centerX + radius * (x * dx - y * dy), + centerY + radius * (y * dx + x * dy) + ); + } else { + if ("string" === typeof sides) { //ideally we'd preload images when mockups are loaded but im too lazy for that atm - if (!drawPolyImgs[sides]) { + if (sides.startsWith('/') | sides.startsWith('./') | sides.startsWith('http')) { drawPolyImgs[sides] = new Image(); drawPolyImgs[sides].src = sides; drawPolyImgs[sides].isBroken = false; drawPolyImgs[sides].onerror = function() { - console.log('Failed to load image!\nURL:', sides); - this.isBroken = true; - }; + this.isBroken = true; } + let img = drawPolyImgs[sides]; - if (img.isBroken || !img.complete) { // check if img is broken and draw placeholder if so - //this is probably the worst way to draw a missing texture checkerboard but im too lazy to do a better one - context.translate(centerX, centerY); - context.rotate(angle); - context.beginPath(); - context.fillStyle = '#ff00ff'; - context.lineTo(-radius,-radius); - context.lineTo(radius,-radius); - context.lineTo(radius,radius); - context.lineTo(-radius,radius); - context.lineTo(-radius,-radius); - context.fill(); - context.closePath(); - context.beginPath(); - context.fillStyle = '#000000'; - context.lineTo(-radius,-radius); - context.lineTo(0,-radius); - context.lineTo(0,0); - context.lineTo(0, radius); - context.lineTo(radius, radius); - context.lineTo(radius, 0); - context.lineTo(0, 0); - context.lineTo(-radius, 0); - context.lineTo(-radius,-radius); - context.fill(); - context.closePath(); - context.rotate(-angle); - context.translate(-centerX, -centerY); - return; - } context.translate(centerX, centerY); context.rotate(angle); context.imageSmoothingEnabled = imageInterpolation; @@ -1884,75 +2030,78 @@ function drawPoly(context, centerX, centerY, radius, sides, angle = 0, borderles context.rotate(-angle); context.translate(-centerX, -centerY); return; - } else { - let path = new Path2D(sides); - context.save(); - context.translate(centerX, centerY); - context.scale(radius, radius); - context.lineWidth /= radius; - context.rotate(angle); - context.lineWidth *= fill ? 1 : 0.5; // Maintain constant border width - if (!borderless) context.stroke(path); - if (fill) context.fill(path); - context.restore(); - return; } + let path = new Path2D(sides); + context.save(); + context.translate(centerX, centerY); + context.scale(radius, radius); + context.lineWidth /= radius; + context.rotate(angle); + context.lineWidth *= fill ? 1 : 0.5; // Maintain constant border width + if (!borderless) context.stroke(path); + if (fill) context.fill(path); + context.restore(); + return; } angle += sides % 2 ? 0 : Math.PI / sides; - } - if (!sides) { - // Circle - let fillcolor = context.fillStyle; - let strokecolor = context.strokeStyle; - context.arc(centerX, centerY, radius, 0, 2 * Math.PI); - context.fillStyle = strokecolor; - context.lineWidth *= fill ? 1 : 0.5; // Maintain constant border width - if (!borderless) context.stroke(); - context.closePath(); - context.beginPath(); - context.fillStyle = fillcolor; - context.arc(centerX, centerY, radius * fill, 0, 2 * Math.PI); - if (fill) context.fill(); - context.closePath(); - return; - } else if (sides < 0) { - // Star - if (settings.graphical.pointy) context.lineJoin = "miter"; - sides = -sides; - angle += (sides % 1) * Math.PI * 2; - sides = Math.floor(sides); - let dip = 1 - 6 / (sides ** 2); - context.moveTo(centerX + radius * Math.cos(angle), centerY + radius * Math.sin(angle)); - context.lineWidth *= fill ? 1 : 0.5; // Maintain constant border width - for (let i = 0; i < sides; i++) { - let htheta = ((i + 0.5) / sides) * 2 * Math.PI + angle, - theta = ((i + 1) / sides) * 2 * Math.PI + angle, - cx = centerX + radius * dip * Math.cos(htheta), - cy = centerY + radius * dip * Math.sin(htheta), - px = centerX + radius * Math.cos(theta), - py = centerY + radius * Math.sin(theta); - /*if (curvyTraps) { - context.quadraticCurveTo(cx, cy, px, py); - } else { - context.lineTo(cx, cy); - context.lineTo(px, py); - }*/ - context.quadraticCurveTo(cx, cy, px, py); } - } else if (sides > 0) { - // Polygon - angle += (sides % 1) * Math.PI * 2; - sides = Math.floor(sides); - context.lineWidth *= fill ? 1 : 0.5; // Maintain constant border width - for (let i = 0; i < sides; i++) { - let theta = (i / sides) * 2 * Math.PI + angle; - context.lineTo(centerX + radius * Math.cos(theta), centerY + radius * Math.sin(theta)); + if (!sides) { + // Circle + let fillcolor = context.fillStyle; + let strokecolor = context.strokeStyle; + context.arc(centerX, centerY, radius, 0, 2 * Math.PI); + context.fillStyle = strokecolor; + context.lineWidth *= fill ? 1 : 0.5; // Maintain constant border width + if (!borderless) context.stroke(); + context.closePath(); + context.beginPath(); + context.fillStyle = fillcolor; + context.arc(centerX, centerY, radius * fill, 0, 2 * Math.PI); + if (fill) context.fill(); + context.closePath(); + return; + } else if (sides < 0) { + // Star + if (settings.graphical.pointy) context.lineJoin = "miter"; + sides = -sides; + angle += (sides % 1) * Math.PI * 2; + sides = Math.floor(sides); + let dip = 1 - 6 / (sides ** 2); + context.moveTo(centerX + radius * Math.cos(angle), centerY + radius * Math.sin(angle)); + context.lineWidth *= fill ? 1 : 0.5; // Maintain constant border width + for (let i = 0; i < sides; i++) { + let htheta = ((i + 0.5) / sides) * 2 * Math.PI + angle, + theta = ((i + 1) / sides) * 2 * Math.PI + angle, + cx = centerX + radius * dip * Math.cos(htheta), + cy = centerY + radius * dip * Math.sin(htheta), + px = centerX + radius * Math.cos(theta), + py = centerY + radius * Math.sin(theta); + /*if (curvyTraps) { + context.quadraticCurveTo(cx, cy, px, py); + } else { + context.lineTo(cx, cy); + context.lineTo(px, py); + }*/ + context.quadraticCurveTo(cx, cy, px, py); + } + } else if (sides > 0) { + // Polygon + angle += (sides % 1) * Math.PI * 2; + sides = Math.floor(sides); + context.lineWidth *= fill ? 1 : 0.5; // Maintain constant border width + for (let i = 0; i < sides; i++) { + let theta = (i / sides) * 2 * Math.PI + angle; + context.lineTo(centerX + radius * Math.cos(theta), centerY + radius * Math.sin(theta)); + } } + context.closePath(); + if (!borderless) context.stroke(); + if (fill) context.fill(); + context.lineJoin = "round"; + } catch (e) { // this actually prevents to panic the client. so we will just call "resizeEvent()". + resizeEvent(); + console.error("Uh oh, 'CanvasRenderingContext2D' has gotton an error! Error: " + e); } - context.closePath(); - if (!borderless) context.stroke(); - if (fill) context.fill(); - context.lineJoin = "round"; } function drawTrapezoid(context, x, y, length, height, aspect, angle, borderless, fill, alpha, strokeWidth, position) { let h = []; @@ -1983,6 +2132,7 @@ function drawTrapezoid(context, x, y, length, height, aspect, angle, borderless, if (fill) context.fill(); context.globalAlpha = 1; } + const drawEntity = (baseColor, x, y, instance, ratio, alpha = 1, scale = 1, lineWidthMult = 1, rot = 0, turretsObeyRot = false, assignedContext = false, turretInfo = false, render = instance.render) => { let context = assignedContext ? assignedContext : ctx; let fade = turretInfo ? 1 : render.status.getFade(), @@ -1996,7 +2146,8 @@ const drawEntity = (baseColor, x, y, instance, ratio, alpha = 1, scale = 1, line initStrokeWidth = lineWidthMult * Math.max(settings.graphical.mininumBorderChunk, ratio * settings.graphical.borderChunk); source.guns.update(); if (fade === 0 || alpha === 0) return; - if (render.expandsWithDeath) drawSize *= 1 + 0.5 * (1 - fade); + if (render.expandsWithDeath && settings.graphical.fancyAnimations) drawSize *= 1 + 0.5 * (1 - fade); + if (!settings.graphical.fancyAnimations) drawSize *= 1 + -2 * (1 - fade); if (settings.graphical.fancyAnimations && assignedContext != ctx2 && (fade !== 1 || alpha !== 1)) { context = ctx2; context.canvas.width = context.canvas.height = drawSize * m.position.axis / ratio * 2 + initStrokeWidth; @@ -2133,11 +2284,10 @@ function drawHealth(x, y, instance, ratio, alpha) { if (instance.drawsHealth) { let health = instance.render.health.get(), shield = instance.render.shield.get(); - if (health < 0.99 || shield < 0.99) { + if (health < 0.99 || shield < 0.99 && global.GUIStatus.renderhealth) { let col = settings.graphical.coloredHealthbars ? gameDraw.mixColors(gameDraw.modifyColor(instance.color), color.guiwhite, 0.5) : color.blue; let yy = y + realSize + 15 * ratio; let barWidth = 3 * ratio; - ctx.globalAlpha = fade * (alpha ** 2); //TODO: seperate option for hp bars // function drawBar(x1, x2, y, width, color) { @@ -2153,15 +2303,16 @@ function drawHealth(x, y, instance, ratio, alpha) { drawBar(x - size, x - size + 2 * size * shield, yy, barWidth, settings.graphical.coloredHealthbars ? gameDraw.mixColors(col, color.guiblack, 0.25) : color.teal); ctx.globalAlpha = 1; } + if (gui.showhealthtext) drawText(Math.round(instance.healthN) + "/" + Math.round(instance.maxHealthN), x, yy + barWidth * 2 + barWidth * settings.graphical.seperatedHealthbars * 2 + 10, 12 * ratio, color.guiwhite, "center"); + ctx.globalAlpha = fade * (alpha ** 2); } } if (instance.id !== gui.playerid && instance.nameplate) { var name = instance.name.substring(7, instance.name.length + 1); var namecolor = instance.name.substring(0, 7); - ctx.globalAlpha = alpha; - drawText(name, x, y - realSize - 22 * ratio, 12 * ratio, namecolor, "center"); - drawText(util.handleLargeNumber(instance.score, 1), x, y - realSize - 12 * ratio, 6 * ratio, namecolor, "center"); - ctx.globalAlpha = 1; + ctx.globalAlpha = fade * (alpha ** 2); + if (global.GUIStatus.renderPlayerNames) drawText(name, x, y - realSize - 22 * ratio, 12 * ratio, namecolor == "#ffffff" ? color.guiwhite : namecolor, "center"); + if (global.GUIStatus.renderPlayerScores) drawText(util.handleLargeNumber(instance.score, 1), x, y - realSize - 12 * ratio, 6 * ratio, namecolor == "#ffffff" ? color.guiwhite : namecolor, "center"); } } @@ -2268,6 +2419,7 @@ window.cancelAnimFrame = window.cancelAnimationFrame || window.mozCancelAnimatio // Drawing states const statMenu = Smoothbar(0, 0.7, 1.5, 0.1); const upgradeMenu = Smoothbar(0, 2, 3, 0.1); +const mobileUpgradeGlide = Smoothbar(0, 2, 3, 0.1); // Define the graph constructor function graph() { var data = []; @@ -2476,6 +2628,9 @@ function drawFloor(px, py, ratio) { //draw it let tile = row[j]; + + if (tile.includes('none')) continue; + ctx.globalAlpha = 1; ctx.fillStyle = settings.graphical.screenshotMode ? color.guiwhite : color.white; ctx.fillRect(left, top, right - left, bottom - top); @@ -2488,24 +2643,33 @@ function drawFloor(px, py, ratio) { ctx.fillRect(left, top, right - left, bottom - top); if (settings.graphical.quality == "cod") { ctx.drawImage(callofduty, left, top, right - left, bottom - top); + + if (settings.graphical.screenshotMode) continue; + + ctx.globalAlpha = 0.3; + ctx.fillStyle = gameDraw.modifyColor(tile); + ctx.fillRect(left, top, right - left + 1, bottom - top + 1); } } } - ctx.lineWidth = 1.25; - ctx.strokeStyle = settings.graphical.screenshotMode ? color.guiwhite : color.guiblack; - ctx.globalAlpha = 0.04; - ctx.beginPath(); - let gridsize = 30 * ratio; - for (let x = (global.screenWidth / 2 - px) % gridsize; x < global.screenWidth; x += gridsize) { - ctx.moveTo(x, 0); - ctx.lineTo(x, global.screenHeight); - } - for (let y = (global.screenHeight / 2 - py) % gridsize; y < global.screenHeight; y += gridsize) { - ctx.moveTo(0, y); - ctx.lineTo(global.screenWidth, y); + if (settings.graphical.showGrid) { + let gridsize = 30 * ratio; + if (gridsize < 7) return; + ctx.lineWidth = ratio; + ctx.strokeStyle = settings.graphical.screenshotMode ? color.guiwhite : color.guiblack; + ctx.globalAlpha = 0.04; + ctx.beginPath(); + for (let x = (global.screenWidth / 2 - px) % gridsize; x < global.screenWidth; x += gridsize) { + ctx.moveTo(x, 0); + ctx.lineTo(x, global.screenHeight); + } + for (let y = (global.screenHeight / 2 - py) % gridsize; y < global.screenHeight; y += gridsize) { + ctx.moveTo(0, y); + ctx.lineTo(global.screenWidth, y); + } + ctx.stroke(); + ctx.globalAlpha = 1; } - ctx.stroke(); - ctx.globalAlpha = 1; } function drawEntities(px, py, ratio) { @@ -2522,7 +2686,7 @@ function drawEntities(px, py, ratio) { } instance.render.x = util.lerp(instance.render.x, Math.round(instance.x + instance.vx), 0.1, true); instance.render.y = util.lerp(instance.render.y, Math.round(instance.y + instance.vy), 0.1, true); - instance.render.f = instance.id === gui.playerid && !global.autoSpin && !instance.twiggle && !global.died ? Math.atan2(global.target.y * global.reverseTank, global.target.x * global.reverseTank) : util.lerpAngle(instance.render.f, instance.facing, 0.15, true); + instance.render.f = instance.id === gui.playerid && !global.autoSpin && !global.syncingWithTank && !instance.twiggle && !global.died ? Math.atan2(global.target.y * global.reverseTank, global.target.x * global.reverseTank) : util.lerpAngle(instance.render.f, instance.facing, 0.15, true); let x = ratio * instance.render.x - px, y = ratio * instance.render.y - py, baseColor = instance.color; @@ -2558,8 +2722,8 @@ function drawEntities(px, py, ratio) { indexes = instance.index.split("-"), m = global.mockups[parseInt(indexes[0])], realSize = (size / m.size) * m.realSize, - x = instance.id === gui.playerid ? 0 : ratio * instance.render.x - px, - y = instance.id === gui.playerid ? 0 : ratio * instance.render.y - py; + x = instance.id === gui.playerid ? global.player.screenx : ratio * instance.render.x - px, + y = instance.id === gui.playerid ? global.player.screeny : ratio * instance.render.y - py; x += global.screenWidth / 2; y += global.screenHeight / 2 - realSize - 46 * ratio; if (instance.id !== gui.playerid && instance.nameplate) y -= 8 * ratio; @@ -2569,7 +2733,7 @@ function drawEntities(px, py, ratio) { let chat = global.chats[instance.id][i], text = chat.text, msgLengthHalf = measureText(text, 15 * ratioForChat) / 2, - alpha = Math.max(0, Math.min(1000, chat.expires - now) / 1000); + alpha = Math.max(!global.mobile ? 0 : 1, Math.min(1000, chat.expires - now) / 1000); ctx.globalAlpha = 0.5 * alpha; if (settings.game.optNoEmojis) { if (text.includes("--troll")) { @@ -2688,13 +2852,20 @@ function drawUpgradeTree(spacing, alcoveSize) { ctx.strokeText(text, global.screenWidth / 2 - w / 2, innerHeight * 0.04); } -function drawMessages(spacing) { +function drawMessages(spacing, alcoveSize) { // Draw messages let vspacing = 4; let len = 0; let height = 18; let x = global.screenWidth / 2; let y = spacing; + if (global.mobile) { + if (global.canUpgrade) { + mobileUpgradeGlide.set(0 + (global.canUpgrade || global.upgradeHover)); + y += (alcoveSize / 1.4 /*+ spacing * 2*/) * mobileUpgradeGlide.get(); + } + y += global.canSkill || global.showSkill ? (alcoveSize / 2.2 /*+ spacing * 2*/) * statMenu.get() : 0; + } // Draw each message for (let i = global.messages.length - 1; i >= 0; i--) { let msg = global.messages[i], @@ -2733,6 +2904,7 @@ function drawMessages(spacing) { function drawSkillBars(spacing, alcoveSize) { // Draw skill bars + if (global.mobile) return drawMobileSkillUpgrades(spacing, alcoveSize); statMenu.set(0 + (global.died || global.statHover || (global.canSkill && !gui.skills.every(skill => skill.cap === skill.amount)))); global.clickables.stat.hide(); let vspacing = 4; @@ -2810,6 +2982,67 @@ function drawSkillBars(spacing, alcoveSize) { drawText("x" + gui.points, Math.round(x + len - 2) + 0.5, Math.round(y + height - 4) + 0.5, 20, color.guiwhite, "right"); } } + function drawMobileSkillUpgrades(spacing, alcoveSize) { + global.canSkill = gui.points > 0 && gui.skills.some(s => s.amount < s.cap) && !global.canUpgrade; + global.showSkill = !global.canUpgrade && !global.canSkill && global.died; + statMenu.set(global.canSkill || global.showSkill || global.disconnected ? 1 : 0); + let n = statMenu.get(); + global.clickables.stat.hide(); + let t = alcoveSize / 2, + q = alcoveSize / 3, + x = 2 * n * spacing - spacing, + statNames = gui.getStatNames(global.mockups[parseInt(gui.type.split("-")[0])].statnames), + clickableRatio = canvas.height / global.screenHeight / global.ratio; + if (global.canSkill || global.showSkill) { + for (let i = 0; i < gui.skills.length; i++) { + let skill = gui.skills[i], + softcap = skill.softcap; + if (softcap <= 0) continue; + let amount = skill.amount, + skillColor = color[skill.color], + cap = skill.cap, + name = statNames[9 - i].split(/\s+/), + halfNameLength = Math.floor(name.length / 2), + [name1, name2] = name.length === 1 ? [name[0], null] : [name.slice(0, halfNameLength).join(" "), name.slice(halfNameLength).join(" ")]; + ctx.globalAlpha = 0.5; + ctx.fillStyle = skillColor; + drawGuiRect(x, spacing, t, 2 * q / 3); + ctx.globalAlpha = 0.1; + ctx.fillStyle = color.black; + drawGuiRect(x, spacing + q * 2 / 3 * 2 / 3, t, q * 2 / 3 / 3); + ctx.globalAlpha = 1; + ctx.fillStyle = color.guiwhite; + drawGuiRect(x, spacing + q * 2 / 3, t, q / 3); + ctx.fillStyle = skillColor; + drawGuiRect(x, spacing + q * 2 / 3, t * amount / softcap, q / 3); + ctx.strokeStyle = color.black; + ctx.lineWidth = 1; + for (let j = 1; j < cap; j++) { + let width = x + j / softcap * t; + drawGuiLine(width, spacing + q * 2 / 3, width, spacing + q); + } + cap === 0 || !gui.points || softcap !== cap && amount === softcap || global.clickables.stat.place(9 - i, x * clickableRatio, spacing * clickableRatio, t * clickableRatio, q * clickableRatio); + if (name2) { + drawText(name2, x + t / 2, spacing + q * 0.55, q / 5, color.guiwhite, "center"); + drawText(name1, x + t / 2, spacing + q * 0.3, q / 5, color.guiwhite, "center"); + } else { + drawText(name1, x + t / 2, spacing + q * 0.425, q / 5, color.guiwhite, "center"); + } + if (amount > 0) { + drawText(amount < softcap ? `+${amount}` : "MAX", x + t / 2, spacing + q * 1.3, q / 4, skillColor, "center"); + } + ctx.strokeStyle = color.black; + ctx.globalAlpha = 1; + ctx.lineWidth = 3; + drawGuiLine(x, spacing + q * 2 / 3, x + t, spacing + q * 2 / 3); + drawGuiRect(x, spacing, t, q, true); + x += n * (t + 14); + } + if (gui.points > 1) { + drawText(`x${gui.points}`, x, spacing + 20, 20, color.guiwhite, "left"); + } + } +} function drawSelfInfo(spacing, alcoveSize, max) { //rendering information @@ -2881,17 +3114,18 @@ function drawSelfInfo(spacing, alcoveSize, max) { // Draw the %-of-leader bar drawBar(x + len * 0.1, x + len * 0.9, y + height / 2, height - 3 + settings.graphical.barChunk, color.black); drawBar(x + len * 0.1, x + len * 0.9, y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.grey); - drawBar(x + len * 0.1, x + len * (0.1 + 0.8 * (max ? Math.min(1, gui.__s.getScore() / max) : 1)), y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.teal); + drawBar(x + len * 0.1, x + len * (0.1 + 0.8 * (max ? Math.min(1, gui.__s.getScore() / max) : 1)), y + height / 2, height - 3 - settings.graphical.barChunk / 4, color.green); //write the score and name - drawText("Score: " + util.formatLargeNumber(Math.floor(gui.__s.getScore())), x + len / 2, y + height / 2 + 1, height - 3.5, color.guiwhite, "center", true); + drawText("Score: " + util.formatLargeNumber(Math.round(gui.__s.getScore())), x + len / 2, y + height / 2 + 1, height - 3.5, color.guiwhite, "center", true); ctx.lineWidth = 4; - drawText(global.player.name, Math.round(x + len / 2) + 0.5, Math.round(y - 10 - vspacing) + 0.5, 32, global.nameColor, "center"); + drawText(global.player.name, Math.round(x + len / 2) + 0.5, Math.round(y - 10 - vspacing) + 0.5, 32, global.nameColor = "#ffffff" ? color.guiwhite : global.nameColor, "center"); } -function drawMinimapAndDebug(spacing, alcoveSize) { +function drawMinimapAndDebug(spacing, alcoveSize, GRAPHDATA) { // Draw minimap and FPS monitors //minimap stuff starts here + let orangeColor = false; let len = alcoveSize; // * global.screenWidth; let height = (len / global.gameWidth) * global.gameHeight; if (global.gameHeight > global.gameWidth || global.gameHeight < global.gameWidth) { @@ -2911,8 +3145,13 @@ function drawMinimapAndDebug(spacing, alcoveSize) { len /= ratio; height /= ratio; } - let x = global.screenWidth - spacing - len; - let y = global.screenHeight - height - spacing; + let upgradeColumns = Math.ceil(gui.upgrades.length / 9); + let x = global.mobile ? spacing : global.screenWidth - spacing - len; + let y = global.mobile ? spacing : global.screenHeight - height - spacing; + if (global.mobile) { + y += global.canUpgrade ? (alcoveSize / 1.5) * mobileUpgradeGlide.get() * upgradeColumns / 1.5 + spacing * (upgradeColumns + 1.55) + 9 : 0; + y += global.canSkill || global.showSkill ? statMenu.get() * alcoveSize / 2.6 + spacing / 0.75 : 0; + } ctx.globalAlpha = 0.4; let W = global.roomSetup[0].length, H = global.roomSetup.length, @@ -2922,6 +3161,14 @@ function drawMinimapAndDebug(spacing, alcoveSize) { let j = 0; for (let xcell = 0; xcell < W; xcell++) { let cell = global.roomSetup[ycell][xcell]; + + if (cell.includes('none')) { + cell = cell.split(' '); + cell.shift(); + cell.unshift('pureBlack'); + cell = cell.join(' '); + } + ctx.fillStyle = gameDraw.modifyColor(cell); if (gameDraw.modifyColor(cell) !== color.white) { drawGuiRect(x + (j * len) / W, y + (i * height) / H, len / W, height / H); @@ -2947,7 +3194,7 @@ function drawMinimapAndDebug(spacing, alcoveSize) { drawGuiCircle(x + (entity.x / global.gameWidth) * len, y + (entity.y / global.gameHeight) * height, (entity.size / global.gameWidth) * len + 0.2); break; case 0: - if (entity.id !== gui.playerid) drawGuiCircle(x + (entity.x / global.gameWidth) * len, y + (entity.y / global.gameHeight) * height, 2); + if (entity.id !== gui.playerid) drawGuiCircle(x + (entity.x / global.gameWidth) * len, y + (entity.y / global.gameHeight) * height, !global.mobile ? 2 : 3.5); break; } } @@ -2962,36 +3209,43 @@ function drawMinimapAndDebug(spacing, alcoveSize) { ctx.lineWidth = 1; ctx.strokeStyle = color.guiblack; ctx.fillStyle = color.guiblack; - drawGuiCircle(x + (global.player.cx / global.gameWidth) * len - 1, y + (global.player.cy / global.gameHeight) * height - 1, 2, false); + drawGuiCircle(x + (global.player.cx / global.gameWidth) * len - 0, y + (global.player.cy / global.gameHeight) * height - 1, !global.mobile ? 2 : 3.5, false); + if (global.mobile) { + x = global.screenWidth - spacing - len; + y = global.screenHeight - spacing; + } if (global.showDebug) { drawGuiRect(x, y - 40, len, 30); lagGraph(lag.get(), x, y - 40, len, 30, color.teal); gapGraph(global.metrics.rendergap, x, y - 40, len, 30, color.pink); - //timingGraph(GRAPHDATA, x, y - 40, len, 30, color.yellow); + timingGraph(GRAPHDATA, x, y - 40, len, 30, color.yellow); } //minimap stuff ends here //debug stuff if (!global.showDebug) y += 14 * 3; + if ((100 * gui.fps).toFixed(2) < 100) orangeColor = true; + if (global.metrics.rendertime < 10) orangeColor = true; // Text if (global.showDebug) { - drawText("Nero Engine v3.1", x + len, y - 50 - 7 * 14 - 2, 15, "#6a36e3", "right"); - //drawText("Prediction: " + Math.round(GRAPHDATA) + "ms", x + len, y - 50 - 4 * 14, 10, color.guiwhite, "right"); - drawText("Update Version: " + "v3.112", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); + drawText("Nero Engine v3.2", x + len, y - 50 - 8 * 14 - 2, 15, "#6a36e3", "right"); + drawText("Prediction: " + Math.round(GRAPHDATA) + "ms : " + global.mspt + " mspt", x + len, y - 50 - 7 * 14, 10, color.guiwhite, "right"); + // drawText(`Bandwidth: ${gui.bandwidth.in} in, ${gui.bandwidth.out} out`, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); + drawText("Memory: " + global.metrics.rendergap.toFixed(1) + " Mib : " + "Class: " + gui.class, x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); + drawText("Update Version: " + "v3.206", x + len, y - 50 - 6 * 14, 10, color.guiwhite, "right"); drawText("Update Rate: " + global.metrics.updatetime + "Hz", x + len, y - 50 - 5 * 14, 10, color.guiwhite, "right"); drawText("Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 4 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); - drawText("Server Speed: " + ((global.metrics.updatetime * global.metrics.rendergap-global.metrics.lag) / 10).toFixed(2) + "%", x + len, y - 50 - 3 * 14, 10, color.guiwhite, "right"); + drawText("Server Speed: " + (100 * gui.fps).toFixed(2) + "% : Client Speed: " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, orangeColor ? color.orange : color.guiwhite, "right"); drawText("Kills: " + global.metrics.killcount + " Shapes: " + global.metrics.shapecount, x + len, y - 50 - 2 * 14, 10, color.guiwhite, "right"); drawText("Song: " + global.music2.songname, x + len, y - 50 - 1 * 14, 10, color.guiwhite, "right"); - drawText(global.metrics.latency + " ms - neroio2 :FFA:", x + len, y - 50, 10, color.guiwhite, "right"); + drawText(global.metrics.latency + " ms - " + global.serverName, x + len, y - 50, 10, color.guiwhite, "right"); document.getElementById("content").style.opacity = 1; - } else { - drawText("Nero.io v3.1", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); - drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, global.metrics.rendertime > 10 ? color.guiwhite : color.orange, "right"); + } else if (!global.GUIStatus.minimapReducedInfo) { + drawText("Nero.io v3.2", x + len, y - 50 - 2 * 14 - 2, 15, "#2eabe6", "right"); + drawText((100 * gui.fps).toFixed(2) + "% : " + global.metrics.rendertime + " FPS", x + len, y - 50 - 1 * 14, 10, orangeColor ? color.orange : color.guiwhite, "right"); drawText(global.metrics.latency + " ms : " + global.metrics.updatetime + "Hz", x + len, y - 50, 10, color.guiwhite, "right"); document.getElementById("content").style.opacity = 0; document.getElementById("content").style.left = x - spacing - 120 - } - global.fps = global.metrics.rendertime; + } else drawText("Open Source Arras", x + len, y - 22 - 2 * 14 - 2, 15, "#1081E5", "right"); } function drawLeaderboard(spacing, alcoveSize, max) { @@ -3002,6 +3256,16 @@ function drawLeaderboard(spacing, alcoveSize, max) { let height = 14; let x = global.screenWidth - len - spacing; let y = spacing + height + 7; + if (!lb.data.length) return; + // Animation things + let mobileGlide = mobileUpgradeGlide.get(); + if (global.mobile) { + if (global.canUpgrade) { + y += (alcoveSize / 1.4) * mobileGlide; + } + y += global.canSkill || global.showSkill ? (alcoveSize / 2.2 /*+ spacing * 2*/) * statMenu.get() : 0; + } + drawText("Leaderboard", Math.round(x + len / 2) + 0.5, Math.round(y - 6) + 0.5, height + 3.5, color.guiwhite, "center"); y += 7; for (let i = 0; i < lb.data.length; i++) { @@ -3012,7 +3276,7 @@ function drawLeaderboard(spacing, alcoveSize, max) { drawBar(x, x + len * shift, y + height / 2, height - 3.5, gameDraw.modifyColor(entry.barColor)); // Leadboard name + score let nameColor = entry.nameColor || "#FFFFFF"; - drawText(entry.label + (": " + util.handleLargeNumber(Math.round(entry.score))), x + len / 2, y + height / 2, height - 5, nameColor, "center", true); + drawText(entry.label + (": " + util.handleLargeNumber(Math.round(entry.score))), x + len / 2, y + height / 2, height - 5, nameColor == "#ffffff" ? color.guiwhite : nameColor, "center", true); // Mini-image let scale = height / entry.position.axis, xx = x - 1.5 * height - scale * entry.position.middle.x * Math.SQRT1_2, @@ -3032,10 +3296,10 @@ function drawAvailableUpgrades(spacing, alcoveSize) { // Animation processing // let columnCount = Math.max(Math.ceil(gui.upgrades.length / 5), 3); - let columnCount = Math.max(3, Math.ceil(gui.upgrades.length / 3)); + global.columnCount = Math.max(global.mobile ? 9 : 3, Math.ceil(gui.upgrades.length / 3)); upgradeMenu.set(0); if (!global.canUpgrade) { - upgradeMenu.force(-columnCount * 3) + upgradeMenu.force(-global.columnCount * 3) global.canUpgrade = true; } let glide = upgradeMenu.get(); @@ -3061,7 +3325,7 @@ function drawAvailableUpgrades(spacing, alcoveSize) { let model = upgrade[2]; // Draw either in the next row or next column - if (ticker === columnCount || upgradeBranch != lastBranch) { + if (ticker === global.columnCount || upgradeBranch != lastBranch) { x = xStart; y += height + internalSpacing; if (upgradeBranch != lastBranch) { @@ -3086,7 +3350,7 @@ function drawAvailableUpgrades(spacing, alcoveSize) { let upgradeKey = getClassUpgradeKey(upgradeNum); // drawEntityIcon(model, y, x, len, height, 1, upgradeSpin, 0.5, colorIndex++, upgradeKey); - drawEntityIcon(model, x, y, len, height, 1, upgradeSpin, 0.6, colorIndex++, upgradeKey, upgradeNum == upgradeHoverIndex); + drawEntityIcon(model, x, y, len, height, 1, upgradeSpin, 0.6, colorIndex++, !global.mobile ? upgradeKey : false, !global.mobile ? upgradeNum == upgradeHoverIndex : false); ticker++; upgradeNum++; @@ -3105,7 +3369,7 @@ function drawAvailableUpgrades(spacing, alcoveSize) { global.clickables.skipUpgrades.place(0, (buttonX - m / 2) * clickableRatio, buttonY * clickableRatio, m * clickableRatio, h * clickableRatio); // Upgrade tooltip - if (upgradeHoverIndex > -1 && upgradeHoverIndex < gui.upgrades.length) { + if (upgradeHoverIndex > -1 && upgradeHoverIndex < gui.upgrades.length && !global.mobile) { let picture = gui.upgrades[upgradeHoverIndex][2]; if (picture.upgradeTooltip.length > 0) { let boxWidth = measureText(picture.name, alcoveSize / 10), @@ -3138,7 +3402,161 @@ function drawAvailableUpgrades(spacing, alcoveSize) { global.clickables.skipUpgrades.hide(); } } +// MOBILE UI FUNCTIONS +function drawMobileJoysticks() { + // Draw the joysticks. + let radius = Math.min( + global.mobileStatus.useBigJoysticks ? global.screenWidth * 0.8 : global.screenWidth * 0.6, + global.mobileStatus.useBigJoysticks ? global.screenHeight * 0.16 : global.screenHeight * 0.12 + ); + ctx.globalAlpha = 0.3; + ctx.fillStyle = "#ffffff"; + ctx.beginPath(); + ctx.arc( + (global.screenWidth * 1) / 6, + (global.screenHeight * 2) / 3, + radius, + 0, + 2 * Math.PI + ); + ctx.arc( + (global.screenWidth * 5) / 6, + (global.screenHeight * 2) / 3, + radius, + 0, + 2 * Math.PI + ); + ctx.fill(); + ctx.globalAlpha = 0.5; + ctx.fillStyle = "#ffffff"; + ctx.beginPath(); + if (global.mobileStatus.showJoysticks) { + ctx.arc( + canvas.movementTouchPos.x + (global.screenWidth * 1) / 6, + canvas.movementTouchPos.y + (global.screenHeight * 2) / 3, + radius / 2.5, + 0, + 2 * Math.PI + ); + ctx.arc( + canvas.controlTouchPos.x + (global.screenWidth * 5) / 6, + canvas.controlTouchPos.y + (global.screenHeight * 2) / 3, + radius / 2.5, + 0, + 2 * Math.PI + ); + } + ctx.fill(); + // crosshair + if (global.mobileStatus.showCrosshair && global.mobileStatus.enableCrosshair) { + const crosshairpos = { + x: global.screenWidth / 2 + global.player.target.x, + y: global.screenHeight / 2 + global.player.target.y + }; + ctx.lineWidth = 1; + ctx.globalAlpha = 1; + ctx.strokeStyle = "#202020" + ctx.beginPath(); + ctx.moveTo(crosshairpos.x, crosshairpos.y - 20); + ctx.lineTo(crosshairpos.x, crosshairpos.y + 20); + ctx.moveTo(crosshairpos.x - 20, crosshairpos.y); + ctx.lineTo(crosshairpos.x + 20, crosshairpos.y); + ctx.closePath(); + ctx.stroke(); + } +} + +function makeButton(index, x, y, width, height, text, clickableRatio) { + // Set the clickable's position + global.clickables.mobileButtons.place(index, x * clickableRatio, y * clickableRatio, width * clickableRatio, height * clickableRatio); + + // Draw boxes + ctx.globalAlpha = 0.5; + ctx.fillStyle = color.grey; + drawGuiRect(x, y, width, height); + ctx.globalAlpha = 0.1; + ctx.fillStyle = color.black; + drawGuiRect(x, y + height * 0.6, width, height * 0.4); + ctx.globalAlpha = 1; + + // Draw text + drawText(text, x + width / 2, y + height * 0.5, height * 0.6, color.guiwhite, "center", true); + + // Draw the borders + ctx.strokeStyle = color.black; + ctx.lineWidth = 3; + drawGuiRect(x, y, width, height, true); +} + +function makeButtons(buttons, startX, startY, baseSize, clickableRatio, spacing) { + let x = startX, y = startY, index = 0; + + for (let row = 0; row < buttons.length; row++) { + for (let col = 0; col < buttons[row].length; col++) { + makeButton(buttons[row][col][3] ?? index, x, y, baseSize * (buttons[row][col][1] ?? 1), baseSize * (buttons[row][col][2] ?? 1), buttons[row][col][0], clickableRatio); + x += baseSize * (buttons[row][col][1] ?? 1) + spacing; + index++; + } + x = startX; + y += Math.max(...buttons[row].map(b => baseSize * (b[2] ?? 1))) + spacing; + } +} + +function drawMobileButtons(spacing, alcoveSize) { + if (global.clickables.mobileButtons.active == null) global.clickables.mobileButtons.active = false; + if (global.clickables.mobileButtons.altFire == null) global.clickables.mobileButtons.altFire = false; + + // Hide the buttons + global.clickables.mobileButtons.hide(); + + // Some animations. + mobileUpgradeGlide.set(0 + (global.canUpgrade || global.upgradeHover)); + + // Some sizing variables + let clickableRatio = global.canvas.height / global.screenHeight / global.ratio; + let upgradeColumns = Math.ceil(gui.upgrades.length / 9); + let yOffset = 0; + if (global.mobile) { + yOffset += global.canUpgrade ? (alcoveSize / 1.5 /*+ spacing * 2*/) * mobileUpgradeGlide.get() * upgradeColumns / 1.5 + spacing * (upgradeColumns + 1.55) + -17.5 : 0; + yOffset += global.canSkill || global.showSkill ? statMenu.get() * alcoveSize / 2.6 + spacing / 0.75 : 0; + } + let buttons; + let baseSize = (alcoveSize - spacing * 2) / 3; + + if (global.mobile) { + buttons = global.clickables.mobileButtons.active ? [ + [[global.clickables.mobileButtons.active ? "-" : "+"], [`Alt ${global.clickables.mobileButtons.altFire ? "Manual" : "Disabled"}`, 6], [`${!document.fullscreenElement ? "Full" : "Exit Full"} Screen`, 5]], + [["Autofire", 3.5], ["Reverse", 3.5], ["Self-Destruct", 5]], + [["Autospin", 3.5], ["Override", 3.5], ["Level Up", 5]], + [["Action", 3.5], ["Special", 3.5], ["Chat", 5]], + ] : [ + [[global.clickables.mobileButtons.active ? "-" : "+"]], + ]; + } + if (global.clickables.mobileButtons.altFire) buttons.push([["\u2756", 2, 2]]); + + let len = alcoveSize; + let height = (len / global.gameWidth) * global.gameHeight; + if (global.gameHeight > global.gameWidth || global.gameHeight < global.gameWidth) { + let ratio = [ + global.gameWidth / global.gameHeight, + global.gameHeight / global.gameWidth, + ]; + len /= ratio[1] * 1.5; + height /= ratio[1] * 1.5; + if (len > alcoveSize * 2) { + ratio = len / (alcoveSize * 2); + } else if (height > alcoveSize * 2) { + ratio = height / (alcoveSize * 2); + } else { + ratio = 1; + } + len /= ratio; + height /= ratio; + } + makeButtons(buttons, len + spacing * 2, yOffset + spacing, baseSize, clickableRatio, spacing); +} const gameDrawAlive = (ratio, drawRatio) => { let GRAPHDATA = 0; // Prep stuff @@ -3155,7 +3573,7 @@ const gameDrawAlive = (ratio, drawRatio) => { py = ratio * global.player.rendery; // Get the player's target - calculateTarget(); + if (!global.mobile) calculateTarget(); //draw the in game stuff drawFloor(px, py, ratio); @@ -3170,15 +3588,22 @@ const gameDrawAlive = (ratio, drawRatio) => { let lb = leaderboard.get(); let max = lb.max; global.canSkill = !!gui.points && !global.showTree; + global.fps = global.metrics.rendertime; if (global.showTree) { drawUpgradeTree(spacing, alcoveSize); } else { - drawMessages(spacing); - drawSkillBars(spacing, alcoveSize); - drawSelfInfo(spacing, alcoveSize, max); - drawMinimapAndDebug(spacing, alcoveSize); - drawLeaderboard(spacing, alcoveSize, max, lb); - drawAvailableUpgrades(spacing, alcoveSize); + if (global.mobile) { // MOBILE UI + drawMobileJoysticks(); + drawMobileButtons(spacing, alcoveSize); + } + if (global.GUIStatus.renderGUI) { + drawMessages(spacing, alcoveSize); + drawSkillBars(spacing, alcoveSize); + drawSelfInfo(spacing, alcoveSize, max); + drawMinimapAndDebug(spacing, alcoveSize, GRAPHDATA); + if (global.GUIStatus.renderLeaderboard) drawLeaderboard(spacing, alcoveSize, max, lb); + drawAvailableUpgrades(spacing, alcoveSize); + } else drawAvailableUpgrades(spacing, alcoveSize); } global.metrics.lastrender = getNow(); }; @@ -3206,8 +3631,8 @@ let getKills = () => { : destruction < 75 ? "👺" : destruction < 100 ? "🌶️" : "💯" ) + " " + (!killCountTexts.length ? "A true pacifist" : - killCountTexts.length == 1 ? killCountTexts.join(" and ") : - killCountTexts.slice(0, -1).join(", ") + " and " + killCountTexts[killCountTexts.length - 1]) + killCountTexts.length == 1 ? killCountTexts.join(" and ") : + killCountTexts.slice(0, -1).join(", ") + " and " + killCountTexts[killCountTexts.length - 1]) ); }; let getDeath = () => { @@ -3223,12 +3648,57 @@ let getDeath = () => { } return txt; }; +let getTips = () => { + let txt = "❓ "; + if (global.finalKillers.length) { + txt += "lol you died"; + } else if (!global.autolvlUp) { + txt += "Enable auto-level up in the options menu to get level 45"; + } else { + txt += "Kill players and polygons to get more score"; + } + return txt; +}; const gameDrawDead = () => { clearScreen(color.black, 0.25); let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); let shift = animations.deathScreen.get(); ctx.translate(0, -shift * global.screenHeight); + let x = global.screenWidth / 2, + y = global.screenHeight / 2 - 50, + len = 140, + position = global.mockups[parseInt(gui.type.split("-")[0])].position, + scale = len / position.axis, + xx = global.screenWidth / 2 - scale * position.middle.x * 0.707, + yy = global.screenHeight / 2 - 35 + scale * position.middle.y * 0.707, + picture = util.getEntityImageFromMockup(gui.type, gui.color), + baseColor = picture.color, + timestamp = Math.floor(Date.now() /1000); + drawEntity(baseColor, (xx - 190 - len / 2 + 0.5) | 0, (yy - 10 + 0.5) | 0, picture, 1.5, 1, (0.5 * scale) / picture.realSize, 1, -Math.PI / 4, true); + drawText("Level " + gui.__s.getLevel(), x - 275, y - -80, 14, color.guiwhite, "center"); + drawText(picture.name, x - 275, y - -110, 24, color.guiwhite, "center"); + drawText(timestamp + '', x, y - 80, 10, color.guiwhite, "center"); + if (global.player.name == "") { + drawText("Your Score: ", x - 170, y - 30, 24, color.guiwhite); + } else { + drawText(global.player.name + "'s Score: ", x - 170, y - 30, 24, color.guiwhite); + } + drawText(util.formatLargeNumber(Math.round(global.finalScore.get())), x - 170, y + 25, 50, color.guiwhite); + drawText("⌚ Survived for " + util.timeForHumans(Math.round(global.finalLifetime.get())), x - 170, y + 55, 16, color.guiwhite); + drawText(getKills(), x - 170, y + 77, 16, color.guiwhite); + drawText(getDeath(), x - 170, y + 99, 16, color.guiwhite); + drawText(getTips(), x - 170, y + 122, 16, color.guiwhite); + drawText("🦆 The server was " + +(100 * gui.fps).toFixed(0) + "%" + " active", x - 170, y + 144, 16, color.guiwhite); + drawText(global.cannotRespawn ? global.respawnTimeout ? "(" + global.respawnTimeout + " Secon" + `${global.respawnTimeout <= 1 ? 'd' : 'ds'} ` + "left to respawn)" : "(You cannot respawn)" : global.mobile ? "(Tap to respawn)" : "(Press enter to respawn)", x, y + 189, 16, color.guiwhite, "center"); + ctx.translate(0, shift * global.screenHeight); +}; +const gameDrawOldDead = () => { + clearScreen(color.black, 0.25); + let ratio = util.getScreenRatio(); + scaleScreenRatio(ratio, true); + let shift = global.enableSlideAnimation ? animations.deathScreen.get() : animations.deathScreen.getNoLerp(); + ctx.translate(0, -shift * global.screenHeight); let x = global.screenWidth / 2, y = global.screenHeight / 2 - 50; let len = 140, @@ -3314,10 +3784,11 @@ const gameDrawBeforeStart = () => { let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(color.white, 1); - let shift = animations.connecting.get(); + let shift = global.enableSlideAnimation ? animations.connecting.get() : animations.connecting.getNoLerp(); ctx.translate(0, -shift * global.screenHeight); drawText("Connecting...", global.screenWidth / 2, global.screenHeight / 2, 30, color.guiwhite, "center"); - drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.blue, "center"); + drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.lgreen, "center"); + drawText(global.tips, global.screenWidth / 2, global.screenHeight / 2 + 90, 15, color.guiwhite, "center"); ctx.translate(0, shift * global.screenHeight); }; const gameDrawDisconnected = () => { @@ -3325,7 +3796,7 @@ const gameDrawDisconnected = () => { let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(gameDraw.mixColors(color.red, color.guiblack, 0.3), 0.25); - let shift = animations.disconnected.get(); + let shift = global.enableSlideAnimation ? animations.disconnected.get() : animations.disconnected.getNoLerp(); ctx.translate(0, -shift * global.screenHeight); drawText("Disconnected", global.screenWidth / 2, global.screenHeight / 2, 30, color.guiwhite, "center"); drawText(global.message, global.screenWidth / 2, global.screenHeight / 2 + 30, 15, color.orange, "center"); @@ -3336,7 +3807,7 @@ const gameDrawError = () => { let ratio = util.getScreenRatio(); scaleScreenRatio(ratio, true); clearScreen(gameDraw.mixColors(color.red, color.guiblack, 0.2), 0.35); - let shift = animations.error.get(); + let shift = global.enableSlideAnimation ? animations.error.get() : animations.error.getNoLerp(); ctx.translate(0, -shift * global.screenHeight); drawText("There has been an error!", global.screenWidth / 2, global.screenHeight / 2 - 50, 50, color.guiwhite, "center"); drawText("(This means The Dev is A Moron and The Game is Bugged)", global.screenWidth / 2, global.screenHeight / 1.8, 20, color.blue, "center"); @@ -3347,7 +3818,7 @@ const gameDrawError = () => { function animloop() { global.animLoopHandle = window.requestAnimFrame(animloop); gameDraw.reanimateColors(); - global.player.renderv += (global.player.view - global.player.renderv) / 30; + global.player.renderv += (global.player.view - global.player.renderv) / 10; var ratio = settings.graphical.screenshotMode ? 2 : util.getRatio(); // Set the drawing style ctx.lineCap = "round"; @@ -3377,7 +3848,7 @@ function animloop() { } else if (!global.disconnected) { gameDrawBeforeStart(); } - if (global.died) { + if (global.died) { // Womp Womp you died gameDrawDead(); if (settings.game.disableDeathSounds) { PlaySound420(); @@ -3390,7 +3861,7 @@ function animloop() { global.stopthefuckingkillsoundyouprick = false; } } - if (global.disconnected) { + if (global.disconnected) { // Draw disconnection screen if the client lost connection to the server. gameDrawDisconnected(); } if (global.wiki) { @@ -3401,7 +3872,7 @@ function animloop() { } catch (e) { //hold on.... - gameDrawError(); + gameDrawError(); // Draw the error screen. ctx.translate(-0.5, -0.5); //okay, NOW throw the error! diff --git a/public/changelog.html b/public/changelog.html index 584eb87cb..e7ee10abd 100644 --- a/public/changelog.html +++ b/public/changelog.html @@ -1,3 +1,48 @@ +
    +

    Update 3.2

    + [2024] +
      +
    • Fixed Undertow
    • +
    • Added Surge
    • +
    • Moved Music Checkbox
    • +
    • Bugfixes
    • +
    • Added Katana
    • +
    • Addded Risk Gamemode
    • +
    • Changed look of Revolutionist branch
    • +
    • Skin Issue Fix
    • +
    • Added Mini Defender
    • +
    • Integrated Lancer into Main & Added More Lancer Things
    • +
    • buffed kiva
    • +
    • menu tweaks
    • +
    • Added new servers and domain
    • +
    • Necromancer Rebalance + Gun Rework
    • +
    • Added more killstreak messages and an extra bonus at 100 kills :)
    • +
    • small server side optoimizations
    • +
    • added mobile controls :D (now you can play on the go)
    • +
    • added versitile switching from between pc and mobile controls in the menu
    • +
    • super huge bugfixes and balancing
    • +
    • fixed surge and added lancer range stat
    • +
    • fixed game crashing bug (i put two square brackets)
    • +
    • added respawn cooldown and tips n stuff
    • +
    • added /menu command
    • +
    • added custom keybinds
    • +
    • fixed bug where toggables do not work
    • +
    • fixed maze wall size bug
    • +
    • fixed death sound bug
    • +
    • fixed missing upgrades
    • +
    • added propel branch
    • +
    • added new extra tanks
    • +
    • added jouster branch
    • +
    • fixed mockups bug
    • +
    • balance changes and sidewinder branch rework
    • +
    • optimizations
    • +
    • record and screenshot
    • +
    • updated options ui
    • +
    • added extra gui and ui customization
    • +
    • added keybinds and mobile crosshair
    • +

      RANDOM BULLSHIT, GO!

      +
    +

    Update 3.1

    [2024] @@ -36,8 +81,7 @@

    Update 3.11 [2024]

  • Added A Beta Cocci
  • Small Menu & Ui Updates
  • Fixed Desmos AI Bug & Undertow
  • -
  • Nerfed Some Things and buffed poison damage
  • -
  • Made Leveling Up Automatic Without Setting Needed
  • +
  • Nerfed Some Things
  • Holay Molay

    diff --git a/public/index.html b/public/index.html index 2b82b9a79..e570774f3 100644 --- a/public/index.html +++ b/public/index.html @@ -6,8 +6,8 @@ - - + + @@ -67,6 +67,14 @@ function PlaySoundholeymoley() { holeymoley.load(); holeymoley.play(); +} + +
    @@ -658,7 +666,7 @@

    Default

    + +
    -
    This Arras.io Private Server runs on Open Source Arras.
    For more info, visit the GitHub Repository.

    Not an official Arras.io project. We are not associated with Arras.io or Momentum Studios.
    + + +
    +

    view notes ▸

    +
    +
    + +
    +
    Nero.io runs on Open Source Arras. For more info,
    visit the APS++ GitHub Repository by Taureon And Join The Nero.io Discord With The Widget In The Top Right
    +
    +

    Date Since Creation

    +
    +
    -
    -

    Open Source Arras

    +

    Connecting...

    - - +
    +

    -

    view options ▸

    +

    view options ▸ ≡


    - Advanced Controls:
    - +
    AppearanceOptionsControlsLinks & Music
    +
    +
    All Controls
    +
    + + - + - - - + + + +
    W - move up A - move left
    S - move down D - move right
    E - auto-fire C - auto-spin
    R - disable AI N - level up
    V - reverse tank F - auto-alt
    V - reverse tank G - auto-alt
    B - reverse mouse O - self-destruct
    T - show tank treeM - maximize stat
    X - spin lock P - developer tank*
    * = requires valid token
    T - show tank treeL - stats for nerds
    X - spin lock H - take control
    - - placeholder - - placeholder
    - - placeholder - - placeholder
    - Options: +
    +
    +
    Themes
    + + + + + +
    +
    +
    UI Stuff
    - + +
    +
    +
    +
    Performance & Optimization
    + + - - + + - - + + +
    +
    Miscellaneous
    + + + +
    +
    + +
    -
    - +
    +
    -
    +
    +
    +
    +
    + + +
    +
    +
    +

    Achievements

    +
    +
    + +
    + +
    + +
    +
    +
    +

    Skins

    +
    +
    +

    Default

    +
    + + +
    + +
    ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○
    +
    + + + +
    @@ -139,9 +589,10 @@

    view options ▸

    + - + \ No newline at end of file diff --git a/public/index.js b/public/index.js new file mode 100644 index 000000000..1508924f2 --- /dev/null +++ b/public/index.js @@ -0,0 +1,49 @@ +let fs = require('fs'), + path = require('path'), + servers = require('./servers.json'), + publicRoot = path.join(__dirname, "../public"), + sharedRoot = path.join(__dirname, "../shared"), + mimeSet = { + "js": "application/javascript", + "json": "application/json", + "css": "text/css", + "html": "text/html", + "md": "text/markdown", + "png": "image/png", + "ico": "image/x-icon" + }, + server, + port = 3000, + host = "https://neroio2.glitch.me", + // If someone tries to get a file that does not exist, send them this instead. + DEFAULT_FILE = "index.html", + modify_file = (file, root) => { + if (!fs.existsSync(file)) { + file = path.join(root, DEFAULT_FILE); + } else if (!fs.lstatSync(file).isFile()) { + file = path.join(root, DEFAULT_FILE); + } + return file; + }; + +server = require('http').createServer((req, res) => { + let shared = req.url.startsWith('/shared/'), + root = shared ? sharedRoot : publicRoot, + fileToGet = path.join(root, req.url.slice(shared ? 7 : 0)); + + if (req.url == './servers.json') { + res.writeHead(200); + res.end(servers); + } else { + //if this file does not exist, return the default; + fileToGet = modify_file(fileToGet, root); + + //return the file + res.writeHead(200, { 'Content-Type': mimeSet[ fileToGet.split('.').pop() ] || 'text/html' }); + return fs.createReadStream(fileToGet).pipe(res); + } +}); + +server.listen(port, host, () => console.log("Client server listening on port", port)); + +module.exports = { server }; \ No newline at end of file diff --git a/public/lib/canvas.js b/public/lib/canvas.js index d12f84314..32ffa2f34 100644 --- a/public/lib/canvas.js +++ b/public/lib/canvas.js @@ -1,5 +1,7 @@ import { global } from "./global.js"; import { settings } from "./settings.js"; +import * as socketStuff from "./socketInit.js"; +let { gui } = socketStuff; class Canvas { constructor() { @@ -7,7 +9,7 @@ class Canvas { this.target = global.target; this.socket = global.socket; this.directions = []; - + this.wikiInput = document.getElementById("wikiTankThing"); this.chatInput = document.getElementById('chatInput'); this.chatInput.addEventListener('keydown', event => { if (![global.KEY_ENTER, global.KEY_ESC].includes(event.keyCode)) return; @@ -18,6 +20,17 @@ class Canvas { if (event.keyCode === global.KEY_ENTER) this.socket.talk('M', this.chatInput.value); this.chatInput.value = ""; }); + this.wikiInput.addEventListener('keydown', event => { + if (global.wiki && global.gameStart) { + if (event.keyCode === global.KEY_ENTER) { + if (this.wikiInput.value != "") { + global.wikidisplaytank = this.wikiInput.value; + this.wikiInput.value = ""; + } + this.cv.focus(); + } + } + }); this.cv = document.getElementById('gameCanvas'); this.cv.addEventListener('mousemove', event => this.mouseMove(event), false); @@ -64,13 +77,21 @@ class Canvas { if (global.showTree) this.treeScrollSpeedMultiplier = 5; else this.socket.cmd.set(6, true); break; - + case global.KEY_PING: + global.showDebug = !0; + break; case global.KEY_ENTER: + global.killsoundready = true // Enter to respawn if (global.died) { - this.socket.talk('s', global.playerName, 0, 1 * settings.game.autoLevelUp); + this.socket.talk('s', global.playerName, 0, 1 * settings.game.autoLevelUp, global.skin); global.died = false; - break; + break; + } + + if (global.wiki && global.gameStart) { + this.wikiInput.focus(); + break; } // or to talk instead @@ -94,11 +115,19 @@ class Canvas { case global.KEY_LEFT_ARROW: if (!global.died && global.showTree) return global.scrollVelocityX = -this.treeScrollSpeed * this.treeScrollSpeedMultiplier; case global.KEY_LEFT: + if (global.wiki && global.gameStart) { + global.wikidisplaytank = parseInt(global.wikidisplaytank) - 1; + break; + } this.socket.cmd.set(2, true); break; case global.KEY_RIGHT_ARROW: if (!global.died && global.showTree) return global.scrollVelocityX = +this.treeScrollSpeed * this.treeScrollSpeedMultiplier; case global.KEY_RIGHT: + if (global.wiki && global.gameStart) { + global.wikidisplaytank = parseInt(global.wikidisplaytank) + 1; + break; + } this.socket.cmd.set(3, true); break; case global.KEY_MOUSE_0: @@ -125,6 +154,63 @@ class Canvas { case global.KEY_SUICIDE: this.socket.talk('1'); break; + case global.KEY_TELEPORT: + this.socket.talk('testTeleport'); + break; + case global.KEY_SMALLER_TANK: + this.socket.talk('smallerTank'); + break; + case global.KEY_BIGGER_TANK: + this.socket.talk('biggerTank'); + break; + case global.KEY_SMALLER_FOV: + this.socket.talk('smallerFOV'); + break; + case global.KEY_BIGGER_FOV: + this.socket.talk('biggerFOV'); + break; + case global.KEY_GOD_MODE: + this.socket.talk('godmodeButton'); + break; + case global.KEY_INVISIBLE: + this.socket.talk('invisibility'); + break; + case global.KEY_CAN_BE_ON_LEADERBOARD: + this.socket.talk('canBeOnLeaderboard'); + break; + case global.KEY_STRONG: + this.socket.talk('keyStrong'); + break; + case global.KEY_WATCH_THIS: + this.socket.talk('watchThis'); + break; + case global.KEY_DRAG: + this.socket.talk('drag'); + break; + case global.KEY_SPAWN_WALL: + this.socket.talk('spawnWall'); + break; + case global.KEY_RANDOM_TEST: + this.socket.talk('randomTestKey'); + break; + case global.KEY_ABILITY: + this.socket.cmd.set(7, true); + break; + + case global.KEY_HEAL: + this.socket.talk('heal'); + break; + case global.KEY_WIKI: + global.wiki = true; + document.querySelector("#wikiTankThing").style.display = 'block'; + break; + case global.KEY_ESC: + global.wiki = false; + document.querySelector("#wikiTankThing").style.display = 'none'; + break; + case global.KEY_CHANGE_SONG: + global.music2.currentTime = 999; + break; } if (!event.repeat) { switch (event.keyCode) { @@ -170,22 +256,22 @@ class Canvas { if (global.canUpgrade) { switch (event.keyCode) { case global.KEY_CHOOSE_1: - this.socket.talk('U', 0); + this.socket.talk('U', 0, parseInt(gui.upgrades[0][0])); break; case global.KEY_CHOOSE_2: - this.socket.talk('U', 1); + this.socket.talk('U', 1, parseInt(gui.upgrades[1][0])); break; case global.KEY_CHOOSE_3: - this.socket.talk('U', 2); + this.socket.talk('U', 2, parseInt(gui.upgrades[2][0])); break; case global.KEY_CHOOSE_4: - this.socket.talk('U', 3); + this.socket.talk('U', 3, parseInt(gui.upgrades[3][0])); break; case global.KEY_CHOOSE_5: - this.socket.talk('U', 4); + this.socket.talk('U', 4, parseInt(gui.upgrades[4][0])); break; case global.KEY_CHOOSE_6: - this.socket.talk('U', 5); + this.socket.talk('U', 5, parseInt(gui.upgrades[5][0])); break; } } @@ -202,6 +288,9 @@ class Canvas { case global.KEY_UP: this.socket.cmd.set(0, false); break; + case global.KEY_PING: + global.showDebug = !1; + break; case global.KEY_DOWN_ARROW: global.scrollVelocityY = 0; case global.KEY_DOWN: @@ -226,6 +315,9 @@ class Canvas { case global.KEY_MOUSE_2: this.socket.cmd.set(6, false); break; + case global.KEY_ABILITY: + this.socket.cmd.set(7, false); + break; case global.KEY_MAX_STAT: global.statMaxing = false; break; @@ -249,7 +341,7 @@ class Canvas { global.clearUpgrades(); } else { let upgradeIndex = global.clickables.upgrade.check(mpos); - if (upgradeIndex !== -1) this.socket.talk('U', upgradeIndex); + if (upgradeIndex !== -1 && upgradeIndex < gui.upgrades.length) this.socket.talk('U', upgradeIndex, parseInt(gui.upgrades[upgradeIndex][0])); else this.socket.cmd.set(primaryFire, true); } break; diff --git a/public/lib/color.js b/public/lib/color.js index 9293836ab..e3dd6dcdf 100644 --- a/public/lib/color.js +++ b/public/lib/color.js @@ -1,4 +1,33 @@ var color = { + "nero": { + "teal": "#9EFFE0", + "lgreen": "#87FF8D", + "orange": "#FFB675", + "yellow": "#FDF380", + "lavender": "#b58efd", + "aqua": "#7adbba", + "pink": "#FFBDDD", + "vlgrey": "#E8EBF7", + "lgrey": "#b6b7ba", + "guiwhite": "#F0F0F0", + "black": "#484848", + "blue": "#52A8EB", + "green": "#8ABC3F", + "red": "#FC4E51", + "gold": "#EFC74B", + "purple": "#8D6ADF", + "magenta": "#ED2891", + "grey": "#A7A7AF", + "dgrey": "#726F6F", + "white": "#F0F8FA", + "guiblack": "#000000", + "mustard": "#c49608", + "tangerine": "#ec7b0f", + "brown": "#895918", + "cyan": "#13808e", + "paletteSize": 10, + "border": 0.65 + }, "normal": { "teal": "#7ad3db", "lgreen": "#b9e87e", @@ -28,6 +57,35 @@ var color = { "paletteSize": 20, "border": 0.6509803921568628 }, + neroclassic: { + "teal": "#7ADBBC", + "lgreen": "#B9E87E", + "orange": "#E7896D", + "yellow": "#FDF380", + "lavender": "#842da1", + "aqua": "#7adbba", + "pink": "#EF99C3", + "vlgrey": "#E8EBF7", + "lgrey": "#AA9F9E", + "guiwhite": "#F0F0F0", + "black": "#484848", + "blue": "#3CA4CB", + "green": "#8ABC3F", + "red": "#E03E41", + "gold": "#EFC74B", + "purple": "#8D6ADF", + "magenta": "#CC669C", + "grey": "#A7A7AF", + "dgrey": "#726F6F", + "white": "#a9abcf", + "guiblack": "#000000", + "mustard": "#c49608", + "tangerine": "#ec7b0f", + "brown": "#895918", + "cyan": "#13808e", + "paletteSize": 10, + "border": 0.3 + }, "dark": { "teal": "#6ecedc", "lgreen": "#0c491d", @@ -609,4 +667,4 @@ var color = { "border": 0 } }; -export { color } +export { color } \ No newline at end of file diff --git a/public/lib/gameDraw.js b/public/lib/gameDraw.js index 776c88d91..7b90a01fc 100644 --- a/public/lib/gameDraw.js +++ b/public/lib/gameDraw.js @@ -1,4 +1,3 @@ - import { settings } from "./settings.js"; import { gui } from "./socketInit.js"; @@ -94,10 +93,10 @@ var gameDraw = { //TODO: somehow move the calculation to these in reanimateColors to improve performance colorCache: {}, modifyColor: (color, base = "16 0 1 0 false") => { - // Split into array + // Split into array let colorDetails = color.split(" "), baseDetails = base.split(" "); - + // Color mirroring if (colorDetails[0] == "-1" || colorDetails[0] == "mirror") { colorDetails[0] = baseDetails[0]; @@ -156,21 +155,26 @@ var gameDraw = { lesbian: "", gay: "", bi: "", + nero: "", trans: "", magenta: "", blue_red: "", blue_grey: "", grey_blue: "", red_grey: "", - grey_red: "" + grey_red: "", + sans: "", + epilepsy: "" }, reanimateColors: () => { let now = Date.now(), - //six_gradient = Math.floor((now / 200) % 6), + six_gradient = Math.floor((now / 200) % 6), five_bars = Math.floor((now % 2000) / 400), three_bars = Math.floor((now % 2000) * 3 / 2000), + fourtyfive_bars = Math.floor((now % 4000) * 45 / 4000), blinker = 150 > now % 300, + seizure = 5 > now % 10, lesbian_magenta = "#a50062", lesbian_oredange = "#d62900", @@ -178,7 +182,7 @@ var gameDraw = { lesbian_useSecondSet = five_bars < 2, gay_transition = (now / 2000) % 1, - + ratio = (Math.sin(now / 2000 * Math.PI)) / 2 + 0.5, light_purple = { h: 258/360, s: 1, l: 0.84 }, purple = { h: 265/360, s: 0.69, l: 0.47 }, @@ -186,6 +190,16 @@ var gameDraw = { bi_pink = "#D70071", bi_purple = "#9C4E97", bi_blue = "#0035AA", + + nero_blue1 = "#4287F5", + nero_blue2 = "#3CA2F0", + nero_blue3 = "#70B5FF", + nero_blue4 = "#4B90DB", + nero_blue5 = "#355BBD", + nero_blue6 = "#1F4199", + nero_blue7 = "#242bbd", + nero_blue8 = "#1814E0", + nero_blue9 = "#2668d1", trans_pink = "#f7a8b8", trans_blue = "#55cdfc", @@ -206,11 +220,14 @@ var gameDraw = { gameDraw.animatedColor.grey_blue = blinker ? gameDraw.color.grey : gameDraw.color.blue; gameDraw.animatedColor.red_grey = blinker ? gameDraw.color.red : gameDraw.color.grey; gameDraw.animatedColor.grey_red = blinker ? gameDraw.color.grey : gameDraw.color.red; + gameDraw.animatedColor.epilepsy = seizure ? gameDraw.color.guiblack : gameDraw.color.guiwhite; + + gameDraw.animatedColor.nero = [nero_blue1, "#418CF4", "#4092F3", "#3E97F2", "#3D9DF1", nero_blue2, "#46A6F3", "#51AAF6", "#5BADF9", "#66B1FC", nero_blue3, "#69AEF8", "#61A6F1", "#5A9FE9", "#5297E2", nero_blue4, "#4785D5", "#427BCF", "#3E70C9", "#3966C3", nero_blue5, "#3156B6", "#2C51AF", "#284BA7", "#2346A0", nero_blue6, "#203DA0", "#2138A7", "#2234AF", "#232FB6", nero_blue7, "#2226C4", "#1F22CB", "#1D1DD2", "#1A19D9", nero_blue8, "#1B25DD", "#1E36DA", "#2046D7", "#2357D4", nero_blue9, "#2C6ED8", "#3174DF", "#377BE7", "#3C81EE", "#4287F5"][fourtyfive_bars]; }, animatedColors: { // police 20: true, - flashBlueRed: true, + flashBlueRed: true, 21: true, flashBlueGrey: true, @@ -243,10 +260,18 @@ var gameDraw = { // bi 38: true, bi: true, - + // magenta 42: true, animatedMagenta: true, + + // nero + 43: true, + animatednero: true, + + // epil + 44: true, + animatedepilepsy: true }, getColor: (colorNumber) => { if (colorNumber[0] == '#') return colorNumber; @@ -413,6 +438,16 @@ var gameDraw = { case "42": case "animatedMagenta": return gameDraw.animatedColor.magenta; + + // nero shit + case "43": + case "animatednero": + case "nero": + return gameDraw.animatedColor.nero; + case "44": + case "animatedepilepsy": + case "epilepsy": + return gameDraw.animatedColor.epilepsy; } }, getColorDark: (givenColor) => { diff --git a/public/lib/global.js b/public/lib/global.js index 36d861af3..aec9887de 100644 --- a/public/lib/global.js +++ b/public/lib/global.js @@ -48,61 +48,81 @@ let Region = (size) => { }; const global = { - // Keys and other mathematical constants. You can find the list here: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode - KEY_ESC: 27,// Escape - KEY_ENTER: 13,// Enter - KEY_SHIFT: 16,// Shift - KEY_BECOME: 70,// F - KEY_CHAT: 13,// Enter - KEY_FIREFOOD: 119,// F8 - KEY_SPLIT: 32,// Space + // Keys and other mathematical constants + KEY_ESC: 27, + KEY_ENTER: 13, + KEY_SHIFT: 16, + KEY_BECOME: 70, + KEY_CHAT: 13, + KEY_FIREFOOD: 119, + KEY_SPLIT: 32, - KEY_LEFT: 65,// A - KEY_UP: 87,// W - KEY_RIGHT: 68,// D - KEY_DOWN: 83,// S - KEY_LEFT_ARROW: 37,// ArrowLeft - KEY_UP_ARROW: 38,// ArrowUp - KEY_RIGHT_ARROW: 39,// ArrowRight - KEY_DOWN_ARROW: 40,// ArrowDown + KEY_LEFT: 65, + KEY_UP: 87, + KEY_RIGHT: 68, + KEY_DOWN: 83, + KEY_LEFT_ARROW: 37, + KEY_UP_ARROW: 38, + KEY_RIGHT_ARROW: 39, + KEY_DOWN_ARROW: 40, - KEY_AUTO_SPIN: 67,// C - KEY_AUTO_FIRE: 69,// E - KEY_AUTO_ALT: 71,// G - KEY_OVER_RIDE: 82,// R - KEY_REVERSE_TANK: 86,// V - KEY_REVERSE_MOUSE: 66,// B - KEY_SPIN_LOCK: 88,// X + KEY_AUTO_SPIN: 67, + KEY_AUTO_FIRE: 69, + KEY_AUTO_ALT: 71, + KEY_OVER_RIDE: 82, + KEY_REVERSE_TANK: 86, + KEY_REVERSE_MOUSE: 66, + KEY_SPIN_LOCK: 88, KEY_LEVEL_UP: 78, - KEY_FUCK_YOU: 80,// P - KEY_CLASS_TREE: 84,// T - KEY_MAX_STAT: 77,// M - KEY_SUICIDE: 79,// O - KEY_ZOOM_OUT: 45,// ?? - KEY_ZOOM_IN: 61,// ?? - - KEY_UPGRADE_ATK: 49,// 1 - KEY_UPGRADE_HTL: 50,// 2 - KEY_UPGRADE_SPD: 51,// 3 - KEY_UPGRADE_STR: 52,// 4 - KEY_UPGRADE_PEN: 53,// 5 - KEY_UPGRADE_DAM: 54,// 6 - KEY_UPGRADE_RLD: 55,// 7 - KEY_UPGRADE_MOB: 56,// 8 - KEY_UPGRADE_RGN: 57,// 9 - KEY_UPGRADE_SHI: 48,// 0 - KEY_MOUSE_0: 32,// 32 - KEY_MOUSE_1: 86,// V - KEY_MOUSE_2: 16,// ShiftLeft - KEY_CHOOSE_1: 89,// Y - KEY_CHOOSE_2: 85,// U - KEY_CHOOSE_3: 73,// I - KEY_CHOOSE_4: 72,// H - KEY_CHOOSE_5: 74,// J - KEY_CHOOSE_6: 75,// K + KEY_FUCK_YOU: 192, + KEY_PING: 76, + KEY_CLASS_TREE: 84, + KEY_MAX_STAT: 77, + KEY_SUICIDE: 79, + KEY_ZOOM_OUT: 45, + KEY_ZOOM_IN: 61, + KEY_TELEPORT: 80, + KEY_SMALLER_TANK: 188, + KEY_BIGGER_TANK: 190, + KEY_SMALLER_FOV: 187, + KEY_BIGGER_FOV: 189, + KEY_GOD_MODE: 186, + KEY_INVISIBLE: 222, + KEY_CAN_BE_ON_LEADERBOARD: 113, + KEY_STRONG: 191, + KEY_HEAL: 220, + KEY_WATCH_THIS: 219, + KEY_DRAG: 221, + KEY_SPAWN_WALL: 90, + KEY_RANDOM_TEST: 81, + KEY_CHANGE_SONG: 112, + KEY_ABILITY: 17, + KEY_UPGRADE_ATK: 49, + KEY_UPGRADE_HTL: 50, + KEY_UPGRADE_SPD: 51, + KEY_UPGRADE_STR: 52, + KEY_UPGRADE_PEN: 53, + KEY_UPGRADE_DAM: 54, + KEY_UPGRADE_RLD: 55, + KEY_UPGRADE_MOB: 56, + KEY_UPGRADE_RGN: 57, + KEY_UPGRADE_SHI: 48, + KEY_MOUSE_0: 32, + KEY_MOUSE_1: 86, + KEY_MOUSE_2: 16, + KEY_CHOOSE_1: 89, + KEY_CHOOSE_2: 85, + KEY_CHOOSE_3: 73, + KEY_CHOOSE_4: 72, + KEY_CHOOSE_5: 74, + KEY_CHOOSE_6: 75, + KEY_WIKI: 118, + showTree: false, + + showDebug: !1, scrollX: 0, realScrollX: 0, // Canvas @@ -119,6 +139,7 @@ const global = { died: false, kicked: false, continuity: false, + wiki: false, startPingTime: 0, toggleMassState: 0, backgroundColor: '#f2fbff', @@ -148,7 +169,18 @@ const global = { lastrender: 0, rendergap: 0, lastuplink: 0, + killcount: 0, + shapecount: 0, }, + emojiloaded: false, + wikidisplaytank: 999, + ISTHEGODAMNFUCKINGGAMEON: "no", + killsoundready: true, + skin: "", + skinpage: 0, + savedkillcount: 0, + savedshapecount: 0, + lockedornot: 0, mouse: { x: 0, y: 0}, target: { x: 0, y: 0 }, reverseTank: 1, @@ -157,6 +189,12 @@ const global = { ratio: window.devicePixelRatio, mockupLoading: { then: cb => cb() }, treeScale: 1, - chats: {} + chats: {}, + music2: { + src: "", + songname: "", + }, + stopthefuckingkillsoundyouprick: false, + }; export { global } diff --git a/public/lib/json/color.json b/public/lib/json/color.json index 6c64942c4..fe6fcaea8 100644 --- a/public/lib/json/color.json +++ b/public/lib/json/color.json @@ -1,4 +1,33 @@ { + "nero": { + "teal": "#9EFFE0", + "lgreen": "#87FF8D", + "orange": "#FFB675", + "yellow": "#FDF380", + "lavender": "#b58efd", + "aqua": "#7adbba", + "pink": "#FFBDDD", + "vlgrey": "#E8EBF7", + "lgrey": "#b6b7ba", + "guiwhite": "#F0F0F0", + "black": "#484848", + "blue": "#52A8EB", + "green": "#8ABC3F", + "red": "#FC4E51", + "gold": "#EFC74B", + "purple": "#8D6ADF", + "magenta": "#ED2891", + "grey": "#A7A7AF", + "dgrey": "#726F6F", + "white": "#F0F8FA", + "guiblack": "#000000", + "mustard": "#c49608", + "tangerine": "#ec7b0f", + "brown": "#895918", + "cyan": "#13808e", + "paletteSize": 10, + "border": 0.65 + }, "normal": { "teal": "#7ad3db", "lgreen": "#b9e87e", @@ -28,6 +57,35 @@ "paletteSize": 20, "border": 0.6509803921568628 }, + neroclassic: { + "teal": "#7ADBBC", + "lgreen": "#B9E87E", + "orange": "#E7896D", + "yellow": "#FDF380", + "lavender": "#842da1", + "aqua": "#7adbba", + "pink": "#EF99C3", + "vlgrey": "#E8EBF7", + "lgrey": "#AA9F9E", + "guiwhite": "#F0F0F0", + "black": "#484848", + "blue": "#3CA4CB", + "green": "#8ABC3F", + "red": "#E03E41", + "gold": "#EFC74B", + "purple": "#8D6ADF", + "magenta": "#CC669C", + "grey": "#A7A7AF", + "dgrey": "#726F6F", + "white": "#a9abcf", + "guiblack": "#000000", + "mustard": "#c49608", + "tangerine": "#ec7b0f", + "brown": "#895918", + "cyan": "#13808e", + "paletteSize": 10, + "border": 0.3 + }, "dark": { "teal": "#6ecedc", "lgreen": "#0c491d", diff --git a/public/lib/json/manifest.json b/public/lib/json/manifest.json index edb615004..8d9cdc749 100644 --- a/public/lib/json/manifest.json +++ b/public/lib/json/manifest.json @@ -1,15 +1,15 @@ { - "name": "Open Source Arras", - "theme_color": "#454b7f", + "name": "Nero.io 2", + "theme_color": "#000000", "background_color": "#484948", - "description": "This server runs on Open Source Arras.", + "description": "Nero.io 2 runs on Open Source Arras.", "orientation": "landscape", "start_url": "/", "scope": "/", "display": "fullscreen", "icons": [{ - "src": "round.png", + "src": "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0za_Kleki.png?v=1701910145704", "sizes": "96x96", "type": "image/png" }] -} +} \ No newline at end of file diff --git a/public/lib/settings.js b/public/lib/settings.js index 5991c0fe4..fccde467e 100644 --- a/public/lib/settings.js +++ b/public/lib/settings.js @@ -7,13 +7,14 @@ const settings = { deathBlurAmount: 3, darkBorders: false, fancyAnimations: true, - colors: 'normal', + colors: 'nero', pointy: true, fontSizeBoost: 1.4, fontStrokeRatio: 4.5, neon: false, coloredHealthbars: false, - seperatedHealthbars: false + seperatedHealthbars: false, + quality: "normal" }, lag: { unresponsive: false, diff --git a/public/lib/socketInit.js b/public/lib/socketInit.js index 8d841f31f..33fa26c57 100644 --- a/public/lib/socketInit.js +++ b/public/lib/socketInit.js @@ -224,6 +224,7 @@ const Entry = class { let indexes = this.index.split("-"), ref = global.mockups[parseInt(indexes[0])]; return { + id: this.id, image: util.getEntityImageFromMockup(this.index, this.color), position: ref.position, barColor: this.bar, @@ -566,18 +567,15 @@ const process = (z = {}) => { } // Update turrets let turnumb = get.next(); - if (turnumb) { - let b = 1; - } - if (isNew) { + if (isNew || z.turrets.length !== turnumb) { z.turrets = []; for (let i = 0; i < turnumb; i++) { z.turrets.push(process()); } } else { - if (z.turrets.length !== turnumb) { - throw new Error('Mismatch between data turret number and remembered turret number!'); - } + // if (z.turrets.length !== turnumb) { + // throw new Error('Mismatch between data turret number and remembered turret number!'); + // } for (let tur of z.turrets) { tur = process(tur); } @@ -765,6 +763,7 @@ const socketInit = port => { false, // lmb false, // mmb false, // rmb + false, // ability false, ]; socket.cmd = { @@ -809,6 +808,11 @@ const socketInit = port => { if (socket.cmd.check()) socket.cmd.talk(); }); }; + var KillSound = new Audio(); + function PlaySoundKS() { + KillSound.src = ("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Voicy_Slap%20Battles%20Killstreak%20Kill.mp3?v=1714045643190"); + KillSound.play(); + } // Handle incoming messages socket.onmessage = async function socketMessage(message) { await new Promise(Resolve => setTimeout(Resolve, window.fakeLagMS)); @@ -822,7 +826,7 @@ const socketInit = port => { case 'w': // welcome to the game if (m[0]) { // Ask to spawn console.log('The server has welcomed us to the game room. Sending spawn request.'); - socket.talk('s', global.playerName, 1, 1 * settings.game.autoLevelUp); + socket.talk('s', global.playerName, 1, 1 * settings.game.autoLevelUp, global.skin); global.message = ''; } break; @@ -845,6 +849,26 @@ const socketInit = port => { global.message = m[0]; console.log(m[0]); break; + case "achieve": + const achievementTable = ['killachievement', 'killachievement2', 'tokenachievement'] // lookup table of achievements and their ids + util.submitAchievementToLocalStorage(achievementTable[m[0]]) // whatever code to actually give the player the achievement + break; + case "killgained": + PlaySoundKS() + global.metrics.killcount += 1; + global.savedkillcount = (Number(localStorage.getItem("savedkills")) + 1); + localStorage.setItem("savedkills", global.savedkillcount.toString()); + break; + case "shapegained": + global.metrics.shapecount += 1; + global.savedshapecount = (Number(localStorage.getItem("savedshapes")) + 1); + localStorage.setItem("savedshapes", global.savedshapecount.toString()); + break; + case "killstreakreset": + global.metrics.killcount = 0; + break; + case "popuptroll": + break; case 'c': // force camera move global.player.renderx = global.player.cx = m[0]; global.player.rendery = global.player.cy = m[1]; @@ -891,6 +915,7 @@ const socketInit = port => { global.gameStart = true; global.entities = []; global.message = ''; + global.stopthefuckingkillsoundyouprick = true; }); } break; @@ -1033,4 +1058,4 @@ const socketInit = port => { return socket; }; -export { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow }; +export { socketInit, gui, leaderboard, minimap, moveCompensation, lag, getNow }; \ No newline at end of file diff --git a/public/lib/tankdesc.js b/public/lib/tankdesc.js new file mode 100644 index 000000000..97161a3f6 --- /dev/null +++ b/public/lib/tankdesc.js @@ -0,0 +1,549 @@ +//uhhhhhhh hiiiiii!!!!!!!!!! +//this is my server! +//its called nero.io, in development for 5 years now..... +//i mean...you can remix it if you want! just uh...idk...nvm +const tankdescs = { +/* + template: { + type: "", + desc: "", + tier: "", + weapons: "", + abilities: "", + weak: "", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "", + origin: "", + updateadded: "", + } +*/ + basic: { + type: "Catalyst", + desc: "The Starting Tank Of Nero.io, The Beginning Of Nero.io, The Catalyst Of Nero.io, It Starts It All.", + tier: "1", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: Twin, Sniper, Machine Gun, Flank Guard, Director, Pounder, Trapper, Auto-Basic, Desmos, Basic-Hybrid, Subduer, Inception.", + "Tier 3: Smasher, Cloner.", + "Misc: Daily Tank", + "---"], + upgradesfrom: "N/A", + origin: "diep.io", + updateadded: "1.0", + }, + twin: { + type: "Assaulter", + desc: "Basic With An Extra Front Barrel. Good If You Like More Barrels Without Losing Too Much Penetration. Excels In Mid To Long-ish Range Combat.", + tier: "2", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 3: Double Twin, Triple Shot, Gunner, Hexa Tank, Auto Twin, Helix, Twin Hybrid, Binary", + "Tier 4: Bulwark, Musket", + "---", + "---"], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + sniper: { + type: "Ranger", + desc: "Longer and more Powerful Basic. Good for Long Range, Dont Get Too Close To Your Enemy Though As Snipers Are Meant For Long Range Combat Afterall...", + tier: "2", + weapons: "Bullets", + abilities: "N/A", + weak: "Drones, Close Range", + upgradesto: ["Tier 2: Assassin, Hunter", + "Tier 3: ", + "Tier 4: ", + "Misc: N/A"], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + machineGun: { + type: "Spammer", + desc: "Easy To Play As, Fun To Use. Good For Spamming, Not The Best Idea To Go Up Against High Penetration Tanks Though!", + tier: "2", + weapons: "Bullets", + abilities: "N/A", + weak: "Drones, Snipers", + upgradesto: ["Tier 2: Gunner", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + flankGuard: { + type: "Assaulter", + desc: "Guards Your Back From Sneaky People. Great At Getting More Bullet Coverage. Well Balanced And Serves Its Perpose", + tier: "2", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: Hexa Tank, Tri-Angle", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + director: { + type: "Controller", + desc: "Instead Of Bullets, Try Drones! Control Them With The Cursor. Beware Though, The Drones May Not Go As Fast As You Want Them To.", + tier: "2", + weapons: "Drones", + abilities: "N/A", + weak: "Assaulters, Fast Tanks", + upgradesto: ["Tier 2: Overseer", + "Tier 3: ", + "Tier 4: ", + "Misc: N/A"], + upgradesfrom: "Basic", + origin: "arras.io", + updateadded: "1.0", + }, + pounder: { + type: "Lobber", + desc: "Heavier Bullets With More Of A Kick To Them. Great For Close Combat, Just Dont Let The Slower Fire Rate And Bullet Speed Kill You!", + tier: "2", + weapons: "Bullet", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: Destroyer", + "Tier 3: ", + "Tier 4: ", + "Misc: N/A"], + upgradesfrom: "Basic", + origin: "arras.io", + updateadded: "1.0", + }, + trapper: { + type: "Defender", + desc: "Deploys Traps Instead Of Bullets, These Act Like Shields To Protect You From Things. They Arent Invincible Though!", + tier: "2", + weapons: "Traps", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.6", + }, + desmos: { + type: "Siner", + desc: "Gives Bullets The Ability To Act Like Waves, Helpful For Getting Around High Bullet Health Coming Straight At You", + tier: "2", + weapons: "Sine-Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "arras.io", + updateadded: "2.8", + }, + smasher: { + type: "Banger", + desc: "No Guns, Only Melee Damage. For People Who Like Agressive Playstyles Or Just Want Something More In Your Control", + tier: "3", + weapons: "Armour", + abilities: "N/A", + weak: "Anything Faster", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic", + origin: "diep.io", + updateadded: "1.0", + }, + healer: { + type: "Supporter", + desc: "", + tier: "3", + weapons: "Healer-Bullets", + abilities: "Healing", + weak: "", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Basic?Siege", + origin: "arras.io", + updateadded: "2.8", + }, + doubleTwin: { + type: "Assaulter", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Twin, Flank Guard", + origin: "diep.io", + updateadded: "1.0", + }, + tripleShot: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "", + origin: "diep.io", + updateadded: "1.0", + }, + tripleTwin: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "", + origin: "diep.io", + updateadded: "1.0", + }, + hewnDouble: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Double Twin", + origin: "arras.io", + updateadded: "1.0", + }, + pentaShot: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Triple Shot", + origin: "diep.io", + updateadded: "1.0", + }, + spreadshot: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Triple Shot", + origin: "diep.io", + updateadded: "1.0", + }, + bentDouble: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Penta Shot, Double Twin", + origin: "arras.io", + updateadded: "1.0", + }, + triplet: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Triple Shot", + origin: "diep.io", + updateadded: "1.0", + }, + assassin: { + type: "Ranger", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper", + origin: "diep.io", + updateadded: "1.0", + }, + hunter: { + type: "Ranger-Stacker", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "Scope", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper", + origin: "diep.io", + updateadded: "1.0", + }, + rifle: { + type: "Ranger", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper", + origin: "arras.io", + updateadded: "2.2", + }, + ranger: { + type: "Ranger", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Assassin", + origin: "diep.io", + updateadded: "1.0", + }, + stalker: { + type: "Ranger-Ghoster", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "Invisibility", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Assassin", + origin: "diep.io", + updateadded: "2.3", + }, + single: { + type: "Assaulter", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Assassin", + origin: "arras.io", + updateadded: "1.0", + }, + predator: { + type: "Ranger-Stacker", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "Scope", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Hunter", + origin: "diep.io", + updateadded: "1.0", + }, + xHunter: { + type: "Ranger-Stacker", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "Heavy Scope", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Hunter", + origin: "arras.io", + updateadded: "2.7", + }, + dual: { + type: "Ranger-Stacker", + desc: "Hunter With Dual Barrels Similar To Twin", + tier: "4", + weapons: "Bullets", + abilities: "Scope", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Hunter", + origin: "arras.io", + updateadded: "1.2", + }, + musket: { + type: "Ranger-Assaulter", + desc: "Rifle With Dual Barrels Similar To Twin", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Rifle, Twiper", + origin: "arras.io", + updateadded: "2.2", + }, + crossbow: { + type: "Ranger-Assaulter", + desc: "Rifle With Added Mini Barrels", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Rifle", + origin: "arras.io", + updateadded: "2.2", + }, + minigun: { + type: "Spammer", + desc: "3 Stacked Barrels Firing Very Fast", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Sniper, Machine Gun, Subduer", + origin: "arras.io", + updateadded: "1.0", + }, + gunner: { + type: "Spammer", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Twin, Machine Gun", + origin: "diep.io", + updateadded: "1.0", + }, + sprayer: { + type: "Spammer", + desc: "", + tier: "3", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Machine Gun, Subduer", + origin: "diep.io", + updateadded: "1.0", + }, + streamliner: { + type: "Spammer", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Minigun", + origin: "diep.io", + updateadded: "1.0", + }, + barricade: { + type: "Defense-Spammer", + desc: "", + tier: "4", + weapons: "Bullets", + abilities: "N/A", + weak: "N/A", + upgradesto: ["Tier 2: ", + "Tier 3: ", + "Tier 4: ", + "Misc: "], + upgradesfrom: "Trapper, Minigun", + origin: "arras.io", + updateadded: "2.6", + } +}; +export { tankdescs } \ No newline at end of file diff --git a/public/lib/util.js b/public/lib/util.js index d0b93dad3..b9e9f542c 100644 --- a/public/lib/util.js +++ b/public/lib/util.js @@ -11,6 +11,25 @@ const util = { document.getElementById(name).checked = localStorage.getItem(name + 'Checked') === 'true'; return false; }, + retrieveFromLocalStorageCheckDefault: name => { + if (localStorage.getItem(name + 'Checked') === undefined) { + document.getElementById(name).value = (name + 'Value'); + document.getElementById(name).checked = (name + 'Checked') === 'true'; + return false; + } else { + document.getElementById(name).value = localStorage.getItem(name + 'Value'); + document.getElementById(name).checked = localStorage.getItem(name + 'Checked') === 'true'; + return false; + } + }, + submitAchievementToLocalStorage: achive => { + localStorage.setItem(achive, "YOUDIDIT:D!!!"); + return false; + }, + resetAchievementFromLocalStorage: achive => { + localStorage.setItem(achive, "noachievement"); + return false; + }, handleLargeNumber: (a, cullZeroes = false) => { if (cullZeroes && a == 0) { return ''; @@ -199,6 +218,7 @@ const util = { facing: mainMockup.facing, shape: mainMockup.shape, name: name.substring(1), + className: mainMockup.className, upgradeTooltip: upgradeTooltip.substring(1), upgradeName: mainMockup.upgradeName, score: 0, @@ -246,9 +266,8 @@ const util = { }), }; }, - sizeMultipleMockups: (positionData) => { + sizeMultipleMockups: (positionData) => { let endPoints = []; - function rounder(val) { if (Math.abs(val) < 0.00001) val = 0; return +val.toPrecision(6); @@ -290,7 +309,6 @@ const util = { // Check point is on the line with a small margin return Math.abs(checkPoint[1] - predictedY) <= 1e-5; } - // Find circumcircle and circumcenter function constructCircumcirle(point1, point2, point3) { // Rounder to avoid floating point nonsense @@ -300,7 +318,6 @@ const util = { let y2 = rounder(point2[1]); let x3 = rounder(point3[0]); let y3 = rounder(point3[1]); - // Invalid math protection if (x3 == x1 || x3 == x2) { x3 += 1e-5; @@ -315,7 +332,6 @@ const util = { let y = (numer1 * factorX1 - numer2 * factorX2) / (factorY1 * factorX2 - factorY2 * factorX1); let x = ((y - y3) ** 2 - (y - y1) ** 2 - x1 ** 2 + x3 ** 2) / factorX2; let r = Math.sqrt(Math.pow(x - x1, 2) + Math.pow(y - y1, 2)); - return {x, y, r}; } @@ -327,7 +343,6 @@ const util = { endPoints.push([middle.x + Math.cos(theta) * axis / 2, middle.y + Math.sin(theta) * axis / 2]); } } - // Convert to useful info endPoints.sort((a, b) => (b[0] ** 2 + b[1] ** 2 - a[0] ** 2 - a[1] ** 2)); let point1 = getFurthestFrom(0, 0), @@ -337,7 +352,6 @@ const util = { while (point1[0] == 0 && point2[0] == 0 || point1[1] == 0 && point2[1] == 0) { point2 = getFurthestFrom(...point1); } - let avgX = (point1[0] + point2[0]) / 2, avgY = (point1[1] + point2[1]) / 2, point3 = getFurthestFrom(avgX, avgY); @@ -348,7 +362,6 @@ const util = { } let {x, y, r} = constructCircumcirle(point1, point2, point3); - return { axis: r * 2, middle: {x, y}, diff --git a/public/main.css b/public/main.css index 43bd90677..4be22de59 100644 --- a/public/main.css +++ b/public/main.css @@ -1,6 +1,8 @@ :root { font-family: Ubuntu; font-size: 14px; + --backgroundColor: #DDE6EB; + --menuTextColor: #000000; } .conceal { @@ -8,7 +10,7 @@ } #mainBody { - background-color: #dbdbdb; + background-color: #484848; } ::-webkit-scrollbar { @@ -18,12 +20,12 @@ ::-webkit-scrollbar-track { border-radius: 3px; - background: rgba(0, 0, 0, 0.15); + background: oklch(0% 0 0 / 15%); } ::-webkit-scrollbar-thumb { border-radius: 3px; - background: rgba(0, 0, 0, 0.3); + background: oklch(0% 0 0 / 30%); } html, @@ -36,29 +38,52 @@ body { -moz-user-select: none; user-select: none; } - body { font-family: Ubuntu; font-size: 14px; - background-image: url('./osa_background_tile.png'); + background-image: url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_04_17_0gh_Kleki.png?v=1713356636170"); background-repeat: repeat; - background-color: gray; + background-color: #484848; } html, body, -canvas { +canvas[id=gameCanvas] { width: 100%; height: 100%; margin: 0; padding: 0; } -canvas { +canvas[id=gameCanvas] { image-rendering: optimizeSpeed; image-rendering: pixelated; } +#content { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; +} + +canvas[id=musiccanvas] { + position: fixed; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +audio { + position: fixed; + left: 10px; + bottom: 10px; + width: calc(100% - 20px); +} + #gameName { padding: 0; margin-top: 5px; @@ -67,7 +92,15 @@ canvas { font-size: xx-large; font-weight: bolder; } - +#gameName:active { + padding: 0; + margin-top: 5px; + margin-bottom: 10px; + text-align: center; + font-size: xx-large; + font-weight: bolder; + animation:pfpDefault 800ms linear both; +} h2 { font-size: small; color: #000000; @@ -85,10 +118,24 @@ options_header { text-align: center; } +miniupdate { + font-size: medium; + color: #000000; + font-weight: bold; + text-align: center; + font-size: 16px; + animation:pfpDefault 800ms linear both; +} + h3 { font-size: small; color: #484848; text-align: center; + animation:pfpDefault 800ms linear both; +} + +h3:hover { + animation:pfpDefault 800ms linear both; } h4 { @@ -139,24 +186,31 @@ input { } input.checkbox { - width: 13px; - height: 13px; + width: 15px; + height: 15px; padding: 0; margin: 0; vertical-align: bottom; position: relative; - top: -2px; + top: -1px; overflow: hidden; + font-family: Ubuntu; +} +input.checkbox:focus, +input.checkbox.focus { + border: none; + box-shadow: 0 0 0px 0px #DDDDDD; } #playerNameInput { padding: 10px; - font-size: large; + font-size: medium; } #playerKeyInput { padding: 3px; color: gray; + } input:focus, @@ -177,7 +231,7 @@ div { } .serverSelector { - height: 25px; + height: 65px; text-align: center; font-size: 14px; font-weight: bold; @@ -205,7 +259,7 @@ div { margin: auto; width: 1150px; padding: 10px; - margin-top: 100px; + margin-top: 74px; margin-bottom: 100px; border-radius: 5px; -moz-border-radius: 5px; @@ -223,14 +277,121 @@ div { .startMenuHolder { width: 350px; - height: 380px; + height: 365px; padding: 10px; overflow: hidden; display: inline-block; vertical-align: text-top; } +.replace1 { +right: 0; +} +.replace2 { +right: -50; +} +a.menuTab { + float: right; + height: 13px; + font: 13px Ubuntu; + border-radius: 0px 0px 5px 5px; + padding: 6px 10px 7px 10px; + color: #FFFFFF !important; + text-decoration: none; + margin-right: 10px; +} +a.menuTab.discordbutton { + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #6175ba; + box-shadow: inset 0 -2px #6175ba; + -webkit-box-shadow: inset 0 -2px #6175ba; + animation:pfpDefault 800ms linear both; + background: #7289DA url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/svg0.svg") 4px 3px/21px no-repeat; +} +a.menuTab.discordbutton:active, +a.menuTab.discordbutton:hover { + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} +a.menuTab.catto { + background: #FF0000 url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/coder.png") 8px 6px no-repeat; + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #c91a1a; + box-shadow: inset 0 -2px #c91a1a; + -webkit-box-shadow: inset 0 -2px #c91a1a; + animation:pfpDefault 800ms linear both; +} +a.menuTab.catto:active, +a.menuTab.catto:hover { + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +a.menuTab.ach { + background: #2bab2f url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png?v=1708025693434") 3px 2px/23px no-repeat; + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #2a802d; + box-shadow: inset 0 -2px #2a802d; + -webkit-box-shadow: inset 0 -2px #2a802d; + animation:pfpDefault 800ms linear both; +} +a.menuTab.ach:active, +a.menuTab.ach:hover { + top: 1px; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} +a.menuTab.skin { + background: #9900FF url("https://cdn.glitch.global/9b9522e6-a4f4-4511-8978-4c190b6759bd/stick.png?v=1708440293253") 3px 2px/23px no-repeat; + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #7b11c2; + box-shadow: inset 0 -2px #7b11c2; + -webkit-box-shadow: inset 0 -2px #7b11c2; + animation:pfpDefault 800ms linear both; +} +a.menuTab.skin:active, +a.menuTab.skin:hover { + top: 1px; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +a.menuTab.stat { + background: #1E8449 url("https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/play.png") 3px 2px/23px no-repeat; + padding: 6px 10px 7px 28px; + border-bottom: 2px solid #156637; + box-shadow: inset 0 -2px #156637; + -webkit-box-shadow: inset 0 -2px #156637; + animation:pfpDefault 800ms linear both; +} +a.menuTab.stat:active, +a.menuTab.stat:hover { + top: 1px; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; +} + +a.menuTab.??? { + background: #FFFFFF url("https://cdn.glitch.global/f80d3eec-1e99-4b8c-b120-79a55addacf9/2022_06_23_11e_Kleki.png?v=1675997243695") 3px 2px/23px no-repeat; + padding: 6px 10px 7px 28px; + animation:pfpDefault 800ms linear both; +} +a.menuTab:link:hover, a.menuTab:visited:hover { + text-decoration: underline; + animation:pfpHoverOn 800ms linear both; +} .sliderHolder { + width: 350px; + height: 323px; + overflow: hidden; +} + +.sliderHolder2 { width: 350px; height: 325px; overflow: hidden; @@ -248,6 +409,7 @@ td { table { width: 100%; + color: black; } .slider { @@ -258,23 +420,97 @@ table { -moz-transition: top 500ms; -o-transition: top 500ms; transition: top 500ms; + animation:pfpDefault 800ms linear both; + transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1.2) +} + +.slider2 { + position: relative; + right: 0px; + width: 100%; + z-index: 0; + display: inline-block; + -webkit-transition: right 1000ms; + -moz-transition: right 1000ms; + -o-transition: right 1000ms; + transition: right 1000ms; + animation:pfpDefault 800ms linear both; + transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1) +} +.slider3 { + position: absolute; + z-index: -6; + right: 400px; + width: 100%; + display: inline-block; + -webkit-transition: right 1000ms; + -moz-transition: right 1000ms; + -o-transition: right 1000ms; + transition: right 1000ms; + animation:pfpDefault 800ms linear both; + transition-timing-function: cubic-bezier(0.175, 0.585, 0.32, 1) +} + +.slidingtrigger3 { + position: relative; + top: 0px; + width: 100%; + -webkit-transition: top 500ms; + -moz-transition: top 500ms; + -o-transition: top 500ms; + transition: top 500ms; } #startMenuSlidingContent { - height: 305px; + height: 300px; } #startMenuSlidingTrigger { cursor: pointer; height: 15px; } - #startMenuSlidingTrigger:hover { text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); } +#startMenuSlidingTrigger:active > h3 { + color: #323232; + animation:pfpDefault 800ms linear both; +} +#startMenuSlidingTrigger:hover > h3 > i.arrow { + border-color: #323232; +} + +#startMenuSlidingTrigger2 { + cursor: pointer; +} +#startMenuSlidingTrigger2:hover { + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); +} +#startMenuSlidingTrigger2:active > h3 { + color: #323232; + animation:pfpDefault 800ms linear both; +} +#startMenuSlidingTrigger2:hover > h3 > i.arrow { + border-color: #323232; +} +#startMenuSlidingTrigger3 { + cursor: pointer; + height: 15px; +} + +#startMenuSlidingTrigger3:hover { + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); +} + +.menuTabs { + height: 26px; + margin: 0 8px; +} update { color: #D83848; + animation:pfpDefault 800ms linear both; + font-weight: bold; } @@ -282,7 +518,7 @@ update { padding-left: 10px; font-size: x-large; font-weight: bold; - text-align: center; + text-align: justify; } .shrinkable { @@ -290,8 +526,65 @@ update { width: 360px; } -#patchNotes { +.dropdown-check-list { + display: inline-block; +} + +.dropdown-check-list .anchor { + position: relative; + cursor: pointer; + display: inline-block; + padding: 5px 50px 5px 10px; + border: 1px solid #cccccc; +} + +.dropdown-check-list .anchor:after { + position: absolute; + content: ""; + border-left: 2px solid black; + border-top: 2px solid black; + padding: 5px; + right: 10px; + top: 20%; + -moz-transform: rotate(-135deg); + -ms-transform: rotate(-135deg); + -o-transform: rotate(-135deg); + -webkit-transform: rotate(-135deg); + transform: rotate(-135deg); +} + +.dropdown-check-list .anchor:active:after { + right: 8px; + top: 21%; +} + +.dropdown-check-list ul.items { + padding: 2px; + display: none; + margin: 10px 10px 10px 10px; + border: 1px solid #cccccc; + border-top: none; + height: 75px; +} + +.dropdown-check-list ul.items li { + padding: 0; + margin-top: 8px; + position: relative; + top: -7px; +} + +.dropdown-check-list.visible .anchor { + color: #0094ff; +} + +.dropdown-check-list.visible .items { + display: block; +} + +#credits { max-width: 330px; + /*animation:pfpDefault 800ms linear both;*/ height: calc(100% - 100px); padding: 5px 20px 10px; overflow: hidden auto; @@ -299,7 +592,7 @@ update { scrollbar-color: rgba(0, 0, 0, 0.3) rgba(0, 0, 0, 0.15); } -#patchNotes div { +#credits div { > .title { margin: 0; font-size: 1.5em; @@ -317,6 +610,47 @@ update { } position: relative; + /*animation:pfpDefault 800ms linear both;*/ + + &::before { + content: ''; + position: absolute; + bottom: 0; + width: 100%; + height: .1em; + background-color: gray; + } +} + +#patchNotes { + max-width: 330px; + /*animation:pfpDefault 800ms linear both;*/ + height: calc(100% - 100px); + padding: 5px 20px 10px; + overflow: hidden auto; + scrollbar-width: thin; + scrollbar-color: rgba(0, 0, 0, 0.3) rgba(0, 0, 0, 0.15); +} + +#patchNotes div { + > .title { + margin: 0; + font-size: 1.5em; + font-weight: bold; + } + + > date { + color: rgba(0, 0, 0, 0.45); + font-style: italic; + } + + > ul li { + margin-left: 1em; + margin-bottom: .5em; + } + + position: relative; + /*animation:pfpDefault 800ms linear both;*/ &::before { content: ''; @@ -351,10 +685,12 @@ update { height: 40px; box-sizing: border-box; font-size: larger; + line-height: 0; color: white; + animation:pfpDefault 800ms linear both; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); - background: #336699; + background: #335099; /*background: #A9D86D;*/ border: 0; border-bottom: 2px solid #1B3353; @@ -369,14 +705,79 @@ update { -webkit-border-radius: 5px; } +#hideongamestart { + position: relative; + z-index: 3; + } + +#resetachievementsbutton { + font-family: Ubuntu; + line-height: 0; + top: 30px; + width: 100%; + height: 40px; + max-height: 100px; + top: 443px; + z-index: 3; + color: white; + animation:pfpDefault 800ms linear both; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); + background: #70b5ff; + font-family: Ubuntu; + position: relative; + border: 0; + border-bottom: 2px solid #1B3353; + cursor: pointer; + -webkit-box-shadow: inset 0 -2px #1B3353; + box-shadow: inset 0 -2px #1B3353; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + float: left; +} + +.icon { + animation:pfpDefault 800ms linear both; +} + +.icon:hover { + animation:pfpHoverOn 800ms linear both; +} + +.icon:active { + animation:pfpDefault 400ms linear both; +} + #startButton:active, #startButton:hover { top: 1px; - background: #1B3353; + background: #335099; + /*background: #A9D86D;*/ + border: 0; + border-bottom: 3px solid #1B3353; + /*background: #1B3353;*/ /*background: #8ABC3F;*/ + line-height: 25px; + text-align: center; outline: none; -webkit-box-shadow: none; box-shadow: none; + height: 39px; +} + +#resetachievementsbutton:active, +#resetachievementsbutton:hover { + line-height: 25px; + text-align: center; + outline: none; + -webkit-box-shadow: none; + box-shadow: none; + height: 39px; + border: 0; + border-bottom: 3px solid #1B3353; + top: 444px; + } #bottomHolder { @@ -404,108 +805,132 @@ a.link { } .discord { + top: 2px; + animation:pfpDefault 800ms linear both; background: #7289da; + line-height: 15px; border-bottom: 2px solid #6175ba; box-shadow: inset 0 -2px #6175ba; -webkit-box-shadow: inset 0 -2px #6175ba; } .discord:active, .discord:hover { - top: 1px; - background: #6175ba; - outline: none; - -webkit-box-shadow: none; - box-shadow: none; -} - -.revolt { - background: #fd6671; - border-bottom: 2px solid #ed4245; - box-shadow: inset 0 -2px #ed4245; - -webkit-box-shadow: inset 0 -2px #ed4245; -} -.revolt:active, -.revolt:hover { - top: 1px; - background: #ed4245; + top: 3px; + background: #7289da; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #6175ba; + box-shadow: inset 0 -2px #6175ba; + -webkit-box-shadow: inset 0 -2px #6175ba; } .reddit { + top: 2px; + animation:pfpDefault 800ms linear both; background: #f75401; + line-height: 15px; border-bottom: 2px solid #d24a01; box-shadow: inset 0 -2px #d24a01; -webkit-box-shadow: inset 0 -2px #d24a01; } + .reddit:active, .reddit:hover { - top: 1px; - background: #d24a01; + top: 3px; + background: #f75401; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #d24a01; + box-shadow: inset 0 -2px #d24a01; + -webkit-box-shadow: inset 0 -2px #d24a01; } .original { + top: 2px; + animation:pfpDefault 800ms linear both; background: #77bf79; + line-height: 15px; border-bottom: 2px solid #679c68; box-shadow: inset 0 -2px #679c68; -webkit-box-shadow: inset 0 -2px #679c68; } + .original:active, .original:hover { - top: 1px; - background: #679c68; + top: 3px; + background: #77bf79; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #679c68; + box-shadow: inset 0 -2px #679c68; + -webkit-box-shadow: inset 0 -2px #679c68; } .developer { + top: 2px; + animation:pfpDefault 800ms linear both; background: #454b7f; + line-height: 15px; border-bottom: 2px solid #313454; box-shadow: inset 0 -2px #313454; -webkit-box-shadow: inset 0 -2px #313454; } .developer:active, .developer:hover { - top: 1px; - background: #313454; + top: 3px; + background: #454b7f; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #313454; + box-shadow: inset 0 -2px #313454; + -webkit-box-shadow: inset 0 -2px #313454; } .youtube { + top: 2px; + animation:pfpDefault 800ms linear both; background: #f71701; + line-height: 15px; border-bottom: 2px solid #d21401; box-shadow: inset 0 -2px #d21401; -webkit-box-shadow: inset 0 -2px #d21401; } + .youtube:active, .youtube:hover { - top: 1px; - background: #d21401; + top: 3px; + background: #f71701; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #d21401; + box-shadow: inset 0 -2px #d21401; + -webkit-box-shadow: inset 0 -2px #d21401; } .github { + top: 2px; + animation:pfpDefault 800ms linear both; background: #666666; + line-height: 15px; border-bottom: 2px solid #333333; - -webkit-box-shadow: inset 0 -2px #333333; box-shadow: inset 0 -2px #333333; + -webkit-box-shadow: inset 0 -2px #333333; } .github:active, .github:hover { - top: 1px; - background: #333333; + top: 3px; + background: #666666; outline: none; - -webkit-box-shadow: none; - box-shadow: none; + height: 85%; + line-height: 15px; + border-bottom: 1px solid #333333; + box-shadow: inset 0 -2px #333333; + -webkit-box-shadow: inset 0 -2px #333333; } #startMenuWrapper { @@ -565,6 +990,17 @@ a.link { color: black; background-color: #ffffff88; } +p.vsaucereference { + animation:pfpHoverOn 400ms linear both; + font-size: 13px; +} +p.vsaucereference:hover { + animation:pfpHoverOn 400ms linear both; +} + +p.vsaucereference:active { + animation: pfpDefault 800ms linear both; +} input [type="image"]:focus { border: none; @@ -575,4 +1011,704 @@ input [type="image"]:focus { *:focus { outline: 1px solid transparent; border-style: none; +} +.popup { + position: absolute; + display: block; + width: auto; + max-width: 42%; + height: auto; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 3; + border-radius: 10px; + background: var(--backgroundColor); + padding: 10px; + font-size: larger; + text-align: center; + border-style: solid; + border-color: #c1cfd8; + color: var(--menuTextColor); +} + +.popup button { + margin: 15px; + padding: 10px 50px 10px 50px; + width: auto; + box-sizing: border-box; + color: white; + text-align: center; + text-shadow: 0 0 3px rgba(0, 0, 0, 0.2), 0 1px 2px rgba(0, 0, 0, 0.2); + background: #A9D86D; + border: 0; + border-bottom: 2px solid #8ABC3F; + cursor: pointer; + box-shadow: inset 0 -2px #8ABC3F; + border-radius: 5px; + font: 18px Ubuntu; +} + +.popup button:hover { + border-bottom: 1px solid #8ABC3F; +} + +.popup button:active { + background: #FFFFFF; + border-bottom: 0; + outline: none; + box-shadow: none; +} + +.popup span.small { + font-size: xx-large; + font-weight: bold; + color: black; + white-space: pre-line; +} + +.popup span { + font-size: x-large; + white-space: pre-line; + font-weight: light; + color: black; +} +.achievementsHolder { + position: absolute; + display: block; + width: 700px; + height: 550px; + padding-top: 50px; + top: 47.5%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 3; + background: var(--backgroundColor); + padding: 10px; + font-size: larger; + text-align: center; + border-style: solid; + border-color: #c1cfd8; + color: black; + display: none; +} + +.achievementsHolder span.small { + font-size: xx-large; + font-weight: bold; + color: black; + animation:pfpDefault 800ms linear both; +} + +.achievementsHolder span { + font-size: x-large; + font-weight: lighter; + color: black; + animation:pfpDefault 800ms linear both; +} + +#achievementsClose { + height: 45px; + width: 50px; + float: right; + position: relative; + opacity: .8; + background-image: url('data:image/svg+xml,%3Csvg xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" fill%3D"%23DD0000" viewBox%3D"0 0 16 16" width%3D"30" height%3D"30"%3E%3Cpath d%3D"M3 0 0 3 6 8 0 13 3 16 8 10 13 16 16 13 10 8 16 3 13 0 8 6 3 0Z"%3E%3C%2Fpath%3E%3C%2Fsvg%3E'); + background-repeat: no-repeat; + background-position: center; +} + +#achievementsClose:hover { + cursor: pointer; + opacity: 1; +} + +#achievementsDisplay { + height: 450px; + margin-top: -20px; + position: absolute; + animation:pfpDefault 800ms linear both; + width: 96.5%; + border-style: solid; + border-color: #c1cfd8; + background-color: rgba(0, 0, 0, 0.2); + background: url("https://cdn.glitch.global/ded4b664-3b74-4a3b-9282-9796baafc60b/41R6Ok5aeKL.jpg?v=1713446403687") 0px -550px/100% repeat; +} + +.achievementsItem { + margin: 16px 16px 12px 16px; + border-radius: 14px; + animation:pfpDefault 800ms linear both; + padding: 6px; + +} + +.achievementsItem h1 { + font-size: 22px; + animation:pfpDefault 800ms linear both; + font-weight: bold; + color: #22160b; +} + +.achievementsItem span { + font-size: 17px; + font-weight: bold; + animation:pfpDefault 800ms linear both; + color: #22160b; +} + +.greenachievement { + background-color: rgb(138, 187, 68); +} + +.greyachievement { + background-color: rgb(159, 159, 159); +} + +.bleenachievement { + background-color: rgb(125, 195, 235); +} + +.grueachievement { + background-color: rgb(160, 170, 180); +} + +#achievementsStatsTable td { + animation:pfpDefault 800ms linear both; + font-size: 18px; +} + +#achievementsStatsTable tr b { + animation:pfpDefault 800ms linear both; + font-size: 22px; +} +.autoBorder { + display: block; + border: 3.5px solid rgba(0, 0, 0, 0.35); +} +.metasip { + height: 10px; + width: 10px; + background-image: "https://cloud-cube.s3.amazonaws.com/m660o440l0wv/public/svg0.svg" +} +#wikiTankThing { + display: none; + position: absolute; + top: 58.5vh; + left: 40%; + z-index: 5; + width: 20%; +} +.skinHolder { + position: absolute; + display: block; + width: 650px; + height: 600px; + top: 47.5%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 3; + background: var(--backgroundColor); + padding: 10px; + font-size: larger; + text-align: center; + border-style: solid; + border-color: #c1cfd8; + color: black; + display: none; +} + +.skinHolder span.small { + font-size: xx-large; + font-weight: bold; + color: black; + animation:pfpDefault 800ms linear both; +} + +.skinHolder span { + font-size: x-large; + font-weight: light; + color: black; + animation:pfpDefault 800ms linear both; +} + +#skinClose { + height: 45px; + width: 50px; + float: right; + position: relative; + opacity: .8; + background-image: url('data:image/svg+xml,%3Csvg xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" fill%3D"%23DD0000" viewBox%3D"0 0 16 16" width%3D"30" height%3D"30"%3E%3Cpath d%3D"M3 0 0 3 6 8 0 13 3 16 8 10 13 16 16 13 10 8 16 3 13 0 8 6 3 0Z"%3E%3C%2Fpath%3E%3C%2Fsvg%3E'); + background-repeat: no-repeat; + background-position: center; +} + +#skinClose:hover { + cursor: pointer; + opacity: 1; +} + +#skinDisplay { + height: 448px; + margin-top: -20px; + position: absolute; + animation:pfpDefault 800ms linear both; + width: 96.5%; + border-style: solid; + border-color: #c1cfd8; + background-color: rgba(0, 0, 0, 0.2); +} + +.skinItem { + margin: 16px 16px 12px 16px; + border-radius: 14px; + animation:pfpDefault 800ms linear both; + padding: 6px; + +} + +.skinItem h1 { + font-size: 22px; + animation:pfpDefault 800ms linear both; + font-weight: light; + color: #22160b; +} + +.skinItem span { + font-size: 17px; + font-weight: bold; + animation:pfpDefault 800ms linear both; + color: #22160b; +} + +#leftarrowbutton { + position: relative; + float: left; + height: 20%; + width: 20%; +} +#rightarrowbutton { + position: relative; + float: right; + height: 20%; + width: 20%; +} +#leftarrowbutton:active { + animation:pfpDefault 800ms linear both; +} +#rightarrowbutton:active { + animation:pfpDefault 800ms linear both; +} +.displaytest { + top: 0; + position: relative; + text-align: center; + margin-left: auto; + margin-right: auto; + margin-top: auto; +} +.displayskinname { + top: -2%; + position: relative; +} +#skinpdiv { + top: -3%; + position: relative; + margin-left: auto; + margin-right: auto; + width: 50%; +} +#skinpreview { + vertical-align: bottom; + width: 100%; + height: 100%; + z-index: 3; + +} +#selectskin { + vertical-align: bottom; + float: center; + margin-left: auto; + margin-right: auto; + height: 130px; + width: 260px; + z-index: 3; +} +#lockedskin { + display: none; + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + z-index: 3; +} +#lockbg { + display: inline-block; + width: 100%; + height: 100%; + top: 0; + left: 0; + position: absolute; + opacity: 0.4; + z-index: -5; +} +#eventtitle { + position: absolute; + float: center; + top: 10%; + left: 50%; + color: white; + outline: #000000 solid; + z-index: 0; + cursor: pointer; + text-shadow: -1px -1px 0 #000000, 1px -1px 0 #000000, -1px 1px 0 #000000, 1px 1px 0 #000000; + background: #202020 url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/channels4_profile.jpg?v=1709324207088") 0px 0px/100px repeat; +} +.horizontalSelector { + padding: 4px 0; + margin-bottom: 4px; + font: bold 12px Ubuntu; + text-align: center; +} +.horizontalSelector span { + padding: 4px 10px; + color: #343434; + cursor: pointer; +} +.horizontalSelector span:hover { + color: #5f5f5f; +} +.horizontalSelector span.active { + background: #335099; + color: #ffffff; + border-radius: 5px; + cursor: default; +} +.tabappearance { + display: block; +} +.taboptions { + display: none; +} +.tabcontrols { + display: none; +} +.tablinks { + display: none; +} +#controls { + height: 200px; +} +.animpop { + animation:pfpDefault 800ms linear both; +} +.animinvert { + animation:invertation 2s linear both; + -webkit-animation-timing-function: linear; + animation-timing-function: linear; +} +.incog:active { + animation:wack2 2s linear 3; + -webkit-animation-timing-function: linear; + animation-timing-function: linear +} +.popuptaskbar { + display: block; + position: relative; + height: 50px; + width: 102.8%; + left: -10px; + top: -32px; + background: #2bab2f url("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Trophy.png?v=1708025693434") 0px 0px/50px no-repeat; +} +#achievementsHeader { + padding: 5px; + text-align: left; + margin-left: 50px; + color: #FFFFFF +} +.popuptaskbar2 { + display: block; + position: relative; + height: 50px; + width: 102.8%; + left: -10px; + top: -32px; + background: #9900FF url("https://cdn.glitch.global/9b9522e6-a4f4-4511-8978-4c190b6759bd/stick.png?v=1708440293253") 0px 0px/50px no-repeat; +} +#skinHeader { + padding: 5px; + text-align: left; + margin-left: 50px; + color: #FFFFFF +} +.atthebottom { + position: relative; + top: 425px; +} +#yes { + opacity: 0; + position: absolute; +} + +@keyframes pfpHoverOn { + 0% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 3.4% { transform: matrix3d(1.032, 0, 0, 0, 0, 1.041, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 4.7% { transform: matrix3d(1.045, 0, 0, 0, 0, 1.06, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 6.81% { transform: matrix3d(1.066, 0, 0, 0, 0, 1.089, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 9.41% { transform: matrix3d(1.088, 0, 0, 0, 0, 1.117, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 10.21% { transform: matrix3d(1.094, 0, 0, 0, 0, 1.123, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 13.61% { transform: matrix3d(1.112, 0, 0, 0, 0, 1.133, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 14.11% { transform: matrix3d(1.114, 0, 0, 0, 0, 1.133, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 17.52% { transform: matrix3d(1.121, 0, 0, 0, 0, 1.124, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 18.72% { transform: matrix3d(1.121, 0, 0, 0, 0, 1.119, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 21.32% { transform: matrix3d(1.12, 0, 0, 0, 0, 1.107, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 24.32% { transform: matrix3d(1.115, 0, 0, 0, 0, 1.096, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 25.23% { transform: matrix3d(1.113, 0, 0, 0, 0, 1.094, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 29.03% { transform: matrix3d(1.106, 0, 0, 0, 0, 1.09, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 29.93% { transform: matrix3d(1.105, 0, 0, 0, 0, 1.09, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 35.54% { transform: matrix3d(1.098, 0, 0, 0, 0, 1.096, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 36.74% { transform: matrix3d(1.097, 0, 0, 0, 0, 1.098, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 41.04% { transform: matrix3d(1.096, 0, 0, 0, 0, 1.102, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 44.44% { transform: matrix3d(1.097, 0, 0, 0, 0, 1.103, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 52.15% { transform: matrix3d(1.099, 0, 0, 0, 0, 1.101, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 59.86% { transform: matrix3d(1.101, 0, 0, 0, 0, 1.099, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 63.26% { transform: matrix3d(1.101, 0, 0, 0, 0, 1.099, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 75.28% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 85.49% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 90.69% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 100% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } +} + +@keyframes pfpDefault { + 0% { transform: matrix3d(1.1, 0, 0, 0, 0, 1.1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 3.4% { transform: matrix3d(1.068, 0, 0, 0, 0, 1.059, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 4.7% { transform: matrix3d(1.055, 0, 0, 0, 0, 1.04, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 6.81% { transform: matrix3d(1.034, 0, 0, 0, 0, 1.011, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 9.41% { transform: matrix3d(1.012, 0, 0, 0, 0, 0.983, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 10.21% { transform: matrix3d(1.006, 0, 0, 0, 0, 0.977, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 13.61% { transform: matrix3d(0.988, 0, 0, 0, 0, 0.967, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 14.11% { transform: matrix3d(0.986, 0, 0, 0, 0, 0.967, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 17.52% { transform: matrix3d(0.979, 0, 0, 0, 0, 0.976, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 18.72% { transform: matrix3d(0.979, 0, 0, 0, 0, 0.981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 21.32% { transform: matrix3d(0.98, 0, 0, 0, 0, 0.993, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 24.32% { transform: matrix3d(0.985, 0, 0, 0, 0, 1.004, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 25.23% { transform: matrix3d(0.987, 0, 0, 0, 0, 1.006, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 29.03% { transform: matrix3d(0.994, 0, 0, 0, 0, 1.01, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 29.93% { transform: matrix3d(0.995, 0, 0, 0, 0, 1.01, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 35.54% { transform: matrix3d(1.002, 0, 0, 0, 0, 1.004, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 36.74% { transform: matrix3d(1.003, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 41.04% { transform: matrix3d(1.004, 0, 0, 0, 0, 0.998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 44.44% { transform: matrix3d(1.003, 0, 0, 0, 0, 0.997, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 52.15% { transform: matrix3d(1.001, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 59.86% { transform: matrix3d(0.999, 0, 0, 0, 0, 1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 63.26% { transform: matrix3d(0.999, 0, 0, 0, 0, 1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 75.28% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 85.49% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 90.69% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } + 100% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } +} +@keyframes invertation { + 0% { + background-color: black; + color: white; + } + + 50% { + background-color: white; + -webkit-filter: invert(1); + filter: invert(1); + } +} +@keyframes wack { + 25% { + transform: scale(1, 5); + } + 75% { + transform: scale(5, 1) + } +} +@keyframes wack2 { + 20% { + transform: scale(100, 5); + } + 40% { + transform: scale(2, 10) + } + 60% { + transform: scale(0.2, 15); + } + 80% { + transform: scale(-10, 6) + } + 100% { + transform: scale(-3, -1) + } +} +@keyframes flashing { + 0% { + background-color: black; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + } + 5% { + background-color: black; + -webkit-filter: invert(1); + filter: invert(1); + } + 10% { + background-color: red; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + } + 15% { + background-color: red; + -webkit-filter: invert(1); + filter: invert(1); + } + 20% { + background-color: black; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + } + 25% { + background-color: black; + -webkit-filter: invert(1); + filter: invert(1); + } + 30% { + background-color: white; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + } + 35% { + background-color: white; + -webkit-filter: invert(1); + filter: invert(1); + } + 40% { + background-color: red; + color: white; + -webkit-filter: invert(0); + filter: invert(0); + + } + 45% { + background-color: black; + } + 50% { + background-color: orange; + color: white; + } + 55% { + background-color: white; + } + 60% { + background-color: yellow; + } + 65% { + background-color: black; + } + 70% { + background-color: green; + } + + 75% { + background-color: white; + } + 80% { + background-color: blue; + } + 85% { + background-color: black; + } + 90% { + background-color: purple; + } + 95% { + background-color: white; + } +} +@keyframes pop { + 0% { + transform: scale(1, 1); + } + 5% { + transform: scale(0.9, 0.9); + } + 10% { + transform: scale(0.8, 0.8); + } + 15% { + transform: scale(0.7, 0.7); + } + 20% { + transform: scale(0.6, 0.6); + } + 25% { + transform: scale(0.5, 0.5); + } + 30% { + transform: scale(0.4, 0.4); + } + 35% { + transform: scale(0.3, 0.3); + } + 40% { + transform: scale(0.2, 0.2); + } + 45% { + transform: scale(0.1, 0.1); + } + 50% { + transform: scale(0, 0); + } + 55% { + transform: scale(0.1, 0.1); + } + 60% { + transform: scale(0.2, 0.2); + } + 65% { + transform: scale(0.3, 0.3); + } + 70% { + transform: scale(0.4, 0.4); + } + 75% { + transform: scale(0.5, 0.5); + } + 80% { + transform: scale(0.6, 0.6); + } + 85% { + transform: scale(0.7, 0.7); + } + 90% { + transform: scale(0.8, 0.8); + } + 95% { + transform: scale(0.9, 0.9); + } +} +@keyframes movedown { + 0% { + padding: 6px 10px 7px 28px; + } + 100% { + padding: 6px 10px 70px 28px; + } +} +@keyframes moveup { + 0% { + transform: translatey(100px); + } + 100% { + transform: translatey(0px); + } } \ No newline at end of file diff --git a/public/osa_background_tile.png b/public/osa_background_tile.png deleted file mode 100644 index 1266bc53d30cd59b94ef59271561b93664c7634d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 748 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 LBMqdQGyMMm(j~<0 diff --git a/run.bat b/public/run.bat similarity index 100% rename from run.bat rename to public/run.bat diff --git a/public/servers.json b/public/servers.json new file mode 100644 index 000000000..c167aa511 --- /dev/null +++ b/public/servers.json @@ -0,0 +1,4 @@ +[ + "http://163.5.76.112:25004", + "https://neroio2.glitch.me" +] \ No newline at end of file diff --git a/server/config.js b/server/config.js index 893ebd919..ba6df06ac 100644 --- a/server/config.js +++ b/server/config.js @@ -3,11 +3,18 @@ module.exports = { // Game server domain. // If 'localhost:NUMBER', the port must equal the port setting. - host: "localhost:26301", + host: "neroio2.glitch.me", // Which port to run the web server on. - port: 26301, - + port: 3000, + + // Region/Location the server is in + // For glitch its US West + region: "US West", + + // name of the server ex. main server, beta server, etc + serverName: "Beta", + // How often to update the list of the entities that players can see. // Has effects of when entities are activated. visibleListInterval: 250, @@ -17,25 +24,28 @@ module.exports = { // Flatten entity definition, which gets rid of PARENT attributes and applies the parents' attributes to the entity definition, if they're not set in the entity already. flattenDefintions: false, - + // Log speed loop warnings - LOGS: true, + LOGS: false, + + // If there's only one server + COMBINED: true, // The \modules\setup\gamemodeconfigs\ files to load. // To change specific things about specific gamemodes (such as team count for tdm), edit their config file in \modules\setup\gamemodeconfigs\. - GAME_MODES: ['tdm', 'domination'], + GAME_MODES: ['ffa'], // The room files to load in the setup/rooms folder. // NOTE: If a /gamemodeconfig/ file "replaces" the value of ROOM_SETUP, it just adds its own ROOM_SETUP's content to this array. // NOTE: Files starting with `map_` are maps. files starting with `overlay_` are overlays that get added on. // NOTE: These prefixes are only for categorisation, a room file would work the same regardless of its prefix. APS++ does nothing based on file name prefixes. - ROOM_SETUP: ['map_apspp_default'], + ROOM_SETUP: ['map_neroio_mazearena'], // The dimensions of a single tile on the map. - TILE_WIDTH: 400, - TILE_HEIGHT: 400, - - + TILE_WIDTH: 200, //400 + TILE_HEIGHT: 200, //400 + + // Miscellaneous @@ -45,43 +55,40 @@ module.exports = { // If you don't want your players to color their messages. // They get sanitized after addons interpret them, but before they're added to the chat message dictionary. - SANITIZE_CHAT_MESSAGE_COLORS: true, - - // If someone tries to get a file that does not exist, send them this instead. - DEFAULT_FILE: 'index.html', + SANITIZE_CHAT_MESSAGE_COLORS: false, // Window name of the server terminal. - WINDOW_NAME: 'OSA Game Server Instance', + WINDOW_NAME: 'Nero Game Server Instance', // Allows you to type and run javascript code in the terminal. REPL_WINDOW: false, // Welcome message once a player spawns. - WELCOME_MESSAGE: "You have spawned! Welcome to the game.\n" - +"You will be invulnerable until you move or shoot.\n" - +"Please report any bugs you encounter!", + WELCOME_MESSAGE: "You have spawned! Welcome to the game, Hold N To Level Up.\n" + +"You will be invulnerable until you move or shoot OR ACCIDENTALLY PRESS THE FUCKING SPACE BAR.\n" + +"Please report any bugs you encounter on our discord! :)", + // How long a popup message lasts before fading out in milliseconds. MESSAGE_DISPLAY_TIME: 10_000, - // Physics // General multiplier for acceleration and max speeds. - runSpeed: 1.5, + runSpeed: 1.5, //1.5 // General damage multiplier everytime damage is dealt. - DAMAGE_CONSTANT: 0.5, + DAMAGE_CONSTANT: 0.5, // 0.5 // General knockback multiplier everytime knockback is applied. - KNOCKBACK_CONSTANT: 1.5, + KNOCKBACK_CONSTANT: 1.5, //1.5 // TODO: Figure out how the math behind this works. GLASS_HEALTH_FACTOR: 2, // How strong the force is that confines entities to the map and portals apply to entities. - ROOM_BOUND_FORCE: 0.01, + ROOM_BOUND_FORCE: 0.01, //0.01 @@ -115,16 +122,16 @@ module.exports = { // How much XP player-bots get per second until they reach LEVEL_CAP. BOT_XP: 125, - + // How much XP player-bots will receive when first created. - BOT_START_XP: 0, + BOT_START_XP: 26302, // The chances of a player-bot upgrading a specific skill when skill upgrades are available. BOT_SKILL_UPGRADE_CHANCES: [ 1, 1, 3, 4, 4, 4, 4, 2, 1, 1], // The chances of a player-bot upgrading a specific amount of times before it stops upgrading. BOT_CLASS_UPGRADE_CHANCES: [ 1, 5, 20, 37, 37], - + // The prefix of the bot's name. BOT_NAME_PREFIX: "[AI] ", @@ -133,22 +140,22 @@ module.exports = { - // Natural Spawns + // Natural Spawns - FOOD_CAP: 3, // Max normal food per normal tile. - FOOD_SPAWN_CHANCE: 0.875, // Likeliness of normal food spawn attempts succeeding. - FOOD_SPAWN_COOLDOWN: 30, // Cooldown (in game ticks) of food spawn attempts being made. + FOOD_CAP: 1, // Max normal food per normal tile. 3 + FOOD_SPAWN_CHANCE: 0.05, // Likeliness of normal food spawn attempts succeedingg. 0.875 + FOOD_SPAWN_COOLDOWN: 100, // Cooldown (in game ticks) of food spawn attempts being made. 30 - FOOD_CAP_NEST: 3, // Max nest food per nest tile. - FOOD_SPAWN_CHANCE_NEST: 0.25, // Likeliness of nest food spawn attempts succeeding. - FOOD_SPAWN_COOLDOWN_NEST: 45, // Cooldown (in game ticks) of nest food spawn attempts being made. + FOOD_CAP_NEST: 1, // Max nest food per nest tile. 3 + FOOD_SPAWN_CHANCE_NEST: 0.05, // Likeliness of nest food spawn attempts succeeding. 0.25 + FOOD_SPAWN_COOLDOWN_NEST: 150, // Cooldown (in game ticks) of nest food spawn attempts being made. 45 - ENEMY_CAP_NEST: 1, // Max nest enemies per nest tile. - ENEMY_SPAWN_CHANCE_NEST: 0.9, // Likeliness of nest enemies spawn attempts succeeding. + ENEMY_CAP_NEST: 0, // Max nest enemies per nest tile. 1 + ENEMY_SPAWN_CHANCE_NEST: 0.9, // Likeliness of nest enemies spawn attempts succeeding. 0.9 ENEMY_SPAWN_COOLDOWN_NEST: 60, // Cooldown (in game ticks) of nest enemies spawn attempts being made. // Cooldown (in seconds) of boss spawns being announced. - BOSS_SPAWN_COOLDOWN: 60, + BOSS_SPAWN_COOLDOWN: 360, //120 // The delay (in seconds) between the boss spawns being announced and the bosses actually spawning. // NOTE: The spawn message (ex. "A strange trembling...") takes half as long to appear than the boss. BOSS_SPAWN_DURATION: 5, @@ -234,5 +241,6 @@ module.exports = { MAZE: false, HUNT: false, MODE: "ffa", - TAG: false + TAG: false, + GOVERNMENTAL: false } diff --git a/server/index.js b/server/index.js index 6358130c4..9fac36584 100644 --- a/server/index.js +++ b/server/index.js @@ -18,9 +18,17 @@ Array.prototype.remove = function (index) { return r; }; +function reopenPopup() { + window.open( + "../../shit/popup.html", + "", + "blankmenubar=no,status=no,toolbar=no,resizable=no,width=350,height=370,titlebar=no,alwaysRaised=yes" + ); +} + //console window title // https://stackoverflow.com/questions/29548477/how-do-you-set-the-terminal-tab-title-from-node-js -process.stdout.write(String.fromCharCode(27) + "]0;" + c.WINDOW_NAME + String.fromCharCode(7)); +process.stdout.write(String.fromCharCode(27) + "]0;" + Config.WINDOW_NAME + String.fromCharCode(7)); util.log(room.width + " x " + room.height + " room initalized."); @@ -59,23 +67,23 @@ function collide(collision) { } if ( (!instance.activation.check() && !other.activation.check()) || - (instance.ac && !instance.alpha) || - (other.ac && !other.alpha) + (instance.isArenaCloser && !instance.alpha) || + (other.isArenaCloser && !other.alpha) ) return 0; switch (true) { case instance.type === "wall" || other.type === "wall": if (instance.type === "wall" && other.type === "wall") return; if (instance.type === "aura" || other.type === "aura") return; if (instance.type === "satellite" || other.type === "satellite") return; + if (instance.type === "shield" || other.type === "shield" || instance.type === "brella" || other.type === "brella") return; let wall = instance.type === "wall" ? instance : other; let entity = instance.type === "wall" ? other : instance; - if (entity.ac || entity.master.ac) return; - switch (true) { - case (wall.shape == 4): - case (wall.shapeData == "M 1 1 L -1 1 L -1 -1 L 1 -1 Z"): + if (entity.isArenaCloser || entity.master.isArenaCloser) return; + switch (wall.shape) { + case 4: mazewallcollide(wall, entity); break; - case (wall.shape == 0): + case 0: mooncollide(wall, entity); break; default: @@ -84,6 +92,35 @@ function collide(collision) { break; } break; + case instance.type === "shield" || other.type === "shield": + if (instance.type === "aura" || other.type === "aura" || instance.type === "satellite" || other.type === "satellite" || instance.type === "satellite" || other.type === "satellite" || instance.team === other.team) return; + let shield = instance.type === "shield" ? instance : other; + let nonshield = instance.type === "shield" ? other : instance; + switch (true) { + case (shield.shapeData == "m -0.7020 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099"): + mirrorcollide(shield, nonshield); + break; + default: + reflectcollide(shield, nonshield); + break; + } + break; + case instance.type === "brella" || other.type === "brella": + if (instance.type === "aura" || other.type === "aura" || instance.type === "satellite" || other.type === "satellite" || instance.type === "satellite" || other.type === "satellite" || instance.team === other.team) return; + let brella = instance.type === "brella" ? instance : other; + let nonbrella = instance.type === "brella" ? other : instance; + switch (true) { + default: + reflectcollide(brella, nonbrella); + break; + } + break; + case instance.type === "hookpoint" || other.type === "hookpoint": + + let hookpoint = instance.type === "hookpoint" ? instance : other; + let hook = instance.type === "hookpoint" ? other : instance; + simplecollide(hookpoint, hook) + break; case instance.team === other.team && (instance.settings.hitsOwnType === "pushOnlyTeam" || other.settings.hitsOwnType === "pushOnlyTeam"): @@ -99,6 +136,9 @@ function collide(collision) { advancedcollide(pusher, entity, false, false, a); } break; + case instance.type === "popup" || other.type === "popup": + reopenPopup(); + break; case (instance.type === "crasher" && other.type === "food" && instance.team === other.team) || (other.type === "crasher" && instance.type === "food" && other.team === instance.team): firmcollide(instance, other); @@ -276,9 +316,9 @@ let maintainloop = () => { instance.health.regenerate(instance.shield.max && instance.shield.max === instance.shield.amount); } } - if (!naturallySpawnedBosses.length && bossTimer++ > c.BOSS_SPAWN_COOLDOWN) { - bossTimer = -c.BOSS_SPAWN_DURATION; - let selection = c.BOSS_TYPES[ran.chooseChance(...c.BOSS_TYPES.map((selection) => selection.chance))], + if (!naturallySpawnedBosses.length && bossTimer++ > Config.BOSS_SPAWN_COOLDOWN) { + bossTimer = -Config.BOSS_SPAWN_DURATION; + let selection = Config.BOSS_TYPES[ran.chooseChance(...Config.BOSS_TYPES.map((selection) => selection.chance))], amount = ran.chooseChance(...selection.amount) + 1; if (selection.message) { sockets.broadcast(selection.message); @@ -304,25 +344,25 @@ let maintainloop = () => { } sockets.broadcast(`${util.listify(names)} ${names.length == 1 ? 'has' : 'have'} arrived!`); - }, c.BOSS_SPAWN_DURATION * 30); + }, Config.BOSS_SPAWN_DURATION * 30); } // upgrade existing ones for (let i = 0; i < bots.length; i++) { let o = bots[i]; - if (o.skill.level < c.LEVEL_CAP) { - o.skill.score += c.BOT_XP; + if (o.skill.level < Config.LEVEL_CAP) { + o.skill.score += Config.BOT_XP; } o.skill.maintain(); - o.skillUp([ "atk", "hlt", "spd", "str", "pen", "dam", "rld", "mob", "rgn", "shi" ][ran.chooseChance(...c.BOT_SKILL_UPGRADE_CHANCES)]); + o.skillUp([ "atk", "hlt", "spd", "str", "pen", "dam", "rld", "mob", "rgn", "shi" ][ran.chooseChance(...Config.BOT_SKILL_UPGRADE_CHANCES)]); if (o.leftoverUpgrades && o.upgrade(ran.irandomRange(0, o.upgrades.length))) { o.leftoverUpgrades--; } } // then add new bots if arena is open - if (!global.arenaClosed && bots.length < c.BOTS) { - let team = c.MODE === "tdm" ? getWeakestTeam() : undefined, + if (!global.arenaClosed && bots.length < Config.BOTS) { + let team = Config.MODE === "tdm" ? getWeakestTeam() : undefined, limit = 20, // give up after 20 attempts and just pick whatever is currently chosen loc; do { @@ -330,13 +370,13 @@ let maintainloop = () => { } while (limit-- && dirtyCheck(loc, 50)) let o = new Entity(loc); o.define('bot'); - o.define(c.SPAWN_CLASS); + o.define(Config.SPAWN_CLASS); o.refreshBodyAttributes(); - o.skill.score = c.BOT_START_XP; + o.skill.score = Config.BOT_START_XP; o.isBot = true; o.name = Config.BOT_NAME_PREFIX + ran.chooseBotName(); - o.leftoverUpgrades = ran.chooseChance(...c.BOT_CLASS_UPGRADE_CHANCES); - let color = c.RANDOM_COLORS ? Math.floor(Math.random() * 20) : team ? getTeamColor(team) : "darkGrey"; + o.leftoverUpgrades = ran.chooseChance(...Config.BOT_CLASS_UPGRADE_CHANCES); + let color = Config.RANDOM_COLORS ? Math.floor(Math.random() * 20) : team ? getTeamColor(team) : "darkGrey"; o.color.base = color; if (team) o.team = team; bots.push(o); @@ -345,7 +385,7 @@ let maintainloop = () => { }; //evaluating js with a seperate console window if enabled -if (c.REPL_WINDOW) { +if (Config.REPL_WINDOW) { util.log('Starting REPL Terminal.'); //TODO: figure out how to spawn a seperate window and put the REPL stdio in there instead //let { stdin, stdout, stderr } = (require('child_process').spawn("cmd.exe", ["/c", "node", "blank.js"], { detached: true })); @@ -359,7 +399,7 @@ setInterval(() => { gamemodeLoop(); roomLoop(); - if (counter++ / c.runSpeed > 30) { + if (counter++ / Config.runSpeed > 30) { chatLoop(); maintainloop(); speedcheckloop(); @@ -367,4 +407,4 @@ setInterval(() => { } syncedDelaysLoop(); -}, room.cycleSpeed); +}, room.cycleSpeed); \ No newline at end of file diff --git a/server/lib/hshg.js b/server/lib/hshg.js index 9374fdf4c..3d6b7a59c 100644 --- a/server/lib/hshg.js +++ b/server/lib/hshg.js @@ -627,4 +627,4 @@ you never will because we fired you lol testAABBOverlap: testAABBOverlap, getLongestAABBEdge: getLongestAABBEdge, }; -})(this); +})(this); \ No newline at end of file diff --git a/server/lib/util.js b/server/lib/util.js index 2a0a8d0ee..307cd5bd7 100644 --- a/server/lib/util.js +++ b/server/lib/util.js @@ -16,6 +16,8 @@ exports.getDirection = (p1, p2) => Math.atan2(p2.y - p1.y, p2.x - p1.x) exports.clamp = (value, min, max) => Math.min(Math.max(value, min), max) +exports.lerp = (value, target, scale) => value + scale * (target - value) + exports.listify = list => { if (list.length === 0) return '' if (list.length === 1) return list[0] diff --git a/server/modules/debug/speedLoop.js b/server/modules/debug/speedLoop.js index c24120637..500b864d0 100644 --- a/server/modules/debug/speedLoop.js +++ b/server/modules/debug/speedLoop.js @@ -12,11 +12,14 @@ const speedcheckloop = () => { let loops = logs.loops.count(), active = logs.entities.count(); global.fps = (1000 / sum).toFixed(2); - if (sum > 1000 / c.runSpeed / 30) { + if (sum > 1000 / Config.runSpeed / 30) { + for (let entity of entities) { + util.warn(...entity.defs) + } //fails++; - if (c.LOGS) { + if (Config.LOGS) { util.warn('~~ LAST SERVER TICK TOOK TOO LONG TO CALCULATE ~~'); - util.warn('~~ LOOPS: ' + loops + '. ENTITIES: ' + entities.length + '//' + Math.round(active / loops) + '. VIEWS: ' + views.length + '. BACKLOGGED :: ' + (sum * c.runSpeed * 3).toFixed(3) + '%! ~~'); + util.warn('~~ LOOPS: ' + loops + '. ENTITIES: ' + entities.length + '//' + Math.round(active / loops) + '. VIEWS: ' + views.length + '. BACKLOGGED :: ' + (sum * Config.runSpeed * 3).toFixed(3) + '%! ~~'); util.warn('Total activation time: ' + activationtime); util.warn('Total collision time: ' + collidetime); util.warn('Total cycle time: ' + movetime); diff --git a/server/modules/definitions/addons/amongus.js b/server/modules/definitions/addons/amongus.js new file mode 100644 index 000000000..7f675df15 --- /dev/null +++ b/server/modules/definitions/addons/amongus.js @@ -0,0 +1,108 @@ + //UNCOMMENT LINE 11 TO DISABLE + //return + console.log('[AMONG US CREWMATE] Addon running'); + + Class.OSAmongus_basebody = { + PARENT: ["genericTank"], + LABEL: "", + SHAPE: "M -0.731 1.979 Q -1.279 -2.215 -0.005 -2.244 Q 1.635 -2.31 1.485 0 Q 1.415 1.801 0.992 1.822 Q 0.599 1.847 0.591 1.342 Q 0.888 1.29 1.078 1.056 Q 0.551 1.132 0.03 1.073 L -0.008 1.871 Q -0.304 2.162 -0.727 1.982", + } + Class.OSAmongus_basebodyshadow = { + PARENT: ["genericTank"], + LABEL: "", + BORDERLESS: true, + SHAPE: "M 0.431 0.765 C -0.809 0.861 -0.8 -0.981 -0.573 -1.968 C -0.451 -2.449 1.348 -2.396 1.331 -1.051 C 1.829 0.495 0.85 0.826 0.423 0.774", + } + Class.OSAmongus_backpack= { + PARENT: ["genericTank"], + LABEL: "", + SHAPE: "M-.6.9-1 1Q-1.615 1.258-1.567-.014-1.581-1.214-1.094-1.014L-1.095-1.009-.7-.9", + } + Class.OSAmongus_backpackshadow= { + PARENT: ["genericTank"], + BORDERLESS: true, + LABEL: "", + SHAPE: "M -1.11 -0.781 C -1.125 -0.812 -1.481 -0.806 -1.532 -0.734 C -1.507 -0.874 -1.517 -1.033 -1.316 -1.033 C -1.073 -1.069 -1.053 -1.028 -1.11 -0.791", + } + Class.OSAmongus_visor= { + PARENT: ["genericTank"], + LABEL: "", + SHAPE: "M 0.004 -1.131 C -0.007 -0.231 1.655 -0.524 1.649 -1.097 C 1.741 -1.807 0.027 -1.962 -0.001 -1.131", + } + Class.OSAmongus_visorshadow= { + PARENT: ["genericTank"], + BORDERLESS: true, + LABEL: "", + SHAPE: "M 0.178 -1.402 C 0.05 -0.851 1.667 -0.668 1.642 -1.374 C 1.654 -1.609 0.251 -1.785 0.175 -1.411", + } + Class.OSAmongus_visorhighlight= { + PARENT: ["genericTank"], + BORDERLESS: true, + LABEL: "", + SHAPE: "M 0.178 -1.402 C 0.05 -0.851 1.667 -0.668 1.642 -1.374 C 1.654 -1.609 0.251 -1.785 0.175 -1.411", + } + Class.OSAmongus_crewmatebase= { + PARENT: ["genericTank"], + LABEL: "AMONG US", + SHAPE: "M 0.178", + COLOR: 12, + TURRETS:[ + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_backpack", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_backpackshadow", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 0,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_basebody", {MIRROR_MASTER_ANGLE: true, COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_basebodyshadow", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: -1, BRIGHTNESS_SHIFT: 0,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_visor", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 10, BRIGHTNESS_SHIFT: -15,}}], + }, + { + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["OSAmongus_visorshadow", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 10, BRIGHTNESS_SHIFT: 0,}}], + }, + { + POSITION: [5, 2.75, -4, 0, 0, 1], + TYPE: ["OSAmongus_visorhighlight", {MIRROR_MASTER_ANGLE: true, COLOR:{BASE: 8, BRIGHTNESS_SHIFT: 0,}}], + }, + ], + } + Class.addons.UPGRADES_TIER_0.push("OSAmongus_crewmatebase"); + Class.OSAmongus_crewmatebase.UPGRADES_TIER_0 = []; + const colors = [ + "red", + "orange", + "gold", + "brown", + "green", + "blue", + "cyan", + "teal", + "pink", + "purple", + "magenta", + "veryLightGray", + "darkGray", + "animatedLesbian", + "animatedTrans", + "rainbow", + ] + for (let i = 0; i < colors.length; i++) { + Class["OSAmongus_" + colors[i] + "crewmate"] = { + PARENT: ["OSAmongus_crewmatebase"], + COLOR: colors[i] + + }; + + Class.OSAmongus_crewmatebase.UPGRADES_TIER_0.push("OSAmongus_" + colors[i] + "crewmate"); +} \ No newline at end of file diff --git a/server/modules/definitions/addons/basicChatModeration.js b/server/modules/definitions/addons/basicChatModeration.js index 5f2c04fe1..decdaafc7 100644 --- a/server/modules/definitions/addons/basicChatModeration.js +++ b/server/modules/definitions/addons/basicChatModeration.js @@ -19,7 +19,7 @@ module.exports = ({ Events }) => { // Fortunately, this returns false if 'recent[id] is 'undefined'. if (recent[id] >= ratelimit) { preventDefault(); // 'preventDefault()' prevents the message from being sent. - socket.talk('m', c.MESSAGE_DISPLAY_TIME, 'Please slow down!'); + socket.talk('m', Config.MESSAGE_DISPLAY_TIME, 'Please slow down!'); return; } @@ -42,10 +42,9 @@ module.exports = ({ Events }) => { // If message above the character limit, lets stop that from getting through if (message.length > 256) { preventDefault(); - socket.talk('m', c.MESSAGE_DISPLAY_TIME, 'Too long!') + socket.talk('m', Config.MESSAGE_DISPLAY_TIME, 'Too long!') } }); console.log('[basicChatModeration] Loaded spam prevention!'); -}; - +}; \ No newline at end of file diff --git a/server/modules/definitions/addons/cooper.js b/server/modules/definitions/addons/cooper.js new file mode 100644 index 000000000..f03dfee49 --- /dev/null +++ b/server/modules/definitions/addons/cooper.js @@ -0,0 +1,30 @@ +const { combineStats, makeAuto, makeOver, makeDeco, makeGuard, makeBird, makeCeption } = require('../facilitators.js'); +const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); +require('../groups/generics.js'); +const g = require('../gunvals.js'); + +Class.sandwichdeco = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled%20Project%20(22).jpg?v=1708356424097"); + +Class.A = { + PARENT: "genericTank", + LABEL: "ChickenSandwichTank", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single, g.op]), + TYPE: "bullet" + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ], + TURRETS: [{ + POSITION: [11, 0, 0, 0, 0, 99], + TYPE: "sandwichdeco" + }] +}; + +Class.addons.UPGRADES_TIER_0.push("A") \ No newline at end of file diff --git a/server/modules/definitions/addons/dailyTanks.js b/server/modules/definitions/addons/dailyTanks.js new file mode 100644 index 000000000..dba1c71fc --- /dev/null +++ b/server/modules/definitions/addons/dailyTanks.js @@ -0,0 +1,1347 @@ +const { dereference, combineStats, makeMulti, makeDeco, makeAuto, makeOver, weaponArray } = require('../facilitators.js'); +const { base, gunCalcNames, statnames, dfltskl, smshskl } = require('../constants.js'); +const g = require('../gunvals.js'); + +const addToMain = true + +// Bullets +Class.masterBullet = { + PARENT: "missile", + FACING_TYPE: "veryfastspin", + MOTION_TYPE: "motor", + HAS_NO_RECOIL: false, + DIE_AT_RANGE: false, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront]), + TYPE: "bullet", + LABEL: "Front", + AUTOFIRE: true, + }, + }, + { + POSITION: [13, 8, 1, 0, -1, 140, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "Thruster", + AUTOFIRE: true, + }, + }, + { + POSITION: [13, 8, 1, 0, 1, 220, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "Thruster", + AUTOFIRE: true, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "Thruster", + AUTOFIRE: true, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: "Thruster", + AUTOFIRE: true, + }, + }, + ], +} + +Class.squareSatellite = { + PARENT: "satellite", + SHAPE: 4 +} + +// Turrets +Class.lamgSpinnerTurret = { + PARENT: "genericTank", + LABEL: "Spinner Turret", + GUNS: weaponArray({ + POSITION: [15, 3.5, 1, 0, 0, 0, 0] + }, 10) +} + +// Decorations +Class.tornadoDeco = makeDeco(4); +Class.tornadoDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.megaTornadoDeco = makeDeco([[0,-1],[0.5,0],[0,1],[-0.5,0]]) +Class.megaTornadoDeco.CONTROLLERS = [["spin", { independent: true }]]; +Class.tempestDeco1 = makeDeco(3); +Class.tempestDeco1.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.tempestDeco2 = makeDeco(3); +Class.tempestDeco2.CONTROLLERS = [["spin", { independent: true, speed: -0.128 }]]; +Class.thunderboltDeco = makeDeco(4); +Class.thunderboltDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.16 }]]; +Class.hurricaneDeco = makeDeco(8); +Class.hurricaneDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.typhoonDeco = makeDeco(10); +Class.typhoonDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.blizzardDeco1 = makeDeco(5); +Class.blizzardDeco1.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]]; +Class.blizzardDeco2 = makeDeco(5); +Class.blizzardDeco2.CONTROLLERS = [["spin", { independent: true, speed: -0.128 }]]; + +// Whirlwind upgrades +Class.dlywhirlwind = { + PARENT: "genericTank", + LABEL: "Whirlwind", + //UPGRADE_TOOLTIP: "Daily Tank!", + //UPGRADE_COLOR: "rainbow", + ANGLE: 60, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "whirlwindDeco" + } + ], + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 6; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 60}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.tornado = { + PARENT: "genericTank", + LABEL: "Tornado", + DANGER: 6, + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + ANGLE: 90, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 4; i++) { + output.push({ + POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), + TYPE: ["satellite", {ANGLE: i * 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.hurricane = { + PARENT: ["genericTank"], + LABEL: "Hurricane", + DANGER: 6, + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "hurricaneDeco", + }, + ], + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 8; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 45}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.hexaWhirl = { + PARENT: ["genericTank"], + LABEL: "Hexa Whirl", + DANGER: 7, + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [18, 8, 1, 0, 0, 300, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} +Class.munition = { + PARENT: ["genericTank"], + DANGER: 7, + LABEL: "Munition", + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + POSITION: [17, 3, 1, 0, -6, -7, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [17, 3, 1, 0, 6, 7, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.gunner, g.artillery]), + TYPE: "bullet", + LABEL: "Secondary", + }, + }, + { + POSITION: [19, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery]), + TYPE: "bullet", + LABEL: "Heavy", + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} +Class.whirl3 = { + PARENT: "genericTank", + LABEL: "Whirl-3", + DANGER: 7, + FACING_TYPE: "autospin", + ANGLE: 90, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + { + POSITION: [11, 8, 0, 0, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 120, 190, 0], + TYPE: "autoTankGun", + }, + { + POSITION: [11, 8, 0, 240, 190, 0], + TYPE: "autoTankGun", + }, + ], + GUNS: (() => { + let output = [] + for (let i = 0; i < 4; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }) + } + return output + })() +} +Class.whirlGuard = { + PARENT: ["genericTank"], + LABEL: "Whirl Guard", + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + DANGER: 7, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet", + }, + }, + { + POSITION: [13, 8, 1, 0, 0, 180, 0], + }, + { + POSITION: [4, 8, 1.7, 13, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} +Class.prophet = { + PARENT: ["genericTank"], + LABEL: "Prophet", + DANGER: 7, + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + BODY: { + SPEED: 0.9 * base.SPEED, + }, + AI: { + SPEED: 2, + }, + SHAPE: 4, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + POSITION: [5.25, 12, 1.2, 8, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + MAX_CHILDREN: 7, + }, + }, + { + POSITION: [5.25, 12, 1.2, 8, 0, 270, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + MAX_CHILDREN: 7, + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["squareSatellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["squareSatellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["squareSatellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["squareSatellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} +Class.vortex = { + PARENT: ["genericTank"], + LABEL: "Vortex", + BODY: { + FOV: base.FOV * 1.1, + }, + ANGLE: 45, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.mixed, + AI: { + SPEED: 2, + }, + DANGER: 7, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tornadoDeco", + }, + ], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [10, 9, 1, 9, 0, 0, 0], + }, + { + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery]), + TYPE: "minimissile", + STAT_CALCULATOR: gunCalcNames.sustained, + }, + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 0}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + }, + { + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: 270}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true, + HAS_NO_RECOIL: true + } + } + ], +} + +// Tornado upgrades +Class.megaTornado = { + PARENT: "genericTank", + LABEL: "Mega Tornado", + DANGER: 7, + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: "megaTornadoDeco", + }, + ], + ANGLE: 180, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 2; i++) { + output.push({ + POSITION: {WIDTH: 16, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder, g.destroyer]), + TYPE: ["satellite", {ANGLE: i * 180}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.tempest = { + PARENT: "genericTank", + LABEL: "Tempest", + DANGER: 7, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "tempestDeco1", + }, + { + POSITION: [4, 0, 0, 180, 360, 1], + TYPE: "tempestDeco2", + }, + ], + ANGLE: 120, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 3; i++) { + output.push({ + POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), + TYPE: ["satellite", {ANGLE: i * 120}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + for (let i = 0; i < 3; i++) { + output.push({ + POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), + TYPE: ["satellite", { ANGLE: i * 120, CONTROLLERS: [['orbit', {invert: true}]] }], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.thunderbolt = { + PARENT: ["genericTank"], + LABEL: "Thunderbolt", + DANGER: 7, + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "thunderboltDeco", + }, + ], + ANGLE: 90, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2.5, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 4; i++) { + output.push({ + POSITION: {WIDTH: 12, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite, g.pounder]), + TYPE: ["satellite", {ANGLE: i * 90}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} + +// Hurricane upgrades +Class.typhoon = { + PARENT: ["genericTank"], + LABEL: "Typhoon", + DANGER: 7, + ANGLE: 36, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "typhoonDeco", + }, + ], + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 10; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 36}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} +Class.blizzard = { + PARENT: "genericTank", + LABEL: "Blizzard", + DANGER: 7, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "blizzardDeco1", + }, + { + POSITION: [6, 0, 0, 180, 360, 1], + TYPE: "blizzardDeco2", + }, + ], + ANGLE: 72, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 5; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", {ANGLE: i * 72}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + for (let i = 0; i < 5; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["satellite", { ANGLE: i * 72, CONTROLLERS: [['orbit', {invert: true}]] }], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: false, + WAIT_TO_CYCLE: true + } + }) + } + return output + })() +} + +// Whirlwind upgrade paths +Class.dlywhirlwind.UPGRADES_TIER_2 = ["tornado", "hurricane", "revolutionist"] + Class.dlywhirlwind.UPGRADES_TIER_3 = ["hexaWhirl", "munition", "whirl3", "whirlGuard", "prophet", "vortex"] + Class.tornado.UPGRADES_TIER_3 = ["megaTornado", "tempest", "thunderbolt"] + Class.hurricane.UPGRADES_TIER_3 = ["typhoon", "blizzard"] + +// December 14th - Master +Class.master = { + PARENT: "genericTank", + LABEL: "Master", + UPGRADE_TOOLTIP: "Daily Tank!", + UPGRADE_COLOR: "rainbow", + BODY: { + HEALTH: base.HEALTH * 0.4, + SHIELD: base.SHIELD * 0.4, + DENSITY: base.DENSITY * 0.3, + }, + DANGER: 8, + GUNS: [ + { + POSITION: [18, 16, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "masterBullet", + MAX_CHILDREN: 4, + DESTROY_OLDEST_CHILD: true, + }, + }, + { + POSITION: [13, 8, 1, 0, -1, 140, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [13, 8, 1, 0, 1, 220, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + ], +} + +// December 16th - Literally a Machine Gun +Class.literallyAMachineGun = { + PARENT: "genericTank", + LABEL: "Literally a Machine Gun", + UPGRADE_TOOLTIP: "Daily Tank!", + UPGRADE_COLOR: "rainbow", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2 + }, + TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + TURRETS: [ + { + POSITION: [10, 14, 0, 0, 0, 1], + TYPE: "lamgSpinnerTurret" + } + ], + GUNS: [ + { + POSITION: [22, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [2, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + } + ] +} + +// Dev shit +Class.dailyTanks = { + PARENT: "genericTank", + LABEL: "Daily Tanks!", + UPGRADE_COLOR: "rainbow", + UPGRADES_TIER_0: [ + "master", + "literallyAMachineGun", + "literallyATank", + "crayon", + ] +} + +// December 19th-20th - Jump Smasher +Class.jumpsmasherBody = { + LABEL: "", + CONTROLLERS: [["spin", { independent: true, speed: 0.3 }]], + COLOR: "black", + SHAPE: 8, + INDEPENDENT: true +} +Class.jumpSmasher = { + PARENT: "genericSmasher", + LABEL: "Jump Smasher", + //UPGRADE_TOOLTIP: "Daily Tank!", + //UPGRADE_COLOR: "rainbow", + DANGER: 7, + GUNS: [ + { + POSITION: [2, 10, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.tonsmorerecoil, g.tonsmorerecoil, g.halfreload, g.halfreload, g.halfreload, g.halfreload, g.norange]), + TYPE: "bullet", + ALT_FIRE: true + } + } + ], + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "jumpsmasherBody" + } + ] +} + +// *InsertCorrectDateHereCuzIdk* - Literally A Tank +class io_turretWithMotion extends IO { + constructor(b, opts = {}) { + super(b) + } + think(input) { + return { + target: this.body.master.velocity, + main: true, + }; + } +} +ioTypes.turretWithMotion = io_turretWithMotion +Class.latTop = makeDeco(0) +Class.latDeco1 = { + PARENT: "genericTank", + LABEL: "Tank Deco", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#5C533F", + SHAPE: "M -1 -2 C -1 -2 -1 -3 0 -3 C 1 -3 1 -2 1 -2 V 2 C 1 2 1 3 0 3 C -1 3 -1 2 -1 2 V -2", + MIRROR_MASTER_ANGLE: true, +} +Class.latDeco2 = { + PARENT: "genericTank", + LABEL: "Tank Deco", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#5C533F", + SHAPE: "M -2 0 H 2 L 0 1 L -2 0", + MIRROR_MASTER_ANGLE: true, +} +Class.latDeco3 = { + PARENT: "genericTank", + LABEL: "Tank Deco", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#3F3B2D", + SHAPE: "M -10 -1 L 10 -1 L 10 1 L -10 1 L -10 -1", + MIRROR_MASTER_ANGLE: true, +} +Class.latRight = { + PARENT: "genericTank", + LABEL: "Tank Side", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#96794E", + SHAPE: "M -6 0 H 5 V 1 C 5 2 4 2 4 2 H -5 C -6 2 -6 1 -6 1 V 0", + MIRROR_MASTER_ANGLE: true, + TURRETS: [ + { + POSITION: [4.8, 31, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 24, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 17, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -42, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -35, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -28, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [18, -5, 0, 0, 0, 1], + TYPE: "latDeco2", + }, + ] +} +Class.latLeft = { + PARENT: "genericTank", + LABEL: "Tank Side", + FACING_TYPE: ["turnWithSpeed"], + COLOR: "#96794E", + SHAPE: "M -5 0 H 6 V 1 C 6 2 5 2 5 2 H -4 C -5 2 -5 1 -5 1 V 0", + MIRROR_MASTER_ANGLE: true, + TURRETS: [ + { + POSITION: [4.8, -31, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -24, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, -17, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 42, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 35, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [4.8, 28, 10, 0, 0, 1], + TYPE: "latDeco1", + }, + { + POSITION: [18, 5, 0, 0, 0, 1], + TYPE: "latDeco2", + }, + ] +} +Class.latBase = { + PARENT: "genericTank", + LABEL: "Tank Base", + CONTROLLERS: ["turretWithMotion"], + COLOR: "#96794E", + SHAPE: [ + [1.1, 1], + [1.4, 0], + [1.1, -1], + [-1.1, -1], + [-0.8, 0], + [-1.1, 1] + ], + GUNS: [ + { + POSITION: [16, 5.5, 1, 1, 6.5, 0, 0] + }, + { + POSITION: [14.5, 5.5, 1, 1, 6.5, 0, 0] + }, + { + POSITION: [13, 5.5, 1, 1, 6.5, 0, 0] + }, + { + POSITION: [16, 5.5, 1, 1, -6.5, 0, 0] + }, + { + POSITION: [14.5, 5.5, 1, 1, -6.5, 0, 0] + }, + { + POSITION: [13, 5.5, 1, 1, -6.5, 0, 0] + }, + { + POSITION: [13, 5.5, 1, 1, 6.5, 180, 0] + }, + { + POSITION: [11.5, 5.5, 1, 1, 6.5, 180, 0] + }, + { + POSITION: [10, 5.5, 1, 1, 6.5, 180, 0] + }, + { + POSITION: [8.5, 5.5, 1, 1, 6.5, 180, 0] + }, + { + POSITION: [13, 5.5, 1, 1, -6.5, 180, 0] + }, + { + POSITION: [11.5, 5.5, 1, 1, -6.5, 180, 0] + }, + { + POSITION: [10, 5.5, 1, 1, -6.5, 180, 0] + }, + { + POSITION: [8.5, 5.5, 1, 1, -6.5, 180, 0] + }, + ], + TURRETS: [ + { + POSITION: [5.3, 0, -10, 0, 0, 1], + TYPE: "latLeft", + }, + { + POSITION: [5.3, 0, -10, 180, 0, 1], + TYPE: "latRight", + }, + { + POSITION: [2, 0, -1.4, 90, 0, 1], + TYPE: "latDeco3", + }, + ] +} +Class.literallyATank = { + PARENT: "genericTank", + UPGRADE_TOOLTIP: "Daily Tank!", + UPGRADE_COLOR: "rainbow", + DANGER: 6, + BODY: { + HEALTH: base.HEALTH * 1.2, + }, + LABEL: "Literally a Tank", + SHAPE: "M -1 -1 H 0 C 1 -1 1 0 1 0 C 1 0 1 1 0 1 H -1 V -1", + GUNS: [ + { + POSITION: [30, 8, 1, 0, 0, 0, 0] + }, + { + POSITION: [4, 8, -1.4, 8, 0, 0, 0] + }, + { + POSITION: [12, 8, 1.3, 30, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "developerBullet" + } + }, + { + POSITION: [2, 11, 1, 34, 0, 0, 0] + } + ], + TURRETS: [ + { + POSITION: [15, 0, 0, 0, 360, 1], + TYPE: [ "latTop", { COLOR: "#5C533F" } ], + }, + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: [ "latTop", { COLOR: "#736245" } ], + }, + { + POSITION: [35, 0, 0, 0, 360, 0], + TYPE: [ "latBase", { COLOR: "#96794E" } ], + }, + ] +} +Class.crayon = { + PARENT: "genericTank", + LABEL: "Crayon", + UPGRADE_COLOR: "rainbow", + UPGRADE_TOOLTIP: "Daily Tank!", + SIZE: 12, + SHAPE: 0, + GUNS: [{ + POSITION: [16.615, 6.4, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet" + } + }, { + POSITION: [16.615, 6.4, 1, 0, -5.538, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet" + }, + }, + { + POSITION: [16.615, 6.4, 1, 0, 5.538, 0, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "bullet" + }, + }, + ], +}; +Class.autocrayon = makeAuto('crayon', 'Auto Crayon'); + +Class.crayon.UPGRADES_TIER_3 = ["autocrayon"]; + +//let dlytanks = ["master", "literallyATank", "literallyAMachineGun", "crayon"]; +//dailytank = dlytanks[global.dayofweek]; + +if (addToMain == true) { +Class.basic.UPGRADES_TIER_1.push("dlywhirlwind") +Class.smasher.UPGRADES_TIER_3.push("jumpSmasher") +Class.hexaTank.UPGRADES_TIER_3.push("hexaWhirl") +Class.artillery.UPGRADES_TIER_3.push("munition") +Class.auto3.UPGRADES_TIER_3.push("whirl3") +Class.trapGuard.UPGRADES_TIER_3.push("whirlGuard") +Class.underseer.UPGRADES_TIER_3.push("prophet") +Class.launcher.UPGRADES_TIER_3.push("vortex") +} else { +//Class.basic.UPGRADES_TIER_3 = [dailytank] +} +Class.addons.UPGRADES_TIER_3 = ["dailyTanks"]; \ No newline at end of file diff --git a/server/modules/definitions/addons/dreadv1.js b/server/modules/definitions/addons/dreadv1.js index 1d59d6a96..9edf9932b 100644 --- a/server/modules/definitions/addons/dreadv1.js +++ b/server/modules/definitions/addons/dreadv1.js @@ -9,6 +9,7 @@ const dreadnoughtBody = { SHIELD: base.SHIELD * 2.5, FOV: base.FOV * 1.4, DENSITY: base.DENSITY * 6, + REGEN: base.REGEN, }; g.dreadv1Generic = { health: 1.4, @@ -21,20 +22,22 @@ g.dreadv1Slow = { maxSpeed: 0.65, }; g.dreadv1Drone = { - health: 1.3, - speed: 0.9, - maxSpeed: 0.9, - reload: 1.4, + health: 1.32, + speed: 0.68, + maxSpeed: 0.68, + reload: 0.8, size: 1.2 } g.dreadv1Trap = { range: 0.9, shudder: 0.2, - reload: 1.75 + speed: 1.15, + reload: 3, + health: 1.75, } // Comment out the line below to enable this addon, uncomment it to disable this addon. -//return console.log('--- Dreadnoughts v1 addon [dreadv1.js] is disabled. See lines 32-33 to enable it. ---'); +// return console.log('--- Dreadnoughts v1 addon [dreadv1.js] is disabled. See lines 32-33 to enable it. ---'); // Set the below variable to true to enable the Medicare and Medicaid healing bodies. const enableHealers = true; @@ -154,7 +157,7 @@ Class.weakMinion = { { POSITION: [17, 9, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, {health: 0.4, speed: 0.8, maxSpeed: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, {health: 0.45, speed: 0.8, maxSpeed: 0.8}]), WAIT_TO_CYCLE: true, TYPE: "bullet", }, @@ -375,7 +378,7 @@ Class.inquisitorOfficialV1 = { GUNS: weaponArray({ POSITION: [7, 7.5, 1.3, 7.5, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.dreadv1Drone, {health: 0.95}]), + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.dreadv1Drone, {speed: 0.95, maxSpeed: 0.95, damage: 0.9, health: 0.92}]), TYPE: "drone", AUTOFIRE: true, SYNCS_SKILLS: true, @@ -391,19 +394,19 @@ Class.assailantOfficialV1 = { UPGRADE_TOOLTIP: "Minions", GUNS: weaponArray([ { - POSITION: [13.5, 8, 1, 0, 0, 0, 0], + POSITION: [13.75, 8, 1, 0, 0, 0, 0], }, { - POSITION: [1.5, 10, 1, 13.5, 0, 0, 0], + POSITION: [1, 10, 1, 13.75, 0, 0, 0], PROPERTIES: { MAX_CHILDREN: 4, - SHOOT_SETTINGS: combineStats([g.factory, g.overseer, g.dreadv1Drone, {health: 0.65, reload: 0.7}]), + SHOOT_SETTINGS: combineStats([g.factory, g.overseer, g.dreadv1Drone, {damage: 0.6, speed: 0.85, maxSpeed: 0.85}]), TYPE: "weakMinion", STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, SYNCS_SKILLS: true } }, { - POSITION: [11.5, 10, 1, 0, 0, 0, 0] + POSITION: [12.25, 10, 1, 0, 0, 0, 0] } ], 3) } @@ -596,8 +599,8 @@ for (let primary of Class.dreadOfficialV1.UPGRADES_TIER_1) { if (secondary.TURRETS) TURRETS.push(...secondary.TURRETS); // Body - if (primary.BODY) for (let m in primary.BODY) BODY *= primary.BODY[m]; - if (secondary.BODY) for (let m in secondary.BODY) BODY *= secondary.BODY[m]; + if (primary.BODY) for (let m in primary.BODY) BODY[m] *= primary.BODY[m]; + if (secondary.BODY) for (let m in secondary.BODY) BODY[m] *= secondary.BODY[m]; // Definition name let definitionName = primaryName + secondaryName; @@ -658,4 +661,4 @@ for (let primary of Class.dreadOfficialV1.UPGRADES_TIER_1) { } } } -} +} \ No newline at end of file diff --git a/server/modules/definitions/addons/dreadv2.js b/server/modules/definitions/addons/dreadv2.js index 3cc2dcda4..e3e5d95ad 100644 --- a/server/modules/definitions/addons/dreadv2.js +++ b/server/modules/definitions/addons/dreadv2.js @@ -1,4 +1,4 @@ -const { combineStats, addAura, makeAuto } = require('../facilitators.js'); +const { combineStats, addAura, makeAuto, weaponArray, dereference } = require('../facilitators.js'); const { gunCalcNames, smshskl, base } = require('../constants.js'); const g = require('../gunvals.js'); @@ -47,6 +47,17 @@ const hexnoughtBody = { RESIST: base.RESIST, DENSITY: base.DENSITY * 3.5, }; +const hpBuffBodyStats = [ + { HEALTH: 1.65, SPEED: 1.2, SHIELD: 1.4, REGEN: 1.3 }, + { HEALTH: 2, SPEED: 1.33, SHIELD: 1.65, REGEN: 1.45 }, + { HEALTH: 2.3, SPEED: 1.45, SHIELD: 1.9, REGEN: 1.6 }, + { HEALTH: 2.55, SPEED: 1.55, SHIELD: 2.15, REGEN: 1.7 }, +]; +const speedBuffBodyStats = [ + { HEALTH: 0.75, SPEED: 2.1, SHIELD: 0.85, REGEN: 1 }, + { HEALTH: 0.62, SPEED: 2.45, SHIELD: 0.72, REGEN: 0.9 }, + { HEALTH: 0.55, SPEED: 2.75, SHIELD: 0.6, REGEN: 0.8 }, +]; // Comment out the line below to enable this addon, uncomment it to disable this addon. // return console.log('--- Dreadnoughts v2 addon [dreadv2.js] is disabled. See lines 60-61 to enable it. ---'); @@ -120,6 +131,19 @@ Class.spamAutoTurret = { }, ], } +Class.spamAutoTurretWeak = { + PARENT: "autoTankGun", + INDEPENDENT: true, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard, g.autoTurret, {reload: 1.1, health: 0.9, damage: 0.8, recoil: 0.2}]), + TYPE: "bullet", + }, + }, + ], +} Class.supermissile = { PARENT: "bullet", LABEL: "Missile", @@ -132,25 +156,23 @@ Class.supermissile = { POSITION: [14, 6, 1, 0, -2, 130, 0], PROPERTIES: { AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, { reload: 0.5 }, g.lowPower, { recoil: 1.35 }, { speed: 1.3, maxSpeed: 1.3 }, { speed: 1.3, maxSpeed: 1.3 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower, {speed: 1.3, maxSpeed: 1.3}]), TYPE: ["bullet", {PERSISTS_AFTER_DEATH: true}], STAT_CALCULATOR: gunCalcNames.thruster, }, - }, - { + }, { POSITION: [14, 6, 1, 0, 2, 230, 0], PROPERTIES: { AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, { reload: 0.5 }, g.lowPower, { recoil: 1.35 }, { speed: 1.3, maxSpeed: 1.3 }, { speed: 1.3, maxSpeed: 1.3 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower, {speed: 1.3, maxSpeed: 1.3}]), TYPE: ["bullet", {PERSISTS_AFTER_DEATH: true}], STAT_CALCULATOR: gunCalcNames.thruster, }, - }, - { + }, { POSITION: [14, 6, 1, 0, 0, 0, 0.2], PROPERTIES: { AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, { reload: 0.5 }, { speed: 1.3, maxSpeed: 1.3 }, { speed: 1.3, maxSpeed: 1.3 }]), + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower, g.skimmer, {speed: 1.3, maxSpeed: 1.3}]), TYPE: ["bullet", {PERSISTS_AFTER_DEATH: true}], }, }, @@ -189,18 +211,13 @@ Class.dreadBodyOfficialV2 = { Class.swordOfficialV2 = { PARENT: "genericEggnought", LABEL: "Sword", - GUNS: [], -} -for (let i = 0; i < 2; i++) { - Class.swordOfficialV2.GUNS.push( - { - POSITION: [20, 7, 1, 0, 0, 180*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, {reload: 0.85}]), - TYPE: "bullet", - }, + GUNS: weaponArray({ + POSITION: [20, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, {reload: 1.1, health: 1.2}]), + TYPE: "bullet", }, - ) + }, 2), } Class.sword2OfficialV2 = { PARENT: "swordOfficialV2", @@ -209,18 +226,13 @@ Class.sword2OfficialV2 = { Class.pacifierOfficialV2 = { PARENT: "genericEggnought", LABEL: "Pacifier", - GUNS: [], -} -for (let i = 0; i < 2; i++) { - Class.pacifierOfficialV2.GUNS.push( - { - POSITION: [15, 7, 1, 0, 0, 180*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, {reload: 0.8}]), - TYPE: "bullet", - }, + GUNS: weaponArray({ + POSITION: [15, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, {speed: 0.9, maxSpeed: 0.9, health: 1.15}]), + TYPE: "bullet", }, - ) + }, 2), } Class.pacifier2OfficialV2 = { PARENT: "pacifierOfficialV2", @@ -229,18 +241,13 @@ Class.pacifier2OfficialV2 = { Class.peacekeeperOfficialV2 = { PARENT: "genericEggnought", LABEL: "Peacekeeper", - GUNS: [], -} -for (let i = 0; i < 2; i++) { - Class.peacekeeperOfficialV2.GUNS.push( - { - POSITION: [17, 9, 1, 0, 0, 180*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, {reload: 1.2, damage: 1.5}]), - TYPE: "bullet", - }, + GUNS: weaponArray({ + POSITION: [17, 9, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 0.9, damage: 0.96}]), + TYPE: "bullet", }, - ) + }, 2), } Class.peacekeeper2OfficialV2 = { PARENT: "peacekeeperOfficialV2", @@ -249,23 +256,18 @@ Class.peacekeeper2OfficialV2 = { Class.invaderOfficialV2 = { PARENT: "genericEggnought", LABEL: "Invader", - GUNS: [], -} -for (let i = 0; i < 2; i++) { - Class.invaderOfficialV2.GUNS.push( - { - POSITION: [5, 9, 1.2, 8, 0, 180*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, {reload: 0.85}]), - TYPE: "drone", - MAX_CHILDREN: 4, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - }, - }, - ) + GUNS: weaponArray({ + POSITION: [5, 9, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, {reload: 0.9, health: 1.05}]), + TYPE: "drone", + MAX_CHILDREN: 4, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + }, + }, 2), } Class.invader2OfficialV2 = { PARENT: "invaderOfficialV2", @@ -274,22 +276,18 @@ Class.invader2OfficialV2 = { Class.centaurOfficialV2 = { PARENT: "genericEggnought", LABEL: "Centaur", - GUNS: [], -} -for (let i = 0; i < 2; i++) { - Class.centaurOfficialV2.GUNS.push( - { - POSITION: [13, 7, 1, 0, 0, 180*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [3, 7, 1.5, 13, 0, 180*i, 0], + POSITION: [13, 7, 1, 0, 0, 0, 0], + }, { + POSITION: [3, 7, 1.5, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, {health: 2}]), + SHOOT_SETTINGS: combineStats([g.trap, g.pounder, {shudder: 0.4}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, }, }, - ) + ], 2), } Class.centaur2OfficialV2 = { PARENT: "centaurOfficialV2", @@ -304,7 +302,7 @@ Class.byteTurretOfficialV2 = { { POSITION: [22, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {health: 1.2, speed: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.turret, {health: 1.2, speed: 0.85, recoil: 1.15}]), TYPE: "bullet", }, }, @@ -315,14 +313,16 @@ Class.byteOfficialV2 = { LABEL: "Byte", TURRETS: [ { - POSITION: [15, 0, 0, 0, 0, 1], - TYPE: 'egg', - }, - { - POSITION: [9, 0, 0, 0, 360, 1], + POSITION: [9, 0, 0, 0, 360, 2], TYPE: 'byteTurretOfficialV2', - }, + } ], + PROPS: [ + { + POSITION: [15, 0, 0, 0, 1], + TYPE: 'egg', + } + ] } Class.atmosphereAuraOfficialV2 = addAura(1, 1, 0.15); Class.atmosphereOfficialV2 = { @@ -330,289 +330,227 @@ Class.atmosphereOfficialV2 = { LABEL: "Atmosphere", TURRETS: [ { - POSITION: [14, 0, 0, 0, 0, 1], - TYPE: 'egg', - }, - { - POSITION: [11, 0, 0, 0, 360, 1], + POSITION: [11, 0, 0, 0, 360, 2], TYPE: 'atmosphereAuraOfficialV2', }, ], + PROPS: [ + { + POSITION: [14, 0, 0, 0, 1], + TYPE: 'egg', + } + ] } Class.juggernautOfficialV2 = { PARENT: "genericEggnought", LABEL: "Juggernaut", - BODY: { - HEALTH: 1.6, - SHIELD: 1.6, - REGEN: 1.5, - SPEED: 0.8, - }, - TURRETS: [ + BODY: hpBuffBodyStats[0], + PROPS: [ { - POSITION: [15, 0, 0, 0, 0, 1], + POSITION: [15, 0, 0, 0, 1], TYPE: 'egg', - }, - { - POSITION: [24, 0, 0, 0, 0, 0], + }, { + POSITION: [24, 0, 0, 0, 0], TYPE: ['egg', {COLOR: 9}] }, ], } // T2 Weapons -Class.sabreOfficialV2 = { +Class.gladiusOfficialV2 = { PARENT: "genericSquarenought", - LABEL: "Sabre", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.sabreOfficialV2.GUNS.push( + LABEL: "Gladius", + GUNS: weaponArray([ { - POSITION: [24, 7, 1, 0, 0, 90*i, 0], + POSITION: [17, 8, 1, 0, 0, 0, 0], + }, { + POSITION: [19.5, 5, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.assassin, {reload: 0.85, density: 1/2}]), + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, {speed: 1.05, maxSpeed: 1.05, health: 1.12}]), TYPE: "bullet", }, }, - { - POSITION: [5, 7, -1.7, 7, 0, 90*i, 0], - }, - ) + ], 4), } -Class.gladiusOfficialV2 = { +Class.sabreOfficialV2 = { PARENT: "genericSquarenought", - LABEL: "Gladius", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.gladiusOfficialV2.GUNS.push( - { - POSITION: [17, 8, 1, 0, 0, 90*i, 0], - }, + LABEL: "Sabre", + GUNS: weaponArray([ { - POSITION: [19.5, 5, 1, 0, 0, 90*i, 0], + POSITION: [24, 7, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, {health: 1.3}]), + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, {reload: 1.23, health: 1.38, speed: 1.1, maxSpeed: 1.1, density: 1.2}]), TYPE: "bullet", }, + }, { + POSITION: [5, 7, -1.7, 7, 0, 0, 0], }, - ) + ], 4), } Class.mediatorOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Mediator", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.mediatorOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [15, 7, 1, 0, 4.25, 90*i, 0], + POSITION: [15, 7, 1, 0, 4.25, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, {reload: 0.85}]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, {health: 1.09}]), TYPE: "bullet", }, - }, - { - POSITION: [15, 7, 1, 0, -4.25, 90*i, 0.5], + }, { + POSITION: [15, 7, 1, 0, -4.25, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, {reload: 0.85}]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, {health: 1.09}]), TYPE: "bullet", }, }, - ) + ], 4), } Class.negotiatorOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Negotiator", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.negotiatorOfficialV2.GUNS.push( - { - POSITION: [9, 8, 1.4, 6, 0, 90*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, {size: 0.8, health: 1.3}]), - TYPE: "bullet", - }, + GUNS: weaponArray({ + POSITION: [9, 8, 1.4, 6, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, {size: 0.8, speed: 0.85, maxSpeed: 0.85, health: 1.23}]), + TYPE: "bullet", }, - ) + }, 4), } Class.enforcerOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Enforcer", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.enforcerOfficialV2.GUNS.push( - { - POSITION: [17, 9, 1, 0, 0, 90*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 0.9}]), - TYPE: "bullet", - }, + GUNS: weaponArray({ + POSITION: [17, 9, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 1.13, health: 1.27}]), + TYPE: "bullet", }, - ) + }, 4), } Class.executorOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Executor", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.executorOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [11, 6, 1, 8, 0, 90*i, 0], + POSITION: [11, 6, 1, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, { speed: 0.5, maxSpeed: 0.5 }, {reload: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, {reload: 1.1, health: 1.25}]), TYPE: "missile", STAT_CALCULATOR: gunCalcNames.sustained, }, + }, { + POSITION: [17, 9, 1, 0, 0, 0, 0], }, - { - POSITION: [17, 9, 1, 0, 0, 90*i, 0], - }, - ) + ], 4), } Class.inquisitorOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Inquisitor", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.inquisitorOfficialV2.GUNS.push( - { - POSITION: [5, 11, 1.1, 8, 0, 90*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, {size: 1.5, reload: 0.6}]), - TYPE: "drone", - MAX_CHILDREN: 3, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - }, - }, - ) + GUNS: weaponArray({ + POSITION: [5, 11, 1.1, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, {reload: 0.9, health: 0.75}]), + TYPE: "drone", + MAX_CHILDREN: 3, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + }, + }, 4), } Class.assailantMinionOfficialV2 = { PARENT: "minion", - BODY: { - SPEED: 0.5, - }, SHAPE: 4, - COLOR: 13, - GUNS: [] -} -for (let i = 0; i < 4; i++) { - Class.assailantMinionOfficialV2.GUNS.push( - { - POSITION: [15, 7.5, 1, 0, 0, 90*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.assassin, g.minionGun]), - WAIT_TO_CYCLE: true, - TYPE: "bullet", - }, + COLOR: "square", + GUNS: weaponArray({ + POSITION: [15, 7.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.assassin, g.minionGun, {reload: 1.7, health: 1.1}]), + WAIT_TO_CYCLE: true, + TYPE: "bullet", }, - ) + }, 4) } Class.assailantOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Assailant", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.assailantOfficialV2.GUNS.push( - { - POSITION: [5, 10, 1, 10.5, 0, 90*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [1.5, 11, 1, 15, 0, 90*i, 0], + POSITION: [5, 10, 1, 10.5, 0, 0, 0], + }, { + POSITION: [1.5, 11, 1, 15, 0, 0, 0], PROPERTIES: { MAX_CHILDREN: 4, - SHOOT_SETTINGS: combineStats([g.factory, {size: 0.9, reload: 0.5}]), + SHOOT_SETTINGS: combineStats([g.factory, {size: 0.9, reload: 1.65, health: 1.3, damage: 0.7, speed: 0.8, maxSpeed: 0.8}]), TYPE: "assailantMinionOfficialV2", STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, SYNCS_SKILLS: true, MAX_CHILDREN: 2, }, + }, { + POSITION: [12, 11, 1, 0, 0, 0, 0], }, - { - POSITION: [12, 11, 1, 0, 0, 90*i, 0], - }, - ) + ], 4), } Class.daemonOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Daemon", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.daemonOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [11.5, 4.5, 1, 0, 4.5, 90*i, 0], - }, - { - POSITION: [2, 4.5, 1.7, 11, 4.5, 90*i, 0], + POSITION: [11.5, 4.5, 1, 0, 4.5, 0, 0], + }, { + POSITION: [2, 4.5, 1.7, 11, 4.5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.twin, {health: 2}]), + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, {health: 0.7, speed: 0.7, maxSpeed: 0.7, range: 0.7, shudder: 0.5}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, }, - }, - { - POSITION: [11.5, 4.5, 1, 0, -4.5, 90*i, 0], - }, - { - POSITION: [2, 4.5, 1.7, 11, -4.5, 90*i, 0], + }, { + POSITION: [11.5, 4.5, 1, 0, -4.5, 0, 0], + }, { + POSITION: [2, 4.5, 1.7, 11, -4.5, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.twin, {health: 2}]), + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, {health: 0.7, speed: 0.7, maxSpeed: 0.7, range: 0.7, shudder: 0.5}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, }, }, - ) + ], 4), } Class.minotaurOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Minotaur", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.minotaurOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [13, 7, 1, 0, 0, 90*i, 0], - }, - { - POSITION: [3.75, 7, 1.75, 13, 0, 90*i, 0], + POSITION: [13, 7, 1, 0, 0, 0, 0], + }, { + POSITION: [3.75, 7, 1.75, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, {health: 2}]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, {shudder: 0.7, range: 0.6}]), TYPE: "unsetTrap", STAT_CALCULATOR: gunCalcNames.block }, }, - ) + ], 4), } // T2 Bodies Class.automationOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Automation", - TURRETS: [ - { - POSITION: [11, 0, 0, 0, 0, 1], - TYPE: ["square", {MIRROR_MASTER_ANGLE: true}], - }, - ], -} -for (let i = 0; i < 4; i++) { - Class.automationOfficialV2.TURRETS.push( + TURRETS: weaponArray({ + POSITION: [4, 9, 0, 45, 180, 2], + TYPE: "spamAutoTurret", + }, 4), + PROPS: [ { - POSITION: [4, 9, 0, 90*i+45, 180, 1], - TYPE: "spamAutoTurret", + POSITION: [11, 0, 0, 0, 1], + TYPE: "square" }, - ) + ] } Class.kilobyteTurretOfficialV2 = { PARENT: "autoTankGun", @@ -621,7 +559,7 @@ Class.kilobyteTurretOfficialV2 = { { POSITION: [26, 10, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.assassin, g.autoTurret, {health: 1.2, speed: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.turret, g.assassin, {health: 1.24, speed: 0.77, recoil: 1.15}]), TYPE: "bullet", }, }, @@ -632,14 +570,16 @@ Class.kilobyteOfficialV2 = { LABEL: "Kilobyte", TURRETS: [ { - POSITION: [12, 0, 0, 0, 0, 1], - TYPE: ["square", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [10, 0, 0, 0, 360, 1], + POSITION: [10, 0, 0, 0, 360, 2], TYPE: "kilobyteTurretOfficialV2", }, ], + PROPS: [ + { + POSITION: [12, 0, 0, 0, 1], + TYPE: "square" + }, + ] } Class.coronaAuraOfficialV2 = addAura(1.5, 0.8, 0.15); Class.coronaOfficialV2 = { @@ -647,14 +587,16 @@ Class.coronaOfficialV2 = { LABEL: "Corona", TURRETS: [ { - POSITION: [14, 0, 0, 0, 0, 1], - TYPE: ["square", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [11, 0, 0, 0, 360, 1], + POSITION: [11, 0, 0, 0, 360, 2], TYPE: "coronaAuraOfficialV2", }, ], + PROPS: [ + { + POSITION: [14, 0, 0, 0, 1], + TYPE: "square" + }, + ] } Class.thermosphereAuraOfficialV2 = addAura(-1, 1.5); Class.thermosphereOfficialV2 = { @@ -662,228 +604,171 @@ Class.thermosphereOfficialV2 = { LABEL: "Thermosphere", TURRETS: [ { - POSITION: [14, 0, 0, 0, 0, 1], - TYPE: ["square", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [11, 0, 0, 0, 360, 1], + POSITION: [11, 0, 0, 0, 360, 2], TYPE: "thermosphereAuraOfficialV2", }, ], + PROPS: [ + { + POSITION: [14, 0, 0, 0, 1], + TYPE: "square" + }, + ] } Class.jumboOfficialV2 = { PARENT: "genericSquarenought", LABEL: "Jumbo", - BODY: { - HEALTH: 2.4, - SHIELD: 2.4, - REGEN: 2, - SPEED: 0.65, - }, - TURRETS: [ - { - POSITION: [15, 0, 0, 0, 0, 1], - TYPE: ['square', {MIRROR_MASTER_ANGLE: true}] - }, + BODY: hpBuffBodyStats[1], + PROPS: [ { - POSITION: [24, 0, 0, 0, 0, 0], - TYPE: ['square', {COLOR: 9, MIRROR_MASTER_ANGLE: true}] + POSITION: [15, 0, 0, 0, 1], + TYPE: 'square' + }, { + POSITION: [24, 0, 0, 0, 0], + TYPE: ['square', {COLOR: 9}] }, ], } Class.colossusTopOfficialV2 = { PARENT: "genericSquarenought", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.colossusTopOfficialV2.GUNS.push( - { - POSITION: [3.5, 17.5, 0.001, 9, 0, 90*i, 0], - PROPERTIES: {COLOR: 9}, - }, - ) + GUNS: weaponArray({ + POSITION: [3.5, 17.5, 0.001, 9, 0, 0, 0], + PROPERTIES: {COLOR: 9}, + }, 4), } Class.colossusBottomOfficialV2 = { PARENT: "genericSquarenought", - GUNS: [], -} -for (let i = 0; i < 4; i++) { - Class.colossusTopOfficialV2.GUNS.push( - { - POSITION: [3.5, 17.5, 0.001, 9, 0, 90*i, 0], - PROPERTIES: {COLOR: 9}, - }, - ) -} -for (let i = 0; i < 4; i++) { - Class.colossusBottomOfficialV2.GUNS.push( - { - POSITION: [4, 17.5, 0.001, 9, 0, 90*i, 0], - PROPERTIES: {COLOR: 9}, - }, - ) + GUNS: weaponArray({ + POSITION: [4, 17.5, 0.001, 9, 0, 0, 0], + PROPERTIES: {COLOR: 9}, + }, 4), } Class.colossusOfficialV2 = { PARENT: "genericSquarenought", - LABEL: "colossus", - BODY: { - SPEED: 1.75, - HEALTH: 0.65, - }, - GUNS: [], - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 0, 1], - TYPE: ['colossusTopOfficialV2', {MIRROR_MASTER_ANGLE: true}] - }, + LABEL: "Colossus", + BODY: speedBuffBodyStats[0], + PROPS: [ { - POSITION: [20, 0, 0, 0, 0, 0], - TYPE: ['colossusBottomOfficialV2', {MIRROR_MASTER_ANGLE: true}] + POSITION: [13, 0, 0, 0, 1], + TYPE: 'colossusTopOfficialV2' + }, { + POSITION: [20, 0, 0, 0, 0], + TYPE: 'colossusBottomOfficialV2' }, ], } // T3 Weapons -Class.bayonetOfficialV2 = { +Class.bladeOfficialV2 = { PARENT: "genericTrinought", - LABEL: "Bayonet", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.bayonetOfficialV2.GUNS.push( + LABEL: "Blade", + GUNS: weaponArray([ { - POSITION: [28, 7, 1, 0, 0, 120*i, 0], + POSITION: [17, 1, 1, 0, 6, 0, 0], + }, { + POSITION: [17, 1, 1, 0, -6, 0, 0], + }, { + POSITION: [18, 5, 1, 0, 3, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.assassin, g.assassin, {reload: 0.8, density: 2/5}]), + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin, {speed: 1.09, maxSpeed: 1.09, health: 1.15}]), TYPE: "bullet", }, - }, - { - POSITION: [5, 7, -1.6, 7, 0, 120*i, 0], - }, - ) -} -Class.bladeOfficialV2 = { - PARENT: "genericTrinought", - LABEL: "Blade", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.bladeOfficialV2.GUNS.push( - { - POSITION: [17, 1, 1, 0, 6, 120*i, 0], - }, - { - POSITION: [17, 1, 1, 0, -6, 120*i, 0], - }, - { - POSITION: [18, 5, 1, 0, 3, 120*i, 0], + }, { + POSITION: [18, 5, 1, 0, -3, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin, {speed: 0.8, health: 1.5}]), + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin, {speed: 1.09, maxSpeed: 1.09, health: 1.15}]), TYPE: "bullet", }, }, + ], 3), +} +Class.bayonetOfficialV2 = { + PARENT: "genericTrinought", + LABEL: "Bayonet", + GUNS: weaponArray([ { - POSITION: [18, 5, 1, 0, -3, 120*i, 0.5], + POSITION: [28, 7, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin, {speed: 0.8, health: 1.5}]), + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.assassin, {reload: 1.05, health: 0.98, density: 0.45}]), TYPE: "bullet", }, + }, { + POSITION: [5, 7, -1.6, 7, 0, 0, 0], }, - ) + ], 3), } Class.mitigatorOfficialV2 = { PARENT: "genericTrinought", LABEL: "Mitigator", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.mitigatorOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [10, 8, 1, 3, 5, 120*i, 0], + POSITION: [10, 8, 1, 3, 5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, {reload: 0.85}]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, {health: 1.15}]), TYPE: "bullet", }, - }, - { - POSITION: [10, 8, 1, 3, -5, 120*i, 0.5], + }, { + POSITION: [10, 8, 1, 3, -5, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, {reload: 0.85}]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, {health: 1.15}]), TYPE: "bullet", }, }, - ) + ], 3), } Class.appeaserOfficialV2 = { PARENT: "genericTrinought", LABEL: "Appeaser", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.appeaserOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [7, 11, 1.35, 6, 0, 120*i, 0], + POSITION: [7, 11, 1.35, 6, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, {size: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.spam, {size: 0.7, health: 0.96}]), TYPE: "bullet", }, - }, - { - POSITION: [7, 10, 1.3, 8, 0, 120*i, 0], + }, { + POSITION: [7, 10, 1.3, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, {size: 0.8, reload: 0.9}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.spam, {size: 0.6, health: 0.95, reload: 1.1}]), TYPE: "bullet", }, }, - ) + ], 3), } Class.suppressorOfficialV2 = { PARENT: "genericTrinought", LABEL: "Suppressor", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.suppressorOfficialV2.GUNS.push( - { - POSITION: [16.5, 11.5, 1, 0, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, {reload: 0.85}]), - TYPE: "bullet", - }, + GUNS: weaponArray({ + POSITION: [16.5, 11.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, {reload: 1.1, health: 1.19}]), + TYPE: "bullet", }, - ) + }, 3), } Class.inhibitorOfficialV2 = { PARENT: "genericTrinought", LABEL: "Inhibitor", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.inhibitorOfficialV2.GUNS.push( - { - POSITION: [10, 14, -0.75, 7, 0, 120*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [15, 15, 1, 0, 0, 120*i, 0], + POSITION: [10, 14, -0.75, 7, 0, 0, 0], + }, { + POSITION: [15, 15, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.skimmer, { speed: 0.5, maxSpeed: 0.5 }, {reload: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, {reload: 1.15, health: 1.33}]), TYPE: "supermissile", STAT_CALCULATOR: gunCalcNames.sustained, }, }, - ) + ], 3), } Class.infiltratorOfficialV2 = { PARENT: "genericTrinought", LABEL: "Infiltrator", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.infiltratorOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [5, 6, 1.4, 6, 5.5, 120*i, 0], + POSITION: [5, 6, 1.4, 6, 5.5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, {size: 1.5, reload: 0.6}]), + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, {maxSpeed: 0.9, size: 1.5, reload: 1.4}]), TYPE: "drone", MAX_CHILDREN: 2, AUTOFIRE: true, @@ -891,11 +776,10 @@ for (let i = 0; i < 3; i++) { STAT_CALCULATOR: gunCalcNames.drone, WAIT_TO_CYCLE: true, }, - }, - { - POSITION: [5, 6, 1.4, 6, -5.5, 120*i, 0], + }, { + POSITION: [5, 6, 1.4, 6, -5.5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, {size: 1.5, reload: 0.6}]), + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, {maxSpeed: 0.9, size: 1.5, reload: 1.4}]), TYPE: "drone", MAX_CHILDREN: 2, AUTOFIRE: true, @@ -903,11 +787,10 @@ for (let i = 0; i < 3; i++) { STAT_CALCULATOR: gunCalcNames.drone, WAIT_TO_CYCLE: true, }, - }, - { - POSITION: [5, 6, 1.4, 8, 0, 120*i, 0], + }, { + POSITION: [5, 6, 1.4, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, g.pounder, {size: 2, reload: 0.4}]), + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, g.pounder, {damage: 0.85, maxSpeed: 0.9, size: 2, reload: 1.4}]), TYPE: "betadrone", MAX_CHILDREN: 2, AUTOFIRE: true, @@ -916,211 +799,174 @@ for (let i = 0; i < 3; i++) { WAIT_TO_CYCLE: true, }, }, - ) + ], 3), } Class.aggressorMinionOfficialV2 = { PARENT: "minion", SHAPE: 3.5, - COLOR: 2, - BODY: { - SPEED: 0.8, - }, - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.aggressorMinionOfficialV2.GUNS.push( - { - POSITION: [16, 8.5, 1, 0, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, { speed: 0.93, maxSpeed: 0.93 }, g.minionGun]), - WAIT_TO_CYCLE: true, - TYPE: "bullet", - }, + COLOR: "triangle", + GUNS: weaponArray({ + POSITION: [16, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.assassin, g.minionGun, {speed: 1.06, maxSpeed: 1.06, reload: 1.8, health: 1.25}]), + WAIT_TO_CYCLE: true, + TYPE: "bullet", }, - ) + }, 3), } Class.aggressorOfficialV2 = { PARENT: "genericTrinought", LABEL: "Aggressor", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.aggressorOfficialV2.GUNS.push( - { - POSITION: [5, 12, 1, 10, 0, 120*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [1.5, 13, 1, 15, 0, 120*i, 0], + POSITION: [5, 12, 1, 10, 0, 0, 0], + }, { + POSITION: [1.5, 13, 1, 15, 0, 0, 0], PROPERTIES: { - MAX_CHILDREN: 4, - SHOOT_SETTINGS: combineStats([g.factory, {size: 0.9, reload: 0.5}]), + SHOOT_SETTINGS: combineStats([g.factory, {size: 0.9, reload: 1.65, health: 1.72, damage: 0.7, speed: 0.8, maxSpeed: 0.8}]), TYPE: "aggressorMinionOfficialV2", STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, SYNCS_SKILLS: true, MAX_CHILDREN: 2, }, + }, { + POSITION: [12, 13, 1, 0, 0, 0, 0], }, - { - POSITION: [12, 13, 1, 0, 0, 120*i, 0], - }, - ) + ], 3), } Class.hydraOfficialV2 = { PARENT: "genericTrinought", LABEL: "Hydra", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.hydraOfficialV2.GUNS.push( - { - POSITION: [6, 3.5, 1, 4, 8.5, 120*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [2, 3.5, 1.8, 10, 8.5, 120*i, 2/3], + POSITION: [6, 3.5, 1, 4, 8.5, 0, 0], + }, { + POSITION: [2, 3.5, 1.8, 10, 8.5, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, { speed: 1.2 }]), + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, {shudder: 0.6, health: 0.7, speed: 1.15, maxSpeed: 1.15, range: 0.85}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, }, - }, - { - POSITION: [6, 3.5, 1, 4, -8.5, 120*i, 0], - }, - { - POSITION: [2, 3.5, 1.8, 10, -8.5, 120*i, 1/3], + }, { + POSITION: [6, 3.5, 1, 4, -8.5, 0, 0], + }, { + POSITION: [2, 3.5, 1.8, 10, -8.5, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, { speed: 1.2 }]), + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, {shudder: 0.6, health: 0.7, speed: 1.15, maxSpeed: 1.15, range: 0.85}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, }, - }, - { - POSITION: [12, 5, 1, 0, 0, 120*i, 0], - }, - { - POSITION: [2.5, 5, 1.7, 12, 0, 120*i, 0], + }, { + POSITION: [12, 5, 1, 0, 0, 0, 0], + }, { + POSITION: [2.5, 5, 1.7, 12, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.twin, g.pounder, { speed: 1.2 }]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.twin, g.pounder, {reload: 1.1, health: 1.02, speed: 0.75, maxSpeed: 0.75, range: 0.65}]), TYPE: "unsetTrap", STAT_CALCULATOR: gunCalcNames.block }, }, - ) + ], 3), } Class.beelzebubOfficialV2 = { PARENT: "genericTrinought", LABEL: "Beelzebub", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.beelzebubOfficialV2.GUNS.push( - { - POSITION: [13, 10, 1, 0, 0, 120*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [3.5, 10, 1.6, 13, 0, 120*i, 0], + POSITION: [13, 10, 1, 0, 0, 0, 0], + }, { + POSITION: [3.5, 10, 1.6, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, { speed: 1.3, maxSpeed: 1.3 }, {size: 1.2, health: 2}]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, {health: 1.4, speed: 1.2, maxSpeed: 1.2, size: 1.2, shudder: 0.65, range: 0.55}]), TYPE: "unsetTrap", STAT_CALCULATOR: gunCalcNames.block }, }, - ) + ], 3), } // T3 Bodies Class.mechanismOfficialV2 = { PARENT: "genericTrinought", LABEL: "Mechanism", - TURRETS: [ - { - POSITION: [10, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], - }, - ], -} -for (let i = 0; i < 3; i++) { - Class.mechanismOfficialV2.TURRETS.push( + TURRETS: weaponArray([ { - POSITION: [3.5, 6, 0, 120*i, 180, 1], + POSITION: [3.5, 6, 0, 0, 180, 2], + TYPE: "spamAutoTurret", + }, { + POSITION: [3.5, 10, 0, 60, 180, 2], TYPE: "spamAutoTurret", }, + ], 3), + PROPS: [ { - POSITION: [3.5, 10, 0, 120*i+60, 180, 1], - TYPE: "spamAutoTurret", + POSITION: [10, 0, 0, 180, 1], + TYPE: "triangle" }, - ) + ], } Class.trinoughtBigAura = addAura(2, 1.5); Class.fusionOfficialV2 = { PARENT: "genericTrinought", LABEL: "Fusion", TURRETS: [ + ...weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 180, 2], + TYPE: "spamAutoTurret", + }, 3), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [9.5, 0, 0, 0, 360, 1], + POSITION: [9.5, 0, 0, 0, 360, 2], TYPE: "trinoughtBigAura", }, ], -} -for (let i = 0; i < 3; i++) { - Class.fusionOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.5, 10.5, 0, 120*i+60, 180, 1], - TYPE: "spamAutoTurret", + POSITION: [13, 0, 0, 180, 1], + TYPE: "triangle" }, - ) + ] } Class.binaryOfficialV2 = { PARENT: "genericTrinought", LABEL: "Binary", TURRETS: [ + ...weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 180, 2], + TYPE: "spamAutoTurret", + }, 3), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], + POSITION: [10, 0, 0, 0, 360, 2], + TYPE: "kilobyteTurretOfficialV2", }, ], -} -for (let i = 0; i < 3; i++) { - Class.binaryOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.5, 10.5, 0, 120*i+60, 180, 1], - TYPE: "spamAutoTurret", + POSITION: [13, 0, 0, 180, 1], + TYPE: "triangle" }, - ) + ], } -Class.binaryOfficialV2.TURRETS.push( - { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: "kilobyteTurretOfficialV2", - }, -) Class.trinoughtBigHealAura = addAura(-1.5, 1.5); Class.exosphereOfficialV2 = { PARENT: "genericTrinought", LABEL: "Exosphere", TURRETS: [ + ...weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 180, 2], + TYPE: "spamAutoTurret", + }, 3), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [9.5, 0, 0, 0, 360, 1], + POSITION: [9.5, 0, 0, 0, 360, 2], TYPE: "trinoughtBigHealAura", }, ], -} -for (let i = 0; i < 3; i++) { - Class.exosphereOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.5, 10.5, 0, 120*i+60, 180, 1], - TYPE: "spamAutoTurret", + POSITION: [13, 0, 0, 180, 1], + TYPE: "triangle" }, - ) + ] } Class.megabyteTurretOfficialV2 = { PARENT: "autoTankGun", @@ -1129,7 +975,7 @@ Class.megabyteTurretOfficialV2 = { { POSITION: [26, 13, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.pounder, g.autoTurret, {health: 1.2, speed: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.turret, g.assassin, g.pounder, {health: 1.18, speed: 0.73, recoil: 1.15}]), TYPE: "bullet", }, }, @@ -1140,481 +986,405 @@ Class.megabyteOfficialV2 = { LABEL: "Megabyte", TURRETS: [ { - POSITION: [15, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], + POSITION: [12, 0, 0, 0, 360, 2], TYPE: "megabyteTurretOfficialV2", }, ], + PROPS: [ + { + POSITION: [15, 0, 0, 180, 1], + TYPE: "triangle" + }, + ] } Class.trinoughtSmallAura = addAura(1, 2.1, 0.15); Class.trojanOfficialV2 = { PARENT: "genericTrinought", LABEL: "Trojan", TURRETS: [ + ...weaponArray({ + POSITION: [3.5, 11, 0, 60, 360, 2], + TYPE: "trinoughtSmallAura", + }, 3), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], + POSITION: [10, 0, 0, 0, 360, 2], + TYPE: "kilobyteTurretOfficialV2", }, ], -} -for (let i = 0; i < 3; i++) { - Class.trojanOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.5, 11, 0, 120*i+60, 360, 1], - TYPE: "trinoughtSmallAura", + POSITION: [13, 0, 0, 180, 1], + TYPE: "triangle" }, - ) + ] } -Class.trojanOfficialV2.TURRETS.push( - { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: "kilobyteTurretOfficialV2", - }, -) Class.trinoughtSmallHealAura = addAura(-2/3, 2.1, 0.15); Class.hardwareOfficialV2 = { PARENT: "genericTrinought", LABEL: "Hardware", TURRETS: [ + ...weaponArray({ + POSITION: [3.5, 11, 0, 60, 360, 2], + TYPE: "trinoughtSmallHealAura", + }, 3), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], + POSITION: [10, 0, 0, 0, 360, 2], + TYPE: "kilobyteTurretOfficialV2", }, ], -} -for (let i = 0; i < 3; i++) { - Class.hardwareOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.5, 11, 0, 120*i+60, 360, 1], - TYPE: "trinoughtSmallHealAura", + POSITION: [13, 0, 0, 180, 1], + TYPE: "triangle" }, - ) + ] } -Class.hardwareOfficialV2.TURRETS.push( - { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: "kilobyteTurretOfficialV2", - }, -) Class.chromosphereOfficialV2 = { PARENT: "genericTrinought", LABEL: "Chromosphere", TURRETS: [ + ...weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 360, 2], + TYPE: "trinoughtSmallAura", + }, 3), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [9.5, 0, 0, 0, 360, 1], + POSITION: [9.5, 0, 0, 0, 360, 2], TYPE: "trinoughtBigAura", }, ], -} -for (let i = 0; i < 3; i++) { - Class.chromosphereOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.5, 10.5, 0, 120*i+60, 360, 1], - TYPE: "trinoughtSmallAura", + POSITION: [13, 0, 0, 180, 1], + TYPE: "triangle" }, - ) + ] } Class.mesosphereOfficialV2 = { PARENT: "genericTrinought", LABEL: "Mesosphere", TURRETS: [ + ...weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 360, 2], + TYPE: "trinoughtSmallHealAura", + }, 3), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [9.5, 0, 0, 0, 360, 1], + POSITION: [9.5, 0, 0, 0, 360, 2], TYPE: "trinoughtBigHealAura", }, ], -} -for (let i = 0; i < 3; i++) { - Class.mesosphereOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.5, 10.5, 0, 120*i+60, 360, 1], - TYPE: "trinoughtSmallHealAura", + POSITION: [13, 0, 0, 180, 1], + TYPE: "triangle" }, - ) + ] } Class.goliathOfficialV2 = { PARENT: "genericTrinought", LABEL: "Goliath", - BODY: { - HEALTH: 3.2, - SHIELD: 3.2, - REGEN: 2.5, - SPEED: 0.5, - }, - TURRETS: [ + BODY: hpBuffBodyStats[2], + PROPS: [ { - POSITION: [14, 0, 0, 180, 0, 1], - TYPE: ['triangle', {COLOR: 9, MIRROR_MASTER_ANGLE: true}] - }, - { - POSITION: [24, 0, 0, 180, 0, 0], - TYPE: ['triangle', {COLOR: 9, MIRROR_MASTER_ANGLE: true}] + POSITION: [14, 0, 0, 180, 1], + TYPE: ['triangle', {COLOR: 9}] + }, { + POSITION: [24, 0, 0, 180, 0], + TYPE: ['triangle', {COLOR: 9}] }, ], } Class.planetOfficialV2 = { PARENT: "genericTrinought", LABEL: "Planet", - BODY: { - HEALTH: 2.4, - SHIELD: 2.4, - REGEN: 2, - SPEED: 0.65, - }, - TURRETS: [ - { - POSITION: [24, 0, 0, 180, 0, 0], - TYPE: ['triangle', {COLOR: 9, MIRROR_MASTER_ANGLE: true}] - }, - { - POSITION: [12, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], + BODY: hpBuffBodyStats[1], + TURRETS: weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 360, 2], + TYPE: "trinoughtSmallAura", + }, 3), + PROPS: [ + { + POSITION: [24, 0, 0, 180, 0], + TYPE: ['triangle', {COLOR: 9}] + }, { + POSITION: [12, 0, 0, 180, 1], + TYPE: "triangle" } ], } -for (let i = 0; i < 3; i++) { - Class.planetOfficialV2.TURRETS.push( - { - POSITION: [3.5, 10.5, 0, 120*i+60, 360, 1], - TYPE: "trinoughtSmallAura", - }, - ) -} Class.moonOfficialV2 = { PARENT: "genericTrinought", LABEL: "Moon", - BODY: { - HEALTH: 2.4, - SHIELD: 2.4, - REGEN: 2, - SPEED: 0.65, - }, - TURRETS: [ - { - POSITION: [24, 0, 0, 180, 0, 0], - TYPE: ['triangle', {COLOR: 9, MIRROR_MASTER_ANGLE: true}] - }, - { - POSITION: [12, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], + BODY: hpBuffBodyStats[1], + TURRETS: weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 360, 2], + TYPE: "trinoughtSmallHealAura", + }, 3), + PROPS: [ + { + POSITION: [24, 0, 0, 180, 0], + TYPE: ['triangle', {COLOR: 9}] + }, { + POSITION: [12, 0, 0, 180, 1], + TYPE: "triangle" } ], } -for (let i = 0; i < 3; i++) { - Class.moonOfficialV2.TURRETS.push( - { - POSITION: [3.5, 10.5, 0, 120*i+60, 360, 1], - TYPE: "trinoughtSmallHealAura", - }, - ) -} Class.titanTopOfficialV2 = { PARENT: "genericTrinought", - GUNS: [], -} -for (let i = 0; i < 3; i++) { - Class.titanTopOfficialV2.GUNS.push( - { - POSITION: [5, 26, 0.001, 8, 0, 120*i, 0], - PROPERTIES: {COLOR: 9}, - }, - ) + GUNS: weaponArray({ + POSITION: [5, 26, 0.001, 8, 0, 0, 0], + PROPERTIES: {COLOR: 9}, + }, 3), } Class.titanOfficialV2 = { PARENT: "genericTrinought", LABEL: "Titan", - BODY: { - SPEED: 2.15, - HEALTH: 0.5, - }, - GUNS: [], - TURRETS: [ - { - POSITION: [11, 0, 0, 0, 0, 1], - TYPE: ["titanTopOfficialV2", {MIRROR_MASTER_ANGLE: true}] - }, + BODY: speedBuffBodyStats[1], + PROPS: [ { - POSITION: [20, 0, 0, 0, 0, 0], - TYPE: ["titanTopOfficialV2", {MIRROR_MASTER_ANGLE: true}] + POSITION: [11, 0, 0, 0, 1], + TYPE: "titanTopOfficialV2" + }, { + POSITION: [20, 0, 0, 0, 0], + TYPE: "titanTopOfficialV2" }, ], } Class.sirenOfficialV2 = { PARENT: "genericTrinought", LABEL: "Siren", - BODY: { - SPEED: 1.75, - HEALTH: 0.65, - }, - GUNS: [], - TURRETS: [ - { - POSITION: [12, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [20, 0, 0, 0, 0, 0], - TYPE: ["titanTopOfficialV2", {MIRROR_MASTER_ANGLE: true}] + BODY: speedBuffBodyStats[0], + TURRETS: weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 360, 1], + TYPE: "trinoughtSmallAura", + }, 3), + PROPS: [ + { + POSITION: [12, 0, 0, 180, 1], + TYPE: "triangle" + }, { + POSITION: [20, 0, 0, 0, 0], + TYPE: "titanTopOfficialV2" }, ], } -for (let i = 0; i < 3; i++) { - Class.sirenOfficialV2.TURRETS.push( - { - POSITION: [3.5, 10.5, 0, 120*i+60, 360, 1], - TYPE: "trinoughtSmallAura", - }, - ) -} Class.harpyOfficialV2 = { PARENT: "genericTrinought", LABEL: "Harpy", - BODY: { - SPEED: 1.75, - HEALTH: 0.65, - }, - GUNS: [], - TURRETS: [ - { - POSITION: [12, 0, 0, 180, 0, 1], - TYPE: ["triangle", {MIRROR_MASTER_ANGLE: true}], - }, + BODY: speedBuffBodyStats[0], + TURRETS: weaponArray({ + POSITION: [3.5, 10.5, 0, 60, 360, 1], + TYPE: "trinoughtSmallHealAura", + }, 3), + PROPS: [ { - POSITION: [20, 0, 0, 0, 0, 0], - TYPE: ["titanTopOfficialV2", {MIRROR_MASTER_ANGLE: true}] + POSITION: [12, 0, 0, 180, 1], + TYPE: "triangle" + }, { + POSITION: [20, 0, 0, 0, 0], + TYPE: "titanTopOfficialV2" }, ], } -for (let i = 0; i < 3; i++) { - Class.harpyOfficialV2.TURRETS.push( - { - POSITION: [3.5, 10.5, 0, 120*i+60, 360, 1], - TYPE: "trinoughtSmallHealAura", - }, - ) -} // T4 Weapons -Class.javelinOfficialV2 = { +Class.rapierOfficialV2 = { PARENT: "genericPentanought", - LABEL: "Javelin", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.javelinOfficialV2.GUNS.push( + LABEL: "Rapier", + GUNS: weaponArray([ { - POSITION: [28, 7, 1, 0, 0, 72*i, 0], + POSITION: [17, 1, 1, 0, 6, 0, 0], + }, { + POSITION: [17, 1, 1, 0, -6, 0, 0], + }, { + POSITION: [18, 5, 1, 0, 3, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.assassin, g.assassin, g.assassin, {reload: 0.8, density: 2/9}]), + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin, {speed: 1.13, maxSpeed: 1.13, health: 1.21}]), TYPE: "bullet", }, - }, - { - POSITION: [5, 7, -1.6, 7, 0, 72*i, 0], - }, - ) -} -Class.rapierOfficialV2 = { - PARENT: "genericPentanought", - LABEL: "Rapier", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.rapierOfficialV2.GUNS.push( - { - POSITION: [17, 1, 1, 0, 6, 72*i, 0], - }, - { - POSITION: [17, 1, 1, 0, -6, 72*i, 0], - }, - { - POSITION: [18, 5, 1, 0, 3, 72*i, 0], + }, { + POSITION: [18, 5, 1, 0, -3, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, {speed: 0.8, health: 1.5}]), + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, g.twin, {speed: 1.13, maxSpeed: 1.13, health: 1.21}]), TYPE: "bullet", }, }, + ], 5), +} +Class.javelinOfficialV2 = { + PARENT: "genericPentanought", + LABEL: "Javelin", + GUNS: weaponArray([ { - POSITION: [18, 5, 1, 0, -3, 72*i, 0.5], + POSITION: [28, 7, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.rifle, {speed: 0.8, health: 1.5}]), + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.assassin, {reload: 1.13, health: 1.12, density: 0.55}]), TYPE: "bullet", }, + }, { + POSITION: [5, 7, -1.6, 7, 0, 0, 0], }, - ) + ], 5), } Class.diplomatOfficialV2 = { PARENT: "genericPentanought", LABEL: "Diplomat", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.diplomatOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [13, 7, 1, 0, 3.25, 72*i, 0.5], + POSITION: [13, 7, 1, 0, 3.25, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.spam, g.spam, {size: 0.85}]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet, {health: 1.24}]), TYPE: "bullet", - }, - }, - { - POSITION: [13, 7, 1, 0, -3.25, 72*i, 0.5], + }, + }, { + POSITION: [13, 7, 1, 0, -3.25, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.spam, g.spam, {size: 0.85}]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet, {health: 1.24}]), TYPE: "bullet", }, - }, - { - POSITION: [15, 7, 1, 0, 0, 72*i, 0], + }, { + POSITION: [15, 7, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.spam, g.spam, {size: 0.85}]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.triplet, {health: 1.24}]), TYPE: "bullet", }, }, - ) + ], 5), } Class.arbitratorOfficialV2 = { PARENT: "genericPentanought", LABEL: "Arbitrator", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.arbitratorOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [7.5, 10.75, 1.33, 5.5, 0, 72*i, 0], + POSITION: [7.5, 10.75, 1.33, 5.5, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.spam, g.spam, {size: 0.7, reload: 1.2}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.triplet, g.spam, g.spam, {size: 0.7, health: 1.33, reload: 1}]), TYPE: "bullet", }, - }, - { - POSITION: [7.5, 9.5, 1.33, 7.5, 0, 72*i, 0], + }, { + POSITION: [7.5, 9.5, 1.33, 7.5, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.spam, g.spam, {size: 0.7, reload: 1.1}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.triplet, g.spam, g.spam, {size: 0.65, health: 1.33, reload: 1.1}]), TYPE: "bullet", }, - }, - { - POSITION: [7.5, 7.25, 1.25, 9.5, 0, 72*i, 0], + }, { + POSITION: [7.5, 7.25, 1.25, 9.5, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.spam, g.spam, {size: 0.7, reload: 1}]), + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.twin, g.triplet, g.spam, g.spam, {size: 0.7, health: 1.33, reload: 1.2}]), TYPE: "bullet", }, }, - ) + ], 5), } Class.retardantOfficialV2 = { PARENT: "genericPentanought", LABEL: "Retardant", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.retardantOfficialV2.GUNS.push( - { - POSITION: [17, 12, 1, 0, 0, 72*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, {reload: 0.9, health: 1.1}]), - TYPE: "bullet", - }, + GUNS: weaponArray({ + POSITION: [17, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, {reload: 1.23, health: 1.35}]), + TYPE: "bullet", }, - ) + }, 5), } Class.tyrantOfficialV2 = { PARENT: "genericPentanought", LABEL: "Tyrant", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.tyrantOfficialV2.GUNS.push( - { - POSITION: [10, 11, -0.75, 7, 0, 72*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [15, 12, 1, 0, 0, 72*i, 0], + POSITION: [10, 11, -0.75, 7, 0, 0, 0], + }, { + POSITION: [15, 12, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.destroyer, g.artillery, g.skimmer, { speed: 0.5, maxSpeed: 0.5 }, {reload: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.skimmer, {reload: 1.18, health: 1.41}]), TYPE: "supermissile", STAT_CALCULATOR: gunCalcNames.sustained, }, }, - ) + ], 5), } Class.raiderOfficialV2 = { PARENT: "genericPentanought", LABEL: "Raider", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.raiderOfficialV2.GUNS.push( + GUNS: weaponArray([ { - POSITION: [4, 5, 2.1, 8, 3.25, 72*i, 0], + POSITION: [4, 5, 2.1, 8, 3, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, g.overseer, {size: 1.5, reload: 0.6}]), - TYPE: ["drone", {COLOR: 5}], + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, {damage: 0.9, health: 0.75, maxSpeed: 0.9, size: 1.5, reload: 1.2}]), + TYPE: "drone", MAX_CHILDREN: 2, AUTOFIRE: true, SYNCS_SKILLS: true, STAT_CALCULATOR: gunCalcNames.drone, WAIT_TO_CYCLE: true, }, - }, - { - POSITION: [4, 5, 2.1, 8, -3.25, 72*i, 0], + }, { + POSITION: [4, 5, 2.1, 8, -3, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, g.overseer, {size: 1.5, reload: 0.6}]), - TYPE: ["drone", {COLOR: 5}], + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, {damage: 0.9, health: 0.75, maxSpeed: 0.9, size: 1.5, reload: 1.2}]), + TYPE: "drone", MAX_CHILDREN: 2, AUTOFIRE: true, SYNCS_SKILLS: true, STAT_CALCULATOR: gunCalcNames.drone, WAIT_TO_CYCLE: true, }, - }, - { - POSITION: [6, 6.5, 1.4, 8, 0, 72*i, 0], + }, { + POSITION: [6, 6.5, 1.4, 8, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, g.overseer, g.pounder, {size: 2, reload: 0.4}]), - TYPE: ["betadrone", {COLOR: 5}], - MAX_CHILDREN: 2, + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.overseer, g.pounder, {damage: 1.04, maxSpeed: 0.9, size: 2, reload: 1.2}]), + TYPE: "betadrone", + MAX_CHILDREN: 1, AUTOFIRE: true, SYNCS_SKILLS: true, STAT_CALCULATOR: gunCalcNames.drone, WAIT_TO_CYCLE: true, }, }, - ) + ], 5), } Class.gladiatorGenericMinionOfficialV2 = { PARENT: "minion", - BODY: { - SPEED: 1, - }, SHAPE: 3.5, - COLOR: 5, + COLOR: "crasher", GUNS: [], } Class.gladiatorTritankMinionOfficialV2 = { PARENT: "gladiatorGenericMinionOfficialV2", - GUNS: [], + GUNS: weaponArray({ + POSITION: [15, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.assassin, g.minionGun, {speed: 1.06, maxSpeed: 1.06, reload: 1.8, health: 1.3}]), + WAIT_TO_CYCLE: true, + TYPE: ["bullet", {COLOR: 5}], + }, + }, 3), } Class.gladiatorTritrapMinionOfficialV2 = { PARENT: "gladiatorGenericMinionOfficialV2", - GUNS: [], + GUNS: weaponArray([ + { + POSITION: [13, 7, 1, 0, 0, 0, 0], + }, { + POSITION: [3, 7, 1.7, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.pounder, g.flankGuard, g.minionGun, {reload: 1.2, speed: 0.8, maxSpeed: 0.8}]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], 3), } Class.gladiatorTriswarmMinionOfficialV2 = { PARENT: "gladiatorGenericMinionOfficialV2", - GUNS: [], + GUNS: weaponArray({ + POSITION: [7, 8.5, -1.5, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.flankGuard, g.minionGun, {speed: 1.1, maxSpeed: 1.1, reload: 1.6, size: 1.6, range: 1.15}]), + TYPE: ["swarm", {COLOR: 5}], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, 3), } Class.gladiatorAutoMinionOfficialV2 = makeAuto({ PARENT: "gladiatorGenericMinionOfficialV2", @@ -1639,134 +1409,80 @@ Class.gladiatorHealAuraMinionOfficialV2 = { } ] } -for (let i = 0; i < 3; i++) { - Class.gladiatorTritankMinionOfficialV2.GUNS.push( - { - POSITION: [15, 8.5, 1, 0, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, { speed: 0.7, maxSpeed: 0.7 }, g.minionGun]), - WAIT_TO_CYCLE: true, - TYPE: ["bullet", {COLOR: 5}], - }, - }, - ); - Class.gladiatorTritrapMinionOfficialV2.GUNS.push( - { - POSITION: [13, 7, 1, 0, 0, 120*i, 0], - }, - { - POSITION: [3, 7, 1.7, 13, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, g.minionGun]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ); - Class.gladiatorTriswarmMinionOfficialV2.GUNS.push( - { - POSITION: [7, 8.5, -1.5, 7, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, {size: 1.6, range: 0.5}]), - TYPE: ["swarm", {COLOR: 5}], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - ); -} Class.gladiatorOfficialV2 = { PARENT: "genericPentanought", LABEL: "Gladiator", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.gladiatorOfficialV2.GUNS.push( - { - POSITION: [4.75, 12, 1, 10, 0, 72*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [1.5, 13, 1, 14.75, 0, 72*i, 0], + POSITION: [4.75, 12, 1, 10, 0, 0, 0], + }, { + POSITION: [1.5, 13, 1, 14.75, 0, 0, 0], PROPERTIES: { - MAX_CHILDREN: 4, - SHOOT_SETTINGS: combineStats([g.factory, {size: 0.9, reload: 0.5}]), + SHOOT_SETTINGS: combineStats([g.factory, {size: 0.9, reload: 1.65, health: 1.16, damage: 0.7, speed: 0.8, maxSpeed: 0.8}]), TYPE: "minion", STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, SYNCS_SKILLS: true, MAX_CHILDREN: 2, }, + }, { + POSITION: [12, 13, 1, 0, 0, 0, 0], }, - { - POSITION: [12, 13, 1, 0, 0, 72*i, 0], - }, - ) + ], 5), +} +let minionIndex = 0; +for (let gun of Class.gladiatorOfficialV2.GUNS) { + minionIndex = setGladiatorMinion(gun, minionIndex); } -Class.gladiatorOfficialV2.GUNS[1].PROPERTIES.TYPE = "gladiatorTritankMinionOfficialV2"; -Class.gladiatorOfficialV2.GUNS[4].PROPERTIES.TYPE = "gladiatorTritrapMinionOfficialV2"; -Class.gladiatorOfficialV2.GUNS[7].PROPERTIES.TYPE = "gladiatorTriswarmMinionOfficialV2"; -Class.gladiatorOfficialV2.GUNS[10].PROPERTIES.TYPE = "gladiatorAutoMinionOfficialV2"; -Class.gladiatorOfficialV2.GUNS[13].PROPERTIES.TYPE = "gladiatorAuraMinionOfficialV2"; Class.cerberusOfficialV2 = { PARENT: "genericPentanought", LABEL: "Cerberus", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.cerberusOfficialV2.GUNS.push( - { - POSITION: [12, 4, 1, 0, 2.5, 72*i+10, 0.5], - }, + GUNS: weaponArray([ { - POSITION: [1.5, 4, 1.6, 12, 2.5, 72*i+10, 0.5], + POSITION: [12, 4, 1, 0, 2.5, 10, 0.5], + }, { + POSITION: [1.5, 4, 1.6, 12, 2.5, 10, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, { speed: 1.2 }]), + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, {range: 1.2, shudder: 0.6, health: 0.55, reload: 1.2, speed: 1.35, maxSpeed: 1.35, range: 0.67}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, }, - }, - { - POSITION: [12, 4, 1, 0, -2.5, 72*i-10, 0.5], - }, - { - POSITION: [1.5, 4, 1.6, 12, -2.5, 72*i-10, 0.5], + }, { + POSITION: [12, 4, 1, 0, -2.5, -10, 0.5], + }, { + POSITION: [1.5, 4, 1.6, 12, -2.5, -10, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, { speed: 1.2 }]), + SHOOT_SETTINGS: combineStats([g.trap, g.twin, g.pounder, {range: 1.2, shudder: 0.6, health: 0.55, reload: 1.2, speed: 1.35, maxSpeed: 1.35, range: 0.67}]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, }, - }, - { - POSITION: [14, 5.5, 1, 0, 0, 72*i, 0], - }, - { - POSITION: [2, 5.5, 1.7, 14, 0, 72*i, 0], + }, { + POSITION: [14, 5.5, 1, 0, 0, 0, 0], + }, { + POSITION: [2, 5.5, 1.7, 14, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.twin, g.pounder, { speed: 1.2 }]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.twin, g.pounder, {reload: 1.15, health: 0.85, speed: 0.75, maxSpeed: 0.75, range: 0.5}]), TYPE: "unsetTrap", STAT_CALCULATOR: gunCalcNames.block }, }, - ) + ], 5), } Class.luciferOfficialV2 = { PARENT: "genericPentanought", LABEL: "Lucifer", - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.luciferOfficialV2.GUNS.push( - { - POSITION: [13, 10, 1, 0, 0, 72*i, 0], - }, + GUNS: weaponArray([ { - POSITION: [3.5, 10, 1.6, 13, 0, 72*i, 0], + POSITION: [13, 10, 1, 0, 0, 0, 0], + }, { + POSITION: [3.5, 10, 1.6, 13, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, { speed: 1.3, maxSpeed: 1.3 }, {size: 1.3, health: 2}]), + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, {reload: 1.2, speed: 1.2, maxSpeed: 1.2, size: 1.25, health: 1.15, range: 0.37}]), TYPE: "unsetTrap", STAT_CALCULATOR: gunCalcNames.block }, }, - ) + ], 5), } // T4 Bodies @@ -1774,97 +1490,83 @@ Class.skynetOfficialV2 = { PARENT: "genericPentanought", LABEL: "Skynet", TURRETS: [ - { - POSITION: [12, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - } + ...weaponArray({ + POSITION: [3.25, 4.5, 0, 0, 180, 2], + TYPE: "spamAutoTurretWeak", + }, 5), + ...weaponArray({ + POSITION: [3.25, 8, 0, 36, 180, 2], + TYPE: "spamAutoTurretWeak", + }, 5) ], -} -for (let i = 0; i < 5; i++) { - Class.skynetOfficialV2.TURRETS.push( - { - POSITION: [3.25, 4.5, 0, 72*i, 180, 1], - TYPE: "spamAutoTurret", - }, - ) -} -for (let i = 0; i < 5; i++) { - Class.skynetOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.25, 8, 0, 72*i+36, 180, 1], - TYPE: "spamAutoTurret", - }, - ) + POSITION: [12, 0, 0, 180, 1], + TYPE: "pentagon", + } + ] } Class.pentanoughtBigAura = addAura(2.5, 1.45); Class.supernovaOfficialV2 = { PARENT: "genericPentanought", LABEL: "Supernova", TURRETS: [ + ...weaponArray({ + POSITION: [3.25, 9, 0, 36, 180, 2], + TYPE: "spamAutoTurret", + }, 5), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [9, 0, 0, 0, 360, 1], + POSITION: [9, 0, 0, 0, 360, 2], TYPE: "pentanoughtBigAura", }, ], -} -for (let i = 0; i < 5; i++) { - Class.supernovaOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.25, 9, 0, 72*i+36, 180, 1], - TYPE: "spamAutoTurret", + POSITION: [13, 0, 0, 180, 1], + TYPE: "pentagon", }, - ) + ] } Class.cipherOfficialV2 = { PARENT: "genericPentanought", LABEL: "Cipher", TURRETS: [ + ...weaponArray({ + POSITION: [3.25, 9, 0, 36, 180, 2], + TYPE: "spamAutoTurret", + }, 5), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], + POSITION: [11.5, 0, 0, 0, 360, 2], + TYPE: "megabyteTurretOfficialV2", }, ], -} -for (let i = 0; i < 5; i++) { - Class.cipherOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.25, 9, 0, 72*i+36, 180, 1], - TYPE: "spamAutoTurret", + POSITION: [13, 0, 0, 180, 1], + TYPE: "pentagon", }, - ) + ] } -Class.cipherOfficialV2.TURRETS.push( - { - POSITION: [11.5, 0, 0, 0, 360, 1], - TYPE: "megabyteTurretOfficialV2", - }, -) Class.pentanoughtBigHealAura = addAura(-2, 1.45); Class.interstellarOfficialV2 = { PARENT: "genericPentanought", LABEL: "Interstellar", TURRETS: [ + ...weaponArray({ + POSITION: [3.25, 9, 0, 36, 180, 2], + TYPE: "spamAutoTurret", + }, 5), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [9.5, 0, 0, 0, 360, 1], + POSITION: [9.5, 0, 0, 0, 360, 2], TYPE: "pentanoughtBigHealAura", }, ], -} -for (let i = 0; i < 5; i++) { - Class.interstellarOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [3.25, 9, 0, 72*i+36, 180, 1], - TYPE: "spamAutoTurret", + POSITION: [13, 0, 0, 180, 1], + TYPE: "pentagon", }, - ) + ] } Class.gigabyteTurretOfficialV2 = { PARENT: "autoTankGun", @@ -1873,7 +1575,7 @@ Class.gigabyteTurretOfficialV2 = { { POSITION: [26, 16, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer, g.autoTurret, {speed: 1.1, health: 0.8}]), + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.turret, g.assassin, g.pounder, g.destroyer, {health: 1.05, speed: 0.7, recoil: 1.15}]), TYPE: "bullet", }, }, @@ -1884,65 +1586,59 @@ Class.gigabyteOfficialV2 = { LABEL: "Gigabyte", TURRETS: [ { - POSITION: [14.5, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [13, 0, 0, 0, 360, 1], + POSITION: [13, 0, 0, 0, 360, 2], TYPE: "gigabyteTurretOfficialV2", }, ], + PROPS: [ + { + POSITION: [14.5, 0, 0, 180, 1], + TYPE: "pentagon", + }, + ] } +Class.pentanoughtSmallAura = addAura(1, 1.6, 0.15); Class.malwareOfficialV2 = { PARENT: "genericPentanought", LABEL: "Malware", TURRETS: [ + ...weaponArray({ + POSITION: [4, 8.5, 0, 36, 360, 2], + TYPE: "pentanoughtSmallAura", + }, 5), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], + POSITION: [11.5, 0, 0, 0, 360, 2], + TYPE: "megabyteTurretOfficialV2", }, ], -} -Class.pentanoughtSmallAura = addAura(1, 1.6, 0.15); -for (let i = 0; i < 5; i++) { - Class.malwareOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [4, 8.5, 0, 72*i+36, 360, 1], - TYPE: "pentanoughtSmallAura", + POSITION: [13, 0, 0, 180, 1], + TYPE: "pentagon", }, - ) + ] } -Class.malwareOfficialV2.TURRETS.push( - { - POSITION: [11.5, 0, 0, 0, 360, 1], - TYPE: "megabyteTurretOfficialV2", - }, -) Class.pentanoughtSmallHealAura = addAura(-2/3, 1.6, 0.15); Class.softwareOfficialV2 = { PARENT: "genericPentanought", LABEL: "Software", TURRETS: [ + ...weaponArray({ + POSITION: [4, 8.5, 0, 36, 360, 2], + TYPE: "pentanoughtSmallHealAura", + }, 5), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], + POSITION: [11.5, 0, 0, 0, 360, 2], + TYPE: "megabyteTurretOfficialV2", }, ], -} -for (let i = 0; i < 5; i++) { - Class.softwareOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [4, 8.5, 0, 72*i+36, 360, 1], - TYPE: "pentanoughtSmallHealAura", + POSITION: [13, 0, 0, 180, 1], + TYPE: "pentagon", }, - ) + ] } -Class.softwareOfficialV2.TURRETS.push( - { - POSITION: [11.5, 0, 0, 0, 360, 1], - TYPE: "megabyteTurretOfficialV2", - }, -) if (useOldPhotosphere) { Class.photosphereSmallAuraOfficialV2 = addAura(1, 1.85, 0.15); Class.photosphereBigAuraOfficialV2 = addAura(1.5, 4); @@ -1950,269 +1646,188 @@ if (useOldPhotosphere) { Class.photosphereOfficialV2 = { PARENT: "genericPentanought", LABEL: "Photosphere", - TURRETS: [ + PROPS: [ { - POSITION: [12, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], + POSITION: [12, 0, 0, 180, 1], + TYPE: "pentagon", }, ], } if (useOldPhotosphere) { - for (let i = 0; i < 5; i++) { - Class.photosphereOfficialV2.TURRETS.push( - { - POSITION: [3.5, 8.75, 0, 72*i+36, 360, 1], - TYPE: "photosphereSmallAuraOfficialV2", - }, - ) - } - for (let i = 0; i < 5; i++) { - Class.photosphereOfficialV2.TURRETS.push( - { - POSITION: [3, 4, 0, 72*i, 360, 1], - TYPE: "photosphereBigAuraOfficialV2", - }, - ) - } + Class.photosphereOfficialV2.TURRETS = [ + ...weaponArray({ + POSITION: [3.5, 8.75, 0, 36, 360, 2], + TYPE: "photosphereSmallAuraOfficialV2", + }, 5), + ...weaponArray({ + POSITION: [3, 4, 0, 0, 360, 2], + TYPE: "photosphereBigAuraOfficialV2", + }, 5) + ] } else { - for (let i = 0; i < 5; i++) { - Class.photosphereOfficialV2.TURRETS.push( - { - POSITION: [4, 8.5, 0, 72*i+36, 360, 1], - TYPE: "pentanoughtSmallAura", - }, - ) - } - Class.photosphereOfficialV2.TURRETS.push( + Class.photosphereOfficialV2.TURRETS = [ + ...weaponArray({ + POSITION: [4, 8.5, 0, 36, 360, 2], + TYPE: "pentanoughtSmallAura", + }, 5), { - POSITION: [9, 0, 0, 0, 360, 1], + POSITION: [9, 0, 0, 0, 360, 2], TYPE: "pentanoughtBigAura", }, - ) + ] } Class.stratosphereOfficialV2 = { PARENT: "genericPentanought", LABEL: "Stratosphere", TURRETS: [ + ...weaponArray({ + POSITION: [4, 8.5, 0, 36, 360, 2], + TYPE: "pentanoughtSmallHealAura", + }, 5), { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [9.5, 0, 0, 0, 360, 1], + POSITION: [9.5, 0, 0, 0, 360, 2], TYPE: "pentanoughtBigHealAura", }, ], -} -for (let i = 0; i < 5; i++) { - Class.stratosphereOfficialV2.TURRETS.push( + PROPS: [ { - POSITION: [4, 8.5, 0, 72*i+36, 360, 1], - TYPE: "pentanoughtSmallHealAura", + POSITION: [13, 0, 0, 180, 1], + TYPE: "pentagon", }, - ) + ] } Class.behemothOfficialV2 = { PARENT: "genericPentanought", LABEL: "Behemoth", - BODY: { - HEALTH: 4, - SHIELD: 4, - REGEN: 2.5, - SPEED: 0.4, - }, - TURRETS: [ - { - POSITION: [15, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: 9, MIRROR_MASTER_ANGLE: true}], - }, + BODY: hpBuffBodyStats[3], + PROPS: [ { - POSITION: [24, 0, 0, 180, 0, 0], - TYPE: ["pentagon", {COLOR: 9, MIRROR_MASTER_ANGLE: true}], + POSITION: [15, 0, 0, 180, 1], + TYPE: ["pentagon", {COLOR: 9}], + }, { + POSITION: [24, 0, 0, 180, 0], + TYPE: ["pentagon", {COLOR: 9}], }, ], } Class.astronomicOfficialV2 = { PARENT: "genericPentanought", LABEL: "Astronomic", - BODY: { - HEALTH: 3.2, - SHIELD: 3.2, - REGEN: 2.5, - SPEED: 0.5, - }, - TURRETS: [ - { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [24, 0, 0, 180, 0, 0], - TYPE: ["pentagon", {COLOR: 9, MIRROR_MASTER_ANGLE: true}], + BODY: hpBuffBodyStats[2], + TURRETS: weaponArray({ + POSITION: [4, 8.5, 0, 36, 360, 2], + TYPE: "pentanoughtSmallAura", + }, 5), + PROPS: [ + { + POSITION: [13, 0, 0, 180, 1], + TYPE: "pentagon", + }, { + POSITION: [24, 0, 0, 180, 0], + TYPE: ["pentagon", {COLOR: 9}], }, ], } -for (let i = 0; i < 5; i++) { - Class.astronomicOfficialV2.TURRETS.push( - { - POSITION: [4, 8.5, 0, 72*i+36, 360, 1], - TYPE: "pentanoughtSmallAura", - }, - ) -} Class.grandioseOfficialV2 = { PARENT: "genericPentanought", LABEL: "Grandiose", - BODY: { - HEALTH: 3.2, - SHIELD: 3.2, - REGEN: 2.5, - SPEED: 0.5, - }, - TURRETS: [ - { - POSITION: [13, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [24, 0, 0, 180, 0, 0], - TYPE: ["pentagon", {COLOR: 9, MIRROR_MASTER_ANGLE: true}], + BODY: hpBuffBodyStats[2], + TURRETS: weaponArray({ + POSITION: [4, 8.5, 0, 36, 360, 2], + TYPE: "pentanoughtSmallHealAura", + }, 5), + PROPS: [ + { + POSITION: [13, 0, 0, 180, 1], + TYPE: "pentagon", + }, { + POSITION: [24, 0, 0, 180, 0], + TYPE: ["pentagon", {COLOR: 9}], }, ], } -for (let i = 0; i < 5; i++) { - Class.grandioseOfficialV2.TURRETS.push( - { - POSITION: [4, 8.5, 0, 72*i+36, 360, 1], - TYPE: "pentanoughtSmallHealAura", - }, - ) -} Class.pentagonLeviathanTopOfficialV2 = { PARENT: "genericPentanought", LABEL: "Leviathan", - MIRROR_MASTER_ANGLE: true, - GUNS: [], + GUNS: weaponArray({ + POSITION: [6, 13.5, 0.001, 9, 0, 0, 0], + PROPERTIES: {COLOR: 9}, + }, 5), } Class.pentagonLeviathanBottomOfficialV2 = { PARENT: "genericPentanought", LABEL: "Leviathan", - MIRROR_MASTER_ANGLE: true, - GUNS: [], -} -for (let i = 0; i < 5; i++) { - Class.pentagonLeviathanTopOfficialV2.GUNS.push( - { - POSITION: [6, 13.5, 0.001, 9, 0, 72*i, 0], - PROPERTIES: {COLOR: 9}, - }, - ); - Class.pentagonLeviathanBottomOfficialV2.GUNS.push( - { - POSITION: [7, 17, 0.001, 9, 0, 72*i, 0], - PROPERTIES: {COLOR: 9}, - }, - ); + GUNS: weaponArray({ + POSITION: [7, 17, 0.001, 9, 0, 0, 0], + PROPERTIES: {COLOR: 9}, + }, 5), } Class.hexagonLeviathanTopOfficialV2 = { PARENT: "genericHexnought", LABEL: "Leviathan", - MIRROR_MASTER_ANGLE: true, - GUNS: [], + GUNS: weaponArray({ + POSITION: [6, 10, 0.001, 9.5, 0, 0, 0], + PROPERTIES: {COLOR: 9}, + }, 6), } Class.hexagonLeviathanBottomOfficialV2 = { PARENT: "genericHexnought", LABEL: "Leviathan", - MIRROR_MASTER_ANGLE: true, - GUNS: [], -} -for (let i = 0; i < 6; i++) { - Class.hexagonLeviathanTopOfficialV2.GUNS.push( - { - POSITION: [6, 10, 0.001, 9.5, 0, 60*i, 0], - PROPERTIES: {COLOR: 9}, - }, - ) - Class.hexagonLeviathanBottomOfficialV2.GUNS.push( - { - POSITION: [7, 13.5, 0.001, 9.5, 0, 60*i, 0], - PROPERTIES: {COLOR: 9}, - }, - ) + GUNS: weaponArray({ + POSITION: [7, 13.5, 0.001, 9.5, 0, 0, 0], + PROPERTIES: {COLOR: 9}, + }, 6), } Class.leviathanOfficialV2 = { PARENT: "genericPentanought", LABEL: "Leviathan", - GUNS: [], - BODY: { - SPEED: 2.35, - HEALTH: 0.35, - }, - TURRETS: [ - { - POSITION: [12, 0, 0, 0, 0, 1], - TYPE: ["pentagonLeviathanTopOfficialV2", {COLOR: -1, MIRROR_MASTER_ANGLE: true}] - }, + BODY: speedBuffBodyStats[2], + PROPS: [ { - POSITION: [20, 0, 0, 0, 0, 0], - TYPE: ["pentagonLeviathanBottomOfficialV2", {COLOR: -1, MIRROR_MASTER_ANGLE: true}] + POSITION: [12, 0, 0, 0, 1], + TYPE: "pentagonLeviathanTopOfficialV2" + }, { + POSITION: [20, 0, 0, 0, 0], + TYPE: "pentagonLeviathanBottomOfficialV2" }, ], } Class.valrayvnOfficialV2 = { PARENT: "genericPentanought", LABEL: "Valrayvn", - GUNS: [], - BODY: { - SPEED: 2.15, - HEALTH: 0.5, - }, - TURRETS: [ - { - POSITION: [12, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [20, 0, 0, 0, 0, 0], - TYPE: ["pentagonLeviathanBottomOfficialV2", {COLOR: -1, MIRROR_MASTER_ANGLE: true}] + BODY: speedBuffBodyStats[1], + TURRETS: weaponArray({ + POSITION: [4, 8.5, 0, 36, 360, 2], + TYPE: "pentanoughtSmallAura", + }, 5), + PROPS: [ + { + POSITION: [12, 0, 0, 180, 1], + TYPE: "pentagon" + }, { + POSITION: [20, 0, 0, 0, 0], + TYPE: "pentagonLeviathanBottomOfficialV2" }, ], } -for (let i = 0; i < 5; i++) { - Class.valrayvnOfficialV2.TURRETS.push( - { - POSITION: [4, 8.5, 0, 72*i+36, 360, 1], - TYPE: "pentanoughtSmallAura", - }, - ) -} Class.pegasusOfficialV2 = { PARENT: "genericPentanought", LABEL: "Pegasus", - GUNS: [], - BODY: { - SPEED: 2.15, - HEALTH: 0.5, - }, - TURRETS: [ - { - POSITION: [12, 0, 0, 180, 0, 1], - TYPE: ["pentagon", {COLOR: -1, MIRROR_MASTER_ANGLE: true}], - }, - { - POSITION: [20, 0, 0, 0, 0, 0], - TYPE: ["pentagonLeviathanBottomOfficialV2", {COLOR: -1, MIRROR_MASTER_ANGLE: true}] + BODY: speedBuffBodyStats[1], + TURRETS: weaponArray({ + POSITION: [4, 8.5, 0, 36, 360, 2], + TYPE: "pentanoughtSmallHealAura", + }, 5), + PROPS: [ + { + POSITION: [12, 0, 0, 180, 1], + TYPE: "pentagon" + }, { + POSITION: [20, 0, 0, 0, 0], + TYPE: "pentagonLeviathanBottomOfficialV2" }, ], } -for (let i = 0; i < 5; i++) { - Class.pegasusOfficialV2.TURRETS.push( - { - POSITION: [4, 8.5, 0, 72*i+36, 360, 1], - TYPE: "pentanoughtSmallHealAura", - }, - ) -} Class.addons.UPGRADES_TIER_0.push("dreadOfficialV2"); Class.dreadOfficialV2.UPGRADES_TIER_0 = [ @@ -2330,7 +1945,7 @@ Class.addons.UPGRADES_TIER_0.push("dreadOfficialV2"); const hexDreadNames = { Javelin: { - Javelin: 'Javelin', + Javelin: 'Javelin II', Rapier: 'Lance', Diplomat: 'Envoy', Arbitrator: 'Cutlass', @@ -2342,7 +1957,7 @@ const hexDreadNames = { Lucifer: 'Kitsune', }, Rapier: { - Rapier: 'Rapier', + Rapier: 'Rapier II', Diplomat: 'Emissary', Arbitrator: 'Umpire', Retardant: 'Impeder', @@ -2353,7 +1968,7 @@ const hexDreadNames = { Lucifer: 'Damocles', }, Diplomat: { - Diplomat: 'Diplomat', + Diplomat: 'Diplomat II', Arbitrator: 'Moderator', Retardant: 'Insurgent', Tyrant: 'Dictator', @@ -2363,7 +1978,7 @@ const hexDreadNames = { Lucifer: 'Manticore', }, Arbitrator: { - Arbitrator: 'Arbitrator', + Arbitrator: 'Arbitrator II', Retardant: 'Extinguisher', Tyrant: 'Shogun', Raider: 'Buccaneer', @@ -2372,7 +1987,7 @@ const hexDreadNames = { Lucifer: 'Keres', }, Retardant: { - Retardant: 'Retardant', + Retardant: 'Retardant II', Tyrant: 'Anarchist', Raider: 'Freebooter', Gladiator: 'Combatant', @@ -2380,76 +1995,136 @@ const hexDreadNames = { Lucifer: 'Demogorgon', }, Tyrant: { - Tyrant: 'Tyrant', + Tyrant: 'Tyrant II', Raider: 'Corsair', Gladiator: 'Amazon', Cerberus: 'Ouroboros', Lucifer: 'Raiju', }, Raider: { - Raider: 'Raider', + Raider: 'Raider II', Gladiator: 'Filibuster', Cerberus: 'Wyvern', Lucifer: 'Kraken', }, Gladiator: { - Gladiator: 'Gladiator', + Gladiator: 'Gladiator II', Cerberus: 'Ogre', Lucifer: 'Wendigo', }, Cerberus: { - Cerberus: 'Cerberus', + Cerberus: 'Cerberus II', Lucifer: 'Oni', }, Lucifer: { - Lucifer: 'Lucifer', + Lucifer: 'Lucifer II', }, }; +function setGladiatorMinion(gun, index) { + if (!gun.PROPERTIES) return index; + if (!gun.PROPERTIES.TYPE) return index; + if (!gun.PROPERTIES.TYPE.includes("inion")) return index; + switch (index) { + case 0: + gun.PROPERTIES.TYPE = "gladiatorTritankMinionOfficialV2"; + break; + case 1: + gun.PROPERTIES.TYPE = "gladiatorTritrapMinionOfficialV2"; + break; + case 2: + gun.PROPERTIES.TYPE = "gladiatorTriswarmMinionOfficialV2"; + break; + case 3: + gun.PROPERTIES.TYPE = "gladiatorAutoMinionOfficialV2"; + break; + case 4: + gun.PROPERTIES.TYPE = "gladiatorAuraMinionOfficialV2"; + break; + case 5: + gun.PROPERTIES.TYPE = "gladiatorHealAuraMinionOfficialV2"; + break; + } + return index + 1; +} function mergeHexnoughtWeaponV2(weapon1, weapon2) { weapon1 = ensureIsClass(weapon1); weapon2 = ensureIsClass(weapon2); - let PARENT = Class.genericHexnought, - BODY = JSON.parse(JSON.stringify(PARENT.BODY)), + let PARENT = "genericHexnought", + BODY = hexnoughtBody, GUNS = [], gunsOnOneSide = [], weapon2GunsOnOneSide = [], - TURRETS = []; + TURRETS = [], + turretsOnOneSide = [], + weapon2TurretsOnOneSide = []; // Label let name1 = hexDreadNames[weapon1.LABEL][weapon2.LABEL], name2 = hexDreadNames[weapon2.LABEL][weapon1.LABEL], - weaponName = "", + weaponName = weapon1.LABEL + weapon2.LABEL, orientationId = 0; - if(name1) { + if (name1) { weaponName = name1; - } else { + } else if (name2) { weaponName = name2, orientationId = 1; } let LABEL = weaponName, - className = weaponName.toLowerCase() + orientationId + "OfficialV2"; + className = weapon1.LABEL.toLowerCase() + weapon2.LABEL + orientationId + "OfficialV2"; // Guns ---------------------- - if (weapon1.GUNS) gunsOnOneSide.push(...JSON.parse(JSON.stringify(weapon1.GUNS.slice(0, weapon1.GUNS.length / 5)))); - if (weapon2.GUNS) weapon2GunsOnOneSide = JSON.parse(JSON.stringify(weapon2.GUNS.slice(0, weapon2.GUNS.length / 5))); + if (weapon1.GUNS) { + for (let i = 0; i < weapon1.GUNS.length; i += 5) { + gunsOnOneSide.push(dereference(weapon1.GUNS[i])); + } + } + if (weapon2.GUNS) { + for (let i = 0; i < weapon2.GUNS.length; i += 5) { + weapon2GunsOnOneSide.push(dereference(weapon2.GUNS[i])); + } + } for (let g in weapon2GunsOnOneSide) weapon2GunsOnOneSide[g].POSITION[5] += 60; gunsOnOneSide.push(...weapon2GunsOnOneSide) + // Turrets ------------------- + if (weapon1.TURRETS) { + for (let i = 0; i < weapon1.TURRETS.length; i += 5) { + turretsOnOneSide.push(dereference(weapon1.TURRETS[i])); + } + } + if (weapon2.TURRETS) { + for (let i = 0; i < weapon2.TURRETS.length; i += 5) { + weapon2TurretsOnOneSide.push(dereference(weapon2.TURRETS[i])); + } + } + + for (let t in weapon2TurretsOnOneSide) weapon2TurretsOnOneSide[t].POSITION[3] += 60; + turretsOnOneSide.push(...weapon2TurretsOnOneSide) + // Scale to fit size constraints for (let g in gunsOnOneSide) { gunsOnOneSide[g].POSITION[1] *= hexnoughtScaleFactor ** 2; gunsOnOneSide[g].POSITION[4] *= hexnoughtScaleFactor ** 2; } + for (let t in turretsOnOneSide) { + turretsOnOneSide[t].POSITION[0] *= hexnoughtScaleFactor ** 2; + } + for (let i = 0; i < 3; i++) { for (let g in gunsOnOneSide) { let gun = JSON.parse(JSON.stringify(gunsOnOneSide[g])); gun.POSITION[5] += 120 * i; GUNS.push(gun); } + for (let t in turretsOnOneSide) { + let turret = JSON.parse(JSON.stringify(turretsOnOneSide[t])); + turret.POSITION[3] += 120 * i; + TURRETS.push(turret); + } }; // Gladiator @@ -2457,26 +2132,7 @@ function mergeHexnoughtWeaponV2(weapon1, weapon2) { let droneSpawnerIndex = 0 for (let g in GUNS) { let gun = GUNS[g]; - if (gun.PROPERTIES && gun.PROPERTIES.TYPE == "gladiatorTritankMinionOfficialV2") { - switch (droneSpawnerIndex) { - case 1: - gun.PROPERTIES.TYPE = "gladiatorTritrapMinionOfficialV2"; - break; - case 2: - gun.PROPERTIES.TYPE = "gladiatorTriswarmMinionOfficialV2"; - break; - case 3: - gun.PROPERTIES.TYPE = "gladiatorAutoMinionOfficialV2"; - break; - case 4: - gun.PROPERTIES.TYPE = "gladiatorAuraMinionOfficialV2"; - break; - case 5: - gun.PROPERTIES.TYPE = "gladiatorHealAuraMinionOfficialV2"; - break; - } - droneSpawnerIndex++; - } + droneSpawnerIndex = setGladiatorMinion(gun, droneSpawnerIndex); } } @@ -2486,7 +2142,7 @@ function mergeHexnoughtWeaponV2(weapon1, weapon2) { // Smash it together Class[className] = { - PARENT, BODY, LABEL, GUNS, TURRETS, + PARENT, BODY, LABEL, GUNS, TURRETS }; return className; } @@ -2495,65 +2151,59 @@ function makeHexnoughtBodyV2(body) { body = ensureIsClass(body); - let PARENT = Class.genericHexnought, + let PARENT = "genericHexnought", BODY = {}, - GUNS = [], - gunsOnOneSide = [], TURRETS = [], + PROPS = [], LABEL = body.LABEL; // Label let className = LABEL.toLowerCase() + "HexOfficialV2"; - // Guns ---------------------- - if (body.GUNS) gunsOnOneSide.push(...JSON.parse(JSON.stringify(body.GUNS.slice(0, body.GUNS.length / 5 * 2)))); - for (let g in gunsOnOneSide) { - gunsOnOneSide[g].POSITION[5] *= 5 / 6; - gunsOnOneSide[g].POSITION[1] *= hexnoughtScaleFactor ** 3; - gunsOnOneSide[g].POSITION[4] *= hexnoughtScaleFactor ** 2; - } - - for (let i = 0; i < 3; i++) { - for (let g in gunsOnOneSide) { - let gun = JSON.parse(JSON.stringify(gunsOnOneSide[g])); - gun.POSITION[5] += 120 * i; - GUNS.push(gun); - } - }; - // Turrets -------------------- - let turretRingLoopLength = Math.floor(body.TURRETS.length / 5); + if (body.TURRETS) { + let turretRingLoopLength = Math.floor(body.TURRETS.length / 5); - // Turret adding - for (let t = 0; t < body.TURRETS.length; t++) { - let turret = body.TURRETS[t]; - if (turret.TYPE[0].indexOf('pentagon') >= 0) { // Replace pentagons with hexagons - TURRETS.push( - { - POSITION: [turret.POSITION[0], 0, 0, 0, 0, turret.POSITION[5]], - TYPE: ['hexagon' + turret.TYPE[0].substring(8), turret.TYPE[1]], - } - ); - } else if (turret.POSITION[1]) { // Do whole turret loop at once - for (let i = 0; i < turretRingLoopLength; i++) { - for (let j = 0; j < 6; j++) { - turret = body.TURRETS[t + i * 5]; - TURRETS.push( - { - POSITION: [turret.POSITION[0] * hexnoughtScaleFactor, turret.POSITION[1] * hexnoughtScaleFactor ** 0.5, turret.POSITION[2], turret.POSITION[3] / 6 * 5 + 60 * j, turret.POSITION[4], turret.POSITION[5]], - TYPE: turret.TYPE, - } - ) + // Turret adding + for (let t = 0; t < body.TURRETS.length; t++) { + let turret = body.TURRETS[t]; + if (turret.POSITION[1]) { // Do whole turret loop at once + for (let i = 0; i < turretRingLoopLength; i++) { + for (let j = 0; j < 6; j++) { + turret = body.TURRETS[t + i * 5 + 1]; + TURRETS.push( + { + POSITION: [turret.POSITION[0] * hexnoughtScaleFactor, turret.POSITION[1] * hexnoughtScaleFactor ** 0.5, turret.POSITION[2], turret.POSITION[3] / 6 * 5 + 60 * j, turret.POSITION[4], turret.POSITION[5]], + TYPE: turret.TYPE, + } + ) + } } + t += 5 * turretRingLoopLength - 1; + } else { // Centered turrets + TURRETS.push( + { + POSITION: [turret.POSITION[0] * hexnoughtScaleFactor ** 0.5, 0, 0, turret.POSITION[3], turret.POSITION[4], turret.POSITION[5]], + TYPE: turret.TYPE, + } + ) + } + } + } + if (body.PROPS) { + for (let prop of body.PROPS) { + prop = dereference(prop); + let type = prop.TYPE; + if (typeof type == "string") { + type = [type]; } - t += 5 * turretRingLoopLength - 1; - } else { // Centered turrets - TURRETS.push( + type[0] = type[0].replace("pentagon", "hexagon"); + PROPS.push( { - POSITION: [turret.POSITION[0] * hexnoughtScaleFactor ** 0.5, 0, 0, turret.POSITION[3], turret.POSITION[4], turret.POSITION[5]], - TYPE: turret.TYPE, + POSITION: [prop.POSITION[0], 0, 0, prop.POSITION[3], prop.POSITION[4]], + TYPE: type } - ) + ); } } @@ -2562,7 +2212,7 @@ function makeHexnoughtBodyV2(body) { // Smash it together Class[className] = { - PARENT, BODY, LABEL, GUNS, TURRETS, + PARENT, BODY, LABEL, TURRETS, PROPS, }; return [className]; } @@ -2575,4 +2225,4 @@ if(buildHexnoughts) { Class[i].UPGRADES_TIER_0.push(mergeHexnoughtWeaponV2(i, j)); } } -} +} \ No newline at end of file diff --git a/server/modules/definitions/addons/exampleAddon.js b/server/modules/definitions/addons/exampleAddon.js index 3eb655784..8c88557be 100644 --- a/server/modules/definitions/addons/exampleAddon.js +++ b/server/modules/definitions/addons/exampleAddon.js @@ -72,4 +72,4 @@ Class.exampleAddon = { }; Class.addons.UPGRADES_TIER_0.push("exampleAddon"); -console.log('[exampleAddon] The Abomination has been created.'); +console.log('[exampleAddon] The Abomination has been created.'); \ No newline at end of file diff --git a/server/modules/definitions/addons/geometryDashDart.js b/server/modules/definitions/addons/geometryDashDart.js new file mode 100644 index 000000000..99a98d793 --- /dev/null +++ b/server/modules/definitions/addons/geometryDashDart.js @@ -0,0 +1,72 @@ +const { combineStats, makeDeco } = require('../facilitators'); +const g = require('../gunvals'); + + Class.geometryDash_square = makeDeco(4, 'blue'); + Class.geometryDash_square.MIRROR_MASTER_ANGLE = true; + + Class.geometryDash_longRect = { + SHAPE: 'M 0 0 L 5 0 L 5 2 L 0 2 L 0 0', + COLOR: 'blue', + MIRROR_MASTER_ANGLE: true + }; + + Class.geometryDash = { + PARENT: 'genericTank', + LABEL: 'Geometry Dash', + SHAPE: 4, + BODY: { + HEALTH: 1e7, + SHIELD: 0, + DAMAGE: 0, + ACCELERATION: 10, + SPEED: 20, + PUSHABILITY: 0 + }, + COLOR: '#FFFF00', + SIZE: 20, + SKILL_CAP: Array(10).fill(10), + EXTRA_SKILL: 10, + FACING_TYPE: 'autospin', + TURRETS: [ + { + POSITION: { SIZE: 5, X: 4, Y: 5, LAYER: 1 }, + TYPE: 'geometryDash_square' + }, + { + POSITION: { SIZE: 5, X: 4, Y: -5, LAYER: 1 }, + TYPE: 'geometryDash_square' + }, + { + POSITION: { SIZE: 5, X: -6.1, Y: 2, ANGLE: 90, LAYER: 1 }, + TYPE: 'geometryDash_longRect' + } + ], + UPGRADES_TIER_0: ['geometryDashWave'] + } + + Class.geometryDashWave = { + PARENT: 'genericTank', + LABEL: 'Dart', + NAME: 'Wave', + SHAPE: 3, + BODY: { + HEALTH: 1e7, + DAMAGE: 1e7, + SHIELD: 0, + ACCELERATION: 0, + SPEED: 0, + PUSHABILITY: 0 + }, + COLOR: '#FFFF00', + SIZE: 20, + GUNS: [{ + POSITION: { LENGTH: 13, WIDTH: 8, ASPECT: 2, ANGLE: 180 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.tonsmorerecoil, g.tonsmorerecoil, g.veryfast, { reload: 0.05, range: 0.2 }]), + TYPE: 'bullet', + COLOR: 'blue' + } + }] + } + + Class.addons.UPGRADES_TIER_0.push('geometryDash'); \ No newline at end of file diff --git a/server/modules/definitions/addons/labyFood.js b/server/modules/definitions/addons/labyFood.js index 72c1ba124..fab32fdda 100644 --- a/server/modules/definitions/addons/labyFood.js +++ b/server/modules/definitions/addons/labyFood.js @@ -20,7 +20,7 @@ module.exports = ({ Config }) => { // 6-wide dimension of the 6 shiny modifiers Array(6).fill().map((_, k, c) => [ // Chance of spawning, set to 200mil for regular polygons and exponents of 10 otherwise - k ? 10 ** (c.length - k - 1) : 200_000_000, + k ? 10 ** (Config.length - k - 1) : 200_000_000, disableCrashers ? // no crashers @@ -45,7 +45,7 @@ module.exports = ({ Config }) => { // 6-wide dimension of the 6 shiny modifiers Array(6).fill().map((_, k, c) => [ // Chance of spawning, set to 200mil for regular polygons and exponents of 10 otherwise - k ? 10 ** (c.length - k - 1) : 200_000_000, + k ? 10 ** (Config.length - k - 1) : 200_000_000, disableCrashers ? // no crashers diff --git a/server/modules/definitions/addons/playerskins.js b/server/modules/definitions/addons/playerskins.js new file mode 100644 index 000000000..51fb376ad --- /dev/null +++ b/server/modules/definitions/addons/playerskins.js @@ -0,0 +1,175 @@ +const { combineStats, makeAuto, makeOver, makeDeco, makeGuard, makeBird, makeCeption } = require('../facilitators.js'); +const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); +require('../groups/generics.js'); +const g = require('../gunvals.js'); + + +Class.bsignalcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/tv.png?v=1708615075011") +Class.tcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_29_0ry_Kleki.png?v=1708536680813") +Class.dfxcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/MOSHED-2023-12-14-17-8-14.gif?v=1708618924966") +Class.primalcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/primal.webp?v=1708602763032") +Class.kangaroocharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/image.webp?v=1708602765689") +Class.cogcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381") +Class.skypecharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/skype.png?v=1708623594494") +Class.coincharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2e2ccc30-5baf-41a2-aceb-c5456a1cc6dc.image.png?v=1708619146196") +Class.discordcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2023_12_06_0yl_Kleki.png?v=1701908710293") +Class.incomcharm = makeDeco("https://cdn.glitch.global/68f0db33-c86d-4aa5-9a35-a6750a92eae7/1200px-Icon-round-Question_mark.svg.png?v=1699273933044") +Class.eggcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682l.webp?v=1714156807621", "veryLightGrey") +Class.squarecharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934167280848969.webp?v=1714156773284", "gold") +Class.trianglecharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165934432608321546.webp?v=1714156768932", "orange") +Class.pentagoncharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165825970528325682.webp?v=1714156764280", "purple") +Class.gemcharm = makeDeco("https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/1165826077843796018.webp?v=1714156778841", "aqua") + +Class.bsignalskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "bsignalcharm" + }] +}; +Class.tankcharmskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, 6, 5.5, 0, 360, 3], + TYPE: "tcharm" + }] +}; +Class.dfxskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "dfxcharm" + }] +}; +Class.primalskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [20, 0, 0, 0, 360, 3], + TYPE: "primalcharm" + }] +}; +Class.kangarooskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "kangaroocharm" + }] +}; +Class.cswmskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 0.5], + TYPE: "sandwichdeco" + }] +}; +Class.cogskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "cogcharm" + }] +}; +Class.skypeskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "skypecharm" + }] +}; +Class.coinskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [18, 0, 0, 0, 360, 3], + TYPE: "coincharm" + }] +}; +Class.discordskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 3], + TYPE: "discordcharm" + }] +}; +Class.deltaDecoskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 3], + TYPE: "deltaDeco" + }] +}; +Class.incomskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -5, 5.5, 0, 360, 3], + TYPE: "incomcharm" + }] +}; +Class.eggskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [15, -5, 5.5, 0, 360, 3], + TYPE: "eggcharm" + }] +}; +Class.squareskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [13, -5, 5.5, 0, 360, 3], + TYPE: "squarecharm" + }] +}; +Class.triangleskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [13, -5, 5.5, 0, 360, 3], + TYPE: "trianglecharm" + }] +}; +Class.pentagonskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [10, -5, 5.5, 0, 360, 3], + TYPE: "pentagoncharm" + }] +}; +Class.gemskin = { + MAX_CHILDREN: 0, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), + TURRETS: [{ + POSITION: [15, -5, 5.5, 0, 360, 3], + TYPE: "gemcharm" + }] +}; \ No newline at end of file diff --git a/server/modules/definitions/addons/solario.js b/server/modules/definitions/addons/solario.js new file mode 100644 index 000000000..dbe5d7c44 --- /dev/null +++ b/server/modules/definitions/addons/solario.js @@ -0,0 +1,573 @@ +const { combineStats, makeDeco } = require('../facilitators.js'); +const { base, gunCalcNames, dfltskl, statnames } = require('../constants.js'); +const g = require('../gunvals.js'); +const fireGun = (gun) => { + gun.fire( + gun.offset * Math.cos(gun.direction + gun.angle + gun.body.facing) + (1.35 * gun.length - gun.width * gun.settings.size / 2) * Math.cos(gun.angle + gun.body.facing), + gun.offset * Math.sin(gun.direction + gun.angle + gun.body.facing) + (1.35 * gun.length - gun.width * gun.settings.size / 2) * Math.sin(gun.angle + gun.body.facing), + gun.body.skill + ); +}; + +Class.solarioTurret1 = { + PARENT: "genericTank", + LABEL: "Turret", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + COLOR: 13, + SHAPE: 0, + BODY: { + FOV: 0.8, + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [16, 14, 1, 0, 0, 0, 0], + }, + { + POSITION: [4, 14, 1.8, 16, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, g.autoTurret, { reload: 1.3 }]), + TYPE: "trap" + }, + }, + ], +} +Class.solarioRingTurret = { + PARENT: "genericTank", + LABEL: "Turret", + COLOR: 13, + HAS_NO_RECOIL: true, + MIRROR_MASTER_ANGLE: true, + GUNS: [{ + POSITION: [10, 8, 0, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.emplaser, g.autoTurret, { reload: 2, speed: 2, maxSpeed: 2 }]), + TYPE: ["laser", { ARENA_CLOSER: true }], + AUTOFIRE: true + }, + }, { + POSITION: [24, 1, 1, 0, 0, 180, 2 / 3], + PROPERTIES: { + COLOR: 'red', + }, + }], +} +Class.solarioCircAttack = { + PARENT: "bullet", + SHAPE: "M 1 0 A 1 1 0 0 0 -1 0 A 1 1 0 0 0 0 1 L 0 0.95 A 0.95 0.95 0 0 1 0 -0.95 A 0.95 0.95 0 0 1 0.95 0 L 1 0", + FACING_TYPE: ["spin", { speed: 0.02 }], + MOTION_TYPE: ["grow", { growSpeed: 2 }], + ARENA_CLOSER: true +} +Class.solarioTurret2 = { + PARENT: "genericTank", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + LABEL: "Turret", + COLOR: 13, + SHAPE: 3, + BODY: { + FOV: 0.8, + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [26, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret, { reload: 1.5 }]), + TYPE: "bullet" + }, + }, + ], +} +Class.solarioTurret3 = { + PARENT: "genericTank", + LABEL: "Turret", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + SHAPE: 4, + COLOR: 13, + BODY: { + FOV: 0.8, + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [16, 4, 1, 0, -3.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.power]), + TYPE: "bullet", + HAS_NO_RECOIL: true + }, + }, + { + POSITION: [16, 4, 1, 0, 3.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.power]), + TYPE: "bullet" + }, + }, + ], +} +Class.solarioTurret4 = { + PARENT: "genericTank", + LABEL: "Turret", + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + COLOR: 13, + SHAPE: 6, + BODY: { + FOV: 0.8, + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [22, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.autoTurret]), + TYPE: "bullet" + }, + }, + ], +} +Class.solarioturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.6 A 1.5 1.5 0 0 0 0 1.6 A 1.5 1.5 0 0 0 0 -1.6 Z M 0 -1.5 A 0.001 0.001 0 0 1 0 1.5 A 0.001 0.001 0 0 1 0 -1.5', + COLOR: 13, + SYNC_TURRET_SKILLS: true, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [5, 15, 0, 90, 220, 1], + TYPE: "solarioTurret1", + }, { + POSITION: [5, 15, 0, 180, 220, 1], + TYPE: "solarioTurret2", + }, { + POSITION: [5, 15, 0, 270, 220, 1], + TYPE: "solarioTurret3", + }, { + POSITION: [5, 15, 0, 0, 220, 1], + TYPE: "solarioTurret4", + }] +} +Class.solarioturretBase2ndRing = { + LABEL: "Base", + SHAPE: 'M 0 -3.1 A 3 3 0 0 0 0 3.1 A 3 3 0 0 0 0 -3.1 Z M 0 -3 A 0.001 0.001 0 0 1 0 3 A 0.001 0.001 0 0 1 0 -3', + COLOR: 13, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [5, 30, 0, 90, 220, 1], + TYPE: "solarioTurret1", + }, { + POSITION: [5, 30, 0, 180, 220, 1], + TYPE: "solarioTurret2", + }, { + POSITION: [5, 30, 0, 270, 220, 1], + TYPE: "solarioTurret3", + }, { + POSITION: [5, 30, 0, 0, 220, 1], + TYPE: "solarioTurret4", + }] +} +Class.solarioRingAttack = { + LABEL: "Base", + SHAPE: 'M 0 -3.1 A 3 3 0 0 0 0 3.1 A 3 3 0 0 0 0 -3.1 Z M 0 -3 A 0.001 0.001 0 0 1 0 3 A 0.001 0.001 0 0 1 0 -3', + COLOR: 13, + BODY: { + PUSHABILITY: 0, + RANGE: 300, + }, + ARENA_CLOSER: true, + DIE_AT_RANGE: true, + MOTION_TYPE: "solarioarena", + FACING_TYPE: ["spin", { speed: 0.3 }], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [3, 30, 0, 270, 0, 1], + TYPE: "solarioRingTurret", + }, { + POSITION: [3, 30, 0, 0, 0, 1], + TYPE: "solarioRingTurret", + }, { + POSITION: [3, 30, 0, 90, 0, 1], + TYPE: "solarioRingTurret", + }, { + POSITION: [3, 30, 0, 180, 0, 1], + TYPE: "solarioRingTurret", + }] +} +Class.solarioturretBase2 = { + LABEL: "Base", + SHAPE: 'M 0 -1.6 A 1.5 1.5 0 0 0 0 1.6 A 1.5 1.5 0 0 0 0 -1.6 Z M 0 -1.5 A 0.001 0.001 0 0 1 0 1.5 A 0.001 0.001 0 0 1 0 -1.5', + COLOR: 33, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [5, 15, 0, 90, 220, 1], + TYPE: ["solarioTurret1", { COLOR: 33 }], + }, { + POSITION: [5, 15, 0, 180, 220, 1], + TYPE: ["solarioTurret2", { COLOR: 33 }], + }, { + POSITION: [5, 15, 0, 270, 220, 1], + TYPE: ["solarioTurret3", { COLOR: 33 }], + }, { + POSITION: [5, 15, 0, 0, 220, 1], + TYPE: ["solarioTurret4", { COLOR: 33 }], + }] +} +Class.solarioturretBase2ndRing2 = { + LABEL: "Base", + SHAPE: 'M 0 -3.1 A 3 3 0 0 0 0 3.1 A 3 3 0 0 0 0 -3.1 Z M 0 -3 A 0.001 0.001 0 0 1 0 3 A 0.001 0.001 0 0 1 0 -3', + COLOR: 33, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [5, 30, 0, 90, 220, 1], + TYPE: ["solarioTurret1", { COLOR: 33 }], + }, { + POSITION: [5, 30, 0, 180, 220, 1], + TYPE: ["solarioTurret2", { COLOR: 33 }], + }, { + POSITION: [5, 30, 0, 270, 220, 1], + TYPE: ["solarioTurret3", { COLOR: 33 }], + }, { + POSITION: [5, 30, 0, 0, 220, 1], + TYPE: ["solarioTurret4", { COLOR: 33 }], + }] +} +Class.solarioOutline = makeDeco("M 0 -3.1 A 3 3 0 0 0 0 3.1 A 3 3 0 0 0 0 -3.1 Z M 0 -3 A 0.001 0.001 0 0 1 0 3 A 0.001 0.001 0 0 1 0 -3", 13) +Class.solariobase = { + PARENT: "genericBoss", + LABEL: "Solario", + SHAPE: 0, + BODY: { + HEALTH: 1000, + }, + SIZE: 15, + DANGER: 10, +} +Class.solario = { + PARENT: "solariobase", + COLOR: 13, + GLOW: { + RADIUS: 50, + COLOR: 13, + ALPHA: 1, + RECURSION: 8 + }, + GUNS: [{ + POSITION: [15, 10, 1, 0, 0, 0, 0], + }, { + POSITION: [15, 10, 1, 0, 0, 180, 0], + }, { + POSITION: [0, 0, 1, 0, 0, 0, 25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, { reload: 5 }]), + TYPE: "bullet", + AUTOFIRE: true, + IDENTIFIER: "startlaserattack" + }, + }, { + POSITION: [1, 10, 1, 0, 0, 0, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, { reload: 75 }]), + TYPE: "bullet", + AUTOFIRE: true, + IDENTIFIER: "solarioAttack" + }, + }, { + POSITION: [1, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.grenade_explosion, g.xxtrahealth, { maxSpeed: 0, speed: 0, range: 5, pen: 3 }]), + TYPE: "solarioCircAttack", + ALT_FIRE: true, + }, + }, { + POSITION: [1, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.xxtrahealth, { maxSpeed: 0, speed: 0, range: 1.4, reload: 5 }]), + TYPE: "solarioRingAttack", + ALT_FIRE: true + }, + }, + ], + TURRETS: [{ + POSITION: [30, 0, 0, 0, 360, 0], + TYPE: "solarioturretBase", + }, { + POSITION: [30, 0, 0, 0, 360, 0], + TYPE: "solarioturretBase2ndRing", + }, { + POSITION: [16, 0, 0, 0, 360, 3], + TYPE: ["minilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] + }, { + POSITION: [8.2, 0, 0, 0, 360, 2], + TYPE: "solarioOutline" + }, + ], + ON: [ + { + event: 'fire', + handler: ({ body, gun }) => { + if (gun.identifier == 'startlaserattack') { + sockets.broadcast('Solario: DODGE THIS!!'); + setTimeout(() => body.define('solariolaser'), 1000); + } + if (gun.identifier == 'solarioAttack') { + body.guns[3].canShoot = false; + let attack = ~~(Math.random() * 2); + switch(attack) { + case 0: + fireGun(body.guns[4]); + setTimeout(() => { if (body != null) fireGun(body.guns[4]) }, 6000); + setTimeout(() => { if (body != null) fireGun(body.guns[4]) }, 12000); + break; + case 1: + fireGun(body.guns[5]); + break; + } + } + } + }, { + event: "death", + handler: ({}) => { + sockets.broadcast('YOU CANT DEFEAT ME!') + } + }, { + event: "damage", + handler: ({ body }) => { + if (body.health.amount < (body.health.max / 3) * 2) { + sockets.broadcast('Solario: YOU CANT STOP ME!!!!!'); + body.define('solariophase2'); + } + } + } + ], +} +Class.solariolaser = { + PARENT: "solariobase", + COLOR: 13, + GLOW: { + RADIUS: 50, + COLOR: 13, + ALPHA: 1, + RECURSION: 8 + }, + GUNS: [{ + POSITION: [15, 10, 1, 0, 0, 0, 5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + TYPE: "laser", + AUTOFIRE: true, + COLOR: "red", + }, + }, { + POSITION: [15, 10, 1, 0, 0, 180, 5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + TYPE: "laser", + AUTOFIRE: true, + COLOR: "red", + }, + }, { + POSITION: [350, 10, 2.5, 0, 0, 355, 0], + PROPERTIES: { + COLOR: "red", + ALPHA: 0.5 + } + }, { + POSITION: [350, 10, 2.5, 0, 0, 175, 0], + PROPERTIES: { + COLOR: "red", + ALPHA: 0.5 + } + }, { + POSITION: [0, 0, 1, 0, 0, 0, 15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, { reload: 5 }]), + TYPE: "bullet", + AUTOFIRE: true, + IDENTIFIER: "endlaserattack", + }, + }, + ], + TURRETS: [{ + POSITION: [30, 0, 0, 0, 360, 0], + TYPE: "solarioturretBase", + }, { + POSITION: [30, 0, 0, 0, 360, 0], + TYPE: "solarioturretBase2ndRing", + }, { + POSITION: [16, 0, 0, 0, 360, 3], + TYPE: ["minilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] + }, { + POSITION: [8.2, 0, 0, 0, 360, 2], + TYPE: "solarioOutline" + }, + ], + ON: [ + { + event: 'fire', + handler: ({ body, gun }) => { + if (gun.identifier == 'endlaserattack') { + sockets.broadcast('Solario: RAHH!'); + body.children = []; + setTimeout(() => body.define('solario'), 500); + } + } + }, { + event: "death", + handler: ({}) => { + sockets.broadcast('YOU CANT DEFEAT ME!') + } + }, { + event: "damage", + handler: ({ body }) => { + if (body.health.amount < (body.health.max / 3) * 2) { + sockets.broadcast('Solario: YOU CANT STOP ME!!!!!'); + body.define('solariolaserphase2'); + } + } + } + ], +}; +Class.solariophase2 = { + PARENT: "solariobase", + COLOR: 33, + GLOW: { + RADIUS: 50, + STRENGTH: 30, + COLOR: 33, + ALPHA: 0.8, + RECURSION: 8 + }, + GUNS: [{ + POSITION: [15, 10, 1, 0, 0, 0, 0], + }, { + POSITION: [15, 10, 1, 0, 0, 90, 0], + }, { + POSITION: [15, 10, 1, 0, 0, 180, 0], + }, { + POSITION: [15, 10, 1, 0, 0, 270, 0], + }, { + POSITION: [0, 0, 1, 0, 0, 0, 25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, { reload: 5 }]), + TYPE: "bullet", + AUTOFIRE: true, + IDENTIFIER: "startlaserattack", + }, + }, + ], + TURRETS: [{ + POSITION: [30, 0, 0, 0, 360, 0], + TYPE: ["solarioturretBase2", { COLOR: 33 }], + }, { + POSITION: [30, 0, 0, 0, 360, 0], + TYPE: ["solarioturretBase2ndRing2", { COLOR: 33 }], + }, { + POSITION: [16, 0, 0, 0, 360, 3], + TYPE: ["minilaser", { HAS_NO_RECOIL: true, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"]}] + }, { + POSITION: [8.2, 0, 0, 0, 360, 2], + TYPE: ["solarioOutline", { COLOR: 33 }] + }, + ], + ON: [ + { + event: 'fire', + handler: ({ body, gun }) => { + if (gun.identifier == 'startlaserattack') { + sockets.broadcast('Solario: DODGE THIS!!'); + setTimeout(() => body.define('solariolaserphase2'), 1000); + } + } + } + ], +}; +Class.solariolaserphase2 = { + PARENT: "solariophase2", + GUNS: [{ + POSITION: [15, 10, 1, 0, 0, 0, 5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + TYPE: "laser", + AUTOFIRE: true, + COLOR: "red", + }, + }, { + POSITION: [15, 10, 1, 0, 0, 90, 5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + TYPE: "laser", + AUTOFIRE: true, + COLOR: "red", + }, + }, { + POSITION: [15, 10, 1, 0, 0, 180, 5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + TYPE: "laser", + AUTOFIRE: true, + COLOR: "red", + }, + }, { + POSITION: [15, 10, 1, 0, 0, 270, 5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.solarioblast]), + TYPE: "laser", + AUTOFIRE: true, + COLOR: "red", + }, + }, { + POSITION: [350, 10, 2.5, 0, 0, 355, 0], + PROPERTIES: { + COLOR: "red", + ALPHA: 0.5 + } + }, { + POSITION: [350, 10, 2.5, 0, 0, 85, 0], + PROPERTIES: { + COLOR: "red", + ALPHA: 0.5 + } + }, { + POSITION: [350, 10, 2.5, 0, 0, 175, 0], + PROPERTIES: { + COLOR: "red", + ALPHA: 0.5 + } + }, { + POSITION: [350, 10, 2.5, 0, 0, 265, 0], + PROPERTIES: { + COLOR: "red", + ALPHA: 0.5 + } + }, { + POSITION: [0, 0, 1, 0, 0, 0, 15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, { reload: 5 }]), + TYPE: "bullet", + AUTOFIRE: true, + IDENTIFIER: "endlaserattack", + }, + }, + ], + ON: [ + { + event: 'fire', + handler: ({ body, gun }) => { + if (gun.identifier == 'endlaserattack') { + sockets.broadcast('Solario: RAHH!'); + setTimeout(() => body.define('solariophase2'), 500); + } + } + }, { + event: "death", + handler: ({ body }) => { + sockets.broadcast('YOU CANT DEFEAT ME!') + } + } + ], +} +Class.devBosses.UPGRADES_TIER_0.push('solario') \ No newline at end of file diff --git a/server/modules/definitions/combined.js b/server/modules/definitions/combined.js index f8b530de3..a07f6b091 100644 --- a/server/modules/definitions/combined.js +++ b/server/modules/definitions/combined.js @@ -28,7 +28,7 @@ function processAddonFolder(directory) { console.log(`Loading addon: ${filename}`); let result = require(filepath); if ('function' === typeof result) { - result({ Config: c, Events: events }); + result({ Config, Events: events }); } loadedAddons.push(filename.slice(0, -3)); } @@ -40,7 +40,7 @@ let addonsLoadEnd = Date.now(); console.log("Loaded addons in " + (addonsLoadEnd - definitionGroupsLoadEnd) + " milliseconds. \n"); // "Flattening" refers to removing PARENT attributes and applying the parents' attributes to the definition themselves, if not overwritten later on. -if (c.flattenDefintions) { +if (Config.flattenDefintions) { console.log(`Flattening ${definitionCount} definitions...`); let flattenDefinition = (output, definition) => { definition = ensureIsClass(definition); @@ -73,7 +73,7 @@ if (c.flattenDefintions) { console.log("Definitions flattened in " + (Date.now() - addonsLoadEnd) + " milliseconds. \n"); } -console.log(`Combined ${groups.length} definition groups and ${loadedAddons.length} addons into ${definitionCount} ${c.flattenDefintions ? 'flattened ' : ''}definitions!\n`); +console.log(`Combined ${groups.length} definition groups and ${loadedAddons.length} addons into ${definitionCount} ${Config.flattenDefintions ? 'flattened ' : ''}definitions!\n`); // Index the definitions let i = 0; diff --git a/server/modules/definitions/constants.js b/server/modules/definitions/constants.js index 25ac48e7f..23182c9e9 100644 --- a/server/modules/definitions/constants.js +++ b/server/modules/definitions/constants.js @@ -75,6 +75,12 @@ module.exports = { BULLET_DAMAGE: 'Ball Damage', RELOAD: 'Ball Density', }, + lancer: { + BULLET_HEALTH: 'Lance Longevity', + BULLET_PEN: 'Lance Sharpness', + BULLET_DAMAGE: 'Lance Damage', + RELOAD: 'Lance Density' + } }, gunCalcNames: { default: 0, diff --git a/server/modules/definitions/facilitators.js b/server/modules/definitions/facilitators.js index 8f0261838..866e89d37 100644 --- a/server/modules/definitions/facilitators.js +++ b/server/modules/definitions/facilitators.js @@ -62,7 +62,7 @@ exports.combineStats = function (stats) { return data; } catch (err) { console.log(err); - console.log(JSON.stringify(stats)); + throw JSON.stringify(stats); } } exports.setBuild = (build) => { @@ -104,27 +104,6 @@ exports.dereference = type => { } // gun functions -exports.makeMulti = (type, count, name = -1, startRotation = 0) => { - type = ensureIsClass(type); - let greekNumbers = ',Double ,Triple ,Quad ,Penta ,Hexa ,Septa ,Octo ,Nona ,Deca ,Hendeca ,Dodeca ,Trideca ,Tetradeca ,Pentadeca ,Hexadeca ,Septadeca ,Octadeca ,Nonadeca ,Icosa ,Henicosa ,Doicosa ,Triaicosa ,Tetraicosa ,Pentaicosa ,Hexaicosa ,Septaicosa ,Octoicosa ,Nonaicosa ,Triaconta '.split(','), - output = exports.dereference(type), - fraction = 360 / count; - output.GUNS = []; - for (let gun of type.GUNS) { - for (let i = 0; i < count; i++) { - let newgun = exports.dereference(gun); - if (Array.isArray(newgun.POSITION)) { - newgun.POSITION[5] += startRotation + fraction * i; - } else { - newgun.POSITION.ANGLE = (newgun.POSITION.ANGLE ?? 0) + startRotation + fraction * i; - } - if (gun.PROPERTIES) newgun.PROPERTIES = gun.PROPERTIES; - output.GUNS.push(newgun); - }; - } - output.LABEL = name == -1 ? (greekNumbers[count - 1] || (count + ' ')) + type.LABEL : name; - return output; -} exports.makeGuard = (type, name = -1) => { type = ensureIsClass(type); let output = exports.dereference(type), @@ -227,16 +206,27 @@ exports.makeOver = (type, name = -1, options = {}) => { let cycle = options.cycle ?? true; let maxChildren = options.maxDrones ?? 3; let stats = options.extraStats ?? []; + let dronetype = options.type ?? "drone"; let spawnerProperties = { SHOOT_SETTINGS: exports.combineStats([g.drone, g.overseer, ...stats]), - TYPE: ["drone", {INDEPENDENT: independent}], + TYPE: [dronetype, {INDEPENDENT: independent}], AUTOFIRE: true, SYNCS_SKILLS: true, STAT_CALCULATOR: gunCalcNames.drone, WAIT_TO_CYCLE: cycle, MAX_CHILDREN: maxChildren, }; - + if (dronetype == "turretedDrone") { + let drivedeco = { + POSITION: [7, 14, 0, 180, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }], + }; + if (type.TURRETS == null) { + output.TURRETS = [drivedeco]; + } else { + output.TURRETS = [...type.TURRETS, drivedeco]; + } + } let spawners = []; if (count % 2 == 1) { spawners.push({ @@ -407,12 +397,14 @@ exports.makeDeco = (shape = 0, color = 16) => { }; } exports.makeRadialAuto = (type, options = {}) => { - /* + - type: what turret (or regular Class) to use as the radial auto + Available options: - count: number of turrets - - turret: what turret definition to use (leave null to make a new turret), overrides the `type` parameter + - isTurret: whether or not the `type` is a turret already (if this option is `false`, the `type` is assumed to + not be a turret and the faciliator will create a new turret modeled after the `type`) - extraStats: extra stats to append to all turret barrels, on top of g.autoTurret - turretIdentifier: Class[turretIdentifier] to refer to the turret in other uses if necessary - size: turret size @@ -433,13 +425,16 @@ exports.makeRadialAuto = (type, options = {}) => { type = exports.dereference(ensureIsClass(type)); let extraStats = options.extraStats ?? []; + if (!Array.isArray(extraStats)) { + extraStats = [extraStats]; + } turretIdentifier = options.turretIdentifier ?? `auto${type.LABEL}Gun`; Class[turretIdentifier] = { PARENT: 'genericTank', LABEL: "", BODY: { - FOV: 3, + FOV: 2, }, CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], COLOR: "grey", @@ -474,10 +469,62 @@ exports.makeRadialAuto = (type, options = {}) => { }, count) } } -exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor) => { +exports.makeTurret = (type, options = {}) => { + + /* + - type: what Class to turn into an auto turret + + Available options: + - canRepel: whether or not the auto turret can fire backwards with secondary fire + - limitFov: whether or not the auto turret should bother to try to limit its FOV arc + - hasAI: whether or not the auto turret can think and shoot on its own + - extraStats: array of stats to append onto the shoot settings of all of the turret's guns + - label: turret label + - color: turret color + - fov: turret FOV + - independent: turret independence + */ + + type = exports.dereference(ensureIsClass(type)); + + let CONTROLLERS = []; + if (options.canRepel) { // default false + CONTROLLERS.push("canRepel", "mapAltToFire"); + } + if (options.limitFov) { // default false + CONTROLLERS.push("onlyAcceptInArc"); + } + if (options.hasAI ?? true) { // default true + CONTROLLERS.push("nearestDifferentMaster"); + } + + let GUNS = type.GUNS; + let extraStats = options.extraStats ?? []; + if (!Array.isArray(extraStats)) { + extraStats = [extraStats]; + } + for (let gun of GUNS) { + if (!gun.PROPERTIES) continue; + if (!gun.PROPERTIES.SHOOT_SETTINGS) continue; + + gun.PROPERTIES.SHOOT_SETTINGS = exports.combineStats([gun.PROPERTIES.SHOOT_SETTINGS, g.autoTurret, ...extraStats]) + } + + return { + PARENT: 'genericTank', + LABEL: options.label ?? "", + COLOR: options.color ?? "grey", + BODY: { FOV: options.fov ?? 2 }, + INDEPENDENT: options.independent ?? false, + CONTROLLERS, + GUNS, + TURRETS: type.TURRETS, + } +} +exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor, symbolType) => { let isHeal = damageFactor < 0; let auraType = isHeal ? "healAura" : "aura"; - let symbolType = isHeal ? "healerSymbol" : "auraSymbol"; + if (symbolType == null) symbolType = isHeal ? "healerSymbol" : "auraSymbol"; auraColor = auraColor ?? (isHeal ? 12 : 0); return { PARENT: "genericTank", @@ -504,6 +551,41 @@ exports.addAura = (damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraColor) = ] }; } +exports.makeAura = (type, name = -1, options = {}) => { + let turret = { + type: "auraBasicGen", + size: 14, + }; + if (options.type != null) { + turret.type = options.type; + } + if (options.size != null) { + turret.size = options.size; + } + let output = exports.dereference(type); + let aurathing = { + /********* SIZE X Y ANGLE ARC */ + POSITION: [turret.size, 0, 0, 0, 0, 1], + TYPE: [ + turret.type, + ], + }; + if (type.GUNS != null) { + output.GUNS = type.GUNS; + } + if (type.TURRETS == null) { + output.TURRETS = [aurathing]; + } else { + output.TURRETS = [...type.TURRETS, aurathing]; + } + if (name == -1) { + output.LABEL = "Aura " + type.LABEL; + } else { + output.LABEL = name; + } + output.DANGER = type.DANGER + 2; + return output; +} // misc functions exports.menu = (name = -1, color = -1, shape = 0) => { @@ -524,22 +606,34 @@ exports.menu = (name = -1, color = -1, shape = 0) => { IGNORED_BY_AI: true, }; } -exports.weaponArray = (weapons, count) => { +exports.weaponArray = (weapons, count, delayIncrement = 0, delayOverflow = false) => { + // delayIncrement: how much each side's delay increases by + // delayOverflow: false to constrain the delay value between [0, 1) if (!Array.isArray(weapons)) { weapons = [weapons] } let isTurret = weapons[0].TYPE != undefined; - let angleIndex = isTurret ? 3 : 5; + let angleKey = isTurret ? 3 : 5; + let delayKey = 6; let output = []; for (let weapon of weapons) { for (let i = 0; i < count; i++) { let angle = 360 / count * i; + let delay = delayIncrement * i; let newWeapon = exports.dereference(weapon); - if (Array.isArray(newWeapon.POSITION)) { - newWeapon.POSITION[angleIndex] += angle; - } else { - newWeapon.POSITION.ANGLE = (newWeapon.POSITION.ANGLE ?? 0) + angle; + + if (!Array.isArray(newWeapon.POSITION)) { + angleKey = "ANGLE"; + delayKey = "DELAY"; + } + + newWeapon.POSITION[angleKey] = (newWeapon.POSITION[angleKey] ?? 0) + angle; + if (!isTurret) { + newWeapon.POSITION[delayKey] = (newWeapon.POSITION[delayKey] ?? 0) + delay; + if (!delayOverflow) { + newWeapon.POSITION[delayKey] %= 1; + } } output.push(newWeapon); } @@ -574,7 +668,7 @@ class LayeredBoss { SHAPE: this.shape, COLOR: -1, INDEPENDENT: true, - CONTROLLERS: [["spin", { independent: true, speed: 0.02 / c.runSpeed * (this.layerID % 2 ? -1 : 1) }]], + CONTROLLERS: [["spin", { independent: true, speed: 0.02 / Config.runSpeed * (this.layerID % 2 ? -1 : 1) }]], MAX_CHILDREN, GUNS: [], TURRETS: [], @@ -605,9 +699,166 @@ class LayeredBoss { } exports.LayeredBoss = LayeredBoss; -//unfinished lolo -exports.makeLabyrinthShape = (type) => { - let output = exports.dereference(type); - let downscale = Math.max(output.SHAPE, 3); - return output; -} \ No newline at end of file +// Food facilitators +exports.makeRelic = (type, scale = 1, gem, SIZE) => { + // Code by Damocles (https://discord.com/channels/366661839620407297/508125275675164673/1090010998053818488) + // Albeit heavily modified because the math in the original didn't work LOL + type = ensureIsClass(type); + let relicCasing = { + PARENT: 'genericEntity', + LABEL: 'Relic Casing', + LEVEL_CAP: 45, + COLOR: type.COLOR, + MIRROR_MASTER_ANGLE: true, + SHAPE: [[-0.4,-1],[0.4,-0.25],[0.4,0.25],[-0.4,1]].map(r => r.map(s => s * scale)) + }, relicBody = { + PARENT: 'genericEntity', + LABEL: 'Relic Mantle', + LEVEL_CAP: 45, + COLOR: type.COLOR, + MIRROR_MASTER_ANGLE: true, + SHAPE: type.SHAPE + }; + Class[Math.random().toString(36)] = relicCasing; + Class[Math.random().toString(36)] = relicBody; + let width = 6 * scale, + y = 8.25 + ((scale % 1) * 5), + isEgg = type.SHAPE == 0, + casings = isEgg ? 8 : type.SHAPE, + fraction = 360 / casings, + GUNS = [], + TURRETS = [{ POSITION: [32.5, 0, 0, 0, 0, 0], TYPE: relicBody }], + PARENT = [type], + additionalAngle = type.SHAPE % 2 === 0 ? 0 : fraction / 2; + + if (SIZE) { + PARENT.push({ SIZE }); + } + + for (let i = 0; i < casings; i++) { + let angle = i * fraction, + gunAngle = angle + additionalAngle; + if (isEgg) { + GUNS.push({ + POSITION: [4, width, 2.5, 12, 0, gunAngle, 0] + }); + TURRETS.push({ + POSITION: [8, -15, 0, angle, 0, 1], + TYPE: relicCasing + }); + } else { + GUNS.push({ + POSITION: [4, width, 2.5, 12, y, gunAngle, 0] + }); + GUNS.push({ + POSITION: [4, width, 2.5, 12, -y, gunAngle, 0] + }); + TURRETS.push({ + POSITION: [8, -15, y, angle, 0, 1], + TYPE: relicCasing + }); + TURRETS.push({ + POSITION: [8, -15, -y, angle, 0, 1], + TYPE: relicCasing + }); + } + } + + if (gem) { + TURRETS.push({ + POSITION: [8, 0, 0, 0, 0, 1], + TYPE: [gem, { MIRROR_MASTER_ANGLE: true }] + }); + } + + return { + PARENT, + LABEL: type.LABEL + ' Relic', + COLOR: "white", // This is the color of the floor, this makes it look hollow. + BODY: { + ACCELERATION: 0.001 + }, + CONTROLLERS: [], + VALUE: type.VALUE * 100_000, + GUNS, + TURRETS + }; +} + +exports.makeCrasher = type => ({ + PARENT: type, + COLOR: 'pink', + TYPE: "crasher", + LABEL: 'Crasher ' + type.LABEL, + CONTROLLERS: ['nearestDifferentMaster', 'mapTargetToGoal'], + MOTION_TYPE: "motor", + FACING_TYPE: "smoothWithMotion", + HITS_OWN_TYPE: "hard", + HAS_NO_MASTER: true, + BODY: { + SPEED: 1 + 5 / Math.max(2, type.TURRETS.length + type.SHAPE), + ACCELERATION: 5, + PUSHABILITY: 0.5, + DENSITY: 10, + RESIST: 2, + }, + AI: { + NO_LEAD: true, + } +}) + +exports.makeRare = (type, level) => { + type = ensureIsClass(type); + return { + PARENT: "food", + LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Trans"][level] + " " + type.LABEL, + VALUE: [100, 500, 2000, 4000, 5000][level] * type.VALUE, + SHAPE: type.SHAPE, + SIZE: type.SIZE + level, + COLOR: ["lightGreen", "teal", "darkGrey", "rainbow", "trans"][level], + ALPHA: level == 2 ? 0.25 : 1, + BODY: { + DAMAGE: type.BODY.DAMAGE + level, + DENSITY: type.BODY.DENSITY + level, + HEALTH: [10, 20, 40, 80, 100][level] * type.BODY.HEALTH, + PENETRATION: type.BODY.PENETRATION + level, + ACCELERATION: type.BODY.ACCELERATION + }, + DRAW_HEALTH: true, + INTANGIBLE: false, + GIVE_KILL_MESSAGE: true, + } +} + +exports.makeLaby = (type, level, baseScale = 1) => { + type = ensureIsClass(type); + let usableSHAPE = Math.max(type.SHAPE, 3), + downscale = Math.cos(Math.PI / usableSHAPE), + strengthMultiplier = 6 ** level; + return { + PARENT: "food", + LABEL: ["", "Beta ", "Alpha ", "Omega ", "Gamma ", "Delta "][level] + type.LABEL, + VALUE: type.VALUE * strengthMultiplier, + SHAPE: type.SHAPE, + SIZE: type.SIZE * baseScale / downscale ** level, + COLOR: type.COLOR, + ALPHA: type.ALPHA ?? 1, + BODY: { + DAMAGE: type.BODY.DAMAGE, + DENSITY: type.BODY.DENSITY, + HEALTH: type.BODY.HEALTH * strengthMultiplier, + PENETRATION: type.BODY.PENETRATION, + PUSHABILITY: (type.BODY.PUSHABILITY / (level + 1)) || 0, + ACCELERATION: type.BODY.ACCELERATION + }, + INTANGIBLE: type.INTANGIBLE, + VARIES_IN_SIZE: false, + DRAW_HEALTH: type.DRAW_HEALTH, + GIVE_KILL_MESSAGE: type.GIVE_KILL_MESSAGE || level > 1, + GUNS: type.GUNS ?? [], + TURRETS: [...(type.TURRETS ? type.TURRETS : []), ...Array(level).fill().map((_, i) => ({ + POSITION: [20 * downscale ** (i + 1), 0, 0, !(i & 1) ? 180 / usableSHAPE : 0, 0, 1], + TYPE: [type, { COLOR: -1, MIRROR_MASTER_ANGLE: true }] + }))] + }; +} diff --git a/server/modules/definitions/groups/bosses.js b/server/modules/definitions/groups/bosses.js index e4ba2d6ca..f15ddccb8 100644 --- a/server/modules/definitions/groups/bosses.js +++ b/server/modules/definitions/groups/bosses.js @@ -1,2943 +1,2778 @@ -const { combineStats, skillSet, makeAuto, addAura, LayeredBoss, makeDeco } = require('../facilitators.js'); -const { base, gunCalcNames, smshskl } = require('../constants.js'); -const g = require('../gunvals.js'); -require('./generics.js'); - -Class.miniboss = { - PARENT: "genericBoss", - CONTROLLERS: ["nearestDifferentMaster", "minion", "canRepel"], - AI: { NO_LEAD: true }, -}; -Class.ramMiniboss = { - PARENT: "genericBoss", - CONTROLLERS: ["nearestDifferentMaster", "canRepel", "mapTargetToGoal"], -}; - -// ELITE CRASHERS -Class.elite = { - PARENT: "miniboss", - LABEL: "Elite Crasher", - COLOR: "pink", - SHAPE: 3, - SIZE: 27, - VARIES_IN_SIZE: true, - VALUE: 15e4, - BODY: { - FOV: 1.25, - SPEED: 0.1 * base.SPEED, - HEALTH: 7 * base.HEALTH, - DAMAGE: 2.5 * base.DAMAGE, - }, -}; -Class.eliteDestroyer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Destroyer", - UPGRADE_COLOR: "pink", - GUNS: [ - { - POSITION: [5, 16, 1, 6, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, { - POSITION: [5, 16, 1, 6, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, { - POSITION: [5, 16, 1, 6, 0, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, - ], - TURRETS: [ - { - POSITION: [11, 0, 0, 180, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, 60, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, -60, 360, 0], - TYPE: ["crasherSpawner"], - }, { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: [ "bigauto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.eliteGunner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Gunner", - UPGRADE_COLOR: "pink", - FACING_TYPE: "toTarget", - GUNS: [ - { - POSITION: [14, 16, 1, 0, 0, 180, 0], - }, { - POSITION: [4, 16, 1.5, 14, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: ["unsetPillbox", {MOTION_TYPE: "glide"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [6, 14, -2, 2, 0, 60, 0], - }, { - POSITION: [6, 14, -2, 2, 0, 300, 0], - }, - ], - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 8, 0, 60, 180, 0], - TYPE: ["auto4gun"], - }, { - POSITION: [14, 8, 0, 300, 180, 0], - TYPE: ["auto4gun"], - }, - ], -}; -Class.eliteSprayer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Sprayer", - UPGRADE_COLOR: "pink", - SKILL: [0, 9, 3, 9, 2, 9, 9, 9, 9, 0], - AI: { NO_LEAD: false }, - HAS_NO_RECOIL: true, - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [6, 0, 0, 0, 360, 1], - TYPE: ["machineTripleTurret", { INDEPENDENT: true }], - }, { - POSITION: [9, 6, -5, 180, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, 180, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, 60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, -5, 60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, 5, -60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, { - POSITION: [9, 6, -5, -60, 130, 0], - TYPE: ["sprayer", { COLOR: "grey" }], - }, - ], -}; -Class.eliteBattleship = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Battleship", - UPGRADE_COLOR: "pink", - GUNS: [ - { - POSITION: [4, 6, 0.6, 7, -8, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, 60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, -8, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, -8, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 0, -60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [4, 6, 0.6, 7, 8, -60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), - TYPE: "autoswarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - ], - TURRETS: [ - { - POSITION: [5, 7, 0, 0, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [5, 7, 0, 120, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [5, 7, 0, 240, 360, 1], - TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.eliteSpawner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Spawner", - UPGRADE_COLOR: "pink", - MAX_CHILDREN: 9, - AI: { STRAFE: false }, - GUNS: [ - { - POSITION: [11, 16, 1, 0, 0, 60, 0], - }, { - POSITION: [11, 16, 1, 0, 0, 180, 0], - }, { - POSITION: [11, 16, 1, 0, 0, 300, 0], - }, { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [2, 18, 1, 11, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentrySwarm", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [2, 18, 1, 11, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentryTrap", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [2, 18, 1, 11, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5 }, {health: 0.1}]), - TYPE: ["sentryGun", {GIVE_KILL_MESSAGE: false}], - SYNCS_SKILLS: true, - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, - ], - TURRETS: [ - { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: ["auto4gun", { INDEPENDENT: false, COLOR: -1 }], - }, - ], -}; -Class.eliteTrapGuard = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Trap Guard", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false }, - GUNS: [], - TURRETS: [ - { - POSITION: [9.5, 0, 0, 0, 360, 1], - TYPE: "triTrapGuardTurret", - }, - ], -}; -for (let i = 0; i < 3; i++) { - Class.eliteTrapGuard.GUNS.push( - { - POSITION: [10.5, 6, 1, 0, 0, 120*i+60, 0], - }, { - POSITION: [3, 6, 1.7, 10.5, 0, 120*i+60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ) - Class.eliteTrapGuard.TURRETS.push( - { - POSITION: [5, 8, -7, 120*i+60, 160, 0], - TYPE: ["autoTurret", { INDEPENDENT: false }], - }, { - POSITION: [5, 8, 7, 120*i+60, 160, 0], - TYPE: ["autoTurret", { INDEPENDENT: false }], - }, - ) -}; -Class.eliteSpinner = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Spinner", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false }, - FACING_TYPE: ["spin", {speed: 0.1}], - GUNS: [], - TURRETS: [ - { - POSITION: [9.5, 0, 0, 0, 360, 1], - TYPE: ["eliteSpinnerCyclone", {COLOR: -1}], - }, - ], -}; -for (let i = 0; i < 3; i++) { - Class.eliteSpinner.GUNS.push( - { - POSITION: [9.5, 2, 1, -1.5, 11.5, 120*i+10, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [9.5, 2, 1, 3.5, 6.5, 120*i+10, 1/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [9.5, 2, 1, 8.5, 1.5, 120*i+10, 2/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, - }, { - POSITION: [2, 20, 0.75, 8, 0, 120*i+60, 0], - }, - ) -}; - -// OLD ELITE -Class.oldEliteSprayer = { - PARENT: "elite", - UPGRADE_LABEL: "Elite Sprayer (Old)", - UPGRADE_COLOR: "pink", - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 6, 0, 180, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, { - POSITION: [14, 6, 0, 60, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, { - POSITION: [14, 6, 0, -60, 190, 0], - TYPE: [ "sprayer", { COLOR: -1 } ], - }, - ], -}; - -// Legionary Crasher -Class.legionaryCrasherTop = { - PARENT: "elite", - AI: { STRAFE: false, NO_LEAD: false }, - CONTROLLERS: [ ["spin", { independent: true, speed: -0.005 }] ], - INDEPENDENT: true, - GUNS: [], - TURRETS: [], -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasherTop.GUNS.push( - { - POSITION: [4, 9.5, 0.7, 7, 5, 120*i+60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), - TYPE: [ "swarm", { INDEPENDENT: true } ], - STAT_CALCULATOR: gunCalcNames.swarm, - AUTOFIRE: true, - - }, - }, { - POSITION: [4, 9.5, 0.7, 7, -5, 120*i+60, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), - TYPE: [ "swarm", { INDEPENDENT: true } ], - STAT_CALCULATOR: gunCalcNames.swarm, - AUTOFIRE: true, - }, - }, - ) - Class.legionaryCrasherTop.TURRETS.push( - { - POSITION: [9.5, 10, 0, 120*i, 190, 0], - TYPE: "auto4gun", - }, - ) -} -Class.legionaryCrasher = { - PARENT: "elite", - LABEL: "Legionary Crasher", - UPGRADE_COLOR: "pink", - AI: { STRAFE: false, NO_LEAD: false }, - HAS_NO_RECOIL: true, - VALUE: 5e6, - SIZE: 75, - BODY: { - FOV: 1.5, - SPEED: 0.1 * base.SPEED, - HEALTH: 2000, - DAMAGE: 5 * base.DAMAGE, - }, - GUNS: [], - TURRETS: [ - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: "legionaryCrasherTop", - } - ], -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasher.GUNS.push( - { - POSITION: [14.5, 13, 1, 0, 0, 120*i, 0], - }, { - POSITION: [3, 13, 1.7, 14.5, 0, 120*i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, g.destroyer, { speed: 2.5, size: 0.6, maxSpeed: 3 }]), - TYPE: "legionaryPillbox", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ) -} -for (let i = 0; i < 3; i++) { - Class.legionaryCrasher.GUNS.push( - { - POSITION: [5, 12, 1.6, -11, 0, 120*i, 0], - } - ) - Class.legionaryCrasher.TURRETS.push( - { - POSITION: [14, 8, 0, 120*i+60, 180, 0], - TYPE: [ "sprayer", { COLOR: -1, } ], - }, - ) -} - -Class.sprayerLegion = { - PARENT: "elite", - UPGRADE_LABEL: "Sprayer Legion", - UPGRADE_COLOR: "pink", - AI: { NO_LEAD: false }, - TURRETS: [ - { - POSITION: [14, 6, 0, 180, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, { - POSITION: [14, 6, 0, 60, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, { - POSITION: [14, 6, 0, -60, 190, 0], - TYPE: ["machineGun", {COLOR: -1}], - }, - ], -}; - -// STRANGE BOSSES -Class.sorcerer = { - PARENT: "miniboss", - LABEL: "Sorcerer", - DANGER: 7, - SHAPE: 0, - COLOR: "veryLightGrey", - UPGRADE_COLOR: "veryLightGrey", - SIZE: 26, - MAX_CHILDREN: 50, - VALUE: 2e5, - BODY: { - FOV: 0.5, - SPEED: 0.12 * base.SPEED, - HEALTH: 6 * base.HEALTH, - DAMAGE: 2 * base.DAMAGE, - }, - GUNS: Array(2).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.machineGun, g.machineGunner, { size: 0.4, spray: 150, speed: 2, shudder: 1.75 }]), - TYPE: "minichip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.summoner = { - PARENT: "miniboss", - LABEL: "Summoner", - DANGER: 8, - SHAPE: 4, - COLOR: "gold", - UPGRADE_COLOR: "gold", - SIZE: 26, - MAX_CHILDREN: 28, - VALUE: 3e5, - BODY: { - FOV: 0.5, - SPEED: 0.1 * base.SPEED, - HEALTH: 7 * base.HEALTH, - DAMAGE: 2.6 * base.DAMAGE, - }, - GUNS: Array(4).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.8 }]), - TYPE: ["sunchip"], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.enchantress = { - PARENT: "miniboss", - LABEL: "Enchantress", - DANGER: 8, - SHAPE: 3.5, - COLOR: "orange", - UPGRADE_COLOR: "orange", - SIZE: 26, - MAX_CHILDREN: 28, - VALUE: 4e5, - BODY: { - FOV: 0.5, - SPEED: 0.09 * base.SPEED, - HEALTH: 10 * base.HEALTH, - DAMAGE: 3 * base.DAMAGE, - }, - GUNS: Array(3).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.9 }]), - TYPE: "dorito", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.exorcistor = { - PARENT: "miniboss", - LABEL: "Exorcistor", - DANGER: 8, - SHAPE: 5.5, - COLOR: "purple", - UPGRADE_COLOR: "purple", - SIZE: 26, - MAX_CHILDREN: 20, - VALUE: 5e5, - BODY: { - FOV: 0.5, - SPEED: 0.08 * base.SPEED, - HEALTH: 15 * base.HEALTH, - DAMAGE: 4 * base.DAMAGE, - }, - GUNS: Array(5).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 72, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), - TYPE: "demonchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.shaman = { - PARENT: "miniboss", - LABEL: "Shaman", - DANGER: 8, - SHAPE: 6, - COLOR: "hexagon", - UPGRADE_COLOR: "hexagon", - SIZE: 26, - MAX_CHILDREN: 20, - VALUE: 6e5, - BODY: { - FOV: 0.5, - SPEED: 0.07 * base.SPEED, - HEALTH: 20 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - }, - GUNS: Array(6).fill().map((_, i) => ({ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { size: 1.1 }]), - TYPE: "realchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, - })) -}; -Class.eliteSkimmer = { - PARENT: "elite", - LABEL: "Elite Skimmer", - COLOR: "orange", - UPGRADE_COLOR: "orange", - TURRETS: [ - { - POSITION: [15, 5, 0, 60, 170, 0], - TYPE: "skimmerTurret", - }, { - POSITION: [15, 5, 0, 180, 170, 0], - TYPE: "skimmerTurret", - }, { - POSITION: [15, 5, 0, 300, 170, 0], - TYPE: "skimmerTurret", - }, - ], -}; - -// Nesters -Class.nestKeeper = { - PARENT: "miniboss", - LABEL: "Nest Keeper", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - MAX_CHILDREN: 15, - VALUE: 3e5, - GUNS: [ - { - POSITION: [3.5, 6.65, 1.2, 8, 0, 35, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, -35, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, 108, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, { - POSITION: [3.5, 6.65, 1.2, 8, 0, -108, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), - TYPE: "drone", - AUTOFIRE: true, - LABEL: "Mega Crasher", - STAT_CALCULATOR: gunCalcNames.drone, - }, - }, - ], - TURRETS: [ - { - POSITION: [8, 9, 0, 72, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 0, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 144, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, 216, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [8, 9, 0, -72, 120, 0], - TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], - }, { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "boomerTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -Class.nestWarden = { - PARENT: "miniboss", - LABEL: "Nest Warden", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - VALUE: 3e5, - GUNS: [], - TURRETS: [ - { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "barricadeTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -for(let i = 0; i < 5; i++) { - Class.nestWarden.GUNS.push( - { - POSITION: [10.7, 8, 1, 0, 0, 72*i+36, 0], - }, { - POSITION: [1.5, 8, 1.2, 10.7, 0, 72*i+36, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, { speed: 1.2 }, g.setTrap, g.constructor]), - TYPE: "unsetTrap", - STAT_CALCULATOR: gunCalcNames.block - }, - }, - ); - Class.nestWarden.TURRETS.push( - { - POSITION: [8, 9, 0, 72*i, 120, 0], - TYPE: [ "cruiserTurret", { INDEPENDENT: true, COLOR: -1 } ], - } - ); -}; -Class.nestGuardian = { - PARENT: "miniboss", - LABEL: "Nest Guardian", - COLOR: "purple", - UPGRADE_COLOR: "purple", - SHAPE: 5, - SIZE: 50, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.25, - HEALTH: base.HEALTH * 9, - SHIELD: base.SHIELD * 1.5, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 2.5, - }, - VALUE: 3e5, - GUNS: [], - TURRETS: [ - { - POSITION: [9, 0, 0, 0, 360, 1], - TYPE: [ "twisterTurret", { INDEPENDENT: true, COLOR: -1 } ], - }, - ], -}; -for(let i = 0; i < 5; i++) { - Class.nestGuardian.GUNS.push( - { - POSITION: [5.5, 7, 1, 6, 0, 72*i+36, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), - TYPE: "bullet", - LABEL: "Devastator", - }, - }, - ); - Class.nestGuardian.TURRETS.push( - { - POSITION: [8, 9, 0, 72*i, 120, 0], - TYPE: [ "swarmerTurret", { INDEPENDENT: true, COLOR: -1 } ], - } - ); -}; - -// Rogues -Class.roguePalisade = { - PARENT: "miniboss", - LABEL: "Rogue Palisade", - COLOR: "darkGrey", - UPGRADE_COLOR: "darkGrey", - SHAPE: 6, - SIZE: 30, - VALUE: 5e5, - CONTROLLERS: ['nearestDifferentMaster', 'onlyAcceptInArc'], - BODY: { - FOV: 1.4, - SPEED: 0.05 * base.SPEED, - HEALTH: 16 * base.HEALTH, - SHIELD: 3 * base.SHIELD, - DAMAGE: 3 * base.DAMAGE, - }, - GUNS: [ - { POSITION: [4, 6, -1.6, 8, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 60, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 120, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 180, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 240, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - { POSITION: [4, 6, -1.6, 8, 0, 300, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }, { reload: 2 } ]), TYPE: ["minion", {INDEPENDENT: true}], STAT_CALCULATOR: gunCalcNames.drone, AUTOFIRE: true, MAX_CHILDREN: 3, SYNCS_SKILLS: true, WAIT_TO_CYCLE: true }}, - ], - TURRETS: [ - { POSITION: [5, 10, 0, 30, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 90, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 150, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 210, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 270, 110, 0], TYPE: "baseTrapTurret" }, - { POSITION: [5, 10, 0, 330, 110, 0], TYPE: "baseTrapTurret" }, - ], -}; -Class.rogueArmada = (() => { - let SHAPE = 7, - GUNS = [], - TURRETS = []; - for (let i = 0; i < SHAPE; i++) { - for (let j = 0; j < 8; j++) { - GUNS.push({ - POSITION: [8, 2 + Math.floor(j / 3), 1, 0, j / 2 - 2, (i + 0.5) * (360 / SHAPE), 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), - TYPE: j % SHAPE < 2 ? "bullet" : "casing" - } - }); - } - GUNS.push({ - POSITION: [8.5, 6, 1, 4, 0, (i + 0.5) * (360 / SHAPE), 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), - TYPE: "casing" - } - }, { - POSITION: [7, 6, -1.6, 4, 0, (i + 0.5) * (360 / SHAPE), 0] - }); - } - for (let i = 0; i < SHAPE; i++) { - TURRETS.push({ - POSITION: [5, 10, 0, i * 360 / SHAPE, 160, 0], - TYPE: "shottrapTurret" - }); - } - return { - PARENT: "miniboss", - LABEL: 'Rogue Armada', - COLOR: "darkGrey", - UPGRADE_COLOR: "darkGrey", - SHAPE, - SIZE: 28, - VALUE: 500000, - BODY: { - FOV: 1.3, - SPEED: base.SPEED * 0.1, - HEALTH: base.HEALTH * 16, - SHIELD: base.SHIELD * 3, - REGEN: base.REGEN, - DAMAGE: base.DAMAGE * 3, - }, - GUNS, TURRETS - }; -})(); - -// Bob. -Class.bob = { - PARENT: "ramMiniboss", - LABEL: "Bob", - SHAPE: 0, - COLOR: "aqua", - UPGRADE_COLOR: "aqua", - SIZE: 18, - BODY: { - FOV: 2, - SPEED: 2 * base.SPEED, - HEALTH: 5 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - REGEN: 8 * base.REGEN, - FOV: 0.5 * base.FOV, - DENSITY: 6 * base.DENSITY, - }, - CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], - TURRETS: [ - { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody", - }, { - POSITION: [21.5, 0, 0, 30, 360, 0], - TYPE: "landmineBody", - }, { - POSITION: [23.75, 0, 0, 0, 360, 0], - TYPE: "spikeBody", - }, - ], -}; -Class.nemesis = { - PARENT: "bob", - LABEL: "Nemesis", - COLOR: "red", - UPGRADE_COLOR: "red", - BODY: { - REGEN: 1e5, - HEALTH: 1e6, - DENSITY: 30, - DAMAGE: 1e5, - FOV: 5, - }, -}; - -// DIEP BOSSES -Class.guardian = { - PARENT: "elite", - LABEL: "Guardian of the Pentagons", - UPGRADE_LABEL: "Guardian", - UPGRADE_COLOR: "pink", - FACING_TYPE: "toTarget", - GUNS: [ - { - POSITION: [4, 12, 1.4, 8, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, { size: 0.5 }]), - TYPE: "swarm", - AUTOFIRE: true, - }, - }, - ], - AI: { NO_LEAD: false }, -}; -Class.defenderAutoTankGun = { - PARENT: "autoTankGun", - GUNS: [ - { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret]), - TYPE: ["bullet", {COLOR: "yellow"}], - }, - }, - ], -}; -Class.defender = { - PARENT: "elite", - LABEL: "Defender", - COLOR: "orange", - UPGRADE_COLOR: "orange", - GUNS: [ - { - POSITION: [15, 7, 1, -3, 0, 60, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [15, 7, 1, -3, 0, 180, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, { - POSITION: [15, 7, 1, -3, 0, 300, 0], - }, { - POSITION: [3, 7, 1.7, 12, 0, 300, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), - TYPE: ["trap", {COLOR: "yellow"}], - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], - TURRETS: [ - { - POSITION: [5, 7, 0, 0, 190, 1], - TYPE: "defenderAutoTankGun", - }, { - POSITION: [5, 7, 0, 120, 190, 1], - TYPE: "defenderAutoTankGun", - }, { - POSITION: [5, 7, 0, 240, 190, 1], - TYPE: "defenderAutoTankGun", - }, - ], - AI: { NO_LEAD: false }, -}; - -// CELESTIALS -Class.terrestrial = { - PARENT: "miniboss", - LABEL: "Terrestrial", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 5e5, - SHAPE: 7, - SIZE: 35, - BODY: { - FOV: 1, - HEALTH: 1000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 9, - }, -}; -Class.celestial = { - PARENT: "miniboss", - LABEL: "Celestial", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 1e6, - SHAPE: 9, - SIZE: 45, - BODY: { - FOV: 1, - HEALTH: 1000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 12, - }, -}; -Class.rogueCelestial = { - PARENT: "celestial", - LABEL: "Rogue Celestial", - COLOR: "darkGrey", -}; -Class.eternal = { - PARENT: "miniboss", - LABEL: "Eternal", - SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], - VALUE: 4e6, - SHAPE: 11, - SIZE: 90, - BODY: { - FOV: 1, - HEALTH: 3000, - SHIELD: 2, - REGEN: base.REGEN * 0.1, - SPEED: 0.75, - DAMAGE: 18, - }, -}; - -// Terrestrials -let ares = new LayeredBoss(null, "Ares", "terrestrial", 7, "purple", "terrestrialTrapTurret", 7, 5.5); -ares.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["demonchip", { INDEPENDENT: true, }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, false, null, 18); -ares.addLayer({turret: { - POSITION: [10, 8.5, 0, null, 160, 0], - TYPE: ["protoSwarmerTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let gersemi = new LayeredBoss(null, "Gersemi", "terrestrial", 7, "lightGreen", "terrestrialTrapTurret", 7, 5.5); -gersemi.addLayer({turret: { - POSITION: [9, 8, 0, null, 160, 0], - TYPE: ["swarmTurret", { INDEPENDENT: true }], -}}); -gersemi.addLayer({turret: { - POSITION: [9.5, 7.5, 0, null, 160, 0], - TYPE: ["basicTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let ezekiel = new LayeredBoss(null, "Ezekiel", "terrestrial", 7, "orange", "terrestrialTrapTurret", 7, 5.5); -ezekiel.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["dorito", { COLOR: "orange", INDEPENDENT: true, }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 18); -ezekiel.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["skimmerTurret", { COLOR: "grey", INDEPENDENT: true }], -}}, true, 6.5) - -let eris = new LayeredBoss(null, "Eris", "terrestrial", 7, "pink", "terrestrialTrapTurret", 7, 5.5); -eris.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), - TYPE: ["minion", { INDEPENDENT: true, COLOR: "pink", HAS_NO_RECOIL: true }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, false, null, 14); -eris.addLayer({turret: { - POSITION: [10, 8.5, 0, null, 160, 0], - TYPE: ["rocketeerTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -let selene = new LayeredBoss(null, "Selene", "terrestrial", 7, "gold", "terrestrialTrapTurret", 7, 5.5); -selene.addLayer({gun: { - POSITION: [3.75, 7, 1.2, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), - TYPE: ["sunchip", { COLOR: "gold", INDEPENDENT: true }], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 18); -selene.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["hyperTwisterTurret", { INDEPENDENT: true }], -}}, true, 6.5); - -// PALADIN -let paladin = new LayeredBoss(null, "Paladin", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); -paladin.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: ["demonchip", {INDEPENDENT: true}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - }, -}}, true, null, 16); -paladin.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: "swarmerTurret", -}}, true, 6); - -// FREYJA -let freyja = new LayeredBoss(null, "Freyja", "celestial", 9, "lightGreen", "baseTrapTurret", 6.5, 5.5); -freyja.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "cruiserTurret", -}}); -freyja.addLayer({turret: { - POSITION: [10.6, 7.5, 0, null, 160, 0], - TYPE: "auto4gun", -}}, true, 6); - -// ZAPHKIEL -let zaphkiel = new LayeredBoss(null, "Zaphkiel", "celestial", 9, "orange", "baseTrapTurret", 6.5, 5.5); -zaphkiel.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), - TYPE: ["drone", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 16); -zaphkiel.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["skimmerTurret", {COLOR: "grey", INDEPENDENT: true}], -}}, true, 6); - -// NYX -let nyx = new LayeredBoss(null, "Nyx", "celestial", 9, "pink", "baseTrapTurret", 6.5, 5.5); -nyx.addLayer({gun: { - POSITION: [3.8, 7, -1.4, 8, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), - TYPE: ["minion", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 16); -nyx.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: "rocketeerTurret", -}}, true, 6); - -// THEIA -let theia = new LayeredBoss(null, "Theia", "celestial", 9, "gold", "baseTrapTurret", 6.5, 5.5); -theia.addLayer({gun: { - POSITION: [3.8, 6, 1.4, 8, 0, null, 1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, { size: 0.5 }]), - TYPE: ["summonerDrone", {INDEPENDENT: true}], - AUTOFIRE: true, - WAIT_TO_CYCLE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 35); -theia.addLayer({turret: { - POSITION: [10, 7.5, 0, null, 160, 0], - TYPE: ["twisterTurret", {COLOR: "grey"}], -}}, true, 6); - -// ATLAS -let atlas = new LayeredBoss(null, "Atlas", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); -atlas.addLayer({turret: { - POSITION: [7, 9, 0, null, 180, 0], - TYPE: "artilleryTurret", -}}); -atlas.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "nailgunTurret", -}}, true, 6); - -// RHEA -let rhea = new LayeredBoss(null, "Rhea", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -rhea.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "wrenchTurret", -}}); -rhea.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "crowbarTurret", -}}, true, 6); - -// JULIUS -let julius = new LayeredBoss(null, "Julius", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -julius.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "juliusLowerTurret", -}}); -julius.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "launcherTurret", -}}, true, 6); - -// GENGHIS -let genghis = new LayeredBoss(null, "Genghis", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -genghis.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "genghisLowerTurret", -}}); -genghis.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "auto4gun", -}}, true, 6); - -// NAPOLEON -let napoleon = new LayeredBoss(null, "Napoleon", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); -napoleon.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 180, 0], - TYPE: "napoleonLowerTurret", -}}); -napoleon.addLayer({turret: { - POSITION: [10.5, 8, 0, null, 160, 0], - TYPE: "napoleonUpperTurret", -}}, true, 6) - -// Eternals -let kronos = new LayeredBoss(null, "Kronos", "eternal", 11, "veryLightGrey", "baseTrapTurret", 6, 5.5); -kronos.addLayer({turret: { - POSITION: [6.5, 9, 0, null, 160, 0], - TYPE: "kronosSkimmerTurret", -}}); -kronos.addLayer({turret: { - POSITION: [6.5, 9, 0, null, 160, 0], - TYPE: "carrierTurret", -}}, true, 4); -kronos.addLayer({turret: { - POSITION: [8.5, 9, 0, null, 160, 0], - TYPE: "tripletTurret", -}}, true, 4); - -let odin = new LayeredBoss(null, "Odin", "eternal", 11, "aqua", "baseTrapTurret", 4.5, 3.5); -odin.addLayer({gun: { - POSITION: [2.25, 3.25, -1.6, 9, 0, null, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }, g.pounder, {size: 1.7}]), - TYPE: ["gemDrone", {INDEPENDENT: true,}], - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, -}}, true, null, 18); -odin.addLayer({turret: { - POSITION: [7, 8, 0, null, 160, 0], - TYPE: "autosmashTurret", -}}, true, 5.5); -odin.addLayer({turret: { - POSITION: [8, 9, 0, null, 160, 0], - TYPE: "gunnerCruiserTurret", -}}, true, 4.5); - -// Developer Bosses -Class.taureonCoreBase = { - SHAPE: 4, - COLOR: '#00A2E8' -}; -Class.taureonCore = { - PARENT: "genericTank", - LABEL: "Core Turret", - SHAPE: 4.5, - COLOR: '#99D9EA', - CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], - INDEPENDENT: true, - GUNS: [{ - POSITION: [10, 14, -0.5, 14, 0, 0, 0] - },{ - POSITION: [21, 15, -1.1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.destroyer, g.sniper]), - TYPE: "snake", - STAT_CALCULATOR: gunCalcNames.sustained - } - }], - TURRETS: [{ - POSITION: [20 * Math.SQRT2, 0, 0, 0, 0, 0], - TYPE: "taureonCoreBase" - }] -}; -Class.taureonBase = { - SHAPE: 4.5, - COLOR: '#161B54', - MIRROR_MASTER_ANGLE: true -}; -let d = 1/4; -Class.taureonStar = { - SHAPE: [[0,1],[d,d],[1,0],[d,-d],[0,-1],[-d,-d],[-1,0],[-d,d]], - COLOR: '#3F48CC', - MIRROR_MASTER_ANGLE: true -}; -Class.taureonRailgunTurret = { - PARENT: "genericTank", - COLOR: "grey", - LABEL: "Railgun Turret", - CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], - INDEPENDENT: true, - GUNS: [{ - POSITION: [20, 7, 1, 0, 0, 0, 0] - },{ - POSITION: [24, 5, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.destroyer, { speed: 5, penetration: 0.8 }]), - TYPE: "bullet" - } - },{ - POSITION: [5, 7.5, -1.6, 8, 0, 0, 0], - }] -}; -Class.taureonThruster = { - PARENT: "genericTank", - COLOR: "grey", - LABEL: "Thruster", - CONTROLLERS: ["onlyAcceptInArc"], - GUNS: [{ - POSITION: [14, 12, 1, 4, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), - TYPE: ["bullet", { ALPHA: 0.5 }] - } - }, { - POSITION: [12, 12, 1.4, 4, 0, 180, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), - TYPE: ["bullet", { ALPHA: 0.5 }] - }, - }] -}; -Class.taureonMissile = { - PARENT: "bullet", - LABEL: "Missile", - FACING_TYPE: "smoothToTarget", - CONTROLLERS: ["nearestDifferentMaster"], - INDEPENDENT: true, - BODY: { - ACCELERATION: 10, - FOV: base.FOV * 2 - }, - TURRETS: [{/** SIZE X Y ANGLE ARC */ - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - }], - GUNS: [{/* LENGTH WIDTH ASPECT X Y ANGLE DELAY */ - POSITION: [6, 12, 1.4, 8, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] - } - },{ - POSITION: [10, 12, 0.8, 8, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] - } - },...Array(32).fill().map((_, i)=>({ - POSITION: [0, (i % 4) + 1, 0, 0, 0, 0, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, { spray: 1e6, range: 0.5, shudder: 1.5, damage: 1 + (i % 4) }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - SHOOT_ON_DEATH: true - }, - }))] -}; -Class.taureonBoss = { - PARENT: "miniboss", - LABEL: "Diamond Marauder", - NAME: "Taureon", - COLOR: '#2B339B', - UPGRADE_COLOR: "spaceGem", - DANGER: 10, - SHAPE: 4.5, - SIZE: 50, - FACING_TYPE: "smoothToTarget", - UPGRADE_TOOLTIP: "With a powerful Gatling Gun on the front, Rocket Launchers as wings, movable Thrusters on the back, " + - "and equipped with Railgun Turrets, it perfectly excells at terminating those who feel its Wrath.\n" + - "An octahedral carbon robot, exclusively designed to eradicate opponents with sheer brutality alone.\n" + - '"NOW YOU FACE MY ULTIMATE CREATION."', - VALUE: 9e6, - BODY: { - FOV: 1, - SPEED: 0.5 * base.SPEED, - HEALTH: 20 * base.HEALTH, - DAMAGE: 3 * base.DAMAGE, - }, - TURRETS: [{ - POSITION: [23.3, 0, 0, 0, 0, 0], - TYPE: "taureonBase" - },{ - POSITION: [5, 10, 0, -45, 180, 0], - TYPE: "taureonRailgunTurret" - },{ - POSITION: [5, 10, 0, 45, 180, 0], - TYPE: "taureonRailgunTurret" - },{ - POSITION: [5, -10, -2, -45, 90, 0], - TYPE: "taureonThruster" - },{ - POSITION: [5, -10, 2, 45, 90, 0], - TYPE: "taureonThruster" - },{ - POSITION: [25, 0, 0, 0, 0, 1], - TYPE: "taureonStar" - },{ - POSITION: [5, 0, 0, 0, 360, 1], - TYPE: "taureonCore" - }], - GUNS: [...Array(6).fill().map((_, i) => ({ - POSITION: [18, 1.75, 1, 0, Math.cos(Math.PI * i / 3) * 2, 0, i / 6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, { speed: 2, maxSpeed: 2, damage: 0.75, size: 0.8 }]), - TYPE: "bullet" - } - })),{ - POSITION: [4, 5, -0.5, 12, 0, -90, 0] - },{ - POSITION: [10, 5, -1.2, 5, 0, -90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), - TYPE: "taureonMissile", - STAT_CALCULATOR: gunCalcNames.sustained - } - },{ - POSITION: [4, 5, -0.5, 12, 0, 90, 0] - },{ - POSITION: [10, 5, -1.2, 5, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), - TYPE: "taureonMissile", - STAT_CALCULATOR: gunCalcNames.sustained - } - },{ - POSITION: [5.5, 5, -1.5, 5, 0, -45, 0] - },{ - POSITION: [5.5, 5, -1.5, 5, 0, 45, 0] - },{ - POSITION: [2, 7, 1, 8, 0, 0, 0] - },{ - POSITION: [2, 7, 1, 14.5, 0, 0, 0] - }] -}; - -Class.zephiMiscDeco = makeDeco(4, "white") -Class.zephiMiscDeco2 = makeDeco(4, "black") -Class.zephiSunchip = makeAuto({ - PARENT: "drone", - SHAPE: 4, - HITS_OWN_TYPE: "hard", - BODY: { - FOV: 0.5, - }, - AI: { - BLIND: true, - FARMER: true, - }, - TURRETS: [{ - POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], - TYPE: ["overdriveDeco", { MIRROR_MASTER_ANGLE: true }] - },{ - POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], - TYPE: ["shinySquare", { MIRROR_MASTER_ANGLE: true }] - }] -}, "Robo-Sunchip", {type: 'autoSmasherTurret', size: 6}) -Class.zephiEggchip = { - PARENT: "drone", - LABEL: "Guided Missile", - SHAPE: 0, - HITS_OWN_TYPE: "hard", - BODY: { - FOV: 0.5, - }, - AI: { - BLIND: true, - FARMER: true, - }, - GUNS: [ - { - POSITION: [14, 6, 1, 0, 0, 180, 0], - PROPERTIES: { - AUTOFIRE: true, - SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, g.lowPower, { reload: 0.5, recoil: 1.35, speed: 1.3, maxSpeed: 1.3 }]), - TYPE: ["bullet", { COLOR: "black", PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.thruster, - }, - }, - ], - TURRETS: [{ - POSITION: [10, 0, 0, 45, 0, 1], - TYPE: "gem" - }] -} -Class.zephiGearOuter = makeDeco('M 0.5 0.0929 V -0.0908 L 0.3875 -0.1096 C 0.3792 -0.1409 0.3667 -0.1701 0.3521 -0.1952 L 0.4187 -0.2871 L 0.2896 -0.4186 L 0.1958 -0.3539 C 0.1687 -0.3685 0.1396 -0.381 0.1104 -0.3894 L 0.0917 -0.5 H -0.0917 L -0.1104 -0.3873 C -0.1417 -0.3789 -0.1688 -0.3664 -0.1958 -0.3518 L -0.2875 -0.4165 L -0.4188 -0.2871 L -0.3521 -0.1952 C -0.3667 -0.1681 -0.3792 -0.1388 -0.3875 -0.1075 L -0.5 -0.0908 V 0.0929 L -0.3875 0.1117 C -0.3792 0.143 -0.3667 0.1701 -0.3521 0.1973 L -0.4188 0.2912 L -0.2896 0.4207 L -0.1958 0.3539 C -0.1688 0.3685 -0.1396 0.381 -0.1083 0.3894 L -0.0896 0.5 H 0.0938 L 0.1125 0.3873 C 0.1417 0.3789 0.1708 0.3664 0.1979 0.3518 L 0.2917 0.4186 L 0.4208 0.2891 L 0.3542 0.1952 C 0.3688 0.1681 0.3812 0.1409 0.3896 0.1096 L 0.5 0.0929 Z M 0.3333 0 C 0.3333 0.1841 0.1841 0.3333 0 0.3333 C -0.1841 0.3333 -0.3333 0.1841 -0.3333 0 C -0.3333 -0.1841 -0.1841 -0.3333 0 -0.3333 C 0.1841 -0.3333 0.3333 -0.1841 0.3333 0 Z', '#7F7F7F') -Class.zephiGearOuter.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearOuter.BORDERLESS = true -Class.zephiGearCentre = makeDeco(0, '#1F1F1F') -Class.zephiGearCentre.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearCentre.BORDERLESS = true -Class.zephiGearRed = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#FF1F1F') -Class.zephiGearRed.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearRed.BORDERLESS = true -Class.zephiGearGreen = makeDeco('M 0.0771 -0.2552 C 0.0743 -0.2561 0.0691 -0.2576 0.0657 -0.2585 L 0.0607 -0.2597 C 0.0571 -0.2605 0.0514 -0.2617 0.0479 -0.2623 L 0.0428 -0.2632 C 0.0392 -0.2638 0.0334 -0.2646 0.0299 -0.265 L 0.0247 -0.2655 C 0.0211 -0.2659 0.0153 -0.2662 0.0117 -0.2664 L 0.0066 -0.2666 C 0.003 -0.2667 -0.0029 -0.2667 -0.0065 -0.2666 L -0.0116 -0.2664 C -0.0153 -0.2662 -0.0211 -0.2659 -0.0247 -0.2655 L -0.0298 -0.265 C -0.0334 -0.2646 -0.0392 -0.2638 -0.0427 -0.2632 L -0.0478 -0.2623 C -0.0514 -0.2617 -0.0571 -0.2605 -0.0606 -0.2597 L -0.0656 -0.2585 C -0.0691 -0.2576 -0.0747 -0.256 -0.0782 -0.2549 C -0.081 -0.254 -0.0833 -0.2502 -0.0833 -0.2466 V 0.2466 C -0.0833 0.2502 -0.0805 0.2541 -0.0771 0.2552 C -0.0743 0.2561 -0.0691 0.2576 -0.0656 0.2585 L -0.0606 0.2597 C -0.0571 0.2605 -0.0514 0.2617 -0.0478 0.2623 L -0.0427 0.2632 C -0.0392 0.2638 -0.0334 0.2646 -0.0298 0.265 L -0.0247 0.2655 C -0.0211 0.2659 -0.0153 0.2663 -0.0116 0.2664 L -0.0065 0.2666 C -0.0029 0.2667 0.003 0.2667 0.0066 0.2666 L 0.0117 0.2664 C 0.0153 0.2663 0.0211 0.2659 0.0247 0.2655 L 0.0299 0.265 C 0.0334 0.2646 0.0392 0.2638 0.0428 0.2632 L 0.0479 0.2623 C 0.0514 0.2617 0.0571 0.2605 0.0607 0.2597 L 0.0657 0.2585 C 0.0691 0.2576 0.0748 0.256 0.0782 0.2549 C 0.0811 0.254 0.0834 0.2502 0.0834 0.2466 V -0.2466 C 0.0834 -0.2502 0.0806 -0.2541 0.0771 -0.2552 Z', '#1FDF1F') -Class.zephiGearGreen.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearGreen.BORDERLESS = true -Class.zephiGearBlue = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#1F7FDF') -Class.zephiGearBlue.CONTROLLERS = [["spin", { independent: true }]] -Class.zephiGearBlue.BORDERLESS = true -Class.zephiBoss = { - PARENT: "miniboss", - LABEL: "Shiny Mecha-Thaumaturge", - NAME: "Zephi", - DANGER: 10, - SHAPE: 4, - COLOR: "lightGreen", - UPGRADE_COLOR: "lightGreen", - SIZE: 50, - VALUE: 5e6, - SKILL: skillSet({ - rld: 1, - dam: 1, - pen: 1, - str: 1, - spd: 1, - atk: 1, - hlt: 1, - shi: 1, - rgn: 1, - mob: 1, - }), - BODY: { - FOV: 0.75, - SPEED: 0.05 * base.SPEED, - HEALTH: 15 * base.HEALTH, - DAMAGE: 5 * base.DAMAGE, - }, - UPGRADE_TOOLTIP: "Good luck.", - GUNS: Array(4).fill().map((_, i) => ([{ - POSITION: [2.5, 3, 1.2, 8, 5, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 50, speed: 1.25, shudder: 1.25 }]), - TYPE: ["zephiEggchip", {COLOR: "black"}], - MAX_CHILDREN: 8, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - COLOR: "black", - } - },{ - POSITION: [2.5, 3, 1.2, 8, -5, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 150, speed: 1.25, shudder: 1.25 }]), - TYPE: ["zephiEggchip", {COLOR: "black"}], - MAX_CHILDREN: 8, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true, - COLOR: "black", - } - },{ - POSITION: [3.5, 8.65, 1.2, 8, 0, i * 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, g.destroyer, { speed: 2.5 }, { maxSpeed: 3 }]), - TYPE: ["zephiSunchip", {COLOR: "black"}], - MAX_CHILDREN: 4, - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - WAIT_TO_CYCLE: true - } - }])).flat(), - TURRETS: [{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearOuter" - },{ - POSITION: [5.375 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearCentre" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearRed" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], - TYPE: "zephiGearGreen" - },{ - POSITION: [16 * Math.SQRT1_2, 0, 0, 180, 360, 2], - TYPE: "zephiGearBlue" - },{ - POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], - TYPE: "overdriveDeco" - },{ - POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], - TYPE: "zephiMiscDeco2" - },{ - POSITION: [20 * Math.SQRT1_2 ** 3, 0, 0, 45, 0, 1], - TYPE: "zephiMiscDeco" - }] -}; - -Class.dogeiscutBody = { - PARENT: "genericTank", - COLOR: "grey", - SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]] -} -Class.dogeiscutTurret = { - PARENT: "genericTank", - COLOR: "grey", - GUNS: [ { - POSITION: [ 50, 5, 2.5, 0, 0, 0, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.minigun, {reload: 0.1}]), - TYPE: "bullet", - }, - }, { - POSITION: [ 18, 8, -2, 0, 0, 0, 0, ], - }, - ], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], - }, - ] -} -function createDogeiscutMissileTurret(color) { - return { - PARENT: "genericTank", - COLOR: "grey", - GUNS: [ { - POSITION: [ 15, 8, 2.5, 0, 0, 180, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ - g.basic, - g.skimmer, - { reload: 0.5 }, - g.lowPower, - { recoil: 1.35 }, - { speed: 1.3, maxSpeed: 1.3 }, - { speed: 1.3, maxSpeed: 1.3 }, - {reload: 0.15, recoil: 1, range: 0.1}]), - TYPE: ["bullet", - { - PERSISTS_AFTER_DEATH: true, - COLOR: color - }, - ], - AUTOFIRE: true, - STAT_CALCULATOR: gunCalcNames.thruster, - }, - }, - ], - } -} -function createDogeiscutMissile(color) { - return { - PARENT: "bullet", - LABEL: color + " Missile", - COLOR: color, - GUNS: [...Array(11).fill().map((_, i)=>({ - POSITION: [0, 8, 0, 0, 0, ((360) / 11)*i, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, density: 30 }]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, COLOR: color }], - SHOOT_ON_DEATH: true, - }, - }))], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutMissileTurret_" + color], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - } - ] - } -} -Class.dogeiscutMissileTurret_red = createDogeiscutMissileTurret('red') -Class.dogeiscutMissile_red = createDogeiscutMissile('red') -Class.dogeiscutMissileTurret_orange = createDogeiscutMissileTurret('orange') -Class.dogeiscutMissile_orange = createDogeiscutMissile('orange') -Class.dogeiscutMissileTurret_yellow = createDogeiscutMissileTurret('yellow') -Class.dogeiscutMissile_yellow = createDogeiscutMissile('yellow') -Class.dogeiscutMissileTurret_green = createDogeiscutMissileTurret('green') -Class.dogeiscutMissile_green = createDogeiscutMissile('green') -Class.dogeiscutMissileTurret_cyan = createDogeiscutMissileTurret('cyan') -Class.dogeiscutMissile_cyan = createDogeiscutMissile('cyan') -Class.dogeiscutMissileTurret_blue = createDogeiscutMissileTurret('blue') -Class.dogeiscutMissile_blue = createDogeiscutMissile('blue') -Class.dogeiscutMissileTurret_purple = createDogeiscutMissileTurret('purple') -Class.dogeiscutMissile_purple = createDogeiscutMissile('purple') -Class.dogeiscutBomb = { - PARENT: "trap", - LABEL: "Bomb", - SHAPE: 0, - GUNS: [...Array(32).fill().map((_, i)=>({ - POSITION: [0, 8, 0, 0, 0, ((360) / 32)*i, 9999], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, size: 0.5}]), - TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], - SHOOT_ON_DEATH: true, - }, - })),...Array(10).fill().map((_,i)=>({ - POSITION: [12, 3.5, 1, 0, 0, (360/10)*i, (i%3)/3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ - g.basic, - g.twin, - g.gunner, - g.cyclone, - {reload: 3} - ]), - TYPE: "bullet", - AUTOFIRE: true, - }, - })) - ], - TURRETS: [ - { - POSITION: [8, 0, 0, 0, 360, 1], - TYPE: ["genericTank", {COLOR: "grey"}], - } - ] - } -Class.dogeiscutBoss = { - PARENT: "miniboss", - LABEL: "DOG", - NAME: "DogeisCut", - DANGER: 10, - FACING_TYPE: "smoothToTarget", - SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]], - COLOR: "yellow", - UPGRADE_COLOR: "yellow", - SIZE: 50, - VALUE: 5e6, - BODY: { - FOV: 0.75, - SPEED: 0.25 * base.SPEED, - HEALTH: 14 * base.HEALTH, - DAMAGE: 4 * base.DAMAGE, - }, - GUNS: [ { - POSITION: [ 6, 8, 1.5, 3, 0, 180, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, {size: 1, reload: 3, recoil: 5}]), - TYPE: ["dogeiscutBomb"], - STAT_CALCULATOR: gunCalcNames.sustained, - } - }, { - POSITION: [ 4, 4, 1.5, 3, 0, 180, 0, ], - PROPERTIES: { - COLOR: "black" - } - }, - - { - POSITION: [ 1, 2, 1, 4, -8, 68, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_red"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'red' - } - }, { - POSITION: [ 1, 2, 1, 4, -5.333, 68, 1/7, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_orange"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'orange' - } - }, { - POSITION: [ 1, 2, 1, 4, -2.666, 68, (1/7)*2, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_yellow"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'yellow' - } - }, { - POSITION: [ 1, 2, 1, 4, 0, 68, (1/7)*3, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_green"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'green' - } - }, { - POSITION: [ 1, 2, 1, 4, 2.666, 68, (1/7)*4, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_cyan"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'cyan' - } - }, { - POSITION: [ 1, 2, 1, 4, 5.333, 68, (1/7)*5, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_blue"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'blue' - } - }, { - POSITION: [ 1, 2, 1, 4, 8, 68, (1/7)*6, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_purple"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'purple' - } - }, - - - { - POSITION: [ 1, 2, 1, 4, 8, -68, 0, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_red"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'red' - } - }, { - POSITION: [ 1, 2, 1, 4, 5.333, -68, 1/7, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_orange"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'orange' - } - }, { - POSITION: [ 1, 2, 1, 4, 2.666, -68, (1/7)*2, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_yellow"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'yellow' - } - }, { - POSITION: [ 1, 2, 1, 4, 0, -68, (1/7)*3, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_green"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'green' - } - }, { - POSITION: [ 1, 2, 1, 4, -2.666, -68, (1/7)*4, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_cyan"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'cyan' - } - }, { - POSITION: [ 1, 2, 1, 4, -5.333, -68, (1/7)*5, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_blue"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'blue' - } - }, { - POSITION: [ 1, 2, 1, 4, -8, -68, (1/7)*6, ], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), - TYPE: ["dogeiscutMissile_purple"], - STAT_CALCULATOR: gunCalcNames.sustained, - COLOR: 'purple' - } - }, - ], - TURRETS: [ - { - POSITION: [16, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], - }, - { - POSITION: [12, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], - }, - { - POSITION: [5, 0, 0, 0, 360, 1], - TYPE: ["dogeiscutTurret", { INDEPENDENT: true, CONTROLLERS: ["nearestDifferentMaster"], COLOR: "yellow" }], - }, - { - POSITION: [1, 10.5, 0, 0, 360, 0], - TYPE: ["genericTank", {COLOR: "black"}], - }, - ] -} -Class.trplnrBossAuraBulletAura = addAura(1, 0.8) -Class.trplnrBossAuraBullet = { - PARENT: 'genericTank', - LABEL: 'Nest', - SHAPE: -4, - PERSISTS_AFTER_DEATH: true, - BODY: { - HEALTH: 100, - }, - SIZE: 25, - COLOR: '#F49EFF', - GLOW: { - STRENGTH: 25, - COLOR: 'mirror', - ALPHA: 1 - }, - DRAW_HEALTH: true, - GUNS: (() => { - let output = [] - for (let i = 0; i < 4; i++) { - output.push({ - POSITION: { ANGLE: (360/4)*i, ASPECT: -0.35, X: -5 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { size: 0.8 }, {reload: 1.6, damage: 1.5}]), - TYPE: 'autoswarm', - AUTOFIRE: true, - }, - }) - } - return output - })(), - TURRETS: [ - { - POSITION: {SIZE: 10, LAYER: 1}, - TYPE: "trplnrBossAuraBulletAura" - } - ] -} -const trplnrBossDecor = { - COLOR: '#F49EFF', - UPGRADE_COLOR: "lavender", - LABEL: 'Lavender', - NAME: 'Trioplane', - SHAPE: 3, - SIZE: 25, - VALUE: 5e7, - DANGER: 10, - GLOW: { - RADIUS: 15, - COLOR: 'mirror', - ALPHA: 1, - RECURSION: 5 - }, - PROPS: [{ - POSITION: { SIZE: 25 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, - TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] - }, { - POSITION: { SIZE: 25 ** Math.SQRT1_2, LAYER: 1 }, - TYPE: ['triangle', { COLOR: -1, MIRROR_MASTER_ANGLE: true }] - }, { - POSITION: { SIZE: 25 }, - TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] - }], -} -Class.trplnrBoss = { - PARENT: "miniboss", - ...trplnrBossDecor, - UPGRADE_TOOLTIP: "\"Heck, even The Guardians are afraid of him, \n" + - "They usually call him the The Light, Victory, Death and Ruler of the Pentagon Race a.k.a Lvndr. \n" + - "We don't know where his teleportation powers came from, \n" + - "He was secretive of it. \n" + - "Though some say there was an old script found at the Neutrality Point \n" + - "at the middle of the nest when it still existed, It had some \n" + - "sort of drawing of a tank going through walls, and this thing that said '6@D M0|)3 \n" + - "Nest Reseachers still haven't been able to decipher it though. \n" + - "One day, The Neutrality Point left and on that same day, \n" + - "A sentry's child went missing, \n" + - "Coincidence? I think not.\"", - BODY: { - HEALTH: 500, - }, - ON: [ - { - event: 'fire', - handler: ({ body, gun }) => { - if (gun.identifier != 'onHandler') return - const messages = [ - 'Attack my little swarms!', - 'Deploying, Attack swarms', - 'You really think you can defeat me? Heres a little challenge for you.', - 'This thing is really gonna annoy you HAHA!', - 'I don\'t know what to say uhhh, die i guess.' - ] - sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) - sockets.broadcast('Lavender will turn into `BULL3T HELL F0rM`, Run!') - for (let i = 0; i < 24; i++) { - i < 12 ? - setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) - : - setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) - } - setTimeout(() => { - let range = 500 - let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - body.x += whereToGoX - body.y += whereToGoY - }, 12 * 50); - setTimeout(() => body.define('trplnrBossBulletHellForm'), 24 * 50) - } - } - ], - GUNS: [], - GUNS: (() => { - let output = [] - for (let i = 0; i<2; i++) { - output.push({ - POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), - TYPE: "trplnrBossAuraBullet", - INDEPENDENT_CHILDREN: true, - } - }) - } - output.push({ - POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * 2) - 180 }, - PROPERTIES: { - COLOR: 'white', - SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), - TYPE: "trplnrBossAuraBullet", - INDEPENDENT_CHILDREN: true, - IDENTIFIER: 'onHandler', - ALPHA: 0, - } - }) - for (let i = 0; i < 3; i++) { - output.push({ - POSITION: { WIDTH: 5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'black' - } - }) - output.push({ - POSITION: { WIDTH: 5, HEIGHT: 5, X: -30, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'black' - } - }, { - POSITION: { WIDTH: 5, HEIGHT: 5, X: -25, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'white' - } - }) - } - return output - })() -} - -Class.trplnrBossBulletHellFormPentagonsAuraBullet = { - PARENT: 'bullet', - PERSISTS_AFTER_DEATH: true, - TURRETS: [{ - POSITION: {SIZE: 13, LAYER: 1}, - TYPE: "trplnrBossAuraBulletAura" - }] -} - -Class.trplnrBossBulletHellFormPentagons = { - PARENT: 'bullet', - LABEL: 'Pentagon', - SHAPE: -5, - PROPS: [{ - POSITION: { SIZE: 40 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, - TYPE: ['pentagon', {COLOR: 'black', MIRROR_MASTER_ANGLE: true}] - }], - GUNS: (() => { - let output = [] - for (let i = 0; i < 5; i++) { - output.push({ - POSITION: { WIDTH: 10, HEIGHT: 10, ANGLE: ((360/5)*i) - 180, DELAY: 11.5 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 0.4}]), - TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', - AUTOFIRE: true, - COLOR: 'white', - } - }) - } - return output - })() -} -Class.trplnrBossBulletHellForm = { - PARENT: "miniboss", - ...trplnrBossDecor, - LABEL: 'Lavender - Bullet Hell Form', - BODY: { - HEALTH: 500, - }, - ON: [ - { - event: "fire", - handler: ({ body, masterStore, gun }) => { - if (gun.identifier != 'onHandler') return - masterStore.shotsFired ??= 0 - masterStore.shotsFired++ - - for (let i = 0; i < 24; i++) { - i < 12 ? - setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) - : - setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) - } - setTimeout(() => { - let range = 500 - let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) - body.x += whereToGoX - body.y += whereToGoY - }, 12 * 50) - - if (masterStore.shotsFired > 5) { - body.define('trplnrBossVulnerableForm') - const messages = [ - 'I\'m a little tired right now', - 'Ouch my leg!', - 'i sleep', - 'Bruh my keyboard isn\'t working', - 'Omg bruh I chose the wrong form' - ] - sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) - sockets.broadcast('Lavender is in its `VULN3RABLE F0RM`, Attack!') - } - } - } - ], - GUNS: [], - GUNS: (() => { - let output = [] - for (let i = 0; i<3; i++) { - output.push({ - POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -25 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 1 }]), - TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', - COLOR: 'black' - } - }, { - POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -20 }, - PROPERTIES: { - COLOR: 'white' - } - }, { - POSITION: { WIDTH: 10, HEIGHT: 5, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 3 }]), - TYPE: 'trplnrBossBulletHellFormPentagons', - COLOR: 'white' - } - }, { - POSITION: { WIDTH: 8, HEIGHT: 3, X: -1, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: 'pureWhite', - } - }, { - POSITION: { WIDTH: 5, HEIGHT: 10, X: 5, ASPECT: 0.2, ANGLE: ((360 / 3) * i) - 180 }, - PROPERTIES: { - COLOR: -1, - } - }) - } - output.push({ - POSITION: { WIDTH: 0, HEIGHT: 0 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 2 }, g.fake]), - TYPE: 'bullet', - IDENTIFIER: 'onHandler', - ALPHA: 0 - } - }) - return output - })() -} -Class.trplnrBossVulnerableForm = { - PARENT: "miniboss", - ...trplnrBossDecor, - LABEL: 'Lavender - Vulnerable Form', - BODY: { - HEALTH: 500, - SPEED: 0.1 - }, - ON: [ - { - event: "tick", - handler: ({ body }) => { - body.store.ticks ??= 0 - body.store.ticks++ - const spawnCrashers = body.store.ticks % 3 == 0 - const spawnSentries = body.store.ticks % 60 == 0 - const sentries = ["sentrySwarm", "sentryGun", "sentryTrap"] - if (spawnCrashers) new Entity(body, body).define("crasher") - if (spawnSentries) new Entity(body, body).define(sentries[Math.floor(Math.random() * sentries.length)]) - } - }, - { - event: "fire", - handler: ({ body, gun }) => { - if (gun.identifier != 'onHandler') return - setTimeout(() => { - body.define('trplnrBoss') - sockets.broadcast('im awake') - }, 15000) - setTimeout(() => sockets.broadcast('Lavender will activate in 10 seconds and turn into S4nctuary F0rM'), 5000) - } - } - ], - GUNS: [{ - POSITION: {LENGTH: 0, WIDTH: 0}, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, {reload: 500}]), - TYPE: 'bullet', - AUTOFIRE: true, - IDENTIFIER: 'onHandler', - ALPHA: 0 - } - }] -} - -Class.frostAuraSmall = { - PARENT: "aura", - LAYER: 30, - FACING_TYPE: ["spin", {speed: -0.04}], - BORDERLESS: true, - SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraSmallOutline' - }] -} -Class.frostAuraSmallOutline = { - PARENT: "aura", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0" + - "L 0.309 0.951 L -0.809 0.588 L -0.809 -0.588 L 0.309 -0.951 L 1 0" + - "L 0 0 L 0.309 0.951 M 0 0 L -0.809 0.588 M 0 0 L -0.809 -0.588 M 0 0 L 0.309 -0.951", -} -Class.frostAuraLarge = { - PARENT: "aura", - LAYER: 30, - FACING_TYPE: ["spin", {speed: -0.04}], - BORDERLESS: true, - SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraLargeOutline' - }] -} -Class.frostAuraLargeOutline = { - PARENT: "aura", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0" + - "M 0.988 -0.156 L 0.988 0.156 L 0.891 0.454 L 0.707 0.707 L 0.454 0.891 L 0.156 0.988 L -0.156 0.988 L -0.454 0.891 L -0.707 0.707 L -0.891 0.454 L -0.988 0.156 L -0.988 -0.156 L -0.891 -0.454 L -0.707 -0.707 L -0.454 -0.891 L -0.156 -0.988 L 0.156 -0.988 L 0.454 -0.891 L 0.707 -0.707 L 0.891 -0.454 L 0.988 -0.156 L 0.949 0" + - "L 0.988 0.156 L 0.891 0.256 L 0.891 0.454 L 0.739 0.537 L 0.707 0.707 L 0.519 0.769 L 0.454 0.891 L 0.293 0.902 L 0.156 0.988 L 0.032 0.927 L -0.156 0.988 L -0.282 0.869 L -0.454 0.891 L -0.571 0.731 L -0.707 0.707 L -0.768 0.558 L -0.891 0.454 L -0.871 0.317 L -0.988 0.156 L -0.914 0 L -0.988 -0.156 L -0.871 -0.317 L -0.891 -0.454 L -0.768 -0.558 L -0.707 -0.707 L -0.571 -0.731 L -0.454 -0.891 L -0.282 -0.869 L -0.156 -0.988 L 0.032 -0.927 L 0.156 -0.988 L 0.293 -0.902 L 0.454 -0.891 L 0.519 -0.769 L 0.707 -0.707 L 0.739 -0.537 L 0.891 -0.454 L 0.891 -0.256 L 0.988 -0.156 L 0.949 0" + - "L 0.891 0.256 L 0.739 0.537 L 0.519 0.769 L 0.293 0.902 L 0.032 0.927 L -0.282 0.869 L -0.571 0.731 L -0.768 0.558 L -0.871 0.317 L -0.914 0 L -0.871 -0.317 L -0.768 -0.558 L -0.571 -0.731 L -0.282 -0.869 L 0.032 -0.927 L 0.293 -0.902 L 0.519 -0.769 L 0.739 -0.537 L 0.891 -0.256 L 0.949 0" + - "M 0.834 0 L 0.891 0.256 L 0.704 0.291 L 0.739 0.537 L 0.495 0.579 L 0.519 0.769 L 0.258 0.793 L 0.032 0.927 L -0.06 0.759 L -0.282 0.869 L -0.398 0.649 L -0.571 0.731 L -0.674 0.49 L -0.871 0.317 L -0.741 0.178 L -0.914 0 L -0.741 -0.178 L -0.871 -0.317 L -0.674 -0.49 L -0.571 -0.731 L -0.398 -0.649 L -0.282 -0.869 L -0.06 -0.759 L 0.032 -0.927 L 0.258 -0.793 L 0.519 -0.769 L 0.495 -0.579 L 0.739 -0.537 L 0.704 -0.291 L 0.891 -0.256 L 0.834 0" + - "L 0.704 0.291 L 0.495 0.579 L 0.258 0.793 L -0.06 0.759 L -0.398 0.649 L -0.674 0.49 L -0.741 0.178 L -0.741 -0.178 L -0.674 -0.49 L -0.398 -0.649 L -0.06 -0.759 L 0.258 -0.793 L 0.495 -0.579 L 0.704 -0.291 L 0.834 0" + - "M 0.592 0 L 0.704 0.291 L 0.413 0.3 L 0.495 0.579 L 0.183 0.563 L -0.06 0.759 L -0.158 0.485 L -0.398 0.649 L -0.479 0.348 L -0.741 0.178 L -0.51 0 L -0.741 -0.178 L -0.479 -0.348 L -0.398 -0.649 L -0.158 -0.485 L -0.06 -0.759 L 0.183 -0.563 L 0.495 -0.579 L 0.413 -0.3 L 0.704 -0.291 L 0.592 0" + - "L 0.413 0.3 L 0.183 0.563 L -0.158 0.485 L -0.479 0.348 L -0.51 0 L -0.479 -0.348 L -0.158 -0.485 L 0.183 -0.563 L 0.413 -0.3 L 0.592 0" + - "M 0.292 0 L 0.413 0.3 L 0.09 0.277 L -0.158 0.485 L -0.236 0.171 L -0.51 0 L -0.236 -0.171 L -0.158 -0.485 L 0.09 -0.277 L 0.413 -0.3 L 0.292 0 L 0.09 0.277" + - "L -0.236 0.171 L -0.236 -0.171 L 0.09 -0.277 L 0.292 0 M 0 0 L 0.949 0" + - "M 0 0 L 0.293 0.902 M 0 0 L -0.768 0.558 M 0 0 L -0.768 -0.558 M 0 0 L 0.293 -0.902", -} -Class.frostAuraSymbol = { - PARENT: "genericTank", - CONTROLLERS: [["spin", { speed: -0.04 }]], - INDEPENDENT: true, - BORDERLESS: true, - COLOR: 'teal', - SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z", - TURRETS: [{ - POSITION: [20, 0, 0, 0, 0, 1], - TYPE: 'frostAuraSymbolOutline' - }] -} -Class.frostAuraSymbolOutline = { - PARENT: "genericTank", - MIRROR_MASTER_ANGLE: true, - DRAW_FILL: false, - SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z" + - "M 0.52 0.3 L 0.52 -0.3 L 0.797 -0.46 M 0.52 -0.3 L 0 -0.6 L 0 -0.92 M 0 -0.6 L -0.52 -0.3 L -0.797 -0.46 M -0.52 -0.3 L -0.52 0.3 L -0.797 0.46 M -0.52 0.3 L 0 0.6 L 0 0.92 M 0 0.6 L 0.52 0.3 L 0.797 0.46" -} - -function addIcosphereAura(damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraSize = "Medium") { - let auraType = "frostAura" + auraSize; - return { - PARENT: "genericTank", - INDEPENDENT: true, - LABEL: "", - COLOR: 17, - GUNS: [ - { - POSITION: [0, 20, 1, 0, 0, 0, 0,], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.aura, { size: sizeFactor, damage: damageFactor }]), - TYPE: [auraType, {ALPHA: opacity}], - MAX_CHILDREN: 1, - AUTOFIRE: true, - SYNCS_SKILLS: true, - }, - }, - ], - TURRETS: [ - { - POSITION: [20, 0, 0, 0, 360, 1], - TYPE: "frostAuraSymbol" - }, - ] - }; -} -Class.frostAuraBlockTop = { - SHAPE: "M -1.3 -0.15 L -1.3 0.15 L -0.3 0.3 L -0.15 1.3 L 0.15 1.3 L 0.3 0.3 L 1.3 0.15 L 1.3 -0.15 L 0.3 -0.3 L 0.15 -1.3 L -0.15 -1.3 L -0.3 -0.3 Z", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 5 }, - MIRROR_MASTER_ANGLE: true, -} -Class.frostAuraBlockTurret = { - PARENT: "genericTank", - INDEPENDENT: true, - COLOR: 17, - CONTROLLERS: ["nearestDifferentMaster"], - LABEL: "", - BODY: { - FOV: 2, - }, - HAS_NO_RECOIL: true, - GUNS: [ - { - POSITION: [18, 15, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} - }, - }, { - POSITION: [23, 11, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, {density: 0.2}]), - TYPE: "bullet", - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [15, 13, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ], -} -Class.frostAuraBlockAura = addIcosphereAura(0.25, 1.6, 0.15, "Small"); -Class.frostAuraBlock = { - PARENT: 'unsetTrap', - TURRETS: [ - { - POSITION: [20, 0, 0, 45, 0, 1], - TYPE: 'frostAuraBlockTop' - }, { - POSITION: [11, 0, 0, 0, 360, 1], - TYPE: 'frostAuraBlockTurret' - }, { - POSITION: [10, 0, 0, 0, 360, 1], - TYPE: 'frostAuraBlockAura' - } - ] -} -Class.frostBossBigAura = addIcosphereAura(1.5, 1.45, 0.3, "Large"); - -Class.frostBossAutoTurret = { - PARENT: "autoTankGun", - INDEPENDENT: true, - COLOR: 17, - GUNS: [ - { - POSITION: [17, 14, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} - }, - }, { - POSITION: [22, 10, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}]), - TYPE: "bullet", - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [14, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}, g.fake]), - TYPE: "bullet", - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ], - TURRETS: [ - { - POSITION: [13, 0, 0, 0, 0, 1], - TYPE: ["egg", {COLOR: -1, BORDERLESS: true}], - }, - ], -} - -Class.frostBossBaseDeco = { - SHAPE: "M -1.1 0 L -0.956 0.292 L -0.669 0.205 L -0.669 -0.205 L -0.956 -0.292 Z" + - "M -0.55 0.952 L -0.225 0.974 L -0.157 0.682 L -0.512 0.477 L -0.731 0.682 Z" + - "M -0.55 -0.952 L -0.225 -0.974 L -0.157 -0.682 L -0.512 -0.477 L -0.731 -0.682 Z" + - "M 0.55 0.952 L 0.225 0.974 L 0.157 0.682 L 0.512 0.477 L 0.731 0.682 Z" + - "M 0.55 -0.952 L 0.225 -0.974 L 0.157 -0.682 L 0.512 -0.477 L 0.731 -0.682 Z" + - "M 1.1 0 L 0.956 0.292 L 0.669 0.205 L 0.669 -0.205 L 0.956 -0.292 Z", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, - MIRROR_MASTER_ANGLE: true, - GUNS: Array(6).fill().flatMap((_, i) => ([ - { - POSITION: [1.75, 3, -0.75, 7.5, 0, 60 * i, 0], - PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 2.5, SATURATION_SHIFT: 0.9 }, DRAW_ABOVE: true }, - }, { - POSITION: [1, 9, 0, 8.5, 0, 60 * i + 30, 0], - PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 10, SATURATION_SHIFT: 1.15 } }, - }, - ])) -} - -const trebuchetStats = [g.basic, g.sniper, g.predator, g.predator, g.predator, g.predator, {speed: 0.93, maxSpeed: 0.93, reload: 1.7, health: 1.7, damage: 1.4, size: 2}]; -const hielamanStats = [g.trap, g.setTrap, g.hexaTrapper, {reload: 2.4, health: 3.2, range: 1.2}]; -Class.frostBoss = { - PARENT: 'miniboss', - LABEL: 'Extrasolar', - NAME: 'Frostbyte', - FACING_TYPE: 'toTarget', - SHAPE: 6, - COLOR: "aqua", - UPGRADE_COLOR: "aqua", - SIZE: 31, - DANGER: 12, - VALUE: 888888, - UPGRADE_TOOLTIP: "\"When the golden rays of sun shine through this world's\n" + - "darkened skies and looming clouds, the legend of the warrior\n" + - "and his eternal blade will finally come to fruition.\"", - BODY: { - SPEED: base.SPEED * 0.6, - HEALTH: base.HEALTH * 11, - SHIELD: base.SHIELD * 7, - REGEN: base.REGEN * 2.5, - FOV: base.FOV * 1.4, - RESIST: base.RESIST * 1.2, - DENSITY: base.DENSITY * 7.5, - }, - GUNS: [ - ...Array(6).fill().flatMap((_, i) => ({ - // Speed - POSITION: [8, 14.5, 0.001, 9.5, 0, 60*i, 0], - PROPERTIES: {COLOR: 9}, - })), - ...Array(3).fill().flatMap((_, i) => ([ - { // Heavy Snipers - POSITION: [26.5, 9.5, 1, 0, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats(trebuchetStats), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6 }, - }, - }, { - POSITION: [24, 6.65, -1.3, 0, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, - BORDERLESS: true - }, - }, { - POSITION: [19.5, 3.8, -1.4, 0, 0, 120 * i, 0], - PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 10 } }, - }, { - POSITION: [4, 11.5, 1, 19.5, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, - }, - }, { - POSITION: [2, 12, 1, 20.5, 0, 120 * i, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), - TYPE: "bullet", - COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, - }, - }, - { // Aura Blocks - POSITION: [15, 9, 1, 0, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6}} - }, { - POSITION: [4, 7.5, -1.6, 9, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5}} - }, { - POSITION: [15, 5.4, -0.1, 0, 0, 120 * i + 60, 0], - PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.75}} - }, { - POSITION: [3, 9, 1.6, 15, 0, 120 * i + 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats(hielamanStats), - TYPE: 'frostAuraBlock', - STAT_CALCULATOR: gunCalcNames.trap, - COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6} - }, - }, { - POSITION: [2, 7, 1.6, 16, 0, 120 * i + 60, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([...hielamanStats, g.fake]), - TYPE: 'bullet', - COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} - }, - }, - ])), - ], - TURRETS: [ - ...Array(6).fill().flatMap((_, i) => ([ - { - POSITION: [2.95, 8.55, 0, 60 * i + 30, 180, 2], - TYPE: "frostBossAutoTurret", - }, - ])), - { - POSITION: [8.55, 0, 0, 0, 360, 2], - TYPE: "frostBossBigAura", - }, - ], - PROPS: [ - { - POSITION: [12, 0, 0, 180, 1], - TYPE: ["hexagon", {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 7.5}}], - }, { - POSITION: [20, 0, 0, 0, 1], - TYPE: ["frostBossBaseDeco"], - }, - ] -} - -const divide = 1000; -const arraySize = 10; -const colorArray = []; -const damageMultiplayer = 3.5; -const reloadMultiplayer = 2; -for (let i = 0; i < arraySize; i++) { - const rgb = Math.round(255 * i / (arraySize - 1)); - colorArray.push('#' + ((1 << 24) + (rgb << 16) + (rgb << 8) + rgb).toString(16).slice(1)); -} -class io_nearestDifferentMaster2 extends ioTypes.nearestDifferentMaster { - constructor(body, opts = {}) { - super(body); - this.lookAtDanger = opts.lookAtDanger ?? true; - this.firingAtMe = opts.firingAtMe ?? false; - this.timeout = opts.timeout || 90; - } - buildList(range) { - // Establish whom we judge in reference to - let mostDangerous = 0, - keepTarget = false; - // Filter through everybody... - let out = entities.filter(e => - // Only look at those within our view, and our parent's view, not dead, not invisible, not our kind, not a bullet/trap/block etc - this.validate(e, this.body, this.body.master.master, range * range, range * range * 4 / 3) - ).filter((e) => { - // Only look at those within range and arc (more expensive, so we only do it on the few) - if (this.body.firingArc == null || this.body.aiSettings.view360 || Math.abs(util.angleDifference(util.getDirection(this.body, e), this.body.firingArc[0])) < this.body.firingArc[1]) { - mostDangerous = Math.max(e.dangerValue, mostDangerous); - return true; - } - }).filter((e) => { - // Even more expensive - return !this.wouldHitWall(this.body, e); - }).filter((e) => { - // Only return the highest tier of danger - if (!this.lookAtDanger) return true; - if (this.body.aiSettings.farm || e.dangerValue === mostDangerous) { - if (this.targetLock && e.id === this.targetLock.id) keepTarget = true; - return true; - } - }); - // Reset target if it's not in there - if (!keepTarget) this.targetLock = undefined; - return out; - } - think(input) { - // Override target lock upon other commands - if (input.main || input.alt || this.body.master.autoOverride) { - this.targetLock = undefined; - return {}; - } - // Otherwise, consider how fast we can either move to ram it or shoot at a potiential target. - let tracking = this.body.topSpeed, - damageRef = (this.body.bond == null) ? this.body : this.body.bond, - range = this.body.fov; - // Use whether we have functional guns to decide - for (let i = 0; i < this.body.guns.length; i++) { - if (this.body.guns[i].canShoot && !this.body.aiSettings.SKYNET) { - let v = this.body.guns[i].getTracking(); - if (v.speed == 0 || v.range == 0) continue; - tracking = v.speed; - range = Math.min(range, (v.speed || 1.5) * (v.range < (this.body.size * 2) ? this.body.fov : v.range)); - break; - } - } - if (!Number.isFinite(tracking)) { - tracking = this.body.topSpeed + .01; - } - if (!Number.isFinite(range)) { - range = 640 * this.body.FOV; - } - // Check if my target's alive - if (this.targetLock && ( - !this.validate(this.targetLock, this.body, this.body.master.master, range * range, range * range * 4 / 3) || - this.wouldHitWall(this.body, this.targetLock) // Very expensive - )) { - this.targetLock = undefined; - this.tick = 100; - } - // Think damn hard - if (this.tick++ > 15 * c.runSpeed) { - this.tick = 0; - this.validTargets = this.buildList(range); - // Ditch our old target if it's invalid - if (this.targetLock && this.validTargets.indexOf(this.targetLock) === -1) { - this.targetLock = undefined; - } - // Lock new target if we still don't have one. - if (this.targetLock == null && this.validTargets.length) { - this.targetLock = (this.validTargets.length === 1) ? this.validTargets[0] : nearest(this.validTargets, { - x: this.body.x, - y: this.body.y - }); - this.tick = -this.timeout; - } - } - // Lock onto whoever's shooting me. - if (this.firingAtMe && damageRef.collisionArray.length && damageRef.health.display() < this.oldHealth) { - this.oldHealth = damageRef.health.display(); - if (this.validTargets.indexOf(damageRef.collisionArray[0]) === -1) { - let a = (damageRef.collisionArray[0].master.id === -1) - ? damageRef.collisionArray[0].source - : damageRef.collisionArray[0].master; - if ( - this.body.firingArc == null || - this.body.aiSettings.view360 || - Math.abs(util.angleDifference(util.getDirection(this.body, a), this.body.firingArc[0])) < this.body.firingArc[1] - ) { - this.targetLock = a; - this.tick = -(this.timeout * 5); - } - } - } - // Consider how fast it's moving and shoot at it - if (this.targetLock != null) { - let radial = this.targetLock.velocity; - let diff = { - x: this.targetLock.x - this.body.x, - y: this.targetLock.y - this.body.y, - } - /// Refresh lead time - if (this.tick % 4 === 0) { - this.lead = 0 - // Find lead time (or don't) - if (!this.body.aiSettings.chase) { - let toi = timeOfImpact(diff, radial, tracking) - this.lead = toi - } - } - if (!Number.isFinite(this.lead)) { - this.lead = 0; - } - if (!this.accountForMovement) this.lead = 0; - // And return our aim - return { - target: { - x: diff.x + this.lead * radial.x, - y: diff.y + this.lead * radial.y, - }, - fire: true, - main: true - }; - } - return {}; - } -} -ioTypes.nearestDifferentMaster2 = io_nearestDifferentMaster2; -Class.toothlessBase = { - PARENT: "genericTank", - LABEL: "NightFury", - UPGRADE_TOOLTIP: "A power league...", - GLOW: { - RADIUS: 2, - COLOR: 42, - ALPHA: 0.6, - RECURSION: 6, - }, - BODY: { - SPEED: 0.8 * base.SPEED, - FOV: 1.5 * base.FOV, - HEALTH: 6 * base.HEALTH, - DAMAGE: 2 * base.DAMAGE, - }, - LEVEL_CAP: 45, - EXTRA_SKILL: 78, // 120 - 42 - SHAPE: 3, - VALUE: 30e+3, - SIZE: 24, - COLOR: "purple", - SKILL_CAP: Array(10).fill(smshskl + 3), - LEVEL_SKILL_POINT_FUNCTION: level => { - if (level < 2) return 0; - if (level <= 40) return 1; - if (level <= 45 && level & 1 == 1) return 1; - return 0; - }, -} -Class.toothlessBossTurret = { - PARENT: "genericTank", - LABEL: "", - BODY: { - FOV: 2, - }, - CONTROLLERS: [ - "onlyAcceptInArc", - [ "nearestDifferentMaster2", { lookAtDanger: false, firingAtMe: true, timeout: 10 } ], - ], - COLOR: "grey", - GUNS: [ - { - POSITION: [32, 8, 1, 0, 0, 0, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, { - pen: 0.8, - health: 0.6, - damage: 0.6, - recoil: 0, - }]), - TYPE: "bullet", - }, - }, - ], - ON: [{ - event: "fire", - handler: ({ body }) => { - const master = body.master; - body._damage ??= []; - body._reload ??= []; - - if (!body._loaded) { - let _temp = 0; - master._maxPower ??= 0; - - body.guns.forEach((gun, i) => { - body._damage[i] = gun.settings.damage; - body._reload[i] = gun.settings.reload; - - _temp += (body._damage[i] * 3) / body._damage[i]; - _temp += body._reload[i] / (body._reload[i] / 3); - _temp /= 2; - }); - - _temp /= body.guns.length; - - master._maxPower += (_temp - 1) * divide * 2; - if (master._maxPower > _temp) master._maxPower /= 2; - - body._loaded = true; - } - - if (master._mode) { - master._power -= 1; - if (master._power < 1) { - master._mode = 0; - master.color.base = 14; - } - } - - if (!master._oldPower) return; - const power = master._oldPower / (divide * 2) + 1; - - body.guns.forEach((gun, i) => { - let _1 = body._damage[i] * (master._mode ? power : 1); - let _2 = body._reload[i] / (master._mode ? power : 1); - let max_damage = body._damage[i] * damageMultiplayer; - let min_reload = body._reload[i] / reloadMultiplayer; - - gun.settings.damage = _1 > max_damage ? max_damage : _1; - gun.settings.reload = _2 < min_reload ? min_reload : _2; - }); - }, - }], -}; -Class.toothlessBossDeco = { - PARENT: "genericTank", - LABEL: "", - SHAPE: 3, - SIZE: 10, - ON: [{ - event: "tick", - handler: ({ body }) => { - const master = body.master; - if (master._maxPower) - body.color.base = colorArray[ - Math.floor(master._power / (master._maxPower / arraySize)) > arraySize - 1 - ? arraySize - 1 - : Math.floor(master._power / (master._maxPower / arraySize) - ) - ]; - }, - }], -}; -Class.toothlessBoss = { - PARENT: "toothlessBase", - UPGRADE_COLOR: "magenta", - TURRETS: [{ - POSITION: { SIZE: 15, LAYER: 1 }, - TYPE: ["toothlessBossDeco", { MIRROR_MASTER_ANGLE: true }], - }, { - POSITION: { SIZE: 23 }, - TYPE: ["triangle", { COLOR: "black", MIRROR_MASTER_ANGLE: true }], - }], - GUNS: [{ - POSITION: { LENGTH: 0, WIDTH: 0 }, - PROPERTIES: { - SHOOT_SETTINGS: combineStats([ g.basic, { - range: 0.1, - speed: 0.1, - maxSpeed: 0.1, - recoil: 0, - }]), - TYPE: "bullet", - ALT_FIRE: true, - }, - }], - ON: [{ - event: "altFire", - handler: ({ body }) => { - if (!body._power || body._mode) return; - const power = Math.floor(body._power); - - if (power >= 1) { - body.sendMessage(`Your power level ${power}`); - body._oldPower = body._power; - body._mode = 1; - body.color.base = 5; - } - }, - }, { - event: "kill", - handler: ({ body, entity }) => { - body._power ??= 0; - body._mode ??= 0; - if (!body._mode) body._power += (entity.skill.score / divide) ** 0.8; - }, - }], -} -for (let b = 0; b < 3; b++) - Class.toothlessBoss.TURRETS.push({ - POSITION: [8, 6, -5.6, 120 * b + 180, 180, 0], - TYPE: "toothlessBossTurret", - }, { - POSITION: [8, 6, 5.6, 120 * b + 180, 180, 0], - TYPE: "toothlessBossTurret", - }); +const { combineStats, skillSet, makeAuto, addAura, LayeredBoss, makeDeco, weaponArray } = require('../facilitators.js'); +const { base, gunCalcNames, smshskl } = require('../constants.js'); +const g = require('../gunvals.js'); +require('./generics.js'); + +Class.miniboss = { + PARENT: "genericBoss", + CONTROLLERS: ["nearestDifferentMaster", "minion", "canRepel"], + AI: { NO_LEAD: true }, +} +Class.ramMiniboss = { + PARENT: "genericBoss", + CONTROLLERS: ["nearestDifferentMaster", "canRepel", "mapTargetToGoal"], +} + +// ELITE CRASHERS +Class.elite = { + PARENT: "miniboss", + LABEL: "Elite Crasher", + COLOR: "pink", + SHAPE: 3, + SIZE: 27, + VARIES_IN_SIZE: true, + VALUE: 15e4, + BODY: { + FOV: 1.25, + SPEED: 0.1 * base.SPEED, + HEALTH: 7 * base.HEALTH, + DAMAGE: 2.5 * base.DAMAGE, + }, +} +Class.eliteDestroyer = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Destroyer", + UPGRADE_COLOR: "pink", + GUNS: weaponArray({ + POSITION: [5, 16, 1, 6, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, 3), + TURRETS: [ + ...weaponArray({ + POSITION: [11, 0, 0, 60, 360, 0], + TYPE: "crasherSpawner", + }, 3), + { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: [ "bigauto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +} +Class.eliteGunner = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Gunner", + UPGRADE_COLOR: "pink", + FACING_TYPE: "toTarget", + GUNS: [ + { + POSITION: [14, 16, 1, 0, 0, 180, 0], + }, { + POSITION: [4, 16, 1.5, 14, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), + TYPE: ["unsetPillbox", {MOTION_TYPE: "glide"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, { + POSITION: [6, 14, -2, 2, 0, 60, 0], + }, { + POSITION: [6, 14, -2, 2, 0, 300, 0], + }, + ], + AI: { NO_LEAD: false }, + TURRETS: [ + { + POSITION: [14, 8, 0, 60, 180, 0], + TYPE: "auto4gun", + }, { + POSITION: [14, 8, 0, 300, 180, 0], + TYPE: "auto4gun", + }, + ], +} +Class.eliteSprayer = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Sprayer", + UPGRADE_COLOR: "pink", + SKILL: [0, 9, 3, 9, 2, 9, 9, 9, 9, 0], + AI: { NO_LEAD: false }, + HAS_NO_RECOIL: true, + TURRETS: [ + { + POSITION: [6, 0, 0, 0, 360, 1], + TYPE: ["machineTripleTurret", { INDEPENDENT: true }], + }, + ...weaponArray([ + { + POSITION: [9, 6, -5, 60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, { + POSITION: [9, 6, 5, 60, 130, 0], + TYPE: ["sprayer", { COLOR: "grey" }], + }, + ], 3) + ], +} +Class.eliteBattleship = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Battleship", + UPGRADE_COLOR: "pink", + GUNS: weaponArray([ + { + POSITION: [4, 6, 0.6, 7, -8, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 0, 60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, { + POSITION: [4, 6, 0.6, 7, 8, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.battleship]), + TYPE: "autoswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], 3), + TURRETS: weaponArray({ + POSITION: [5, 7, 0, 0, 360, 1], + TYPE: [ "autoTankGun", { INDEPENDENT: true, COLOR: -1 } ], + }, 3) +} +Class.eliteSpawner = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Spawner", + UPGRADE_COLOR: "pink", + MAX_CHILDREN: 9, + AI: { STRAFE: false }, + GUNS: [ + { + POSITION: [11, 16, 1, 0, 0, 60, 0], + }, { + POSITION: [11, 16, 1, 0, 0, 180, 0], + }, { + POSITION: [11, 16, 1, 0, 0, 300, 0], + }, { + POSITION: [2, 18, 1, 11, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5, health: 2.5 }]), + TYPE: ["sentrySwarm", {CLEAR_ON_MASTER_UPGRADE: true, ACCEPTS_SCORE: false, VARIES_IN_SIZE: false, GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [2, 18, 1, 11, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5, health: 2.5 }]), + TYPE: ["sentryTrap", {CLEAR_ON_MASTER_UPGRADE: true, ACCEPTS_SCORE: false, VARIES_IN_SIZE: false, GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, { + POSITION: [2, 18, 1, 11, 0, 300, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.weak, g.weak, g.weak, { size: 0.5, health: 2.5 }]), + TYPE: ["sentryGun", {CLEAR_ON_MASTER_UPGRADE: true, ACCEPTS_SCORE: false, VARIES_IN_SIZE: false, GIVE_KILL_MESSAGE: false}], + SYNCS_SKILLS: true, + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, + ], + TURRETS: [ + { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: ["auto4gun", { INDEPENDENT: false, COLOR: -1 }], + }, + ], +} +Class.eliteTrapGuard = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Trap Guard", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false }, + GUNS: weaponArray([ + { + POSITION: [10.5, 6, 1, 0, 0, 60, 0], + }, { + POSITION: [3, 6, 1.7, 10.5, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], 3), + TURRETS: [ + { + POSITION: [9.5, 0, 0, 0, 360, 1], + TYPE: "triTrapGuardTurret", + }, + ...weaponArray([ + { + POSITION: [5, 8, -7, 60, 160, 0], + TYPE: ["autoTurret", { INDEPENDENT: false }], + }, { + POSITION: [5, 8, 7, 60, 160, 0], + TYPE: ["autoTurret", { INDEPENDENT: false }], + }, + ], 3) + ], +} +Class.eliteSpinner = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Spinner", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false }, + FACING_TYPE: ["spin", {speed: 0.1}], + GUNS: weaponArray([ + { + POSITION: [9.5, 2, 1, -1.5, 11.5, 10, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [9.5, 2, 1, 3.5, 6.5, 10, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [9.5, 2, 1, 8.5, 1.5, 10, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: "bullet", + }, + }, { + POSITION: [2, 20, 0.75, 8, 0, 60, 0], + }, + ], 3), + TURRETS: [ + { + POSITION: [9.5, 0, 0, 0, 360, 1], + TYPE: ["eliteSpinnerCyclone", {COLOR: -1}], + }, + ], +} + +// OLD ELITE +Class.oldEliteSprayer = { + PARENT: "elite", + UPGRADE_LABEL: "Elite Sprayer (Old)", + UPGRADE_COLOR: "pink", + AI: { NO_LEAD: false }, + TURRETS: weaponArray({ + POSITION: [14, 6, 0, 60, 190, 0], + TYPE: [ "sprayer", { COLOR: -1 } ], + }, 3) +}; + +// Legionary Crasher +Class.legionaryCrasherTop = { + PARENT: "elite", + AI: { STRAFE: false, NO_LEAD: false }, + CONTROLLERS: [ ["spin", { independent: true, speed: -0.005 }] ], + INDEPENDENT: true, + GUNS: weaponArray([ + { + POSITION: [4, 9.5, 0.7, 7, 5, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), + TYPE: [ "swarm", { INDEPENDENT: true } ], + STAT_CALCULATOR: gunCalcNames.swarm, + AUTOFIRE: true, + + }, + }, { + POSITION: [4, 9.5, 0.7, 7, -5, 60, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.pounder, { speed: 3, maxSpeed: 1.7, size: 0.6, range: 2.8}]), + TYPE: [ "swarm", { INDEPENDENT: true } ], + STAT_CALCULATOR: gunCalcNames.swarm, + AUTOFIRE: true, + }, + }, + ], 3), + TURRETS: weaponArray({ + POSITION: [9.5, 10, 0, 0, 190, 0], + TYPE: "auto4gun", + }, 3), +} +Class.legionaryCrasher = { + PARENT: "elite", + LABEL: "Legionary Crasher", + UPGRADE_COLOR: "pink", + AI: { STRAFE: false, NO_LEAD: false }, + HAS_NO_RECOIL: true, + VALUE: 5e6, + SIZE: 75, + BODY: { + FOV: 1.5, + SPEED: 0.1 * base.SPEED, + HEALTH: 2000, + DAMAGE: 5 * base.DAMAGE, + }, + GUNS: [ + ...weaponArray([ + { + POSITION: [14.5, 13, 1, 0, 0, 0, 0], + }, { + POSITION: [3, 13, 1.7, 14.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.pounder, g.destroyer, { speed: 2.5, size: 0.6, maxSpeed: 3 }]), + TYPE: "legionaryPillbox", + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], 3), + ...weaponArray({ + POSITION: [5, 12, 1.6, -11, 0, 0, 0], + }, 3) + ], + TURRETS: [ + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: "legionaryCrasherTop", + }, + ...weaponArray({ + POSITION: [14, 8, 0, 60, 180, 0], + TYPE: [ "sprayer", { COLOR: -1, } ], + }, 3) + ], +} + +Class.sprayerLegion = { + PARENT: "elite", + UPGRADE_LABEL: "Sprayer Legion", + UPGRADE_COLOR: "pink", + AI: { NO_LEAD: false }, + TURRETS: weaponArray({ + POSITION: [14, 6, 0, 60, 190, 0], + TYPE: ["machineGun", {COLOR: -1}], + }, 3) +}; + +// STRANGE BOSSES +Class.sorcerer = { + PARENT: "miniboss", + LABEL: "Sorcerer", + DANGER: 7, + SHAPE: 0, + COLOR: "veryLightGrey", + UPGRADE_COLOR: "veryLightGrey", + SIZE: 26, + MAX_CHILDREN: 50, + VALUE: 2e5, + BODY: { + FOV: 0.5, + SPEED: 0.12 * base.SPEED, + HEALTH: 6 * base.HEALTH, + DAMAGE: 2 * base.DAMAGE, + }, + GUNS: weaponArray({ + POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.machineGun, g.machineGunner, { size: 0.4, spray: 150, speed: 2, shudder: 1.75 }]), + TYPE: "minichip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + }, 2) +}; +Class.summoner = { + PARENT: "miniboss", + LABEL: "Summoner", + DANGER: 8, + SHAPE: 4, + COLOR: "gold", + UPGRADE_COLOR: "gold", + SIZE: 26, + MAX_CHILDREN: 28, + VALUE: 3e5, + BODY: { + FOV: 0.5, + SPEED: 0.1 * base.SPEED, + HEALTH: 7 * base.HEALTH, + DAMAGE: 2.6 * base.DAMAGE, + }, + GUNS: weaponArray({ + POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.8 }]), + TYPE: ["sunchip"], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + }, 4) +}; +Class.enchantress = { + PARENT: "miniboss", + LABEL: "Enchantress", + DANGER: 8, + SHAPE: 3.5, + COLOR: "orange", + UPGRADE_COLOR: "orange", + SIZE: 26, + MAX_CHILDREN: 28, + VALUE: 4e5, + BODY: { + FOV: 0.5, + SPEED: 0.09 * base.SPEED, + HEALTH: 10 * base.HEALTH, + DAMAGE: 3 * base.DAMAGE, + }, + GUNS: weaponArray({ + POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, { size: 0.9 }]), + TYPE: "dorito", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + }, 3) +}; +Class.exorcistor = { + PARENT: "miniboss", + LABEL: "Exorcistor", + DANGER: 8, + SHAPE: 5.5, + COLOR: "purple", + UPGRADE_COLOR: "purple", + SIZE: 26, + MAX_CHILDREN: 20, + VALUE: 5e5, + BODY: { + FOV: 0.5, + SPEED: 0.08 * base.SPEED, + HEALTH: 15 * base.HEALTH, + DAMAGE: 4 * base.DAMAGE, + }, + GUNS: weaponArray({ + POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer]), + TYPE: "demonchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + }, 5) +}; +Class.shaman = { + PARENT: "miniboss", + LABEL: "Shaman", + DANGER: 8, + SHAPE: 6, + COLOR: "hexagon", + UPGRADE_COLOR: "hexagon", + SIZE: 26, + MAX_CHILDREN: 20, + VALUE: 6e5, + BODY: { + FOV: 0.5, + SPEED: 0.07 * base.SPEED, + HEALTH: 20 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + }, + GUNS: weaponArray({ + POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { size: 1.1 }]), + TYPE: "realchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, + }, 6) +}; +Class.eliteSkimmer = { + PARENT: "elite", + LABEL: "Elite Skimmer", + COLOR: "orange", + UPGRADE_COLOR: "orange", + TURRETS: weaponArray({ + POSITION: [15, 5, 0, 60, 170, 0], + TYPE: "skimmerTurret", + }, 3) +}; + +// Nesters +Class.nestKeeper = { + PARENT: "miniboss", + LABEL: "Nest Keeper", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + MAX_CHILDREN: 15, + VALUE: 3e5, + GUNS: weaponArray({ + POSITION: [3.5, 6.65, 1.2, 8, 0, 36, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.nestKeeper]), + TYPE: "drone", + AUTOFIRE: true, + LABEL: "Mega Crasher", + STAT_CALCULATOR: gunCalcNames.drone, + }, + }, 5), + TURRETS: [ + ...weaponArray({ + POSITION: [8, 9, 0, 0, 120, 0], + TYPE: [ "auto4gun", { INDEPENDENT: true, COLOR: -1 } ], + }, 5), + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "boomerTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ], +}; +Class.nestWarden = { + PARENT: "miniboss", + LABEL: "Nest Warden", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + VALUE: 3e5, + GUNS: weaponArray([ + { + POSITION: [10.7, 8, 1, 0, 0, 36, 0], + }, { + POSITION: [1.5, 8, 1.2, 10.7, 0, 36, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, { speed: 1.2 }, g.setTrap, g.constructor]), + TYPE: "unsetTrap", + STAT_CALCULATOR: gunCalcNames.block + }, + } + ], 5), + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "barricadeTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ...weaponArray({ + POSITION: [8, 9, 0, 0, 120, 0], + TYPE: [ "cruiserTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, 5) + ], +} +Class.nestGuardian = { + PARENT: "miniboss", + LABEL: "Nest Guardian", + COLOR: "purple", + UPGRADE_COLOR: "purple", + SHAPE: 5, + SIZE: 50, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.25, + HEALTH: base.HEALTH * 9, + SHIELD: base.SHIELD * 1.5, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 2.5, + }, + VALUE: 3e5, + GUNS: weaponArray({ + POSITION: [5.5, 7, 1, 6, 0, 36, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.pounder, g.destroyer]), + TYPE: "bullet", + LABEL: "Devastator", + }, + }, 5), + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: [ "twisterTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, + ...weaponArray({ + POSITION: [8, 9, 0, 0, 120, 0], + TYPE: [ "swarmerTurret", { INDEPENDENT: true, COLOR: -1 } ], + }, 5) + ], +} + +// Rogues +Class.roguePalisade = { + PARENT: "miniboss", + LABEL: "Rogue Palisade", + COLOR: "darkGrey", + UPGRADE_COLOR: "darkGrey", + SHAPE: 6, + SIZE: 30, + VALUE: 5e5, + CONTROLLERS: ['nearestDifferentMaster', 'onlyAcceptInArc'], + BODY: { + FOV: 1.4, + SPEED: 0.05 * base.SPEED, + HEALTH: 16 * base.HEALTH, + SHIELD: 3 * base.SHIELD, + DAMAGE: 3 * base.DAMAGE, + }, + GUNS: weaponArray({ + POSITION: [4, 6, -1.6, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ g.factory, g.pounder, { reload: 2 }]), + TYPE: ["minion", {INDEPENDENT: true}], + STAT_CALCULATOR: gunCalcNames.drone, + AUTOFIRE: true, + MAX_CHILDREN: 3, + SYNCS_SKILLS: true, + WAIT_TO_CYCLE: true + } + }, 6), + TURRETS: weaponArray({ + POSITION: [5, 10, 0, 30, 110, 0], + TYPE: "baseTrapTurret" + }, 6) +}; +Class.rogueArmada = { + PARENT: "miniboss", + LABEL: 'Rogue Armada', + COLOR: "darkGrey", + UPGRADE_COLOR: "darkGrey", + SHAPE: 7, + SIZE: 28, + VALUE: 500000, + BODY: { + FOV: 1.3, + SPEED: base.SPEED * 0.1, + HEALTH: base.HEALTH * 16, + SHIELD: base.SHIELD * 3, + REGEN: base.REGEN, + DAMAGE: base.DAMAGE * 3, + }, + GUNS: weaponArray([ + { + POSITION: [8, 2, 1, 0, -2, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: "casing" + } + }, { + POSITION: [8, 2, 1, 0, -1.5, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: "casing" + } + }, { + POSITION: [8, 2, 1, 0, -1, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: "bullet" + } + }, { + POSITION: [8, 3, 1, 0, 0.5, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: "bullet" + } + }, { + POSITION: [8, 3, 1, 0, 0, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: "bullet" + } + }, { + POSITION: [8, 3, 1, 0, 0.5, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: "bullet" + } + }, { + POSITION: [8, 4, 1, 0, 1, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: "bullet" + } + }, { + POSITION: [8, 4, 1, 0, 1.5, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, {damage: 3}]), + TYPE: "casing" + } + }, { + POSITION: [8.5, 6, 1, 4, 0, 360 / 14, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.fake]), + TYPE: "casing" + } + }, { + POSITION: [7, 6, -1.6, 4, 0, 360 / 14, 0] + } + ], 7), + TURRETS: weaponArray({ + POSITION: [5, 10, 0, 0, 160, 0], + TYPE: "shottrapTurret" + }, 7), +} + +// Bob. +Class.bob = { + PARENT: "ramMiniboss", + LABEL: "Bob", + SHAPE: 0, + COLOR: "aqua", + UPGRADE_COLOR: "aqua", + SIZE: 18, + BODY: { + FOV: 2, + SPEED: 2 * base.SPEED, + HEALTH: 5 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + REGEN: 8 * base.REGEN, + FOV: 0.5 * base.FOV, + DENSITY: 6 * base.DENSITY, + }, + CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody", + }, { + POSITION: [21.5, 0, 0, 30, 360, 0], + TYPE: "landmineBody", + }, { + POSITION: [23.75, 0, 0, 0, 360, 0], + TYPE: "spikeBody", + }, + ], +}; +Class.nemesis = { + PARENT: "bob", + LABEL: "Nemesis", + COLOR: "red", + UPGRADE_COLOR: "red", + BODY: { + REGEN: 1e5, + HEALTH: 1e6, + DENSITY: 30, + DAMAGE: 1e5, + FOV: 5, + }, +}; + +// DIEP BOSSES +Class.guardian = { + PARENT: "elite", + LABEL: "Guardian of the Pentagons", + UPGRADE_LABEL: "Guardian", + UPGRADE_COLOR: "pink", + FACING_TYPE: "toTarget", + GUNS: [ + { + POSITION: [4, 12, 1.4, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, { size: 0.5 }]), + TYPE: "swarm", + AUTOFIRE: true, + }, + }, + ], + AI: { NO_LEAD: false }, +}; +Class.defenderAutoTankGun = { + PARENT: "autoTankGun", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret]), + TYPE: ["bullet", {COLOR: "yellow"}], + }, + }, + ], +}; +Class.defender = { + PARENT: "elite", + LABEL: "Defender", + COLOR: "orange", + UPGRADE_COLOR: "orange", + GUNS: weaponArray([ + { + POSITION: [15, 7, 1, -3, 0, 60, 0], + }, { + POSITION: [3, 7, 1.7, 12, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard, {reload: 1.33, damage: 2.5}]), + TYPE: ["trap", {COLOR: "yellow"}], + STAT_CALCULATOR: gunCalcNames.trap, + }, + }, + ], 3), + TURRETS: weaponArray({ + POSITION: [5, 7, 0, 0, 190, 1], + TYPE: "defenderAutoTankGun", + }, 3), + AI: { NO_LEAD: false }, +}; + +// CELESTIALS +Class.terrestrial = { + PARENT: "miniboss", + LABEL: "Terrestrial", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 5e5, + SHAPE: 7, + SIZE: 35, + BODY: { + FOV: 1, + HEALTH: 1000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 9, + }, +}; +Class.celestial = { + PARENT: "miniboss", + LABEL: "Celestial", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 1e6, + SHAPE: 9, + SIZE: 45, + BODY: { + FOV: 1, + HEALTH: 1000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 12, + }, +}; +Class.rogueCelestial = { + PARENT: "celestial", + LABEL: "Rogue Celestial", + COLOR: "darkGrey", +}; +Class.eternal = { + PARENT: "miniboss", + LABEL: "Eternal", + SKILL: [9, 9, 9, 9, 9, 9, 9, 9, 9, 9], + VALUE: 4e6, + SHAPE: 11, + SIZE: 90, + BODY: { + FOV: 1, + HEALTH: 3000, + SHIELD: 2, + REGEN: base.REGEN * 0.1, + SPEED: 0.75, + DAMAGE: 18, + }, +}; + +// Terrestrials +let ares = new LayeredBoss(null, "Ares", "terrestrial", 7, "purple", "terrestrialTrapTurret", 7, 5.5); +ares.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["demonchip", { INDEPENDENT: true, }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, false, null, 18); +ares.addLayer({turret: { + POSITION: [10, 8.5, 0, null, 160, 0], + TYPE: ["protoSwarmerTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let gersemi = new LayeredBoss(null, "Gersemi", "terrestrial", 7, "lightGreen", "terrestrialTrapTurret", 7, 5.5); +gersemi.addLayer({turret: { + POSITION: [9, 8, 0, null, 160, 0], + TYPE: ["swarmTurret", { INDEPENDENT: true }], +}}); +gersemi.addLayer({turret: { + POSITION: [9.5, 7.5, 0, null, 160, 0], + TYPE: ["basicTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let ezekiel = new LayeredBoss(null, "Ezekiel", "terrestrial", 7, "orange", "terrestrialTrapTurret", 7, 5.5); +ezekiel.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["dorito", { COLOR: "orange", INDEPENDENT: true, }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 18); +ezekiel.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["skimmerTurret", { COLOR: "grey", INDEPENDENT: true }], +}}, true, 6.5) + +let eris = new LayeredBoss(null, "Eris", "terrestrial", 7, "pink", "terrestrialTrapTurret", 7, 5.5); +eris.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), + TYPE: ["minion", { INDEPENDENT: true, COLOR: "pink", HAS_NO_RECOIL: true }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, false, null, 14); +eris.addLayer({turret: { + POSITION: [10, 8.5, 0, null, 160, 0], + TYPE: ["rocketeerTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +let selene = new LayeredBoss(null, "Selene", "terrestrial", 7, "gold", "terrestrialTrapTurret", 7, 5.5); +selene.addLayer({gun: { + POSITION: [3.75, 7, 1.2, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, { speed: 0.5, maxSpeed: 0.5 }]), + TYPE: ["sunchip", { COLOR: "gold", INDEPENDENT: true }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 18); +selene.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["hyperTwisterTurret", { INDEPENDENT: true }], +}}, true, 6.5); + +// PALADIN +let paladin = new LayeredBoss(null, "Paladin", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); +paladin.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: ["demonchip", {INDEPENDENT: true}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + }, +}}, true, null, 16); +paladin.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: "swarmerTurret", +}}, true, 6); + +// FREYJA +let freyja = new LayeredBoss(null, "Freyja", "celestial", 9, "lightGreen", "baseTrapTurret", 6.5, 5.5); +freyja.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "cruiserTurret", +}}); +freyja.addLayer({turret: { + POSITION: [10.6, 7.5, 0, null, 160, 0], + TYPE: "auto4gun", +}}, true, 6); + +// ZAPHKIEL +let zaphkiel = new LayeredBoss(null, "Zaphkiel", "celestial", 9, "orange", "baseTrapTurret", 6.5, 5.5); +zaphkiel.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: ["drone", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 16); +zaphkiel.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["skimmerTurret", {COLOR: "grey", INDEPENDENT: true}], +}}, true, 6); + +// NYX +let nyx = new LayeredBoss(null, "Nyx", "celestial", 9, "pink", "baseTrapTurret", 6.5, 5.5); +nyx.addLayer({gun: { + POSITION: [3.8, 7, -1.4, 8, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }]), + TYPE: ["minion", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 16); +nyx.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: "rocketeerTurret", +}}, true, 6); + +// THEIA +let theia = new LayeredBoss(null, "Theia", "celestial", 9, "gold", "baseTrapTurret", 6.5, 5.5); +theia.addLayer({gun: { + POSITION: [3.8, 6, 1.4, 8, 0, null, 1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip, { size: 0.5 }]), + TYPE: ["summonerDrone", {INDEPENDENT: true}], + AUTOFIRE: true, + WAIT_TO_CYCLE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 35); +theia.addLayer({turret: { + POSITION: [10, 7.5, 0, null, 160, 0], + TYPE: ["twisterTurret", {COLOR: "grey"}], +}}, true, 6); + +// ATLAS +let atlas = new LayeredBoss(null, "Atlas", "celestial", 9, "purple", "baseTrapTurret", 6.5, 5.5); +atlas.addLayer({turret: { + POSITION: [7, 9, 0, null, 180, 0], + TYPE: "artilleryTurret", +}}); +atlas.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "nailgunTurret", +}}, true, 6); + +// RHEA +let rhea = new LayeredBoss(null, "Rhea", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +rhea.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "wrenchTurret", +}}); +rhea.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "crowbarTurret", +}}, true, 6); + +// JULIUS +let julius = new LayeredBoss(null, "Julius", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +julius.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "juliusLowerTurret", +}}); +julius.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "launcherTurret", +}}, true, 6); + +// GENGHIS +let genghis = new LayeredBoss(null, "Genghis", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +genghis.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "genghisLowerTurret", +}}); +genghis.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "auto4gun", +}}, true, 6); + +// NAPOLEON +let napoleon = new LayeredBoss(null, "Napoleon", "celestial", 9, "darkGrey", "baseTrapTurret", 6.5, 5.5); +napoleon.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 180, 0], + TYPE: "napoleonLowerTurret", +}}); +napoleon.addLayer({turret: { + POSITION: [10.5, 8, 0, null, 160, 0], + TYPE: "napoleonUpperTurret", +}}, true, 6) + +// Eternals +let kronos = new LayeredBoss(null, "Kronos", "eternal", 11, "veryLightGrey", "baseTrapTurret", 6, 5.5); +kronos.addLayer({turret: { + POSITION: [6.5, 9, 0, null, 160, 0], + TYPE: "kronosSkimmerTurret", +}}); +kronos.addLayer({turret: { + POSITION: [6.5, 9, 0, null, 160, 0], + TYPE: "carrierTurret", +}}, true, 4); +kronos.addLayer({turret: { + POSITION: [8.5, 9, 0, null, 160, 0], + TYPE: "tripletTurret", +}}, true, 4); + +let odin = new LayeredBoss(null, "Odin", "eternal", 11, "aqua", "baseTrapTurret", 4.5, 3.5); +odin.addLayer({gun: { + POSITION: [2.25, 3.25, -1.6, 9, 0, null, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, { size: 0.5 }, g.pounder, {size: 1.7}]), + TYPE: ["gemDrone", {INDEPENDENT: true,}], + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, +}}, true, null, 18); +odin.addLayer({turret: { + POSITION: [7, 8, 0, null, 160, 0], + TYPE: "autoSmasherLauncherTurret", +}}, true, 5.5); +odin.addLayer({turret: { + POSITION: [8, 9, 0, null, 160, 0], + TYPE: "gunnerCruiserTurret", +}}, true, 4.5); + +// Developer Bosses +Class.taureonCoreBase = { + SHAPE: 4, + COLOR: '#00A2E8' +}; +Class.taureonCore = { + PARENT: "genericTank", + LABEL: "Core Turret", + SHAPE: 4.5, + COLOR: '#99D9EA', + CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], + INDEPENDENT: true, + GUNS: [{ + POSITION: [10, 14, -0.5, 14, 0, 0, 0] + },{ + POSITION: [21, 15, -1.1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.destroyer, g.sniper]), + TYPE: "snakeOld", + STAT_CALCULATOR: gunCalcNames.sustained + } + }], + TURRETS: [{ + POSITION: [20 * Math.SQRT2, 0, 0, 0, 0, 0], + TYPE: "taureonCoreBase" + }] +}; +Class.taureonBase = { + SHAPE: 4.5, + COLOR: '#161B54', + MIRROR_MASTER_ANGLE: true +}; +let d = 1/4; +Class.taureonStar = { + SHAPE: [[0,1],[d,d],[1,0],[d,-d],[0,-1],[-d,-d],[-1,0],[-d,d]], + COLOR: '#3F48CC', + MIRROR_MASTER_ANGLE: true +}; +Class.taureonRailgunTurret = { + PARENT: "genericTank", + COLOR: "grey", + LABEL: "Railgun Turret", + CONTROLLERS: ["nearestDifferentMaster", "onlyAcceptInArc"], + INDEPENDENT: true, + GUNS: [{ + POSITION: [20, 7, 1, 0, 0, 0, 0] + },{ + POSITION: [24, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.destroyer, { speed: 5, penetration: 0.8 }]), + TYPE: "bullet" + } + },{ + POSITION: [5, 7.5, -1.6, 8, 0, 0, 0], + }] +}; +Class.taureonThruster = { + PARENT: "genericTank", + COLOR: "grey", + LABEL: "Thruster", + CONTROLLERS: ["onlyAcceptInArc"], + GUNS: [{ + POSITION: [14, 12, 1, 4, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), + TYPE: ["bullet", { ALPHA: 0.5 }] + } + }, { + POSITION: [12, 12, 1.4, 4, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.machineGun, g.thruster, { range: 0.175, reload: 0.25, recoil: 0.25 }]), + TYPE: ["bullet", { ALPHA: 0.5 }] + }, + }] +}; +Class.taureonMissile = { + PARENT: "bullet", + LABEL: "Missile", + FACING_TYPE: "smoothToTarget", + CONTROLLERS: ["nearestDifferentMaster"], + INDEPENDENT: true, + BODY: { + ACCELERATION: 10, + FOV: base.FOV * 2 + }, + TURRETS: [{ + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + }], + GUNS: [{ + POSITION: [6, 12, 1.4, 8, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] + } + },{ + POSITION: [10, 12, 0.8, 8, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, { reload: 0.25, range: 0.075 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, ALPHA: 0.5 }] + } + },...Array(32).fill().map((_, i)=>({ + POSITION: [0, (i % 4) + 1, 0, 0, 0, 0, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, { spray: 1e6, range: 0.5, shudder: 1.5, damage: 1 + (i % 4) }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true + }, + }))] +}; +Class.taureonBoss = { + PARENT: "miniboss", + LABEL: "Diamond Marauder", + NAME: "Taureon", + COLOR: '#2B339B', + UPGRADE_COLOR: "spaceGem", + DANGER: 10, + SHAPE: 4.5, + SIZE: 50, + FACING_TYPE: "smoothToTarget", + UPGRADE_TOOLTIP: "With a powerful Gatling Gun on the front, Rocket Launchers as wings, movable Thrusters on the back, " + + "and equipped with Railgun Turrets, it perfectly excells at terminating those who feel its Wrath.\n" + + "An octahedral carbon robot, exclusively designed to eradicate opponents with sheer brutality alone.\n" + + '"NOW YOU FACE MY ULTIMATE CREATION."', + VALUE: 9e6, + BODY: { + FOV: 1, + SPEED: 0.5 * base.SPEED, + HEALTH: 20 * base.HEALTH, + DAMAGE: 3 * base.DAMAGE, + }, + TURRETS: [{ + POSITION: [23.3, 0, 0, 0, 0, 0], + TYPE: "taureonBase" + },{ + POSITION: [5, 10, 0, -45, 180, 0], + TYPE: "taureonRailgunTurret" + },{ + POSITION: [5, 10, 0, 45, 180, 0], + TYPE: "taureonRailgunTurret" + },{ + POSITION: [5, -10, -2, -45, 90, 0], + TYPE: "taureonThruster" + },{ + POSITION: [5, -10, 2, 45, 90, 0], + TYPE: "taureonThruster" + },{ + POSITION: [25, 0, 0, 0, 0, 1], + TYPE: "taureonStar" + },{ + POSITION: [5, 0, 0, 0, 360, 1], + TYPE: "taureonCore" + }], + GUNS: [...Array(6).fill().map((_, i) => ({ + POSITION: [18, 1.75, 1, 0, Math.cos(Math.PI * i / 3) * 2, 0, i / 6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, { speed: 2, maxSpeed: 2, damage: 0.75, size: 0.8 }]), + TYPE: "bullet" + } + })),{ + POSITION: [4, 5, -0.5, 12, 0, -90, 0] + },{ + POSITION: [10, 5, -1.2, 5, 0, -90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), + TYPE: "taureonMissile", + STAT_CALCULATOR: gunCalcNames.sustained + } + },{ + POSITION: [4, 5, -0.5, 12, 0, 90, 0] + },{ + POSITION: [10, 5, -1.2, 5, 0, 90, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, g.destroyer, { shudder: 0.1, reload: 0.6, speed: 5, range: 2 }]), + TYPE: "taureonMissile", + STAT_CALCULATOR: gunCalcNames.sustained + } + },{ + POSITION: [5.5, 5, -1.5, 5, 0, -45, 0] + },{ + POSITION: [5.5, 5, -1.5, 5, 0, 45, 0] + },{ + POSITION: [2, 7, 1, 8, 0, 0, 0] + },{ + POSITION: [2, 7, 1, 14.5, 0, 0, 0] + }] +}; + +Class.zephiMiscDeco = makeDeco(4, "white") +Class.zephiMiscDeco2 = makeDeco(4, "black") +Class.zephiSunchip = makeAuto({ + PARENT: "drone", + SHAPE: 4, + HITS_OWN_TYPE: "hard", + BODY: { + FOV: 0.5, + }, + AI: { + BLIND: true, + FARMER: true, + }, + TURRETS: [{ + POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], + TYPE: ["overdriveDeco", { MIRROR_MASTER_ANGLE: true }] + },{ + POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], + TYPE: ["shinySquare", { MIRROR_MASTER_ANGLE: true }] + }] +}, "Robo-Sunchip", {type: 'autoSmasherTurret', size: 6}) +Class.zephiEggchip = { + PARENT: "drone", + LABEL: "Guided Missile", + SHAPE: 0, + HITS_OWN_TYPE: "hard", + BODY: { + FOV: 0.5, + }, + AI: { + BLIND: true, + FARMER: true, + }, + GUNS: [ + { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, g.lowPower, { reload: 0.5, recoil: 1.35, speed: 1.3, maxSpeed: 1.3 }]), + TYPE: ["bullet", { COLOR: "black", PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], + TURRETS: [{ + POSITION: [10, 0, 0, 45, 0, 1], + TYPE: "gem" + }] +} +Class.zephiGearOuter = makeDeco('M 0.5 0.0929 V -0.0908 L 0.3875 -0.1096 C 0.3792 -0.1409 0.3667 -0.1701 0.3521 -0.1952 L 0.4187 -0.2871 L 0.2896 -0.4186 L 0.1958 -0.3539 C 0.1687 -0.3685 0.1396 -0.381 0.1104 -0.3894 L 0.0917 -0.5 H -0.0917 L -0.1104 -0.3873 C -0.1417 -0.3789 -0.1688 -0.3664 -0.1958 -0.3518 L -0.2875 -0.4165 L -0.4188 -0.2871 L -0.3521 -0.1952 C -0.3667 -0.1681 -0.3792 -0.1388 -0.3875 -0.1075 L -0.5 -0.0908 V 0.0929 L -0.3875 0.1117 C -0.3792 0.143 -0.3667 0.1701 -0.3521 0.1973 L -0.4188 0.2912 L -0.2896 0.4207 L -0.1958 0.3539 C -0.1688 0.3685 -0.1396 0.381 -0.1083 0.3894 L -0.0896 0.5 H 0.0938 L 0.1125 0.3873 C 0.1417 0.3789 0.1708 0.3664 0.1979 0.3518 L 0.2917 0.4186 L 0.4208 0.2891 L 0.3542 0.1952 C 0.3688 0.1681 0.3812 0.1409 0.3896 0.1096 L 0.5 0.0929 Z M 0.3333 0 C 0.3333 0.1841 0.1841 0.3333 0 0.3333 C -0.1841 0.3333 -0.3333 0.1841 -0.3333 0 C -0.3333 -0.1841 -0.1841 -0.3333 0 -0.3333 C 0.1841 -0.3333 0.3333 -0.1841 0.3333 0 Z', '#7F7F7F') +Class.zephiGearOuter.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearOuter.BORDERLESS = true +Class.zephiGearCentre = makeDeco(0, '#1F1F1F') +Class.zephiGearCentre.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearCentre.BORDERLESS = true +Class.zephiGearRed = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#FF1F1F') +Class.zephiGearRed.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearRed.BORDERLESS = true +Class.zephiGearGreen = makeDeco('M 0.0771 -0.2552 C 0.0743 -0.2561 0.0691 -0.2576 0.0657 -0.2585 L 0.0607 -0.2597 C 0.0571 -0.2605 0.0514 -0.2617 0.0479 -0.2623 L 0.0428 -0.2632 C 0.0392 -0.2638 0.0334 -0.2646 0.0299 -0.265 L 0.0247 -0.2655 C 0.0211 -0.2659 0.0153 -0.2662 0.0117 -0.2664 L 0.0066 -0.2666 C 0.003 -0.2667 -0.0029 -0.2667 -0.0065 -0.2666 L -0.0116 -0.2664 C -0.0153 -0.2662 -0.0211 -0.2659 -0.0247 -0.2655 L -0.0298 -0.265 C -0.0334 -0.2646 -0.0392 -0.2638 -0.0427 -0.2632 L -0.0478 -0.2623 C -0.0514 -0.2617 -0.0571 -0.2605 -0.0606 -0.2597 L -0.0656 -0.2585 C -0.0691 -0.2576 -0.0747 -0.256 -0.0782 -0.2549 C -0.081 -0.254 -0.0833 -0.2502 -0.0833 -0.2466 V 0.2466 C -0.0833 0.2502 -0.0805 0.2541 -0.0771 0.2552 C -0.0743 0.2561 -0.0691 0.2576 -0.0656 0.2585 L -0.0606 0.2597 C -0.0571 0.2605 -0.0514 0.2617 -0.0478 0.2623 L -0.0427 0.2632 C -0.0392 0.2638 -0.0334 0.2646 -0.0298 0.265 L -0.0247 0.2655 C -0.0211 0.2659 -0.0153 0.2663 -0.0116 0.2664 L -0.0065 0.2666 C -0.0029 0.2667 0.003 0.2667 0.0066 0.2666 L 0.0117 0.2664 C 0.0153 0.2663 0.0211 0.2659 0.0247 0.2655 L 0.0299 0.265 C 0.0334 0.2646 0.0392 0.2638 0.0428 0.2632 L 0.0479 0.2623 C 0.0514 0.2617 0.0571 0.2605 0.0607 0.2597 L 0.0657 0.2585 C 0.0691 0.2576 0.0748 0.256 0.0782 0.2549 C 0.0811 0.254 0.0834 0.2502 0.0834 0.2466 V -0.2466 C 0.0834 -0.2502 0.0806 -0.2541 0.0771 -0.2552 Z', '#1FDF1F') +Class.zephiGearGreen.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearGreen.BORDERLESS = true +Class.zephiGearBlue = makeDeco('M -0.2667 0 C -0.2667 0.0074 -0.2664 0.0147 -0.2658 0.022 C -0.2651 0.0293 -0.2642 0.0366 -0.263 0.0439 C -0.2618 0.0511 -0.2603 0.0583 -0.2585 0.0655 C -0.2567 0.0726 -0.2546 0.0796 -0.2522 0.0866 C -0.2498 0.0935 -0.2472 0.1004 -0.2442 0.1071 C -0.2412 0.1139 -0.238 0.1205 -0.2345 0.1269 C -0.231 0.1334 -0.2273 0.1397 -0.2232 0.1459 C -0.2192 0.152 -0.2149 0.158 -0.2104 0.1638 C -0.2059 0.1696 -0.2012 0.1752 -0.1962 0.1806 C -0.1912 0.186 -0.186 0.1912 -0.1806 0.1962 C -0.1752 0.2012 -0.1696 0.2059 -0.1638 0.2104 C -0.158 0.215 -0.152 0.2192 -0.1458 0.2232 C -0.1397 0.2273 -0.1334 0.231 -0.1269 0.2345 C -0.1204 0.238 -0.1138 0.2413 -0.1071 0.2442 C -0.1032 0.2458 -0.1 0.2436 -0.1 0.2393 V -0.2393 C -0.1 -0.2436 -0.1032 -0.2458 -0.1071 -0.2442 C -0.1138 -0.2413 -0.1204 -0.238 -0.1269 -0.2345 C -0.1334 -0.231 -0.1397 -0.2273 -0.1458 -0.2232 C -0.152 -0.2192 -0.158 -0.215 -0.1638 -0.2104 C -0.1696 -0.2059 -0.1752 -0.2012 -0.1806 -0.1962 C -0.186 -0.1912 -0.1912 -0.186 -0.1962 -0.1806 C -0.2012 -0.1752 -0.2059 -0.1696 -0.2104 -0.1638 C -0.2149 -0.158 -0.2192 -0.152 -0.2232 -0.1458 C -0.2273 -0.1397 -0.231 -0.1334 -0.2345 -0.1269 C -0.238 -0.1205 -0.2412 -0.1138 -0.2442 -0.1071 C -0.2472 -0.1004 -0.2498 -0.0935 -0.2522 -0.0866 C -0.2546 -0.0796 -0.2567 -0.0726 -0.2585 -0.0655 C -0.2603 -0.0583 -0.2618 -0.0511 -0.263 -0.0439 C -0.2642 -0.0366 -0.2651 -0.0293 -0.2658 -0.022 C -0.2664 -0.0147 -0.2667 -0.0073 -0.2667 0 Z', '#1F7FDF') +Class.zephiGearBlue.CONTROLLERS = [["spin", { independent: true }]] +Class.zephiGearBlue.BORDERLESS = true +Class.zephiBoss = { + PARENT: "miniboss", + LABEL: "Shiny Mecha-Thaumaturge", + NAME: "Zephi", + DANGER: 10, + SHAPE: 4, + COLOR: "lightGreen", + UPGRADE_COLOR: "lightGreen", + SIZE: 50, + VALUE: 5e6, + SKILL: skillSet({ + rld: 1, + dam: 1, + pen: 1, + str: 1, + spd: 1, + atk: 1, + hlt: 1, + shi: 1, + rgn: 1, + mob: 1, + }), + BODY: { + FOV: 0.75, + SPEED: 0.05 * base.SPEED, + HEALTH: 15 * base.HEALTH, + DAMAGE: 5 * base.DAMAGE, + }, + UPGRADE_TOOLTIP: "Good luck.", + GUNS: weaponArray([ + { + POSITION: [2.5, 3, 1.2, 8, 5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 50, speed: 1.25, shudder: 1.25 }]), + TYPE: ["zephiEggchip", {COLOR: "black"}], + MAX_CHILDREN: 8, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + COLOR: "black", + } + }, { + POSITION: [2.5, 3, 1.2, 8, -5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.pounder, { speed: 2.5 }, g.machineGun, { spray: 150, speed: 1.25, shudder: 1.25 }]), + TYPE: ["zephiEggchip", {COLOR: "black"}], + MAX_CHILDREN: 8, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true, + COLOR: "black", + } + }, { + POSITION: [3.5, 8.65, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.summoner, g.destroyer, g.destroyer, { speed: 2.5 }, { maxSpeed: 3 }]), + TYPE: ["zephiSunchip", {COLOR: "black"}], + MAX_CHILDREN: 4, + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, + WAIT_TO_CYCLE: true + } + } + ], 4), + TURRETS: [{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearOuter" + },{ + POSITION: [5.375 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearCentre" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearRed" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 0, 360, 2], + TYPE: "zephiGearGreen" + },{ + POSITION: [16 * Math.SQRT1_2, 0, 0, 180, 360, 2], + TYPE: "zephiGearBlue" + },{ + POSITION: [20 * Math.SQRT1_2, 0, 0, 45, 0, 1], + TYPE: "overdriveDeco" + },{ + POSITION: [20 * Math.SQRT1_2 ** 2, 0, 0, 0, 0, 1], + TYPE: "zephiMiscDeco2" + },{ + POSITION: [20 * Math.SQRT1_2 ** 3, 0, 0, 45, 0, 1], + TYPE: "zephiMiscDeco" + }] +}; + +Class.dogeiscutBody = { + PARENT: "genericTank", + COLOR: "grey", + SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]] +} +Class.dogeiscutTurret = { + PARENT: "genericTank", + COLOR: "grey", + GUNS: [ { + POSITION: [ 50, 5, 2.5, 0, 0, 0, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.minigun, {reload: 0.1}]), + TYPE: "bullet", + }, + }, { + POSITION: [ 18, 8, -2, 0, 0, 0, 0, ], + }, + ], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["genericTank", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], + }, + ] +} +function createDogeiscutMissileTurret(color) { + return { + PARENT: "genericTank", + COLOR: "grey", + GUNS: [ { + POSITION: [ 15, 8, 2.5, 0, 0, 180, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ + g.basic, + g.skimmer, + { reload: 0.5 }, + g.lowPower, + { recoil: 1.35 }, + { speed: 1.3, maxSpeed: 1.3 }, + { speed: 1.3, maxSpeed: 1.3 }, + {reload: 0.15, recoil: 1, range: 0.1}]), + TYPE: ["bullet", + { + PERSISTS_AFTER_DEATH: true, + COLOR: color + }, + ], + AUTOFIRE: true, + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], + } +} +function createDogeiscutMissile(color) { + return { + PARENT: "bullet", + LABEL: color + " Missile", + COLOR: color, + GUNS: [...Array(11).fill().map((_, i)=>({ + POSITION: [0, 8, 0, 0, 0, ((360) / 11)*i, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, density: 30 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true, COLOR: color }], + SHOOT_ON_DEATH: true, + }, + }))], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutMissileTurret_" + color], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + } + ] + } +} +Class.dogeiscutMissileTurret_red = createDogeiscutMissileTurret('red') +Class.dogeiscutMissile_red = createDogeiscutMissile('red') +Class.dogeiscutMissileTurret_orange = createDogeiscutMissileTurret('orange') +Class.dogeiscutMissile_orange = createDogeiscutMissile('orange') +Class.dogeiscutMissileTurret_yellow = createDogeiscutMissileTurret('yellow') +Class.dogeiscutMissile_yellow = createDogeiscutMissile('yellow') +Class.dogeiscutMissileTurret_green = createDogeiscutMissileTurret('green') +Class.dogeiscutMissile_green = createDogeiscutMissile('green') +Class.dogeiscutMissileTurret_cyan = createDogeiscutMissileTurret('cyan') +Class.dogeiscutMissile_cyan = createDogeiscutMissile('cyan') +Class.dogeiscutMissileTurret_blue = createDogeiscutMissileTurret('blue') +Class.dogeiscutMissile_blue = createDogeiscutMissile('blue') +Class.dogeiscutMissileTurret_purple = createDogeiscutMissileTurret('purple') +Class.dogeiscutMissile_purple = createDogeiscutMissile('purple') +Class.dogeiscutBomb = { + PARENT: "trap", + LABEL: "Bomb", + SHAPE: 0, + GUNS: [...Array(32).fill().map((_, i)=>({ + POSITION: [0, 8, 0, 0, 0, ((360) / 32)*i, 9999], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.shotgun, g.noSpread, { recoil: 0, range: 0.4, damage: 2.5, size: 0.5}]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + }, + })),...Array(10).fill().map((_,i)=>({ + POSITION: [12, 3.5, 1, 0, 0, (360/10)*i, (i%3)/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ + g.basic, + g.twin, + g.gunner, + g.cyclone, + {reload: 3} + ]), + TYPE: "bullet", + AUTOFIRE: true, + }, + })) + ], + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: ["genericTank", {COLOR: "grey"}], + } + ] + } +Class.dogeiscutBoss = { + PARENT: "miniboss", + LABEL: "DOG", + NAME: "DogeisCut", + DANGER: 10, + FACING_TYPE: "smoothToTarget", + SHAPE: [[1,0],[-0.7,0.7],[-0.35,0],[-0.7,-0.7]], + COLOR: "yellow", + UPGRADE_COLOR: "yellow", + SIZE: 50, + VALUE: 5e6, + BODY: { + FOV: 0.75, + SPEED: 0.25 * base.SPEED, + HEALTH: 14 * base.HEALTH, + DAMAGE: 4 * base.DAMAGE, + }, + GUNS: [ { + POSITION: [ 6, 8, 1.5, 3, 0, 180, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, {size: 1, reload: 3, recoil: 5}]), + TYPE: ["dogeiscutBomb"], + STAT_CALCULATOR: gunCalcNames.sustained, + } + }, { + POSITION: [ 4, 4, 1.5, 3, 0, 180, 0, ], + PROPERTIES: { + COLOR: "black" + } + }, + + { + POSITION: [ 1, 2, 1, 4, -8, 68, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_red"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'red' + } + }, { + POSITION: [ 1, 2, 1, 4, -5.333, 68, 1/7, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_orange"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'orange' + } + }, { + POSITION: [ 1, 2, 1, 4, -2.666, 68, (1/7)*2, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_yellow"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'yellow' + } + }, { + POSITION: [ 1, 2, 1, 4, 0, 68, (1/7)*3, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_green"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'green' + } + }, { + POSITION: [ 1, 2, 1, 4, 2.666, 68, (1/7)*4, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_cyan"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'cyan' + } + }, { + POSITION: [ 1, 2, 1, 4, 5.333, 68, (1/7)*5, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_blue"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'blue' + } + }, { + POSITION: [ 1, 2, 1, 4, 8, 68, (1/7)*6, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_purple"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'purple' + } + }, + + + { + POSITION: [ 1, 2, 1, 4, 8, -68, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_red"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'red' + } + }, { + POSITION: [ 1, 2, 1, 4, 5.333, -68, 1/7, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_orange"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'orange' + } + }, { + POSITION: [ 1, 2, 1, 4, 2.666, -68, (1/7)*2, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_yellow"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'yellow' + } + }, { + POSITION: [ 1, 2, 1, 4, 0, -68, (1/7)*3, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_green"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'green' + } + }, { + POSITION: [ 1, 2, 1, 4, -2.666, -68, (1/7)*4, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_cyan"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'cyan' + } + }, { + POSITION: [ 1, 2, 1, 4, -5.333, -68, (1/7)*5, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_blue"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'blue' + } + }, { + POSITION: [ 1, 2, 1, 4, -8, -68, (1/7)*6, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.hunter, g.sidewinder, {speed: 3, range: 0.8, reload: 4}]), + TYPE: ["dogeiscutMissile_purple"], + STAT_CALCULATOR: gunCalcNames.sustained, + COLOR: 'purple' + } + }, + ], + TURRETS: [ + { + POSITION: [16, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "#f6c6a2"}], + }, + { + POSITION: [12, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutBody", { MIRROR_MASTER_ANGLE: true, COLOR: "pink"}], + }, + { + POSITION: [5, 0, 0, 0, 360, 1], + TYPE: ["dogeiscutTurret", { INDEPENDENT: true, CONTROLLERS: ["nearestDifferentMaster"], COLOR: "yellow" }], + }, + { + POSITION: [1, 10.5, 0, 0, 360, 0], + TYPE: ["genericTank", {COLOR: "black"}], + }, + ] +} +Class.trplnrBossAuraBulletAura = addAura(1, 0.8) +Class.trplnrBossAuraBullet = { + PARENT: 'genericTank', + LABEL: 'Nest', + SHAPE: -4, + PERSISTS_AFTER_DEATH: true, + BODY: { + HEALTH: 100, + }, + SIZE: 25, + COLOR: '#F49EFF', + GLOW: { + STRENGTH: 25, + COLOR: 'mirror', + ALPHA: 1 + }, + DRAW_HEALTH: true, + GUNS: weaponArray({ + POSITION: { ASPECT: -0.35, X: -5 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, { size: 0.8 }, {reload: 1.6, damage: 1.5}]), + TYPE: 'autoswarm', + AUTOFIRE: true, + }, + }, 4), + TURRETS: [ + { + POSITION: {SIZE: 10, LAYER: 1}, + TYPE: "trplnrBossAuraBulletAura" + } + ] +} +const trplnrBossDecor = { + COLOR: '#F49EFF', + UPGRADE_COLOR: "lavender", + LABEL: 'Lavender', + NAME: 'Trioplane', + SHAPE: 3, + SIZE: 25, + VALUE: 5e7, + DANGER: 10, + GLOW: { + RADIUS: 15, + COLOR: 'mirror', + ALPHA: 1, + RECURSION: 5 + }, + PROPS: [{ + POSITION: { SIZE: 25 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, + TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] + }, { + POSITION: { SIZE: 25 ** Math.SQRT1_2, LAYER: 1 }, + TYPE: ['triangle', { COLOR: -1, MIRROR_MASTER_ANGLE: true }] + }, { + POSITION: { SIZE: 25 }, + TYPE: ['triangle', { COLOR: 'black', MIRROR_MASTER_ANGLE: true }] + }], +} +Class.trplnrBoss = { + PARENT: "miniboss", + ...trplnrBossDecor, + UPGRADE_TOOLTIP: "\"Heck, even The Guardians are afraid of him, \n" + + "They usually call him the The Light, Victory, Death and Ruler of the Pentagon Race a.k.a Lvndr. \n" + + "We don't know where his teleportation powers came from, \n" + + "He was secretive of it. \n" + + "Though some say there was an old script found at the Neutrality Point \n" + + "at the middle of the nest when it still existed, It had some \n" + + "sort of drawing of a tank going through walls, and this thing that said '6@D M0|)3 \n" + + "Nest Reseachers still haven't been able to decipher it though. \n" + + "One day, The Neutrality Point left and on that same day, \n" + + "A sentry's child went missing, \n" + + "Coincidence? I think not.\"", + BODY: { + HEALTH: 500, + }, + ON: [ + { + event: 'fire', + handler: ({ body, gun }) => { + if (gun.identifier != 'onHandler') return + const messages = [ + 'Attack my little swarms!', + 'Deploying, Attack swarms', + 'You really think you can defeat me? Heres a little challenge for you.', + 'This thing is really gonna annoy you HAHA!', + 'I don\'t know what to say uhhh, die i guess.' + ] + sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) + sockets.broadcast('Lavender will turn into `BULL3T HELL F0rM`, Run!') + for (let i = 0; i < 24; i++) { + i < 12 ? + setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) + : + setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) + } + setTimeout(() => { + let range = 500 + let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + body.x += whereToGoX + body.y += whereToGoY + }, 12 * 50); + setTimeout(() => body.define('trplnrBossBulletHellForm'), 24 * 50) + } + } + ], + GUNS: [], + GUNS: (() => { + let output = [] + for (let i = 0; i<2; i++) { + output.push({ + POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), + TYPE: "trplnrBossAuraBullet", + INDEPENDENT_CHILDREN: true, + } + }) + } + output.push({ + POSITION: { WIDTH: 10, X: -5, ASPECT: -0.7, ANGLE: ((360 / 3) * 2) - 180 }, + PROPERTIES: { + COLOR: 'white', + SHOOT_SETTINGS: combineStats([g.basic, {reload: 100}]), + TYPE: "trplnrBossAuraBullet", + INDEPENDENT_CHILDREN: true, + IDENTIFIER: 'onHandler', + ALPHA: 0, + } + }) + for (let i = 0; i < 3; i++) { + output.push({ + POSITION: { WIDTH: 5, ASPECT: -0.7, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'black' + } + }) + output.push({ + POSITION: { WIDTH: 5, HEIGHT: 5, X: -30, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'black' + } + }, { + POSITION: { WIDTH: 5, HEIGHT: 5, X: -25, ASPECT: 0, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'white' + } + }) + } + return output + })() +} + +Class.trplnrBossBulletHellFormPentagonsAuraBullet = { + PARENT: 'bullet', + PERSISTS_AFTER_DEATH: true, + TURRETS: [{ + POSITION: {SIZE: 13, LAYER: 1}, + TYPE: "trplnrBossAuraBulletAura" + }] +} + +Class.trplnrBossBulletHellFormPentagons = { + PARENT: 'bullet', + LABEL: 'Pentagon', + SHAPE: -5, + PROPS: [{ + POSITION: { SIZE: 40 ** Math.SQRT1_2, ANGLE: 180, LAYER: 1 }, + TYPE: ['pentagon', {COLOR: 'black', MIRROR_MASTER_ANGLE: true}] + }], + GUNS: weaponArray({ + POSITION: { WIDTH: 10, HEIGHT: 10, ANGLE: 180, DELAY: 11.5 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, {reload: 0.4}]), + TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', + AUTOFIRE: true, + COLOR: 'white', + } + }, 5) +} +Class.trplnrBossBulletHellForm = { + PARENT: "miniboss", + ...trplnrBossDecor, + LABEL: 'Lavender - Bullet Hell Form', + BODY: { + HEALTH: 500, + }, + ON: [ + { + event: "fire", + handler: ({ body, masterStore, gun }) => { + if (gun.identifier != 'onHandler') return + masterStore.shotsFired ??= 0 + masterStore.shotsFired++ + + for (let i = 0; i < 24; i++) { + i < 12 ? + setTimeout(() => { body.SIZE /= 1.1; body.alpha /= 1.2 }, i * 50) + : + setTimeout(() => { body.SIZE *= 1.1; body.alpha *= 1.2 }, i * 50) + } + setTimeout(() => { + let range = 500 + let whereToGoX = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + let whereToGoY = Math.random() > 0.5 ? Math.floor(Math.random() * -range) : Math.floor(Math.random() * range) + body.x += whereToGoX + body.y += whereToGoY + }, 12 * 50) + + if (masterStore.shotsFired > 5) { + body.define('trplnrBossVulnerableForm') + const messages = [ + 'I\'m a little tired right now', + 'Ouch my leg!', + 'i sleep', + 'Bruh my keyboard isn\'t working', + 'Omg bruh I chose the wrong form' + ] + sockets.broadcast(messages[Math.floor(Math.random() * messages.length)]) + sockets.broadcast('Lavender is in its `VULN3RABLE F0RM`, Attack!') + } + } + } + ], + GUNS: (() => { + let output = [] + for (let i = 0; i<3; i++) { + output.push({ + POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -25 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 1 }]), + TYPE: 'trplnrBossBulletHellFormPentagonsAuraBullet', + COLOR: 'black' + } + }, { + POSITION: { WIDTH: 15, HEIGHT: 5, ANGLE: ((360 / 3) * i)-180, ASPECT: 0, X: -20 }, + PROPERTIES: { + COLOR: 'white' + } + }, { + POSITION: { WIDTH: 10, HEIGHT: 5, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 3 }]), + TYPE: 'trplnrBossBulletHellFormPentagons', + COLOR: 'white' + } + }, { + POSITION: { WIDTH: 8, HEIGHT: 3, X: -1, ASPECT: 1.5, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: 'pureWhite', + } + }, { + POSITION: { WIDTH: 5, HEIGHT: 10, X: 5, ASPECT: 0.2, ANGLE: ((360 / 3) * i) - 180 }, + PROPERTIES: { + COLOR: -1, + } + }) + } + output.push({ + POSITION: { WIDTH: 0, HEIGHT: 0 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer, g.annihilator, { reload: 2 }, g.fake]), + TYPE: 'bullet', + IDENTIFIER: 'onHandler', + ALPHA: 0 + } + }) + return output + })() +} +Class.trplnrBossVulnerableForm = { + PARENT: "miniboss", + ...trplnrBossDecor, + LABEL: 'Lavender - Vulnerable Form', + BODY: { + HEALTH: 500, + SPEED: 0.1 + }, + ON: [ + { + event: "tick", + handler: ({ body }) => { + body.store.ticks ??= 0 + body.store.ticks++ + const spawnCrashers = body.store.ticks % 3 == 0 + const spawnSentries = body.store.ticks % 60 == 0 + const sentries = ["sentrySwarm", "sentryGun", "sentryTrap"] + if (spawnCrashers) new Entity(body, body).define("crasher") + if (spawnSentries) new Entity(body, body).define(sentries[Math.floor(Math.random() * sentries.length)]) + } + }, + { + event: "fire", + handler: ({ body, gun }) => { + if (gun.identifier != 'onHandler') return + setTimeout(() => { + body.define('trplnrBoss') + sockets.broadcast('im awake') + }, 15000) + setTimeout(() => sockets.broadcast('Lavender will activate in 10 seconds and turn into S4nctuary F0rM'), 5000) + } + } + ], + GUNS: [{ + POSITION: {LENGTH: 0, WIDTH: 0}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, {reload: 500}]), + TYPE: 'bullet', + AUTOFIRE: true, + IDENTIFIER: 'onHandler', + ALPHA: 0 + } + }] +} + +Class.frostAuraSmall = { + PARENT: "aura", + LAYER: 30, + FACING_TYPE: ["spin", {speed: -0.04}], + BORDERLESS: true, + SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraSmallOutline' + }] +} +Class.frostAuraSmallOutline = { + PARENT: "aura", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.715 0.519 L 0.309 0.951 L -0.273 0.84 L -0.809 0.588 L -0.883 0 L -0.809 -0.588 L -0.273 -0.84 L 0.309 -0.951 L 0.715 -0.519 L 1 0" + + "L 0.309 0.951 L -0.809 0.588 L -0.809 -0.588 L 0.309 -0.951 L 1 0" + + "L 0 0 L 0.309 0.951 M 0 0 L -0.809 0.588 M 0 0 L -0.809 -0.588 M 0 0 L 0.309 -0.951", +} +Class.frostAuraLarge = { + PARENT: "aura", + LAYER: 30, + FACING_TYPE: ["spin", {speed: -0.04}], + BORDERLESS: true, + SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraLargeOutline' + }] +} +Class.frostAuraLargeOutline = { + PARENT: "aura", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.988 0.156 L 0.951 0.309 L 0.891 0.454 L 0.809 0.588 L 0.707 0.707 L 0.588 0.809 L 0.454 0.891 L 0.309 0.951 L 0.156 0.988 L 0 1 L -0.156 0.988 L -0.309 0.951 L -0.454 0.891 L -0.588 0.809 L -0.707 0.707 L -0.809 0.588 L -0.891 0.454 L -0.951 0.309 L -0.988 0.156 L -1 0 L -0.988 -0.156 L -0.951 -0.309 L -0.891 -0.454 L -0.809 -0.588 L -0.707 -0.707 L -0.588 -0.809 L -0.454 -0.891 L -0.309 -0.951 L -0.156 -0.988 L 0 -1 L 0.156 -0.988 L 0.309 -0.951 L 0.454 -0.891 L 0.588 -0.809 L 0.707 -0.707 L 0.809 -0.588 L 0.891 -0.454 L 0.951 -0.309 L 0.988 -0.156 L 1 0" + + "M 0.988 -0.156 L 0.988 0.156 L 0.891 0.454 L 0.707 0.707 L 0.454 0.891 L 0.156 0.988 L -0.156 0.988 L -0.454 0.891 L -0.707 0.707 L -0.891 0.454 L -0.988 0.156 L -0.988 -0.156 L -0.891 -0.454 L -0.707 -0.707 L -0.454 -0.891 L -0.156 -0.988 L 0.156 -0.988 L 0.454 -0.891 L 0.707 -0.707 L 0.891 -0.454 L 0.988 -0.156 L 0.949 0" + + "L 0.988 0.156 L 0.891 0.256 L 0.891 0.454 L 0.739 0.537 L 0.707 0.707 L 0.519 0.769 L 0.454 0.891 L 0.293 0.902 L 0.156 0.988 L 0.032 0.927 L -0.156 0.988 L -0.282 0.869 L -0.454 0.891 L -0.571 0.731 L -0.707 0.707 L -0.768 0.558 L -0.891 0.454 L -0.871 0.317 L -0.988 0.156 L -0.914 0 L -0.988 -0.156 L -0.871 -0.317 L -0.891 -0.454 L -0.768 -0.558 L -0.707 -0.707 L -0.571 -0.731 L -0.454 -0.891 L -0.282 -0.869 L -0.156 -0.988 L 0.032 -0.927 L 0.156 -0.988 L 0.293 -0.902 L 0.454 -0.891 L 0.519 -0.769 L 0.707 -0.707 L 0.739 -0.537 L 0.891 -0.454 L 0.891 -0.256 L 0.988 -0.156 L 0.949 0" + + "L 0.891 0.256 L 0.739 0.537 L 0.519 0.769 L 0.293 0.902 L 0.032 0.927 L -0.282 0.869 L -0.571 0.731 L -0.768 0.558 L -0.871 0.317 L -0.914 0 L -0.871 -0.317 L -0.768 -0.558 L -0.571 -0.731 L -0.282 -0.869 L 0.032 -0.927 L 0.293 -0.902 L 0.519 -0.769 L 0.739 -0.537 L 0.891 -0.256 L 0.949 0" + + "M 0.834 0 L 0.891 0.256 L 0.704 0.291 L 0.739 0.537 L 0.495 0.579 L 0.519 0.769 L 0.258 0.793 L 0.032 0.927 L -0.06 0.759 L -0.282 0.869 L -0.398 0.649 L -0.571 0.731 L -0.674 0.49 L -0.871 0.317 L -0.741 0.178 L -0.914 0 L -0.741 -0.178 L -0.871 -0.317 L -0.674 -0.49 L -0.571 -0.731 L -0.398 -0.649 L -0.282 -0.869 L -0.06 -0.759 L 0.032 -0.927 L 0.258 -0.793 L 0.519 -0.769 L 0.495 -0.579 L 0.739 -0.537 L 0.704 -0.291 L 0.891 -0.256 L 0.834 0" + + "L 0.704 0.291 L 0.495 0.579 L 0.258 0.793 L -0.06 0.759 L -0.398 0.649 L -0.674 0.49 L -0.741 0.178 L -0.741 -0.178 L -0.674 -0.49 L -0.398 -0.649 L -0.06 -0.759 L 0.258 -0.793 L 0.495 -0.579 L 0.704 -0.291 L 0.834 0" + + "M 0.592 0 L 0.704 0.291 L 0.413 0.3 L 0.495 0.579 L 0.183 0.563 L -0.06 0.759 L -0.158 0.485 L -0.398 0.649 L -0.479 0.348 L -0.741 0.178 L -0.51 0 L -0.741 -0.178 L -0.479 -0.348 L -0.398 -0.649 L -0.158 -0.485 L -0.06 -0.759 L 0.183 -0.563 L 0.495 -0.579 L 0.413 -0.3 L 0.704 -0.291 L 0.592 0" + + "L 0.413 0.3 L 0.183 0.563 L -0.158 0.485 L -0.479 0.348 L -0.51 0 L -0.479 -0.348 L -0.158 -0.485 L 0.183 -0.563 L 0.413 -0.3 L 0.592 0" + + "M 0.292 0 L 0.413 0.3 L 0.09 0.277 L -0.158 0.485 L -0.236 0.171 L -0.51 0 L -0.236 -0.171 L -0.158 -0.485 L 0.09 -0.277 L 0.413 -0.3 L 0.292 0 L 0.09 0.277" + + "L -0.236 0.171 L -0.236 -0.171 L 0.09 -0.277 L 0.292 0 M 0 0 L 0.949 0" + + "M 0 0 L 0.293 0.902 M 0 0 L -0.768 0.558 M 0 0 L -0.768 -0.558 M 0 0 L 0.293 -0.902", +} +Class.frostAuraSymbol = { + PARENT: "genericTank", + CONTROLLERS: [["spin", { speed: -0.04 }]], + INDEPENDENT: true, + BORDERLESS: true, + COLOR: 'teal', + SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z", + TURRETS: [{ + POSITION: [20, 0, 0, 0, 0, 1], + TYPE: 'frostAuraSymbolOutline' + }] +} +Class.frostAuraSymbolOutline = { + PARENT: "genericTank", + MIRROR_MASTER_ANGLE: true, + DRAW_FILL: false, + SHAPE: "M 1 0 L 0.797 0.46 L 0.5 0.866 L 0 0.92 L -0.5 0.866 L -0.797 0.46 L -1 0 L -0.797 -0.46 L -0.5 -0.866 L 0 -0.92 L 0.5 -0.866 L 0.797 -0.46 L 1 0 Z" + + "M 0.52 0.3 L 0.52 -0.3 L 0.797 -0.46 M 0.52 -0.3 L 0 -0.6 L 0 -0.92 M 0 -0.6 L -0.52 -0.3 L -0.797 -0.46 M -0.52 -0.3 L -0.52 0.3 L -0.797 0.46 M -0.52 0.3 L 0 0.6 L 0 0.92 M 0 0.6 L 0.52 0.3 L 0.797 0.46" +} + +function addIcosphereAura(damageFactor = 1, sizeFactor = 1, opacity = 0.3, auraSize = "Medium") { + let auraType = "frostAura" + auraSize; + return { + PARENT: "genericTank", + INDEPENDENT: true, + LABEL: "", + COLOR: 17, + GUNS: [ + { + POSITION: [0, 20, 1, 0, 0, 0, 0,], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.aura, { size: sizeFactor, damage: damageFactor }]), + TYPE: [auraType, {ALPHA: opacity}], + MAX_CHILDREN: 1, + AUTOFIRE: true, + SYNCS_SKILLS: true, + }, + }, + ], + TURRETS: [ + { + POSITION: [20, 0, 0, 0, 360, 1], + TYPE: "frostAuraSymbol" + }, + ] + }; +} +Class.frostAuraBlockTop = { + SHAPE: "M -1.3 -0.15 L -1.3 0.15 L -0.3 0.3 L -0.15 1.3 L 0.15 1.3 L 0.3 0.3 L 1.3 0.15 L 1.3 -0.15 L 0.3 -0.3 L 0.15 -1.3 L -0.15 -1.3 L -0.3 -0.3 Z", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 5 }, + MIRROR_MASTER_ANGLE: true, +} +Class.frostAuraBlockTurret = { + PARENT: "genericTank", + INDEPENDENT: true, + COLOR: 17, + CONTROLLERS: ["nearestDifferentMaster"], + LABEL: "", + BODY: { + FOV: 2, + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [18, 15, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} + }, + }, { + POSITION: [23, 11, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, {density: 0.2}]), + TYPE: "bullet", + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [15, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minionGun, g.turret, g.power, g.autoTurret, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ], +} +Class.frostAuraBlockAura = addIcosphereAura(0.25, 1.6, 0.15, "Small"); +Class.frostAuraBlock = { + PARENT: 'unsetTrap', + TURRETS: [ + { + POSITION: [20, 0, 0, 45, 0, 1], + TYPE: 'frostAuraBlockTop' + }, { + POSITION: [11, 0, 0, 0, 360, 1], + TYPE: 'frostAuraBlockTurret' + }, { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: 'frostAuraBlockAura' + } + ] +} +Class.frostBossBigAura = addIcosphereAura(1.5, 1.45, 0.3, "Large"); + +Class.frostBossAutoTurret = { + PARENT: "autoTankGun", + INDEPENDENT: true, + COLOR: 17, + GUNS: [ + { + POSITION: [17, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: -7.5} + }, + }, { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}]), + TYPE: "bullet", + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -10, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [14, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, {recoil: 0.1}, g.fake]), + TYPE: "bullet", + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ], + TURRETS: [ + { + POSITION: [13, 0, 0, 0, 0, 1], + TYPE: ["egg", {COLOR: -1, BORDERLESS: true}], + }, + ], +} + +Class.frostBossBaseDeco = { + SHAPE: "M -1.1 0 L -0.956 0.292 L -0.669 0.205 L -0.669 -0.205 L -0.956 -0.292 Z" + + "M -0.55 0.952 L -0.225 0.974 L -0.157 0.682 L -0.512 0.477 L -0.731 0.682 Z" + + "M -0.55 -0.952 L -0.225 -0.974 L -0.157 -0.682 L -0.512 -0.477 L -0.731 -0.682 Z" + + "M 0.55 0.952 L 0.225 0.974 L 0.157 0.682 L 0.512 0.477 L 0.731 0.682 Z" + + "M 0.55 -0.952 L 0.225 -0.974 L 0.157 -0.682 L 0.512 -0.477 L 0.731 -0.682 Z" + + "M 1.1 0 L 0.956 0.292 L 0.669 0.205 L 0.669 -0.205 L 0.956 -0.292 Z", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, + MIRROR_MASTER_ANGLE: true, + GUNS: weaponArray([ + { + POSITION: [1.75, 3, -0.75, 7.5, 0, 0, 0], + PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 2.5, SATURATION_SHIFT: 0.9 }, DRAW_ABOVE: true }, + }, { + POSITION: [1, 9, 0, 8.5, 0, 30, 0], + PROPERTIES: { COLOR: { BASE: -1, BRIGHTNESS_SHIFT: 10, SATURATION_SHIFT: 1.15 } }, + }, + ], 6) +} +Class.frostBossBaseDeco2 = { + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 7.5}, + GUNS: weaponArray([ + { + POSITION: [5, 10, 0.001, 9.5, 0, 0, 0], + PROPERTIES: {COLOR: {BASE: 9, BRIGHTNESS_SHIFT: 10}}, + }, { + POSITION: [1.6, 9, 0, 8.4, 0, 0, 0], + PROPERTIES: {COLOR: {BASE: 9, BRIGHTNESS_SHIFT: 10}, DRAW_ABOVE: true}, + }, + ], 6), +} + +const trebuchetStats = [g.basic, g.sniper, g.predator, g.predator, g.predator, g.predator, {speed: 0.93, maxSpeed: 0.93, reload: 2, health: 1.7, damage: 1.4, size: 2}]; +const hielamanStats = [g.trap, g.setTrap, g.hexaTrapper, {reload: 2.85, health: 3.2, range: 1.2}]; +Class.frostBoss = { + PARENT: 'miniboss', + LABEL: 'Extrasolar', + NAME: 'Frostbyte', + CONTROLLERS: [["minion", {orbit: 260, leash: 190, repel: 270}]], + FACING_TYPE: 'toTarget', + SHAPE: 6, + COLOR: "aqua", + UPGRADE_COLOR: "aqua", + SIZE: 31, + DANGER: 12, + VALUE: 888888, + UPGRADE_TOOLTIP: "\"When the golden rays of sun shine through this world's\n" + + "darkened skies and looming clouds, the legend of the warrior\n" + + "and his eternal blade will finally come to fruition.\"", + BODY: { + SPEED: base.SPEED * 0.6, + HEALTH: base.HEALTH * 11, + SHIELD: base.SHIELD * 7, + REGEN: base.REGEN * 2.5, + FOV: base.FOV * 1.4, + RESIST: base.RESIST * 1.2, + DENSITY: base.DENSITY * 7.5, + }, + GUNS: [ + ...weaponArray({ + // Speed + POSITION: [8, 14.5, 0.001, 9.5, 0, 0, 0], + PROPERTIES: {COLOR: 9}, + }, 6), + ...weaponArray([ + { // Heavy Snipers + POSITION: [26.5, 9.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats(trebuchetStats), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6 }, + }, + }, { + POSITION: [24, 6.65, -1.3, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, + BORDERLESS: true + }, + }, { + POSITION: [4.25, 9.5, -0.5, 1.425, -8.5, 90, 0], + PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 } }, + }, { + POSITION: [4.25, 9.5, -0.5, 1.425, 8.5, -90, 0], + PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 } }, + }, { + POSITION: [4.25, 6.65, -0.35, 0.67, -8.5, 90, 0], + PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 7.5 }, BORDERLESS: true }, + }, { + POSITION: [4.25, 6.65, -0.35, 0.67, 8.5, -90, 0], + PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 7.5 }, BORDERLESS: true }, + }, { + POSITION: [19.5, 3.8, -1.4, 0, 0, 0, 0], + PROPERTIES: { COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 10 } }, + }, { + POSITION: [4, 11.5, 1, 19.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.6 }, + }, + }, { + POSITION: [2, 12, 1, 20.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...trebuchetStats, g.fake]), + TYPE: "bullet", + COLOR: { BASE: 17, BRIGHTNESS_SHIFT: 2.5 }, + }, + }, + { // Aura Blocks + POSITION: [15, 8.5, 1, 0, 0, 60, 0], + PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6}} + }, { + POSITION: [4, 7, -1.6, 9, 0, 60, 0], + PROPERTIES: {COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 5}} + }, { + POSITION: [3, 6, -1.55, 9, 0, 60, 0], + PROPERTIES: {COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 12.5}, BORDERLESS: true} + }, { + POSITION: [15, 5.4, -0.1, 0, 0, 60, 0], + PROPERTIES: {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -5, SATURATION_SHIFT: 0.75}} + }, { + POSITION: [3, 8.5, 1.6, 15, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats(hielamanStats), + TYPE: 'frostAuraBlock', + STAT_CALCULATOR: gunCalcNames.trap, + COLOR: {BASE: -1, BRIGHTNESS_SHIFT: -15, SATURATION_SHIFT: 0.6} + }, + }, { + POSITION: [2, 6, 1.6, 16, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([...hielamanStats, g.fake]), + TYPE: 'bullet', + COLOR: {BASE: 17, BRIGHTNESS_SHIFT: 7.5} + }, + }, + ], 3), + ], + TURRETS: [ + ...weaponArray({ + POSITION: [2.95, 8.55, 0, 30, 180, 2], + TYPE: "frostBossAutoTurret", + }, 6), + { + POSITION: [8.55, 0, 0, 0, 360, 2], + TYPE: "frostBossBigAura", + }, + ], + PROPS: [ + { + POSITION: [12, 0, 0, 180, 1], + TYPE: ["hexagon", {COLOR: {BASE: -1, BRIGHTNESS_SHIFT: 7.5}}], + }, { + POSITION: [12, 0, 0, 0, 1], + TYPE: "frostBossBaseDeco2" + }, { + POSITION: [20, 0, 0, 0, 1], + TYPE: "frostBossBaseDeco", + } + ] +} + +const divide = 1000; +const arraySize = 10; +const colorArray = []; +const damageMultiplayer = 3.5; +const reloadMultiplayer = 2; +for (let i = 0; i < arraySize; i++) { + const rgb = Math.round(255 * i / (arraySize - 1)); + colorArray.push('#' + ((1 << 24) + (rgb << 16) + (rgb << 8) + rgb).toString(16).slice(1)); +} +class io_nearestDifferentMaster2 extends ioTypes.nearestDifferentMaster { + constructor(body, opts = {}) { + super(body); + this.lookAtDanger = opts.lookAtDanger ?? true; + this.firingAtMe = opts.firingAtMe ?? false; + this.timeout = opts.timeout || 90; + } + buildList(range) { + // Establish whom we judge in reference to + let mostDangerous = 0, + keepTarget = false; + // Filter through everybody... + let out = entities.filter(e => + // Only look at those within our view, and our parent's view, not dead, not invisible, not our kind, not a bullet/trap/block etc + this.validate(e, this.body, this.body.master.master, range * range, range * range * 4 / 3) + ).filter((e) => { + // Only look at those within range and arc (more expensive, so we only do it on the few) + if (this.body.firingArc == null || this.body.aiSettings.view360 || Math.abs(util.angleDifference(util.getDirection(this.body, e), this.body.firingArc[0])) < this.body.firingArc[1]) { + mostDangerous = Math.max(e.dangerValue, mostDangerous); + return true; + } + }).filter((e) => { + // Even more expensive + return !this.wouldHitWall(this.body, e); + }).filter((e) => { + // Only return the highest tier of danger + if (!this.lookAtDanger) return true; + if (this.body.aiSettings.farm || e.dangerValue === mostDangerous) { + if (this.targetLock && e.id === this.targetLock.id) keepTarget = true; + return true; + } + }); + // Reset target if it's not in there + if (!keepTarget) this.targetLock = undefined; + return out; + } + think(input) { + // Override target lock upon other commands + if (input.main || input.alt || this.body.master.autoOverride) { + this.targetLock = undefined; + return {}; + } + // Otherwise, consider how fast we can either move to ram it or shoot at a potiential target. + let tracking = this.body.topSpeed, + damageRef = (this.body.bond == null) ? this.body : this.body.bond, + range = this.body.fov; + // Use whether we have functional guns to decide + for (let i = 0; i < this.body.guns.length; i++) { + if (this.body.guns[i].canShoot && !this.body.aiSettings.SKYNET) { + let v = this.body.guns[i].getTracking(); + if (v.speed == 0 || v.range == 0) continue; + tracking = v.speed; + range = Math.min(range, (v.speed || 1.5) * (v.range < (this.body.size * 2) ? this.body.fov : v.range)); + break; + } + } + if (!Number.isFinite(tracking)) { + tracking = this.body.topSpeed + .01; + } + if (!Number.isFinite(range)) { + range = 640 * this.body.FOV; + } + // Check if my target's alive + if (this.targetLock && ( + !this.validate(this.targetLock, this.body, this.body.master.master, range * range, range * range * 4 / 3) || + this.wouldHitWall(this.body, this.targetLock) // Very expensive + )) { + this.targetLock = undefined; + this.tick = 100; + } + // Think damn hard + if (this.tick++ > 15 * Config.runSpeed) { + this.tick = 0; + this.validTargets = this.buildList(range); + // Ditch our old target if it's invalid + if (this.targetLock && this.validTargets.indexOf(this.targetLock) === -1) { + this.targetLock = undefined; + } + // Lock new target if we still don't have one. + if (this.targetLock == null && this.validTargets.length) { + this.targetLock = (this.validTargets.length === 1) ? this.validTargets[0] : nearest(this.validTargets, { + x: this.body.x, + y: this.body.y + }); + this.tick = -this.timeout; + } + } + // Lock onto whoever's shooting me. + if (this.firingAtMe && damageRef.collisionArray.length && damageRef.health.display() < this.oldHealth) { + this.oldHealth = damageRef.health.display(); + if (this.validTargets.indexOf(damageRef.collisionArray[0]) === -1) { + let a = (damageRef.collisionArray[0].master.id === -1) + ? damageRef.collisionArray[0].source + : damageRef.collisionArray[0].master; + if ( + this.body.firingArc == null || + this.body.aiSettings.view360 || + Math.abs(util.angleDifference(util.getDirection(this.body, a), this.body.firingArc[0])) < this.body.firingArc[1] + ) { + this.targetLock = a; + this.tick = -(this.timeout * 5); + } + } + } + // Consider how fast it's moving and shoot at it + if (this.targetLock != null) { + let radial = this.targetLock.velocity; + let diff = { + x: this.targetLock.x - this.body.x, + y: this.targetLock.y - this.body.y, + } + /// Refresh lead time + if (this.tick % 4 === 0) { + this.lead = 0 + // Find lead time (or don't) + if (!this.body.aiSettings.chase) { + let toi = timeOfImpact(diff, radial, tracking) + this.lead = toi + } + } + if (!Number.isFinite(this.lead)) { + this.lead = 0; + } + if (!this.accountForMovement) this.lead = 0; + // And return our aim + return { + target: { + x: diff.x + this.lead * radial.x, + y: diff.y + this.lead * radial.y, + }, + fire: true, + main: true + }; + } + return {}; + } +} +ioTypes.nearestDifferentMaster2 = io_nearestDifferentMaster2; +Class.toothlessBase = { + PARENT: "genericTank", + LABEL: "NightFury", + UPGRADE_TOOLTIP: "A cute...", + GLOW: { + RADIUS: 2, + COLOR: 42, + ALPHA: 0.6, + RECURSION: 6, + }, + BODY: { + SPEED: 0.8 * base.SPEED, + FOV: 1.5 * base.FOV, + HEALTH: 6 * base.HEALTH, + DAMAGE: 2 * base.DAMAGE, + }, + LEVEL_CAP: 45, + EXTRA_SKILL: 78, // 120 - 42 + SHAPE: 3, + VALUE: 30e+3, + SIZE: 24, + COLOR: "purple", + SKILL_CAP: Array(10).fill(smshskl + 3), + LEVEL_SKILL_POINT_FUNCTION: level => { + if (level < 2) return 0; + if (level <= 40) return 1; + if (level <= 45 && level & 1 == 1) return 1; + return 0; + }, +} +Class.toothlessBossTurret = { + PARENT: "genericTank", + LABEL: "", + BODY: { + FOV: 3, + }, + CONTROLLERS: [ + "onlyAcceptInArc", + [ "nearestDifferentMaster2", { lookAtDanger: false, firingAtMe: true, timeout: 10 } ], + ], + COLOR: "grey", + GUNS: [ + { + POSITION: [32, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, { + pen: 0.8, + health: 0.6, + damage: 0.6, + recoil: 0, + }]), + TYPE: "bullet", + }, + }, + ], + ON: [{ + event: "fire", + handler: ({ body }) => { + const master = body.master; + body._damage ??= []; + body._reload ??= []; + + if (!body._loaded) { + let _temp = 0; + master._maxPower ??= 0; + + body.guns.forEach((gun, i) => { + body._damage[i] = gun.settings.damage; + body._reload[i] = gun.settings.reload; + + _temp += (body._damage[i] * 3) / body._damage[i]; + _temp += body._reload[i] / (body._reload[i] / 3); + _temp /= 2; + }); + + _temp /= body.guns.length; + + master._maxPower += (_temp - 1) * divide * 2; + if (master._maxPower > _temp) master._maxPower /= 2; + + body._loaded = true; + } + + if (master._mode) { + master._power -= 1; + if (master._power < 1) { + master._mode = 0; + master.color.base = 14; + } + } + + if (!master._oldPower) return; + const power = master._oldPower / (divide * 2) + 1; + + body.guns.forEach((gun, i) => { + let _1 = body._damage[i] * (master._mode ? power : 1); + let _2 = body._reload[i] / (master._mode ? power : 1); + let max_damage = body._damage[i] * damageMultiplayer; + let min_reload = body._reload[i] / reloadMultiplayer; + + gun.settings.damage = _1 > max_damage ? max_damage : _1; + gun.settings.reload = _2 < min_reload ? min_reload : _2; + }); + }, + }], +}; +Class.toothlessBossDeco = { + PARENT: "genericTank", + LABEL: "", + SHAPE: 3, + SIZE: 10, + ON: [{ + event: "tick", + handler: ({ body }) => { + const master = body.master; + if (master._maxPower) + body.color.base = colorArray[ + Math.floor(master._power / (master._maxPower / arraySize)) > arraySize - 1 + ? arraySize - 1 + : Math.floor(master._power / (master._maxPower / arraySize) + ) + ]; + }, + }], +}; +Class.toothlessBoss = { + PARENT: "toothlessBase", + UPGRADE_COLOR: "magenta", + TURRETS: [{ + POSITION: { SIZE: 15, LAYER: 1 }, + TYPE: ["toothlessBossDeco", { MIRROR_MASTER_ANGLE: true }], + }, { + POSITION: { SIZE: 23 }, + TYPE: ["triangle", { COLOR: "black", MIRROR_MASTER_ANGLE: true }], + }], + GUNS: [{ + POSITION: { LENGTH: 0, WIDTH: 0 }, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([ g.basic, { + range: 0.1, + speed: 0.1, + maxSpeed: 0.1, + recoil: 0, + }]), + TYPE: "bullet", + ALT_FIRE: true, + }, + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + if (!body._power || body._mode) return; + const power = Math.floor(body._power); + + if (power >= 1) { + body._oldPower = body._power; + body._mode = 1; + body.color.base = 5; + } + }, + }, { + event: "kill", + handler: ({ body, entity }) => { + body._power ??= 0; + body._mode ??= 0; + if (!body._mode) body._power += (entity.skill.score / divide) ** 0.8; + }, + }], +} +Class.toothlessBoss.TURRETS = Class.toothlessBoss.TURRETS.concat(weaponArray([{ + POSITION: [8, 6, -5.6, 180, 180, 0], + TYPE: "toothlessBossTurret", +}, { + POSITION: [8, 6, 5.6, 180, 180, 0], + TYPE: "toothlessBossTurret", +}], 3)); \ No newline at end of file diff --git a/server/modules/definitions/groups/dev.js b/server/modules/definitions/groups/dev.js index acae1892f..32a80ad0b 100644 --- a/server/modules/definitions/groups/dev.js +++ b/server/modules/definitions/groups/dev.js @@ -1,8 +1,8 @@ -const { combineStats, menu, addAura, makeDeco, LayeredBoss, newWeapon, weaponArray, makeRadialAuto } = require('../facilitators.js'); +const { combineStats, menu, addAura, makeAuto, makeDeco, LayeredBoss, newWeapon, weaponArray, makeRadialAuto, makeTurret } = require('../facilitators.js'); const { base, gunCalcNames, basePolygonDamage, basePolygonHealth, dfltskl, statnames } = require('../constants.js'); const g = require('../gunvals.js'); -require('./tanks.js'); require('./food.js'); +require('./tanks.js'); // Menus Class.developer = { @@ -276,7 +276,6 @@ for (let x = 0; x < tensorWidth; x++) { } } } - // Testing tanks Class.diamondShape = { PARENT: "basic", @@ -284,6 +283,12 @@ Class.diamondShape = { SHAPE: 4.5 }; +Class.rotatedTrap = { + PARENT: "basic", + LABEL: "Rotated Inverted Body", + SHAPE: -3.5 +}; + Class.mummyHat = { SHAPE: 4.5, COLOR: -1 @@ -331,6 +336,39 @@ Class.mummifier = { TYPE: ["mummyHat"] }] }; + +Class.colorMan = { + PARENT: "genericTank", + LABEL: "Testing Animated Colors", + SHAPE: 4, + COLOR: "rainbow", + TURRETS: [{ + POSITION: [20, -20, -20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedBlueRed" } + },{ + POSITION: [20, 0 , -20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedBlueGrey" } + },{ + POSITION: [20, 20, -20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedGreyBlue" } + },{ + POSITION: [20, -20, 0 , 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedRedGrey" } + },{ + POSITION: [20, 20, 0 , 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedGreyRed" } + },{ + POSITION: [20, 20, 20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedLesbian" } + },{ + POSITION: [20, 0 , 20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedTrans" } + },{ + POSITION: [20, 20, 20, 0, 0, 1], + TYPE: { SHAPE: 4, COLOR: "animatedBi" } + }] +}; + Class.miscTestHelper2 = { PARENT: "genericTank", LABEL: "Turret Reload 3", @@ -507,7 +545,7 @@ Class.alphaGunTest = { }] } -Class.radialAutoTest = makeRadialAuto("gunner", { +Class.radialAutoTest = makeRadialAuto("alphaGunTest", { count: 5, isTurret: false, extraStats: [{spray: 4, speed: 1.4, maxSpeed: 1.4, recoil: 0.2}], @@ -520,11 +558,20 @@ Class.radialAutoTest = makeRadialAuto("gunner", { rotation: 0.04, danger: 10, }) +Class.makeAutoTestTurret = makeTurret("ranger", {canRepel: true, limitFov: true, extraStats: {reload: 0.5}}); +Class.makeAutoTest = { + PARENT: 'genericTank', + LABEL: "Make Auto Test", + TURRETS: weaponArray({ + POSITION: [8, 10, 0, 0, 180, 0], + TYPE: 'makeAutoTestTurret' + }, 3) +} Class.imageShapeTest = { PARENT: 'genericTank', LABEL: "Image Shape Test", - SHAPE: 'round.png', + SHAPE: 'favicon.png', GUNS: [ { POSITION: [18, 8, 1, 0, 0, 0, 0], @@ -613,26 +660,16 @@ Class.onTest = { }] } -Class.auraBasicGen = addAura(); -Class.auraBasic = { - PARENT: "genericTank", - LABEL: "Aura Basic", - TURRETS: [ - { - POSITION: [14, 0, 0, 0, 0, 1], - TYPE: "auraBasicGen" - } - ], - GUNS: [ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), - TYPE: "bullet", - }, - }, - ], -}; +Class.turretStatScaleTest = { + PARENT: 'genericTank', + LABEL: 'Turret Stat Test', + TURRETS: Array(5).fill().map((_, i) => ({ + POSITION: [15, 0, -40 + 20 * i, 0, 360, 1], + TYPE: ['autoTankGun', {GUN_STAT_SCALE: {speed: 1 + i / 5, maxSpeed: 1 + i / 5, reload: 1 + i / 5, recoil: 0}}] + })) +} + +Class.auraBasicGen = addAura(5, 1.3); Class.auraHealerGen = addAura(-1); Class.auraHealer = { PARENT: "genericTank", @@ -845,6 +882,49 @@ Class.armyOfOne = { } ], }; +Class.godbasic = { + PARENT: "genericTank", + LABEL: "God Basic", + SKILL_CAP: [31, 31, 31, 31, 31, 31, 31, 31, 31, 31], + SKILL: [ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31 ], + BODY: { + ACCELERATION: base.ACCEL * 1, + SPEED: base.SPEED * 1, + HEALTH: base.HEALTH * 1, + DAMAGE: base.DAMAGE * 1, + PENETRATION: base.PENETRATION * 1, + SHIELD: base.SHIELD * 1, + REGEN: base.REGEN * 1, + FOV: base.FOV * 1, + DENSITY: base.DENSITY * 1, + PUSHABILITY: 1, + HETERO: 3, + }, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet", + COLOR: "grey", + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 0, + ALT_FIRE: false, + NEGATIVE_RECOIL: false, + }, + }, + ], +}; +Class.maximumOverdrive = { + PARENT: "overdrive", + LABEL: "Maximum Overdrive", + SKILL_CAP: Array(10).fill(255), + SKILL: Array(10).fill(255), +}; Class.weirdAutoBasic = { PARENT: "genericTank", LABEL: "Weirdly defined Auto-Basic", @@ -897,7 +977,6 @@ Class.bulletSpawnTest = { } ] } - Class.propTestProp = { PARENT: 'genericTank', SHAPE: 6, @@ -912,6 +991,7 @@ Class.propTestProp = { } ] } + Class.propTest = { PARENT: 'genericTank', LABEL: 'Deco Prop Test', @@ -938,17 +1018,17 @@ Class.weaponArrayTest = { { POSITION: [20, 8, 1, 0, 0, 25, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), + SHOOT_SETTINGS: combineStats([g.basic, {reload: 2}]), TYPE: 'bullet' } }, { - POSITION: [17, 8, 1, 0, 0, 25, 0.5], + POSITION: [17, 8, 1, 0, 0, 25, 0.1], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic]), + SHOOT_SETTINGS: combineStats([g.basic, {reload: 2}]), TYPE: 'bullet' } } - ], 5), + ], 5, 0.4, false), TURRETS: weaponArray( { POSITION: [7, 10, 0, -11, 180, 0], @@ -960,7 +1040,7 @@ Class.weaponArrayTest = { Class.levels = menu("Levels") Class.levels.UPGRADES_TIER_0 = [] for (let i = 0; i < 12; i++) { - let LEVEL = i * c.TIER_MULTIPLIER; + let LEVEL = i * Config.TIER_MULTIPLIER; Class["level" + LEVEL] = { PARENT: "levels", LEVEL, @@ -995,8 +1075,15 @@ Class['Team' + TEAM_ENEMIES] = { }; Class.teams.UPGRADES_TIER_0.push('Team' + TEAM_ROOM, 'Team' + TEAM_ENEMIES); -Class.testing = menu("Testing") - +Class.testing = menu("Beta Tanks") +Class.features = menu("Features") +Class.overpowered = menu("Dev Funny", "rainbow") +Class.overpowered.UPGRADE_COLOR = "rainbow" +Class.goofytanks = menu("Goofy Shit", "rainbow") +Class.goofytanks.UPGRADE_COLOR = "rainbow" +Class.overpowered.UPGRADE_TOOLTIP = "The Funny v2" +Class.goofytanks.UPGRADE_TOOLTIP = "The Funny v3" + Class.addons = menu("Addon Entities") Class.addons.UPGRADES_TIER_0 = [] @@ -1048,7 +1135,7 @@ Class.snakeOld = { } Class.sidewinderOld = { PARENT: "genericTank", - LABEL: "Sidewinder (old)", + LABEL: "Sidewinder (Legacy)", DANGER: 7, BODY: { SPEED: 0.8 * base.SPEED, @@ -1068,6 +1155,7 @@ Class.sidewinderOld = { }, ], } + Class.whirlwindDeco = makeDeco(6) Class.whirlwindDeco.CONTROLLERS = [["spin", { independent: true, speed: 0.128 }]] Class.whirlwind = { @@ -1104,6 +1192,7 @@ Class.whirlwind = { return output })() } + let testLayeredBoss = new LayeredBoss("testLayeredBoss", "Test Layered Boss", "terrestrial", 7, 3, "terrestrialTrapTurret", 5, 7, {SPEED: 10}); testLayeredBoss.addLayer({gun: { POSITION: [3.6, 7, -1.4, 8, 0, null, 0], @@ -1129,6 +1218,14 @@ Class.flailBallSpike = { Class.flailBall = { PARENT: "genericTank", COLOR: "grey", + TYPE: "flail", + BODY: { + DENSITY: 2 * base.DENSITY, + HEALTH: 10000, + SHIELD: 10000, + DAMAGE: 4.5, + REGEN: 10000 + }, HITS_OWN_TYPE: 'hard', INDEPENDENT: true, TURRETS: [{ @@ -1145,7 +1242,8 @@ Class.flailBolt1 = { }], TURRETS: [{ POSITION: [48, 56, 0, 0, 360, 1], - TYPE: "flailBall" + TYPE: "flailBall", + VULNERABLE: true }], }; Class.flailBolt2 = { @@ -1225,25 +1323,1324 @@ Class.tripleFlail = { }] } -Class.developer.UPGRADES_TIER_0 = ["tanks", "bosses", "spectator", "levels", "teams", "eggGenerator", "testing", "addons"] - Class.tanks.UPGRADES_TIER_0 = ["basic", "unavailable", "arenaCloser", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun"] - Class.unavailable.UPGRADES_TIER_0 = ["flail", "healer", "volute", "whirlwind"] - Class.flail.UPGRADES_TIER_2 = ["doubleFlail"] - Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] - Class.volute.UPGRADES_TIER_3 = ["sidewinderOld"] - Class.dominators.UPGRADES_TIER_0 = ["destroyerDominator", "gunnerDominator", "trapperDominator"] - Class.sanctuaries.UPGRADES_TIER_0 = ["sanctuaryTier1", "sanctuaryTier2", "sanctuaryTier3", "sanctuaryTier4", "sanctuaryTier5", "sanctuaryTier6"] +Class.Trapper_guy = { + PARENT: "trapper", + LABEL: "Trapper_guy", + UPGRADE_COLOR: "blue", + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/6fcc71bf-255f-4d26-b13e-e3f9f68fb77a.image.png?v=1705291478159", + GUNS: [ + { + POSITION: [15, 7, 1, 0, 0, 0, 0] + }, + { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + }, { + POSITION: [3, 7, 1.7, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.nomove, g.halfrange, { damage: 5, pen: 5 }]), + TYPE: "shockwave", + STAT_CALCULATOR: gunCalcNames.trap, + ALT_FIRE: true + } + } + ] +}; +Class.shockwave = { + PARENT: "bullet", + LABEL: "funy", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + MOTION_TYPE: "trappershockwave" +}; +Class.watergun = { + LABEL: 'Auto Turret', + SYNCS_SKILLS: true, + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png?v=1705294702951", + BODY: { + FOV: 1, + }, + COLOR: "blue", + CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], + GUNS: [{ + POSITION: [10, 8, 1, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.op, { damage: 5, pen: 5 }]), + TYPE: "bullet", + HAS_NO_RECOIL: true + } + } + ] +} +Class.watergundormant = { + LABEL: 'Auto Turret', + SYNCS_SKILLS: true, + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/e304fc26-480b-47b5-8270-949f7df44d92.image.png?v=1705294702951", + BODY: { + FOV: 1 + }, + COLOR: 16, + GUNS: [{ + POSITION: [13.5, 10, 1, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.fake]), + TYPE: "bullet" + } + } + ] +} +Class.waterpet = { + PARENT: "boomerang", + LABEL: "Base", + SHAPE: 0, + INDEPENDENT: true, + TURRETS: [{ + POSITION: [25, 0, 0, 180, 360, 1], + TYPE: "watergun", + }], +ON: [{ + event: "death", + handler: ({ body }) => { + if (!body.master.isDead) return + body.master.define(Class.watertank) + } + } + ] +}; +Class.watertank = { + PARENT: "triAngle", + LABEL: "Waduh", + DANGER: 6, + SYNC_TURRET_SKILLS: true, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, { + POSITION: [1, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.bitlessspeed, { damage: 5, pen: 5, health: 5 }]), + TYPE: "waterpet", + ALT_FIRE: true, + } + }], + TURRETS: [{ + POSITION: [17, 9.85, 0, 180, 360, 1], + TYPE: "watergundormant", + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + body.define(Class.watertankFire) + } + } + ] +}; +Class.watertankFire = { + PARENT: "genericTank", + LABEL: "Waduh", + DANGER: 6, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.triAngleFront, { recoil: 4 }]), + TYPE: "bullet", + LABEL: "Front", + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + ] +}; +Class.piszerbeam = { + PARENT: "genericTank", + LABEL: "Pissliner", + COLOR: "yellow", + TEAM: TEAM_ROOM, + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 0.6, + SPEED: base.SPEED * 0.85, + FOV: base.FOV * 3, + }, + GUNS: [ + { + POSITION: [25, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [23, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [21, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner]), + TYPE: "bullet", + }, + }, { + POSITION: [25, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + }, + }, + { + POSITION: [23, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + + }, + }, + { + POSITION: [21, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + + }, + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + + }, + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.streamliner, g.op, g.op]), + TYPE: "oplaser", + ALT_FIRE: true + + }, + }, + ], +}; +Class.oplaser = { + PARENT: "bullet", + SHAPE: -1, + MOTION_TYPE: "fuckingnuclearbomb", + BODY: { + PENETRATION: 10, + SPEED: 30, + RANGE: 155, + DENSITY: 1.25, + HEALTH: 999, + DAMAGE: 999, + PUSHABILITY: 0.3, + }, + BUFF_VS_FOOD: true, +} +Class.deltabaseBullet = { + PARENT: "boomerang", + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + CONTROLLERS: [["spin", { independent: true, speed: 0.1 }]], + INDEPENDENT: true, + COLOR: "rainbow", + BODY: { + COLOR: "rainbow" + }, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["deltagun", { COLOR: "rainbow" }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["deltagun", { COLOR: "rainbow" }] + }], +ON: [{ + event: "death", + handler: ({ body }) => { + if (!body.master.isDead) return + body.master.define(Class.baseThrowerDelta) + } + } + ] +}; +Class.deltagun = { + LABEL: 'Auto Turret', + SYNCS_SKILLS: true, + BODY: { + FOV: 1 + }, + COLOR: 16, + CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], + GUNS: [{ + POSITION: [13.5, 10, 1, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.halfreload, g.halfspeed, g.op, g.op, g.op]), + TYPE: "grenade", + HAS_NO_RECOIL: true + } + } + ] +} +Class.turretBaseDelta = { + LABEL: "Basethingygygyyasgsdgajskhg", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: "rainbow",//iT WonT FUckING SpIN + SYNC_TURRET_SKILLS: true, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["deltagun", { COLOR: "rainbow" }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["deltagun", { COLOR: "rainbow" }] + }] +}; +Class.deltaDeco = { + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/2024_01_15_05q_Kleki.png", +}; +Class.baseThrowerDelta = { + PARENT: "genericTank", + LABEL: "Delta", + DANGER: 6, + SYNC_TURRET_SKILLS: true, + GUNS: [ + { + POSITION: [26, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [23, 10, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.machineGun, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "bullet", + }, + }, { + POSITION: [1, 38, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.bitlessspeed, g.op, g.xxtrahealth]), + TYPE: ["deltabaseBullet", { COLOR: "rainbow" }], + ALT_FIRE: true, + ALPHA: 0, + HAS_NO_RECOIL: true, + } + }], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBaseDelta" + }, { + POSITION: [34, 0, 0, 0, 360, 3], + TYPE: "deltaDeco" + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + body.define(Class.baseThrowerFireDelta) + } + } + ] +}; +Class.baseThrowerFireDelta = { + PARENT: "genericTank", + LABEL: "Delta Congregation", + DANGER: 6, + GUNS: [ + { + POSITION: [26, 7, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.halfrecoil, g.machineGun, g.op, g.op, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [23, 10, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.lowPower, g.halfrecoil, g.machineGun, g.op, g.op, { recoil: 1.15 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.halfrecoil, g.op, g.op]), + TYPE: "bullet", + }, + }, { + POSITION: [24, 1, 1, 0, 0, 0, 2 / 3], + PROPERTIES: { + COLOR: 'red', + SHOOT_SETTINGS: combineStats([g.basic, g.op, g.op, g.halfrecoil, g.op]), + TYPE: "laser", + HAS_NO_RECOIL: true, + }, + }], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 3], + TYPE: "deltaDeco" + } + ] +}; +Class.pounerbullet = { + PARENT: "bullet", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/74ccbc9f-e1fa-4144-8a05-bebbd593fba3.image.png?v=1705772359444' +}; +Class.pouner = { + PARENT: "genericTank", + LABEL: "PouNer", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Untitled979_20240120123618.png?v=1705772311845', + GUNS: [ + { + POSITION: [20.5, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.op]), + TYPE: "pounerbullet" + } + } + ] +} + +Class.grappletest = { + PARENT: "genericTank", + LABEL: "GrappleTest", + DANGER: 4, + ON: [ + { + event: "define", + handler: ({ body }) => { + if (body.hasDefined) { + body.children = [] + body.hasDefined = false + } else { + body.hasDefined = true + } + } + }, + { + event: "tick", + handler: ({ body }) => { + if (body.children != null) { + for (let instance of body.children) { + let deltaX = instance.x - body.x, + deltaY = instance.y - body.y, + distance = util.getDistance(instance, body) + angle = Math.atan2(deltaY, deltaX), + combinedRadii = instance.realSize + body.realSize; + body.velocity.x += 5 * Math.cos(angle) + body.velocity.y += 5 * Math.sin(angle) + if (combinedRadii * 1.3 > distance) { + body.children = [] + break + } + + } + } + if (body.socket.player.command.ability) { + for (instance of entities) { + if (instance != body && instance.type == "wall" && util.getDistance(instance, { + x: body.control.target.x + body.x, + y: body.control.target.y + body.y + }) < instance.size * 1.3) { + if (body.children == 0) { + body.children.push(instance) + } + } + } + } + } + } + ] +} +Class.hook = { + PARENT: "bullet", + LABEL: "boolet", + ON: [ + { + event: "define", + handler: ({ body }) => { + if (body.master.hasDefined) { + body.master.children = [] + body.master.hasDefined = false + } else { + body.master.hasDefined = true + } + } + }, + { + event: "tick", + handler: ({ body }) => { + if (body.master.children != null) { + for (let instance of body.master.children) { + let deltaX = instance.x - body.master.x, + deltaY = instance.y - body.master.y, + distance = util.getDistance(instance, body) + angle = Math.atan2(deltaY, deltaX), + combinedRadii = instance.realSize + body.realSize; + body.master.velocity.x += 5 * Math.cos(angle) + body.master.velocity.y += 5 * Math.sin(angle) + if (combinedRadii * 1.3 > distance) { + body.master.children = [] + break + } + + } + } + if (body.master.control.fire) { + for (instance of entities) { + if (instance != body.master && instance.type == "wall" && util.getDistance(instance, { + x: body.master.control.target.x + body.master.x, + y: body.master.control.target.y + body.master.y + }) < instance.size * 1.3) { + if (body.master.children == 0) { + body.master.children.push(instance) + } + } + } + } + } + } + ] +}; +Class.hook2 = { + PARENT: "bullet", + TYPE: "hook", + LABEL: "boolet2", + BODY: { + SPEED: 3, + RANGE: 100, + }, + ON: [{ + event: "collide", + handler: ({ instance, other }) => { + if (other.type === "hookpoint") { + instance.master.sendMessage(`Grappling...`) + instance.x = other.x; + instance.y = other.y; + instance.velocity.x = 0; + instance.velocity.y = 0; + let deltaX = other.x - instance.master.x, + deltaY = other.y - instance.master.y, + distance = util.getDistance(other, instance.master) + angle = Math.atan2(deltaY, deltaX), + combinedRadii = other.realSize + instance.master.realSize; + instance.master.velocity.x += 5 * Math.cos(angle) + instance.master.velocity.y += 5 * Math.sin(angle) + if (util.getDistance(other, instance.master) < other.size && util.getDistance(other, instance.master) > -other.size) { instance.kill() } + } + } + }] +} +Class.grappletest2 = { + PARENT: "genericTank", + LABEL: "Grappling Hook 2", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single, {damage: 0.01, health: 25, speed: 2}]), + TYPE: "hook2", + //MAX_CHILDREN: 1 + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ] +}; + +Class.devtesttemplate = { + PARENT: "genericTank", + LABEL: "Single", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ] +}; +Class.alchem = { + PARENT: "genericTank", + LABEL: "Alchem", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { range: 50, damage: 0, pen: 0, health: 100 }]), + TYPE: "stickyTrap" + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ], + MAX_CHILDREN: 6 +}; +Class.speedoflight = { + PARENT: "genericTank", + LABEL: "SpeedOfLight", + DANGER: 7, + GUNS: [ + { + POSITION: [24, 4, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.acceltospeedoflight, { range: 999 }]), + TYPE: ["bullet", { MOTION_TYPE: "acceleratetothespeedoflight" }] + } + } + ] +}; +Class.maxStatTank = { + PARENT: ['genericTank'], + DANGER: 11, + BODY: { + ACCELERATION: base.ACCEL*2, + SPEED: base.SPEED*2, + HEALTH: base.HEALTH*2, + DAMAGE: base.DAMAGE*2, + PENETRATION: base.PENETRATION*2, + SHIELD: base.SHIELD*2, + REGEN: base.REGEN*2, + FOV: base.FOV*2, + DENSITY: base.DENSITY*2, + PUSHABILITY: 2, + HETERO: 6, + }, + SKILL_CAP: Array(10).fill(255), + SKILL: Array(10).fill(255), +} +Class.qlamgSpinnerTurret = { + PARENT: "genericTank", + LABEL: "Spinner Turret", + GUNS: [ + { + POSITION: [15, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.6], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.8], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, { + POSITION: [15, 3.5, 1, 0, 0, 0, 0.9], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun]), + TYPE: "bullet" + } + }, + ] +} +Class.quiteliterallyAMachineGun = { + PARENT: "genericTank", + LABEL: "Quite Literally a Motherfucking Machine Gun", + UPGRADE_COLOR: "red", + DANGER: 7, + BODY: { + FOV: base.FOV * 1.2 + }, + TURRETS: [ + { + POSITION: [10, 14, 0, 0, 0, 1], + TYPE: "qlamgSpinnerTurret" + }, { + POSITION: [5, 14, 0, 0, 0, 3], + TYPE: "lamgSpinnerTurret" + }, { + POSITION: [10, 14, 0, 0, 0, 2], + TYPE: "lamgSpinnerTurret" + } + ], + GUNS: [ + { + POSITION: [22, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [2, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.gunner, g.nailgun, g.literallyamachinegun, g.op]), + TYPE: "bullet" + } + } + ] +} +Class.goofysatellite = { + LABEL: "Satellite", + TYPE: "bullet", + ACCEPTS_SCORE: false, + CONTROLLERS: ["orbit"], + DANGER: 2, + SHAPE: 0, + LAYER: 13, + BODY: { + PENETRATION: 1.2, + PUSHABILITY: 0.6, + ACCELERATION: 0.75, + HEALTH: 0.3, + DAMAGE: 3.375, + SPEED: 10, + RANGE: 10, + DENSITY: 0.03, + RESIST: 1.5, + FOV: 0.5, + }, + COLOR: 'nero', + DRAW_HEALTH: true, + CLEAR_ON_MASTER_UPGRADE: true, + BUFF_VS_FOOD: true, + DIE_AT_RANGE: true, +} + +Class.goofywhirlwind = { + PARENT: "genericTank", + LABEL: "Goofy Whirlwind", + ANGLE: 60, + CONTROLLERS: ["whirlwind"], + HAS_NO_RECOIL: true, + STAT_NAMES: statnames.whirlwind, + TURRETS: [ + { + POSITION: [8, 0, 0, 0, 360, 1], + TYPE: "whirlwindDeco" + } + ], + AI: { + SPEED: 2, + }, + GUNS: (() => { + let output = [] + for (let i = 0; i < 5; i++) { + output.push({ + POSITION: {WIDTH: 8, LENGTH: 1, DELAY: i * 0.25}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.satellite]), + TYPE: ["goofysatellite", {ANGLE: i * 72}], + MAX_CHILDREN: 4, + AUTOFIRE: true, + SYNCS_SKILLS: false, + } + }) + } + return output + })() +} + +Class.pisseroo = { + PARENT: ['basic'], + LABEL: 'Winsor', + UPGRADES_TIER_0: [], + RESET_UPGRADE_MENU: true, + ON: [ + { + event: "fire", + handler: ({ body, globalMasterStore: store, gun }) => { + if (gun.identifier != 'pisserooGun') return + store.pisseroo_i ??= 0; + store.pisseroo_i++; + store.pisseroo_i %= 4; + body.define(Class.winsor0.UPGRADES_TIER_0[store.pisseroo_i]); + setTimeout(() => body.define("pisseroo"), 3000); + } + } + ], + GUNS: [{ + POSITION: {}, + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: 'bullet', + IDENTIFIER: 'pisserooGun' + } + }] +} +Class.adsfoipuasdfiopu = { + PARENT: "genericTank", + LABEL: "Random tank i made in music class because i can", + UPGRADE_TOOLTIP: "send this * to the penis explosion chamber and have his penis exploded immediately", + GUNS: [{ + POSITION: [21, 10, 0, 0, 1, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.op]), + TYPE: "bullet" + } + } + ] +} +Class.adsfoipuasdfiopu.UPGRADE_COLOR = "animatednero", +Class.adsfoipuasdfiopu2 = { + PARENT: "genericTank", + LABEL: "Random tank i made on the bus because i can", + UPGRADE_TOOLTIP: "send this non-* to the asshole explosion chamber and have his ashole exploded immediately", + GUNS: [{ + POSITION: [21, 0, 0, 0, 1, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.op]), + TYPE: "bullet" + } + }, { + POSITION: [17, 0, 0, 0, 2, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.op]), + TYPE: "bee", + MAX_CHILDREN: 30, + } + } + ] +} +Class.adsfoipuasdfiopu3 = { + PARENT: "genericTank", + LABEL: "Random tank i made in health class because i can", + UPGRADE_TOOLTIP: "send this nonon-* to the tit explosion chamber and have her tits exploded immediately", + GUNS: [{ + POSITION: [18, 8, 1, 0, 10, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "denseasfbullet" + } + } + ] +} +Class.adsfoipuasdfiopu2.UPGRADE_COLOR = "animatednero", +//wait whats stuff +Class.placeableWall = { + PARENT: "rock", + LABEL: "Wall", + SIZE: 30, + SHAPE: 4, + CLEAR_ON_MASTER_UPGRADE: false, + TEAM: TEAM_ENEMIES, + VARIES_IN_SIZE: false, +}; +Class.placeableWallSmall = { + PARENT: "rock", + LABEL: "Wall", + SIZE: 15, + SHAPE: 4, + CLEAR_ON_MASTER_UPGRADE: false, + TEAM: TEAM_ENEMIES, + VARIES_IN_SIZE: false, +}; +Class.wallPlacerThing = { + PARENT: "genericTank", + SHAPE:0, + MIRROR_MASTER_ANGLE: true, + INTANGIBLE: true, + DRAW_SELF: false, + COLOR: 16, + CLEAR_ON_MASTER_UPGRADE: false, + BODY: { + ACCELERATION: 0.1, + SPEED: true, + HEALTH: 340282366920938463463374607431768211455, + RESIST: 1, + SHIELD: 340282366920938463463374607431768211455, + REGEN: 340282366920938463463374607431768211455, + DAMAGE: false, + PENETRATION: true, + RANGE: true, + FOV: true, + SHOCK_ABSORB: 340282366920938463463374607431768211455, + RECOIL_MULTIPLIER: false, + DENSITY: 340282366920938463463374607431768211455, + STEALTH: true, + PUSHABILITY: false, + HETERO: false, + }, + MOTION_TYPE: "aimassist", + GUNS: [ + { + POSITION: [0, 20, 1, 10, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([{reload:10, speed:0, maxSpeed:0, shudder:0.0001, spray:0.0001}]), + TYPE: "placeableWall", + COLOR: 16, + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 0, + ALT_FIRE: false, + NEGATIVE_RECOIL: false, + DRAW_FILL:false, + BORDERLESS:true, + }, + }, + ], + +}; +Class.wallPlacer = { + PARENT: "genericTank", + LABEL: "Messin' Around", + BODY: { + ACCELERATION: base.ACCEL * 1, + SPEED: base.SPEED * 1, + HEALTH: base.HEALTH * 1, + DAMAGE: base.DAMAGE * 1, + PENETRATION: base.PENETRATION * 1, + SHIELD: base.SHIELD * 1, + REGEN: base.REGEN * 1, + FOV: base.FOV * 1, + DENSITY: base.DENSITY * 1, + PUSHABILITY: 1, + HETERO: 3, + }, + GUNS: [ + { + POSITION: [16, 20, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic,{reload:1/8}]), + TYPE: "wallPlacerThing", + COLOR: 16, + LABEL: "", + STAT_CALCULATOR: 0, + WAIT_TO_CYCLE: false, + AUTOFIRE: false, + SYNCS_SKILLS: false, + MAX_CHILDREN: 1, + ALT_FIRE: false, + NEGATIVE_RECOIL: false, + }, + }, + ], +}; +Class.lavenderspawner = { + PARENT: "spectator", + LABEL: "Lavender Spawner", + SKILL_CAP: [31, 0, 0, 0, 0, 0, 0, 0, 0, 31], + GUNS: [{ + POSITION: [14, 12, 1, 4, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + TYPE: "bullet" + } + }, { + POSITION: [12, 12, 1.4, 4, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0 }]), + INDEPENDENT_CHILDREN: true, + TYPE: "trplnrBoss", + ALT_FIRE: true + }, + }], + }; +Class.imagetest = { + PARENT: "genericTank", + UPGRADE_COLOR: "black", + LABEL: "PapyrusButBlackHoleOfDeath.exe", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "spaghetti" + } + } + ], + ON: [ + { + event: "damage", + handler: ({ body, damageInflictor, damageTool }) => { + damageTool[0].kill() + } + }, + { + event: "tick", + handler: ({ body }) => { + for (let instance of entities) { + let diffX = instance.x - body.x, + diffY = instance.y - body.y, + dist2 = diffX ** 2 + diffY ** 2, + number1 = 1, + number2 = 1, + number3 = 1/7, + number4 = 1, + number5 = 1, + distance = 250, + forceMulti = (((((body.size / 12)*250) ** 2)** number1) * number2) / dist2; + if (dist2 <= ((body.size / 12)*250) ** 2) { + if (instance.id != body.id /*&& !instance.ac && instance.alpha*/) { + instance.velocity.x += util.clamp(body.x - instance.x, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 + instance.velocity.y += util.clamp(body.y - instance.y, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 + } + } + if (dist2 < body.size ** 2 + instance.size ** 2) { + if (instance.id != body.id) { + instance.isProtected = false; + instance.invuln = false; + instance.damageReceived = Infinity, + instance.kill(), + instance.destroy(), + instance.removeFromGrid(), + instance.isGhost = true; + } + } + } + } + }, + ], +} +Class.papyrus = { + PARENT: "genericTank", + LABEL: "Papyrus", + UPGRADE_COLOR: 23, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "spaghetti" + } + } + ] +} +Class.oppenheimer = { + PARENT: "genericTank", + LABEL: "Oppen Heimer", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "nuke" + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ] +} +Class.homingdevbullet = { + PARENT: "bullet", + TYPE: "swarm", + SHAPE: [[-1, -1], [1, -1], [2, 0], [1, 1], [-1, 1]], + ACCEPTS_SCORE: false, + MOTION_TYPE: "swarm", + CONTROLLERS: ["nearestDifferentMaster", "mapTargetToGoal"], + BUFF_VS_FOOD: true, + AI: { + FARMER: true + }, + INDEPENDENT: true +} +Class.homingdev = { + PARENT: "developer", + LABEL: "Homing Developer", + GUNS: [ + { + POSITION: [18, 10, -1.4, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.op]), + TYPE: "homingdevbullet" + } + } + ] +} +Class.brella = { + PARENT: "genericTank", + LABEL: "Nero-Brella", + DANGER: 7, + SYNC_TURRET_SKILLS: true, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [1, 10, 0, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.brella]), + TYPE: "brellaShield", + ALT_FIRE: true, + MAX_CHILDREN: 1, + //ALPHA: 1 + } + }] +}; +Class.winsor0 = { + PARENT: "genericTank", + LABEL: "Wi3nsor", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Papyrus.webp?v=1701450294185', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} + +Class.winsor1 = { + PARENT: "genericTank", + LABEL: "Winsor has no Friends 🧐", + SIZE: 30, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144411762_LAYER.jpg?v=1701714034323', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +Class.winsor2 = { + PARENT: "genericTank", + LABEL: "Winsor has no Brain 🧐🧐", + SIZE: 30, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144409218_LAYER.jpg?v=1701714037274', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +Class.winsor3 = { + PARENT: "genericTank", + LABEL: "Winsor has no Muscle 🧐🧐🧐", + SIZE: 30, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144406913_LAYER.jpg?v=1701714040278', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +Class.winsor4 = { + PARENT: "genericTank", + LABEL: "And Winsor certainly, has no Bitches 🧐🧐🧐🧐", + SIZE: 30, + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20231204_144358408_LAYER.jpg?v=1701714043765', + DANGER: 7, + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +Class.pickaxe = { + PARENT: "genericTank", + TYPE: "flail", + COLOR: "teal", + BODY: { + DENSITY: 2 * base.DENSITY, + HEALTH: 10000, + SHIELD: 10000, + DAMAGE: 4.5, + REGEN: 10000 + }, + HITS_OWN_TYPE: 'hard', + INDEPENDENT: true, + SHAPE: "M -0 -2 C 1.5 -1 1.5 1 0 2 C 1 1 1 -1 -0 -2", +} +Class.pickaxehandle = { + PARENT: "genericTank", + TYPE: "shield", + COLOR: "brown", + BODY: { + HEALTH: 10000, + SHIELD: 10000, + REGEN: 10000 + }, + HITS_OWN_TYPE: 'hard', + INDEPENDENT: true, + SHAPE: "M -0 -0.5 L 6 -0.5 L 6 0.5 L 0 0.5 L -0 -0.5", + TURRETS: [{ + POSITION: [40, 0, 40, 0, 360, 0], + TYPE: ["pickaxe"], + VULNERABLE: true + }] +} +Class.gettingoverit = { + PARENT: "genericTank", + LABEL: "getting over it", + TURRETS: [{ + POSITION: [13, 0, 0, 0, 360, 0], + TYPE: ["pickaxehandle"], + VULNERABLE: true + }] +} + +Class.utilities = { + PARENT: "genericTank", + LABEL: "Utilities", + SHAPE: 'https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/Gear-icon-transparent-background.png?v=1705579178381' +}; +Class.AIT = menu("AIT") + +Class.developer.UPGRADES_TIER_0 = ["basic", "tanks", "AIT", "utilities", "addons"] + Class.tanks.UPGRADES_TIER_0 = ["developer", "overpowered", "testing", "unavailable", "features"] + Class.AIT.UPGRADES_TIER_0 = ["developer", "bosses", "dominators", "sanctuaries", "mothership", "baseProtector", "antiTankMachineGun", "arenaCloser"] + Class.utilities.UPGRADES_TIER_0 = ["developer", "levels", "teams", "eggGenerator", "spectator", "wallPlacer"] + Class.unavailable.UPGRADES_TIER_0 = ["developer", "healer", "doubleFlail", "winsor0", "volute"] + Class.volute.UPGRADES_TIER_3 = ["sidewinderOld"] + //Class.flail.UPGRADES_TIER_2 = ["doubleFlail"] + Class.doubleFlail.UPGRADES_TIER_3 = ["tripleFlail"] + Class.testing.UPGRADES_TIER_0 = ["tanks", "vanquisher", "mummifier", "tracker3", ["grappletest", "basic"], "grappletest2", "dasher"] + Class.dominators.UPGRADES_TIER_0 = ["AIT", "destroyerDominator", "gunnerDominator", "trapperDominator"] + Class.sanctuaries.UPGRADES_TIER_0 = ["AIT", "sanctuaryTier1", "sanctuaryTier2", "sanctuaryTier3", "sanctuaryTier4", "sanctuaryTier5", "sanctuaryTier6"] + + Class.bosses.UPGRADES_TIER_0 = ["AIT", "sentries", "elites", "mysticals", "nesters", "rogues", "rammers", "terrestrials", "celestials", "eternals", "devBosses"] + Class.sentries.UPGRADES_TIER_0 = ["bosses", "sentrySwarm", "sentryGun", "sentryTrap", "shinySentrySwarm", "shinySentryGun", "shinySentryTrap", "sentinelMinigun", "sentinelLauncher", "sentinelCrossbow"] + Class.elites.UPGRADES_TIER_0 = ["bosses", "eliteDestroyer", "eliteGunner", "eliteSprayer", "eliteBattleship", "eliteSpawner", "eliteTrapGuard", "eliteSpinner", "eliteSkimmer", "legionaryCrasher", "guardian", "defender", "sprayerLegion"] + Class.mysticals.UPGRADES_TIER_0 = ["bosses", "sorcerer", "summoner", "enchantress", "exorcistor", "shaman"] + Class.nesters.UPGRADES_TIER_0 = ["bosses", "nestKeeper", "nestWarden", "nestGuardian"] + Class.rogues.UPGRADES_TIER_0 = ["bosses", "roguePalisade", "rogueArmada", "julius", "genghis", "napoleon"] + Class.rammers.UPGRADES_TIER_0 = ["bosses", "bob", "nemesis"] + Class.terrestrials.UPGRADES_TIER_0 = ["bosses", "ares", "gersemi", "ezekiel", "eris", "selene"] + Class.celestials.UPGRADES_TIER_0 = ["bosses", "paladin", "freyja", "zaphkiel", "nyx", "theia", "atlas", "rhea", "julius", "genghis", "napoleon"] + Class.eternals.UPGRADES_TIER_0 = ["bosses", "odin", "kronos"] + Class.devBosses.UPGRADES_TIER_0 = ["bosses", "taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss"] - Class.bosses.UPGRADES_TIER_0 = ["sentries", "elites", "mysticals", "nesters", "rogues", "rammers", "terrestrials", "celestials", "eternals", "devBosses"] - Class.sentries.UPGRADES_TIER_0 = ["sentrySwarm", "sentryGun", "sentryTrap", "shinySentrySwarm", "shinySentryGun", "shinySentryTrap", "sentinelMinigun", "sentinelLauncher", "sentinelCrossbow"] - Class.elites.UPGRADES_TIER_0 = ["eliteDestroyer", "eliteGunner", "eliteSprayer", "eliteBattleship", "eliteSpawner", "eliteTrapGuard", "eliteSpinner", "eliteSkimmer", "legionaryCrasher", "guardian", "defender", "sprayerLegion"] - Class.mysticals.UPGRADES_TIER_0 = ["sorcerer", "summoner", "enchantress", "exorcistor", "shaman"] - Class.nesters.UPGRADES_TIER_0 = ["nestKeeper", "nestWarden", "nestGuardian"] - Class.rogues.UPGRADES_TIER_0 = ["roguePalisade", "rogueArmada", "julius", "genghis", "napoleon"] - Class.rammers.UPGRADES_TIER_0 = ["bob", "nemesis"] - Class.terrestrials.UPGRADES_TIER_0 = ["ares", "gersemi", "ezekiel", "eris", "selene"] - Class.celestials.UPGRADES_TIER_0 = ["paladin", "freyja", "zaphkiel", "nyx", "theia", "atlas", "rhea", "julius", "genghis", "napoleon"] - Class.eternals.UPGRADES_TIER_0 = ["odin", "kronos"] - Class.devBosses.UPGRADES_TIER_0 = ["taureonBoss", "zephiBoss", "dogeiscutBoss", "trplnrBoss", "frostBoss", "toothlessBoss"] + Class.features.UPGRADES_TIER_0 = ["tanks", "diamondShape", "rotatedTrap", "colorMan", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "radialAutoTest", "makeAutoTest", "imageShapeTest", "turretStatScaleTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] + Class.overpowered.UPGRADES_TIER_0 = ["tanks", "goofytanks", "armyOfOne", "godbasic", "maximumOverdrive", "oppenheimer", "homingdev", ["maxStatTank", "basic"], "quiteliterallyAMachineGun", "speedoflight", "lavenderspawner"] + Class.goofytanks.UPGRADES_TIER_0 = ["overpowered", "pisseroo", "papyrus", "Trapper_guy", "watertank", "piszerbeam", "baseThrowerDelta", "pouner", "adsfoipuasdfiopu", "goofywhirlwind", "gettingoverit", "alchem"] - Class.testing.UPGRADES_TIER_0 = ["diamondShape", "miscTest", "mmaTest", "vulnturrettest", "onTest", "alphaGunTest", "strokeWidthTest", "testLayeredBoss", "tooltipTank", "turretLayerTesting", "bulletSpawnTest", "propTest", "weaponArrayTest", "radialAutoTest", "imageShapeTest", "auraBasic", "auraHealer", "weirdAutoBasic", "ghoster", "switcheroo", ["developer", "developer"], "armyOfOne", "vanquisher", "mummifier"] + //the "winsor" tank needs this to function, it worked before the "ON" thing was added + Class.winsor0.UPGRADES_TIER_0 = ["winsor1", "winsor2", "winsor3", "winsor4"] + Class.papyrus.UPGRADES_TIER_0 = ["imagetest"] + Class.adsfoipuasdfiopu.UPGRADES_TIER_0 = ["adsfoipuasdfiopu2", "adsfoipuasdfiopu3"] \ No newline at end of file diff --git a/server/modules/definitions/groups/food.js b/server/modules/definitions/groups/food.js index 9e82ca96d..cfe51e1cd 100644 --- a/server/modules/definitions/groups/food.js +++ b/server/modules/definitions/groups/food.js @@ -1,170 +1,5 @@ -const { basePolygonDamage, basePolygonHealth, base } = require('../constants.js'), - -// Code by Damocles (https://discord.com/channels/366661839620407297/508125275675164673/1090010998053818488) -// Albeit heavily modified because the math in the original didn't work LOL -makeRelic = (type, scale = 1, gem, SIZE) => { - type = ensureIsClass(type); - let relicCasing = { - PARENT: 'genericEntity', - LABEL: 'Relic Casing', - LEVEL_CAP: 45, - COLOR: type.COLOR, - MIRROR_MASTER_ANGLE: true, - SHAPE: [[-0.4,-1],[0.4,-0.25],[0.4,0.25],[-0.4,1]].map(r => r.map(s => s * scale)) - }, relicBody = { - PARENT: 'genericEntity', - LABEL: 'Relic Mantle', - LEVEL_CAP: 45, - COLOR: type.COLOR, - MIRROR_MASTER_ANGLE: true, - SHAPE: type.SHAPE - }; - Class[Math.random().toString(36)] = relicCasing; - Class[Math.random().toString(36)] = relicBody; - let width = 6 * scale, - y = 8.25 + ((scale % 1) * 5), - isEgg = type.SHAPE == 0, - casings = isEgg ? 8 : type.SHAPE, - fraction = 360 / casings, - GUNS = [], - TURRETS = [{ POSITION: [32.5, 0, 0, 0, 0, 0], TYPE: relicBody }], - PARENT = [type], - additionalAngle = type.SHAPE % 2 === 0 ? 0 : fraction / 2; - - if (SIZE) { - PARENT.push({ SIZE }); - } - - for (let i = 0; i < casings; i++) { - let angle = i * fraction, - gunAngle = angle + additionalAngle; - if (isEgg) { - GUNS.push({ - POSITION: [4, width, 2.5, 12, 0, gunAngle, 0] - }); - TURRETS.push({ - POSITION: [8, -15, 0, angle, 0, 1], - TYPE: relicCasing - }); - } else { - GUNS.push({ - POSITION: [4, width, 2.5, 12, y, gunAngle, 0] - }); - GUNS.push({ - POSITION: [4, width, 2.5, 12, -y, gunAngle, 0] - }); - TURRETS.push({ - POSITION: [8, -15, y, angle, 0, 1], - TYPE: relicCasing - }); - TURRETS.push({ - POSITION: [8, -15, -y, angle, 0, 1], - TYPE: relicCasing - }); - } - } - - if (gem) { - TURRETS.push({ - POSITION: [8, 0, 0, 0, 0, 1], - TYPE: [gem, { MIRROR_MASTER_ANGLE: true }] - }); - } - - return { - PARENT, - LABEL: type.LABEL + ' Relic', - COLOR: "white", // This is the color of the floor, this makes it look hollow. - BODY: { - ACCELERATION: 0.001 - }, - CONTROLLERS: [], - VALUE: type.VALUE * 100_000, - GUNS, - TURRETS - }; -}, - -makeCrasher = type => ({ - PARENT: type, - COLOR: 'pink', - TYPE: "crasher", - LABEL: 'Crasher ' + type.LABEL, - CONTROLLERS: ['nearestDifferentMaster', 'mapTargetToGoal'], - MOTION_TYPE: "motor", - FACING_TYPE: "smoothWithMotion", - HITS_OWN_TYPE: "hard", - HAS_NO_MASTER: true, - DRAW_HEALTH: true, - BODY: { - SPEED: 1 + 5 / Math.max(2, type.TURRETS.length + type.SHAPE), - ACCELERATION: 5, - DAMAGE: 5, - PUSHABILITY: 0.5, - DENSITY: 10, - RESIST: 2, - }, - AI: { - NO_LEAD: true, - } -}), - -makeRare = (type, level) => { - type = ensureIsClass(type); - return { - PARENT: "food", - LABEL: ["Shiny", "Legendary", "Shadow", "Rainbow", "Trans"][level] + " " + type.LABEL, - VALUE: [100, 500, 2000, 4000, 5000][level] * type.VALUE, - SHAPE: type.SHAPE, - SIZE: type.SIZE + level, - COLOR: ["lightGreen", "teal", "darkGrey", "rainbow", "trans"][level], - ALPHA: level == 2 ? 0.25 : 1, - BODY: { - DAMAGE: type.BODY.DAMAGE + level, - DENSITY: type.BODY.DENSITY + level, - HEALTH: [10, 20, 40, 80, 100][level] * type.BODY.HEALTH, - PENETRATION: type.BODY.PENETRATION + level, - ACCELERATION: type.BODY.ACCELERATION - }, - DRAW_HEALTH: true, - INTANGIBLE: false, - GIVE_KILL_MESSAGE: true, - } -}, - -lerp = (a, b, t) => a + (b - a) * t, - -makeLaby = (type, level) => { - type = ensureIsClass(type); - let usableSHAPE = Math.max(type.SHAPE, 3), - downscale = Math.cos(Math.PI / usableSHAPE), - strenghtMultiplier = 6 ** level; - return { - PARENT: "food", - LABEL: ["", "Beta ", "Alpha ", "Omega ", "Gamma ", "Delta "][level] + type.LABEL, - VALUE: type.VALUE * strenghtMultiplier, - SHAPE: type.SHAPE, - SIZE: level > 3 ? Math.max(40, type.SIZE * 2) * (1 + (level - 3) / 6) : type.SIZE * lerp(2 ** level, 1 + level / 3, Math.min(1, (type.SIZE - 5) / 17)), - COLOR: type.COLOR, - ALPHA: type.ALPHA, - BODY: { - DAMAGE: type.BODY.DAMAGE, - DENSITY: type.BODY.DENSITY, - HEALTH: type.BODY.HEALTH * strenghtMultiplier, - PENETRATION: type.BODY.PENETRATION, - PUSHABILITY: (type.BODY.PUSHABILITY / (level + 1)) || 0, - ACCELERATION: type.BODY.ACCELERATION - }, - VARIES_IN_SIZE: false, - DRAW_HEALTH: type.DRAW_HEALTH, - GIVE_KILL_MESSAGE: type.GIVE_KILL_MESSAGE || level > 2, - GUNS: type.GUNS, - TURRETS: [...(type.TURRETS ? type.TURRETS : []), ...Array(level).fill().map((_, i) => ({ - POSITION: [20 * downscale ** (i + 1), 0, 0, !(i & 1) ? 180 / usableSHAPE : 0, 0, 1], - TYPE: [type, { COLOR: -1, MIRROR_MASTER_ANGLE: true }] - }))] - }; -}; +const { basePolygonDamage, basePolygonHealth, base } = require('../constants.js'); +const { makeRelic, makeRare, makeCrasher, makeLaby } = require('../facilitators.js'); // EGGS Class.egg = { @@ -172,7 +7,7 @@ Class.egg = { LABEL: "Egg", VALUE: 10, SHAPE: 0, - SIZE: 5, + SIZE: 4.5, COLOR: "veryLightGrey", INTANGIBLE: true, BODY: { @@ -189,7 +24,7 @@ Class.gem = { LABEL: "Gem", VALUE: 2e3, SHAPE: 6, - SIZE: 5, + SIZE: 4.5, COLOR: "aqua", BODY: { DAMAGE: basePolygonDamage / 4, @@ -236,7 +71,7 @@ Class.square = { LABEL: "Square", VALUE: 30, SHAPE: 4, - SIZE: 10, + SIZE: 14, COLOR: "gold", BODY: { DAMAGE: basePolygonDamage, @@ -284,7 +119,7 @@ Class.pentagon = { LABEL: "Pentagon", VALUE: 400, SHAPE: 5, - SIZE: 20, + SIZE: 21, COLOR: "purple", BODY: { DAMAGE: 1.5 * basePolygonDamage, @@ -362,7 +197,7 @@ Class.hexagon = { LABEL: "Hexagon", VALUE: 500, SHAPE: 6, - SIZE: 22, + SIZE: 25, COLOR: "hexagon", BODY: { DAMAGE: 3 * basePolygonDamage, @@ -528,7 +363,7 @@ for (let [gemColor, name] of [ let gem; if (gemColor) { gem = Class[name + "Gem"] = { - PARENT: ['gem'], + PARENT: 'gem', LABEL: name + ' Gem', SHAPE: 6, COLOR: gemColor @@ -579,7 +414,7 @@ for (let tier = 0; tier < 6; tier++) { food = food[0].toLowerCase() + food.slice(1); Class[`laby${tier}${food}`] = // backwards compatability, DO NOT ADD A SEMICOLON HERE. javascript is funny about whitespace characters :)))))) - Class[`laby_${poly}_${tier}_${shiny}_0`] = makeLaby(Class[food], tier); + Class[`laby_${poly}_${tier}_${shiny}_0`] = makeLaby(Class[food], tier, (polyName == "Triangle" && tier > 0) ? 2/3 : 1); Class[`laby_${poly}_${tier}_${shiny}_1`] = makeCrasher(Class[`laby_${poly}_${tier}_${shiny}_0`]); } diff --git a/server/modules/definitions/groups/generics.js b/server/modules/definitions/groups/generics.js index a4f57a39f..0feb0cafe 100644 --- a/server/modules/definitions/groups/generics.js +++ b/server/modules/definitions/groups/generics.js @@ -138,6 +138,12 @@ Class.genericSmasher = { DENSITY: 2 * base.DENSITY } } +Class.genericLancer = { + PARENT: "genericTank", + DANGER: 6, + SKILL_CAP: [dfltskl, dfltskl, dfltskl, dfltskl, 0, dfltskl, dfltskl, dfltskl, dfltskl, dfltskl], + STAT_NAMES: statnames.lancer, +} Class.genericBoss = { PARENT: "genericTank", TYPE: "miniboss", @@ -170,7 +176,7 @@ Class.food = { MOTION_TYPE: "drift", FACING_TYPE: "turnWithSpeed", VARIES_IN_SIZE: true, - LEVEL_CAP: 45, + LEVEL_CAP: 1, BODY: { STEALTH: 30, PUSHABILITY: 1, @@ -308,7 +314,8 @@ Class.satellite = { DRAW_HEALTH: false, CLEAR_ON_MASTER_UPGRADE: true, BUFF_VS_FOOD: true, - MOTION_TYPE: 'motor' + MOTION_TYPE: 'motor', + CAN_GO_OUTSIDE_ROOM: true } Class.auraBase = { @@ -357,3 +364,10 @@ Class.auraSymbol = { COLOR: "teal", SHAPE: [[-0.598,-0.7796],[-0.3817,-0.9053],[0.9688,-0.1275],[0.97,0.125],[-0.3732,0.9116],[-0.593,0.785]] }; +Class.rangeAuraSymbol = { + PARENT: "genericTank", + CONTROLLERS: [["spin", {speed: -0.04}]], + INDEPENDENT: true, + COLOR: "teal", + SHAPE: "M -0.7671 0.6521 L -0.7671 -0.6521 L -0.6521 -0.7671 L -0.6521 -0.7671 L 0.6521 -0.7671 L 0.7671 -0.6521 L 0.7671 0.6521 L 0.6521 0.7671 L -0.6521 0.7671 L -0.7671 0.6521" +}; \ No newline at end of file diff --git a/server/modules/definitions/groups/misc.js b/server/modules/definitions/groups/misc.js index d868c7879..931bb4556 100644 --- a/server/modules/definitions/groups/misc.js +++ b/server/modules/definitions/groups/misc.js @@ -1,8 +1,8 @@ -const { combineStats, skillSet, makeAuto, makeDeco, makeMulti } = require('../facilitators.js'); -const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); +const { combineStats, skillSet, makeAuto, weaponArray } = require('../facilitators.js') +const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js') require('./generics.js') -require('./tanks.js'); -const g = require('../gunvals.js'); +require('./tanks.js') +const g = require('../gunvals.js') // OBSTACLES Class.rock = { @@ -43,9 +43,40 @@ Class.wall = { PARENT: "rock", LABEL: "Wall", SIZE: 25, - SHAPE: "M 1 1 L -1 1 L -1 -1 L 1 -1 Z", + SHAPE: 4, VARIES_IN_SIZE: false } +Class.dfxwall = { + PARENT: "rock", + LABEL: "Wall", + SIZE: 25, + SHAPE: "M 1 1 L -1 1 L -1 -1 L 1 -1 Z", + VARIES_IN_SIZE: false, + TURRETS: [{ + POSITION: [7, -5, -5, 0, 0, 3], + TYPE: "dfxskin" + },] +} +Class.hookpoint = { + TYPE: "hookpoint", + DAMAGE_CLASS: 1, + SIZE: 20, + ALPHA: 0.5, + SHAPE: "M 1 1 L -1 1 L -1 -1 L 1 -1 Z", + COLOR: "cyan", + VARIES_IN_SIZE: false, + BODY: { + PUSHABILITY: 0, + HEALTH: 10000, + SHIELD: 10000, + REGEN: 1000, + DAMAGE: 1, + RESIST: 0, + STEALTH: 1, + DENSITY: 100000, + }, + VALUE: 0, +} Class.moon = { PARENT: "rock", LABEL: "Moon", @@ -93,6 +124,24 @@ Class.dominator = { ACCEPTS_SCORE: false, HITS_OWN_TYPE: "pushOnlyTeam" } +Class.territoryCapturePoint = { + PARENT: "dominator", + LABEL: "Capture Point", + BODY: { + HEALTH: 200, + DAMAGE: 5, + PENETRATION: 0.2, + }, +} +Class.trapTerritoryCapturePoint = { + PARENT: "trapperDominator", + LABEL: "Capture Point", + BODY: { + HEALTH: 350, + DAMAGE: 5, + PENETRATION: 0.2, + }, +} Class.destroyerDominator = { PARENT: "dominator", UPGRADE_LABEL: 'Destroyer', @@ -139,12 +188,11 @@ Class.gunnerDominator = { } ] } -Class.trapperDominator = makeMulti({ +Class.trapperDominator = { PARENT: "dominator", UPGRADE_LABEL: 'Trapper', FACING_TYPE: ["spin", {speed: 0.02}], - CONTROLLERS: ["alwaysFire"], - GUNS: [ + GUNS: weaponArray([ { POSITION: [4, 3.75, 1, 8, 0, 0, 0] }, @@ -153,11 +201,12 @@ Class.trapperDominator = makeMulti({ PROPERTIES: { SHOOT_SETTINGS: combineStats([g.trap, g.trapperDominator]), TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap + STAT_CALCULATOR: gunCalcNames.trap, + AUTOFIRE: true } } - ] -}, 8, "Dominator") + ], 8) +} // SANCTUARIES let sancTiers = [3, 6, 8, 9, 10, 12] @@ -190,7 +239,6 @@ Class.sanctuary = { LEVEL: 45, SIZE: 20, FACING_TYPE: ["spin", {speed: 0.02}], - CONTROLLERS: ["alwaysFire"], SKILL: skillSet({ rld: 1.25, dam: 1.25, @@ -395,7 +443,7 @@ Class.shinySentrySwarm = { ], }; Class.shinySentryGun = makeAuto("shinySentry", "Sentry", { - type: Class.artilleryAutoTankgun, + type: "artilleryTurret", size: 12, }); Class.shinySentryGun.UPGRADE_LABEL = "Shiny Gun Sentry"; @@ -510,43 +558,43 @@ Class.sentinelMinigun = { { POSITION: [16, 7.5, 1, 0, 4.5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin, g.spam, g.spam]), TYPE: "bullet", }, }, { POSITION: [11.5, 7.5, -1.33, 1, 4.5, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin, g.spam, g.spam]), TYPE: "bullet", }, }, { POSITION: [16, 7.5, 1, 0, -4.5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin, g.spam, g.spam]), TYPE: "bullet", }, }, { POSITION: [11.5, 7.5, -1.33, 1, -4.5, 0, 0.5], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin, g.spam, g.spam]), TYPE: "bullet", }, }, { POSITION: [22.5, 9, 1, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin, g.spam, g.spam]), TYPE: "bullet", }, }, { POSITION: [20.4, 9, 1, 0, 0, 0, 1/3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin, g.spam, g.spam]), TYPE: "bullet", }, }, { POSITION: [18.3, 9, 1, 0, 0, 0, 2/3], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin]), + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.twin, g.spam, g.spam]), TYPE: "bullet", }, }, @@ -590,49 +638,19 @@ Class.baseProtector = { POSITION: [25, 0, 0, 0, 360, 0], TYPE: "dominationBody", }, - { + ...weaponArray({ POSITION: [12, 7, 0, 45, 100, 0], TYPE: "baseSwarmTurret", - }, - { - POSITION: [12, 7, 0, 135, 100, 0], - TYPE: "baseSwarmTurret", - }, - { - POSITION: [12, 7, 0, 225, 100, 0], - TYPE: "baseSwarmTurret", - }, - { - POSITION: [12, 7, 0, 315, 100, 0], - TYPE: "baseSwarmTurret", - }, + }, 4) ], - GUNS: [ + GUNS: weaponArray([ { POSITION: [4.5, 11.5, -1.3, 6, 0, 45, 0], }, - { - POSITION: [4.5, 11.5, -1.3, 6, 0, 135, 0], - }, - { - POSITION: [4.5, 11.5, -1.3, 6, 0, 225, 0], - }, - { - POSITION: [4.5, 11.5, -1.3, 6, 0, 315, 0], - }, { POSITION: [4.5, 8.5, -1.5, 7, 0, 45, 0], }, - { - POSITION: [4.5, 8.5, -1.5, 7, 0, 135, 0], - }, - { - POSITION: [4.5, 8.5, -1.5, 7, 0, 225, 0], - }, - { - POSITION: [4.5, 8.5, -1.5, 7, 0, 315, 0], - }, - ], + ], 4) }; Class.mothership = { @@ -656,46 +674,36 @@ Class.mothership = { DAMAGE: 1.5, }, HITS_OWN_TYPE: "pushOnlyTeam", - GUNS: (() => { - let e = [], - T = [1]; - for (let e = 1; e < 8.5; e += 0.5) { - let t = e / 16; - T.push(t); - } - for (let t = 0; t < 16; t++) { - let S = 22.5 * (t + 1), - E = { - MAX_CHILDREN: 2, - SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.mothership]), - TYPE: "drone", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.drone, - WAIT_TO_CYCLE: true, - }; - t % 2 == 0 && - (E.TYPE = [ - "drone", - { - AI: { - skynet: true, - }, + GUNS: + weaponArray([ + { + POSITION: [4.3, 3.1, 1.2, 8, 0, 22.5, 0], + PROPERTIES: { + MAX_CHILDREN: 2, + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.mothership]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + } + }, { + POSITION: [4.3, 3.1, 1.2, 8, 0, 45, 1/32], + PROPERTIES: { + MAX_CHILDREN: 2, + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.mothership]), + TYPE: ["drone", { + AI: {skynet: true}, INDEPENDENT: true, - LAYER: 10, - BODY: { - FOV: 2, - }, - }, - ]); - let O = { - POSITION: [4.3, 3.1, 1.2, 8, 0, S, T[t]], - PROPERTIES: E, - }; - e.push(O); + BODY: {FOV: 2}, + }], + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + } } - return e; - })(), + ], 8, 1/16) } Class.arenaCloser = { PARENT: "genericTank", @@ -797,21 +805,10 @@ Class.tracker3 = { LABEL: "Tracker-3", FACING_TYPE: ["spin", {speed: 0.02}], SKILL_CAP: [0, 0, 0, 0, 0, smshskl, smshskl, smshskl, smshskl, smshskl], - TURRETS: [ - { - /* SIZE X Y ANGLE ARC */ - POSITION: [11, 8, 0, 0, 190, 0], - TYPE: ["tracker3gun", { INDEPENDENT: true }], - }, - { - POSITION: [11, 8, 0, 120, 190, 0], - TYPE: ["tracker3gun", { INDEPENDENT: true }], - }, - { - POSITION: [11, 8, 0, 240, 190, 0], - TYPE: ["tracker3gun", { INDEPENDENT: true }], - }, - ], + TURRETS: weaponArray({ + POSITION: [11, 8, 0, 0, 190, 0], + TYPE: ["tracker3gun", { INDEPENDENT: true }], + }, 3) }; // BOTS diff --git a/server/modules/definitions/groups/projectiles.js b/server/modules/definitions/groups/projectiles.js index f4eddd911..d3d49907e 100644 --- a/server/modules/definitions/groups/projectiles.js +++ b/server/modules/definitions/groups/projectiles.js @@ -1,4 +1,4 @@ -const { combineStats, makeAuto } = require('../facilitators.js'); +const { combineStats, makeAuto, makeOver, weaponArray } = require('../facilitators.js'); const { gunCalcNames, base } = require('../constants.js'); const g = require('../gunvals.js'); @@ -230,52 +230,19 @@ Class.hive = { }, FACING_TYPE: "turnWithSpeed", INDEPENDENT: true, - CONTROLLERS: ["alwaysFire", "nearestDifferentMaster", "targetSelf"], + CONTROLLERS: ["nearestDifferentMaster", "targetSelf"], AI: { NO_LEAD: true, }, - GUNS: [ - { - POSITION: [7, 9.5, 0.6, 7, 0, 108, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), - TYPE: ["bee", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 9.5, 0.6, 7, 0, 180, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), - TYPE: ["bee", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 9.5, 0.6, 7, 0, 252, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), - TYPE: ["bee", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 9.5, 0.6, 7, 0, 324, 0.6], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), - TYPE: ["bee", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 9.5, 0.6, 7, 0, 36, 0.8], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), - TYPE: ["bee", { PERSISTS_AFTER_DEATH: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, + GUNS: weaponArray({ + POSITION: [7, 9.5, 0.6, 7, 0, 108, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), + TYPE: ["bee", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + AUTOFIRE: true }, - ], + }, 5, 0.2) } Class.protoHive = { PARENT: "bullet", @@ -286,32 +253,17 @@ Class.protoHive = { }, FACING_TYPE: "turnWithSpeed", INDEPENDENT: true, - CONTROLLERS: ["alwaysFire", "nearestDifferentMaster", "targetSelf"], + CONTROLLERS: ["nearestDifferentMaster", "targetSelf"], AI: { NO_LEAD: true }, - GUNS: [ - { - POSITION: [7, 9.5, 0.6, 7, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), - TYPE: ["bee", { INDEPENDENT: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [7, 9.5, 0.6, 7, 0, 120, 0.2], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), - TYPE: ["bee", { INDEPENDENT: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, { - POSITION: [7, 9.5, 0.6, 7, 0, -120, 0.4], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), - TYPE: ["bee", { INDEPENDENT: true }], - STAT_CALCULATOR: gunCalcNames.swarm, - }, + GUNS: weaponArray({ + POSITION: [7, 9.5, 0.6, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee]), + TYPE: ["bee", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + AUTOFIRE: true }, - ], + }, 5, 1/3) } Class.snake = { PARENT: "bullet", @@ -659,7 +611,6 @@ Class.assemblerTrap = { }, TURRETS: [ { - /** SIZE X Y ANGLE ARC */ POSITION: [4, 0, 0, 0, 360, 1], TYPE: 'assemblerDot' } @@ -743,3 +694,531 @@ Class.homingBullet = { }, CAN_GO_OUTSIDE_ROOM: true } + +//delta projectiles +Class.autobullet = makeAuto('bullet', "AutoBullet", {type: 'projectileAutoTurret'}) +Class.heavyautobullet = makeAuto('bullet', "HeavyAutoBullet", {type: 'pillboxTurret'}) +Class.shrapnel = { + PARENT: "bullet", + SHAPE: 5, + LABEL: "expold heheahah", + BODY: { + RANGE: 1, + FOV: 0.5, + }, + INDEPENDENT: true, + CONTROLLERS: ["alwaysFire"], + AI: { + NO_LEAD: true, + }, + GUNS: [ + { + POSITION: [7, 9.5, 1, 7, 0, 72, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfspeed, g.halfrange, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 9.5, 1, 7, 0, 72*2, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 9.5, 1, 7, 0, 72*3, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 9.5, 1, 7, 0, 72*4, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 9.5, 1, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm, g.hive, g.bee, g.halfspeed, g.halfspeed, g.halfrange, g.halfspeed, g.halfrange]), + TYPE: ["trap", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], +} +Class.grenade = { + PARENT: "bullet", + INDEPENDENT: true, + BODY: { RANGE: 80 }, + GUNS: [{ + POSITION: [1, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.grenade_explosion]), + TYPE: ["shrapnel", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + } + }, { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, g.skimmer, { reload: 0.5 }, g.lowPower, { recoil: 1.35 }, { speed: 1.3, maxSpeed: 1.3 }]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + } + } + ], + TURRETS: [{ + POSITION: [9, -8, 0, 0, 0, 1], + TYPE: ["grenadeDeco"] + } + ] +} +Class.firecrackerbomb = { + PARENT: "bullet", + INDEPENDENT: true, + BODY: { RANGE: 70 }, + GUNS: [{ + POSITION: [1, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.explosion]), + TYPE: ["growBullet", { PERSISTS_AFTER_DEATH: true }], + SHOOT_ON_DEATH: true, + } + }, { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0.5 }, g.lowPower]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: "firecrackerDeco" + }] +} +Class.baseBullet = { + PARENT: "trap", + MOTION_TYPE: "motor", + HITS_OWN_TYPE: "never", + BODY: { + SPEED: 1.25, + RANGE: 120, + }, + LABEL: "Base", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + CONTROLLERS: [["spin", { independent: true, speed: 0.1 }], "kiva"], + INDEPENDENT: true, + FACING_TYPE: "toTarget", + COLOR: "#FC8208", + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["revogun", { COLOR: "#FC8208", BODY: { FOV: 2 } }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["revogun", { COLOR: "#FC8208", BODY: { FOV: 2 } }] + }], +ON: [{ + event: "death", + handler: ({ body }) => { + if (!body.master.isDead) return + body.master.define(Class.baseThrower) + } + } + ] +}; +Class.brellaShield = { + PARENT: "bullet", + TYPE: "brella", + LABEL: "Base", + SIZE: 7, + //SHAPE: 'M 1 3.5 L 2 2 L 2 0 L 1 -1.5 L 0 -1.8 L 0 -1 L 2 0.5 L 0 -1 L 0 0 L 2 0.85 L 0 0 L 0 1 L 2 1 L 0 1 L 0 1 L 0 2 L 2 1.15 L 0 2 L 0 3 L 2 1.5 L 0 3 L 0 3.8 L 1 3.5', + SHAPE: 'M -0 2.2587 L 0.9 0.905 L 0.9 -0.9 L -0 -2.2537 L -0.9 -2.5245 L -0.9 2.5295 L -0 2.2587', + INDEPENDENT: true, + COLOR: "grey", + GUNS: [ + { + POSITION: [14, 6, 1, 0, 0, 180, 0], + PROPERTIES: { + AUTOFIRE: true, + SHOOT_SETTINGS: combineStats([g.basic, { recoil: 0.35 }, g.lowPower]), + TYPE: ["bullet", { PERSISTS_AFTER_DEATH: true }], + STAT_CALCULATOR: gunCalcNames.thruster, + }, + }, + ], +}; +Class.laser = { + PARENT: ["bullet"], + SHAPE: -1, + BODY: { + PENETRATION: 1, + SPEED: 5.8, + RANGE: 100, + DENSITY: 0.9, + HEALTH: 0.155, + DAMAGE: 5.6, + }, + BUFF_VS_FOOD: true, +} +Class.fastdrone = { + PARENT: "drone", + LABEL: 'Drone', + BODY: { + PENETRATION: 1.2, + PUSHABILITY: 0.6, + ACCELERATION: 0.05, + HEALTH: 0.5, + DAMAGE: 3.125, + SPEED: 6, + RANGE: 200, + DENSITY: 0.03, + RESIST: 1.5, + FOV: 0.8, + }, + GUNS: [ { /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [ 15, 5, 1, 0, 0, 180, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.muchmorerecoil, g.muchmorerecoil, g.weak]), + TYPE: "bullet", + AUTOFIRE: true + }, }, + ], + HITS_OWN_TYPE: 'hard', + DRAW_HEALTH: false, + CLEAR_ON_MASTER_UPGRADE: true, + BUFF_VS_FOOD: true, +}; + +Class.revoorbitdrone = { + PARENT: "drone", + LABEL: 'Drone', + SYNC_TURRET_SKILLS: true, + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "droneturretBase", + }, + ], +}; +Class.hiveprobe = { + PARENT: "genericTank", + LABEL: "Probe", + TYPE: "drone", + HITS_OWN_TYPE: "hardWithBuffer", + DRAW_HEALTH: true, + BODY: { + FOV: 0.5, + SPEED: 3, + ACCELERATION: 0.4, + HEALTH: 2.5, + SHIELD: 0, + DAMAGE: 1.2, + RESIST: 1, + PENETRATION: 1, + DENSITY: 0.4 + }, + AI: { + BLIND: true + }, + CLEAR_ON_MASTER_UPGRADE: true, + GIVE_KILL_MESSAGE: false, + ACCEPTS_SCORE: false, + CONTROLLERS: [ + "nearestDifferentMaster", + "mapAltToFire", + "minion", + "canRepel", + "hangOutNearMaster" + ], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower]), + TYPE: "bullet" + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [27, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; +Class.clonerprobe = { + PARENT: "hiveprobe", + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lowPower]), + TYPE: "bullet" + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [24, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +} +Class.autoclonerprobe = makeAuto(Class.clonerprobe) +Class.spaghetti = { + PARENT: "bullet", + SHOOT_ON_DEATH: true, + SHAPE: "https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/afg-spaghetti-alla-assassina-1-19ef-superJumbo.jpg?v=1701450288242", + GUNS: [ + { + POSITION: [2, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet" + } + } + ] +} +const timer = (run, duration) => { + let timer = setInterval(() => run(), 31.25); + setTimeout(() => { + clearInterval(timer); + }, duration * 1000); +}; + const damageOnTick = (body, instance, multiplier, duration, stopAtSetHealth, hitsOwnTeam) => { + if (!instance) return + if (!instance.damageOnTicking && !instance.godmode && !instance.invuln && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) { + instance.damageOnTicking = true; + setTimeout(() => { + instance.damageOnTicking = false; + }, 2 * duration * 1000); + timer(() => { + if (instance.damageOnTicking && instance.health.amount > stopAtSetHealth && instance.health.amount - (multiplier * 0.5) > stopAtSetHealth) { + instance.health.amount -= multiplier * 0.5; + } //else {if (instance.health.amount - (multiplier * 0.5) < stopAtSetHealth) {instance.health.amount === stopAtSetHealth}} + }, 2 * duration); + } +}; +const iceOnTick = (body, instance, multiplier, duration, hitsOwnTeam) => { + if (!instance) return + if (!instance.invuln && !instance.godmode && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) timer(() => { + instance.velocity.x /= 1.05 * multiplier; + instance.velocity.y /= 1.05 * multiplier; + }, 1.5 * duration); +}; +Class.poisonbullet = { + PARENT: "bullet", + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + TURRETS: [{ + POSITION: [5.5, 0, 0, 0, 0, 1], + TYPE: ["effectBulletDeco", { color: "green" }] + }], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + damageOnTick(body, damageTool[0], 2, 1, 1, false); + } + }] +} +Class.icebullet = { + PARENT: "bullet", + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + TURRETS: [{ + POSITION: [5.5, 0, 0, 0, 0, 1], + TYPE: ["effectBulletDeco", { color: "#28B1DE" }] + }], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + iceOnTick(body, damageTool[0], 1, 1, true); + } + }] +} +Class.empBullet = { + PARENT: "bullet", + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + iceOnTick(body, damageTool[0], Infinity, 2.5, true); + } + }] +} +Class.ceptionistbullet = { + PARENT: "bullet", + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.lesspower, g.lesspower, g.halfreload, g.halfreload, g.turret]), + TYPE: "bullet", + COLOR: "black", + AUTOFIRE: true + } + } + ] +} +Class.autoturretswarm = makeAuto('swarm', "AutoturretSwarm", {type: 'droneAutoTurret'}) +Class.hybridclonerprobe = makeOver('clonerprobe', "hybrid-cloner-probe", {count: 1, independent: true, cycle: false}) +Class.nuke = { + PARENT: "growBullet", + LABEL: "Nuke", + MOTION_TYPE: "fuckingnuclearbomb", + BODY: { + PENETRATION: 100, + SPEED: 7, + RANGE: 600, + DENSITY: 99999999999, + HEALTH: 99999, + DAMAGE: 999999, + PUSHABILITY: -99999999, + }, +}; +Class.denseasfbullet = { + PARENT: "bullet", + BODY: { + DENSITY: 999999999, + SPEED: 12 + } +} +Class.undertowbullet = { + PARENT: "bullet", + GUNS: [{ + POSITION: [4, 4, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.magnet]), + TYPE: ["bullet", { SIZE: 5, ALPHA: 0.5 }], + AUTOFIRE: true + }, + }], + ON: [{ + event: "tick", + handler: ({ body }) => { + for (let instance of entities) { + if (instance.team != body.team && instance.master.type == "tank" && (instance.isPlayer || instance.master.isPlayer || instance.type == "food")) { + let diffX = instance.x - body.x, + diffY = instance.y - body.y, + dist2 = diffX ** 2 + diffY ** 2, + number1 = 1, + number2 = 1, + number3 = 1/7, + number4 = 1, + number5 = 1, + forceMulti = (((((body.size / 24)*150) ** 2)** number1) * number2) / dist2; + if (dist2 <= (((body.size / 24)*150) ** 2) * 2) { + instance.velocity.x += util.clamp(body.x - instance.x, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 + instance.velocity.y += util.clamp(body.y - instance.y, -90, 90) * instance.damp * ((number5 - (number5/((forceMulti ** number3)* number4)))+ 0.001);//0.05 + } + } + } + } + }, + ], +} +Class.surgeempBullet = { + PARENT: "bullet", + HITS_OWN_TYPE: "never", + COLOR: "spaceGem", + BORDERLESS: true, + GLOW: { + RADIUS: 1, + COLOR: "spaceGem", + ALPHA: 1, + RECURSION: 1, + } +}; +Class.lineEMP = { + PARENT: "bullet", + LABEL: 'Line', + SHAPE: -1, + ARENA_CLOSER: true, + HAS_NO_RECOIL: true, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.lance]), + TYPE: "empBullet", + AUTOFIRE: true, + ALPHA: 0, + } + }], + GLOW: { + RADIUS: 3, + COLOR: "spaceGem", + ALPHA: 1, + RECURSION: 3, + } +} +Class.stickyTrap = { + PARENT: "setTrap", + TYPE: "popup", + HITS_OWN_TYPE: "hard", + LABEL: "Sticky Trap", + SHAPE: -5, + GUNS: [{ + POSITION: [4, 4, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.magnet]), + TYPE: ["bullet", { SIZE: 5, ALPHA: 0.5 }], + AUTOFIRE: true + }, + }], + ON: [{ + event: "collide", + handler: ({ body, other }) => { + body.velocity.x = 0; + body.velocity.y = 0; + let amount = util.getDistance(body, other), + angle = Math.atan2(body.y - other.y, body.x - other.x); + other.velocity.x += amount * Math.cos(angle); + other.velocity.y += amount * Math.sin(angle); + } + }], +} +Class.katanaparticle = { + LABEL: "kpartic", + ACCEPTS_SCORE: false, + BODY: { + PENETRATION: 1, + SPEED: 3.75, + RANGE: 90, + DENSITY: 1.25, + HEALTH: 10, + DAMAGE: 6, + PUSHABILITY: 0.3, + }, + COLOR: 'mirror', + FACING_TYPE: "toTarget", + CAN_GO_OUTSIDE_ROOM: true, + HITS_OWN_TYPE: "never", + DIE_AT_RANGE: true, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + }, { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + } + ], +} \ No newline at end of file diff --git a/server/modules/definitions/groups/tanks.js b/server/modules/definitions/groups/tanks.js index 49ccee8bd..654de8ca2 100644 --- a/server/modules/definitions/groups/tanks.js +++ b/server/modules/definitions/groups/tanks.js @@ -1,13 +1,23 @@ -const { combineStats, makeAuto, makeOver, makeDeco, makeGuard, makeBird, makeMulti, makeRadialAuto, weaponArray } = require('../facilitators.js'); +const { combineStats, makeAuto, makeOver, makeDeco, makeGuard, makeBird, makeRadialAuto, weaponArray, makeCeption, makeAura } = require('../facilitators.js'); const { base, statnames, gunCalcNames, dfltskl, smshskl } = require('../constants.js'); require('./generics.js'); const g = require('../gunvals.js'); +const fireGun = (gun) => { + gun.fire( + gun.offset * Math.cos(gun.direction + gun.angle + gun.body.facing) + (1.35 * gun.length - gun.width * gun.settings.size / 2) * Math.cos(gun.angle + gun.body.facing), + gun.offset * Math.sin(gun.direction + gun.angle + gun.body.facing) + (1.35 * gun.length - gun.width * gun.settings.size / 2) * Math.sin(gun.angle + gun.body.facing), + gun.body.skill + ); +}; + // Basic & starting upgrades Class.basic = { PARENT: "genericTank", LABEL: "Basic", DANGER: 4, + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + SKILL: Array(10).fill(12), /*BODY: { ACCELERATION: base.ACCEL * 1, SPEED: base.SPEED * 1, @@ -1196,22 +1206,13 @@ Class.hexaTank = { PARENT: "genericTank", LABEL: "Hexa Tank", DANGER: 6, - GUNS: weaponArray([ - { - POSITION: [18, 8, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet" - } - }, - { - POSITION: [18, 8, 1, 0, 0, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), - TYPE: "bullet" - } + GUNS: weaponArray({ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), + TYPE: "bullet" } - ], 3) + }, 6, 0.5) } Class.triAngle = { PARENT: "genericTank", @@ -1257,6 +1258,7 @@ Class.octoTank = { LABEL: "Octo Tank", DANGER: 7, GUNS: weaponArray([ + // Must be kept like this to preserve visual layering { POSITION: [18, 8, 1, 0, 0, 0, 0], PROPERTIES: { @@ -1465,7 +1467,7 @@ Class.surfer = { // Auto-3 upgrades Class.auto5 = makeRadialAuto("autoTankGun", {isTurret: true, danger: 7, label: "Auto-5", count: 5}) -Class.mega3 = makeRadialAuto("megaAutoTankGun", {isTurret: true, danger: 7, size: 14, label: "Mega-5", body: {SPEED: 0.95 * base.SPEED}}) +Class.mega3 = makeRadialAuto("megaAutoTankGun", {isTurret: true, danger: 7, size: 14, label: "Mega-3", body: {SPEED: 0.95 * base.SPEED}}) Class.auto4 = makeRadialAuto("auto4gun", {isTurret: true, danger: 7, size: 13, x: 6, angle: 45, label: "Auto-4", count: 4}) Class.banshee = makeRadialAuto("bansheegun", {isTurret: true, danger: 7, size: 10, arc: 80, label: "Banshee", body: {SPEED: 0.8 * base.SPEED, FOV: 1.1 * base.FOV}}) Class.banshee.GUNS = weaponArray({ @@ -1689,8 +1691,8 @@ Class.commander = { BODY: { FOV: base.FOV * 1.15, }, - GUNS: weaponArray([ - { + GUNS: [ + ...weaponArray({ POSITION: [8, 11, 1.3, 6, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.drone]), @@ -1700,16 +1702,16 @@ Class.commander = { MAX_CHILDREN: 2, STAT_CALCULATOR: gunCalcNames.drone, }, - }, - { - POSITION: [7, 7.5, 0.6, 7, 0, 180, 0], + }, 3), + ...weaponArray({ + POSITION: [7, 7.5, 0.6, 7, 0, 60, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.swarm, g.commander]), TYPE: "swarm", STAT_CALCULATOR: gunCalcNames.swarm, }, - } - ], 3) + }, 3, 1/3), + ] } // Cruiser upgrades @@ -1807,6 +1809,7 @@ Class.fortress = { FOV: 1.2 * base.FOV, }, GUNS: [ + ...weaponArray( { POSITION: [7, 7.5, 0.6, 7, 0, 60, 0], PROPERTIES: { @@ -1814,23 +1817,7 @@ Class.fortress = { TYPE: "swarm", STAT_CALCULATOR: gunCalcNames.swarm, }, - }, - { - POSITION: [7, 7.5, 0.6, 7, 0, 180, 1 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, - { - POSITION: [7, 7.5, 0.6, 7, 0, 300, 2 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.swarm]), - TYPE: "swarm", - STAT_CALCULATOR: gunCalcNames.swarm, - }, - }, + }, 3, 1/3), ...weaponArray([ { POSITION: [14, 9, 1, 0, 0, 0, 0], @@ -1858,50 +1845,16 @@ Class.necromancer = { }, SHAPE: 4, MAX_CHILDREN: 14, - GUNS: [ - { - POSITION: [5.25, 12, 1.2, 8, 0, 90, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - }, - }, - { - POSITION: [5.25, 12, 1.2, 8, 0, 270, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - STAT_CALCULATOR: gunCalcNames.necro, - }, - }, - { - POSITION: [5.25, 12, 1.2, 8, 0, 0, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - MAX_CHILDREN: 4, - STAT_CALCULATOR: gunCalcNames.necro, - }, - }, - { - POSITION: [5.25, 12, 1.2, 8, 0, 180, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), - TYPE: "sunchip", - AUTOFIRE: true, - SYNCS_SKILLS: true, - MAX_CHILDREN: 4, - STAT_CALCULATOR: gunCalcNames.necro, - }, + GUNS: weaponArray({ + POSITION: [5.25, 12, 1.2, 8, 0, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.sunchip]), + TYPE: "sunchip", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.necro, }, - ], + }, 4, 0.75), } Class.maleficitor = { PARENT: "genericTank", @@ -2313,7 +2266,6 @@ Class.fieldGun = { }, }, { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ POSITION: [10, 9, 1, 9, 0, 0, 0], }, { @@ -2576,7 +2528,6 @@ Class.assembler = { ], TURRETS: [ { - /** SIZE X Y ANGLE ARC */ POSITION: [2.5, 14, 0, 0, 360, 1], TYPE: 'assemblerDot' } @@ -2586,7 +2537,6 @@ Class.assembler = { // Tri-Trapper upgrades Class.hexaTrapper = makeAuto({ PARENT: "genericTank", - LABEL: "Hexa-Trapper", DANGER: 7, BODY: { SPEED: 0.8 * base.SPEED, @@ -2605,19 +2555,8 @@ Class.hexaTrapper = makeAuto({ STAT_CALCULATOR: gunCalcNames.trap, }, }, - { - POSITION: [15, 7, 1, 0, 0, 180, 0.5], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 180, 0.5], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], 3), -}) + ], 6, 0.5), +}, "Hexa-Trapper") Class.septaTrapper = { PARENT: "genericTank", LABEL: "Septa-Trapper", @@ -2627,7 +2566,7 @@ Class.septaTrapper = { }, STAT_NAMES: statnames.trap, HAS_NO_RECOIL: true, - GUNS: [ + GUNS: weaponArray([ { POSITION: [15, 7, 1, 0, 0, 0, 0], }, @@ -2639,73 +2578,7 @@ Class.septaTrapper = { STAT_CALCULATOR: gunCalcNames.trap, }, }, - { - POSITION: [15, 7, 1, 0, 0, 360 / 7, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 360 / 7, 1 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, -360 / 7, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, -360 / 7, 1 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 360 / 7 * 2, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 360 / 7 * 2, 2 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, -360 / 7 * 2, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, -360 / 7 * 2, 2 / 3], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, 360 / 7 * 3, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, 360 / 7 * 3, 1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - { - POSITION: [15, 7, 1, 0, 0, -360 / 7 * 3, 0], - }, - { - POSITION: [3, 7, 1.7, 15, 0, -360 / 7 * 3, 1], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.hexaTrapper]), - TYPE: "trap", - STAT_CALCULATOR: gunCalcNames.trap, - }, - }, - ], + ], 7, 4/7), } Class.architect = makeRadialAuto("architectGun", {isTurret: true, danger: 7, size: 12, label: "Architect", body: {SPEED: 1.1 * base.SPEED}}) @@ -2880,7 +2753,7 @@ Class.helix = { { POSITION: [20, 8, 0.75, 0, -5, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos]), + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.desmos, {shudder: 0, spray: 0, size: 0.8}]), TYPE: ["bullet", {MOTION_TYPE: ["desmos", {invert: false}]}] }, }, @@ -2931,13 +2804,13 @@ Class.undertow = { PARENT: "genericTank", LABEL: "Undertow", DANGER: 6, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + //UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", GUNS: [ { POSITION: [14, 12, 0.8, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { reload: 1.2 }]), - TYPE: "bullet" + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { health: 1.2, damage: 0.05 }]), + TYPE: "undertowbullet", } }, { @@ -3064,8 +2937,8 @@ Class.quadruplex = { { POSITION: [20, 10, 0.8, 0, 0, -135, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin]), - TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 10, invert: true}]}] + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, g.twin, { reload: 2 }]), + TYPE: ["bullet", {MOTION_TYPE: ["desmos", {period: 7, amplitude: 12.5, invert: true}]}] } }, { @@ -3166,14 +3039,64 @@ Class.oroboros = { STAT_NAMES: statnames.desmos, UPGRADE_TOOLTIP: "[DEV NOTE] This tank is a placeholder!" } +Class.cocciPart1 = { + PARENT: "genericSmasher", + LABEL: "", + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, + { + POSITION: [20, -22, 0, 0, 90/4, 0], + TYPE: "smasher", + VULNERABLE: true + }, + ] +} +Class.cocciPart2 = { + PARENT: "genericSmasher", + LABEL: "", + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, + { + POSITION: [20, -22, 0, 0, 90/3, 0], + TYPE: "cocciPart1", + VULNERABLE: true + }, + ] +} +Class.cocciPart3 = { + PARENT: "genericSmasher", + LABEL: "", + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, + { + POSITION: [20, -22, 0, 0, 90/2, 0], + TYPE: "cocciPart2", + VULNERABLE: true + }, + ] +} Class.cocci = { PARENT: "genericSmasher", LABEL: "Cocci", - UPGRADE_TOOLTIP: "[DEV NOTE] This tank is a placeholder!", + UPGRADE_TOOLTIP: "[DEV NOTE] this is a very early prototype and probably won't work so well lol", TURRETS: [ { POSITION: [21.5, 0, 0, 0, 360, 0], TYPE: "smasherBody" + }, + { + POSITION: [20, -22, 0, 0, 90, 0], + TYPE: "cocciPart3", + VULNERABLE: true } ] } @@ -3183,7 +3106,7 @@ Class.riptide = { PARENT: "genericTank", LABEL: "Riptide", DANGER: 7, - UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", + //UPGRADE_TOOLTIP: "[DEV NOTE] This tank does not function as intended yet!", GUNS: [ { POSITION: [6.5, 23.5, 0.25, 3, 0, 180, 0], @@ -3191,8 +3114,8 @@ Class.riptide = { { POSITION: [18, 16, 0.75, 0, 0, 0, 0], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { size: 0.9, reload: 1.2 }]), - TYPE: "bullet" + SHOOT_SETTINGS: combineStats([g.basic, g.desmos, { size: 0.9, speed: 0.75, reload: 1.45, health: 1.5, damage: 0.1, maxSpeed: 0.8 }]), + TYPE: "undertowbullet", } }, { @@ -3532,13 +3455,6 @@ Class.vulture = makeBird({ Class.phoenix = makeBird("sprayer", "Phoenix") Class.eagle = makeBird("pounder", "Eagle") -// Hybrid tanks -Class.bentHybrid = makeOver('tripleShot', "Bent Hybrid", {count: 1, independent: true, cycle: false}) -Class.poacher = makeOver('hunter', "Poacher", {count: 1, independent: true, cycle: false}) -Class.armsman = makeOver('rifle', "Armsman", {count: 1, independent: true, cycle: false}) -Class.cropDuster = makeOver('minigun', "Crop Duster", {count: 1, independent: true, cycle: false}) -Class.hybrid = makeOver('destroyer', "Hybrid", {count: 1, independent: true, cycle: false}) - // Over tanks Class.overgunner = makeOver({ PARENT: "genericTank", @@ -3588,76 +3504,2467 @@ Class.overtrapper = makeOver({ ] }) -// Auto tanks -Class.autoDouble = makeAuto("doubleTwin", "Auto-Double") -Class.autoAssassin = makeAuto("assassin") -Class.autoGunner = makeAuto("gunner") -Class.autoTriAngle = makeAuto("triAngle") -Class.autoOverseer = makeAuto("overseer") -Class.autoCruiser = makeAuto("cruiser") -Class.autoSpawner = makeAuto("spawner") -Class.autoBuilder = makeAuto("builder") -Class.autoSmasher = makeAuto({ - PARENT: "genericSmasher", +//delta upgrades +Class.minilaser = { + PARENT: "genericTank", + LABEL: "Plasma SMG", DANGER: 6, - TURRETS: [ + BODY: { + FOV: 1.2, + }, + GUNS: [ { - POSITION: [21.5, 0, 0, 0, 360, 0], - TYPE: "smasherBody" + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [21, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 1 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 2 / 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.doublereload, g.one_third_reload]), + TYPE: "laser", + }, + }, + { + POSITION: [24, 1, 1, 0, 0, 0, 2 / 3], + PROPERTIES: { + COLOR: 'red', + SHOOT_SETTINGS: combineStats([g.fake]), + TYPE: "laser", + }, } ], - SKILL_CAP: [smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl] -}, "Auto-Smasher", {type: "autoSmasherTurret", size: 11}) - -// Upgrade paths -Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "desmos"] - Class.basic.UPGRADES_TIER_2 = ["smasher"] - Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "autoSmasher", "landmine", "cocci"] - Class.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] - - Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "helix"] - Class.twin.UPGRADES_TIER_3 = ["dual", "bulwark", "musket"] - Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble"] - Class.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentHybrid", "bentDouble", "triplet", "triplex"] - - Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle"] - Class.sniper.UPGRADES_TIER_3 = ["bushwhacker"] - Class.assassin.UPGRADES_TIER_3 = ["ranger", "falcon", "stalker", "autoAssassin", "single"] - Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "dual"] - Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman"] - - Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer"] - Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture"] - Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner"] - Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal"] - - Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper"] - Class.flankGuard.UPGRADES_TIER_3 = ["tripleTwin", "quadruplex"] - Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper"] - Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "surfer", "eagle", "phoenix", "vulture"] - Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee"] - - Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "spawner"] - Class.director.UPGRADES_TIER_3 = ["manager", "bigCheese"] - Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "overdrive", "commander"] - Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "autoCruiser", "commander"] - Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor"] - Class.spawner.UPGRADES_TIER_3 = ["factory", "autoSpawner", "ranch"] - - Class.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher"] - Class.pounder.UPGRADES_TIER_3 = ["shotgun", "eagle"] - Class.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct"] - Class.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun"] - Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun"] - - Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard"] - Class.trapper.UPGRADES_TIER_3 = ["barricade", "overtrapper"] - Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror"] - Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect"] - Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark"] - - Class.desmos.UPGRADES_TIER_2 = ["helix", "sidewinder", "undertow", "repeater"] - Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "coil", "duplicator"] - Class.sidewinder.UPGRADES_TIER_3 = ["coil", "python", "ranch", "oroboros", "cocci"] - Class.undertow.UPGRADES_TIER_3 = ["riptide"] - Class.repeater.UPGRADES_TIER_3 = ["iterator", "duplicator"] +} +Class.cruiserdrive = { + PARENT: "genericTank", + LABEL: "Swarmdrive", + DANGER: 6, + FACING_TYPE: "locksFacing", + STAT_NAMES: statnames.swarm, + BODY: { + FOV: 1.2 * base.FOV, + }, + GUNS: [ + { + POSITION: [7, 7.5, 0.6, 7, 4, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "autoturretswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + { + POSITION: [7, 7.5, 0.6, 7, -4, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.swarm]), + TYPE: "autoturretswarm", + STAT_CALCULATOR: gunCalcNames.swarm, + }, + }, + ], +} +Class.shrapnelgun = { + PARENT: "genericTank", + LABEL: "Albuquerque", + DANGER: 7, + GUNS: [{ + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, { reload: 1.8 }]), + TYPE: "grenade" + } + } + ], + TURRETS: [{ + POSITION: [8.2, 16.7, 0, 0, 0, 0], + TYPE: ["grenadeDeco", { MIRROR_MASTER_ANGLE: true }], + } + ] +} +Class.firecracker = { + PARENT: "genericTank", + LABEL: "Firecracker", + DANGER: 7, + GUNS: [{ + POSITION: [17, 13, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, g.artillery, g.halfspeed, g.halfspeed, { reload: 2.5 }]), + TYPE: "firecrackerbomb" + } + } + ], + TURRETS: [{ + POSITION: [8.2, 13, 0, 0, 0, 2], + TYPE: ["firecrackerDeco", { MIRROR_MASTER_ANGLE: true }], + } + ] +} +Class.inception = { + PARENT: "genericTank", + LABEL: "Inception", + DANGER: 4, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "autobullet", + } + } + ], + TURRETS: [{ + POSITION: [5.5, 18, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.inceptionist = { + PARENT: "genericTank", + LABEL: "Ceptionist", + DANGER: 4, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "ceptionistbullet", + } + } + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.twinceptionist = { + PARENT: "genericTank", + LABEL: "Twinceptionist", + DANGER: 4, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "ceptionistbullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin]), + TYPE: "ceptionistbullet" + } + } + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.machinception = { + PARENT: "genericTank", + LABEL: "Machceptioner", + DANGER: 4, + GUNS: [ + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "autobullet" + } + } + ], + TURRETS: [{ + POSITION: [6.5, 20, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.machceptionist = { + PARENT: "genericTank", + LABEL: "Machceptionist", + DANGER: 4, + GUNS: [ + { + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun]), + TYPE: "ceptionistbullet" + } + } + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.flankinception = { + PARENT: "genericTank", + LABEL: "Flankceptioner", + BODY: { + SPEED: 1.1 * base.SPEED + }, + GUNS: weaponArray({ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "autobullet" + } + }, 3), + TURRETS: weaponArray({ + POSITION: [5.5, 18, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + }, 3) +} +Class.flankceptionist = { + PARENT: "genericTank", + LABEL: "Flankceptionist", + BODY: { + SPEED: 1.1 * base.SPEED + }, + GUNS: weaponArray({ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "ceptionistbullet" + } + }, 3), + TURRETS: weaponArray({ + POSITION: [5.5, 18, 0, 0, 0, 0], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + }, 3) +} +Class.flankdue = { + PARENT: "genericTank", + LABEL: "Flankduer", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + SPEED: base.SPEED * 1.1, + }, + GUNS: weaponArray([{ + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.hunter]), + TYPE: "bullet" + } + }], 3) +} +Class.tailgator = { + PARENT: "genericTank", + LABEL: "Tailgator", + DANGER: 4, + GUNS: [ + { + POSITION: [20.5, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), + TYPE: "heavyautobullet" + } + } + ], + TURRETS: [{ + POSITION: [7.5, 20, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.poundceptionist = { + PARENT: "genericTank", + LABEL: "PoundCeptionist", + DANGER: 4, + GUNS: [ + { + POSITION: [20.5, 12, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder]), + TYPE: "ceptionistbullet" + } + } + ], + TURRETS: [{ + POSITION: [10, 0, 0, 0, 0, 1], + TYPE: ["ceptionistturret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.interceptor = { + PARENT: "genericTank", + LABEL: "Interceptor", + DANGER: 4, + GUNS: [ + { + POSITION: [21, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), + TYPE: "heavyautobullet" + } + } + ], + TURRETS: [{ + POSITION: [7.5, 20, 0, 0, 0, 0], + TYPE: ["autoTurret", { INDEPENDENT: true, MIRROR_MASTER_ANGLE: true }] + } + ] +} +Class.revolutionist = { + PARENT: "genericTank", + LABEL: "Revolutionist", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBase", + }, + ], +}; +Class.proton = { + PARENT: "genericTank", + LABEL: "Proton", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "protonturretBase", + }, + ], +}; +Class.baseThrower = { + PARENT: "genericTank", + LABEL: "Kivaaritehdas", + DANGER: 6, + SYNC_TURRET_SKILLS: true, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [1, 38, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.boomerang, g.kiva]), + TYPE: ["baseBullet", { COLOR: "#FC8208", KEEP_OWN_COLOR: false }], + ALT_FIRE: true, + ALPHA: 0 + } + }], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBaseKiva", + }], + ON: [{ + event: "altFire", + handler: ({ body }) => { + body.define(Class.baseThrowerFire) + } + } + ] +}; +Class.baseThrowerFire = { + PARENT: "genericTank", + LABEL: "Kivaaritehdas", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet" + } + }] +}; +Class.subverter = { + PARENT: "genericTank", + LABEL: "Subverter", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "subverterturretBase", + }, + ], +}; +Class.pion = { + PARENT: "genericSmasher", + LABEL: "Pion", + DANGER: 6, + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, { + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "pionturretBase", + }] +} +Class.equilibrium = { + PARENT: "genericTank", + LABEL: "Equilibrium", + DANGER: 6, + GUNS: [ + { + POSITION: [20, 8, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.twin]), + TYPE: "bullet" + } + }, + { + POSITION: [20, 8, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.twin]), + TYPE: "bullet" + } + } + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBase", + }, + ], +}; +Class.hadron = { + PARENT: "genericTank", + LABEL: "Hadron", + DANGER: 6, + GUNS: [{ + POSITION: [20, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard]), + TYPE: "bullet", + }, + }, + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "hadronturretBase", + } + ], +}; +Class.hivemind = { + PARENT: "genericTank", + LABEL: "Hivemind", + //CONTROLLERS: ['nearestDifferentMaster'], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.cloner]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 90, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "hiveprobe", + MAX_CHILDREN: 1 + } + }, + { + POSITION: [0, 20, 1, 0, 0, 270, 3.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "hiveprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [27, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; +Class.cloner = { + PARENT: ["genericTank"], + LABEL: "Cloner", + //CONTROLLERS: ['nearestDifferentMaster'], + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.cloner]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 180, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "clonerprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [24, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}; + Class.dictator = { + PARENT: ["genericTank"], + LABEL: "Dictator", + STAT_NAMES: statnames.drone, + DANGER: 5, + SHAPE: 8, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + FOV: base.FOV * 1.1, + }, + MAX_CHILDREN: 4, + GUNS: [ { /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [ 6, 12, 1.2, 8, 0, 0, 0, ], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer]), + TYPE: "fastdrone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + }, }, + ], + }; +Class.littleHunter = { + PARENT: "genericTank", + LABEL: "Subduer", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter]), + TYPE: "bullet" + } + }] +}; +Class.subway = makeBird({ + PARENT: "genericTank", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.05 + }, + GUNS: [{ + POSITION: [23, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.triAngle, g.triAngleFront, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.triAngle, g.triAngleFront, g.hunter]), + TYPE: "bullet" + } + }] +}, "Subway") +Class.binary = { + PARENT: "genericTank", + LABEL: "Binary", + DANGER: 5, + BODY: { + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [20, 5, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [17, 8, 1, 0, 5.5, 0, 0.2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter]), + TYPE: "bullet" + } + }, { + POSITION: [20, 5, 1, 0, -5.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter, g.hunterSecondary]), + TYPE: "bullet" + } + }, { + POSITION: [17, 8, 1, 0, -5.5, 0, 0.7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.twin, g.hunter]), + TYPE: "bullet" + } + }] +} +Class.trinary = { + PARENT: "genericTank", + LABEL: 'Trinary', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .7, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [22, 5, 1, 0, 2, 20, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [19, 8, 1, 0, 2, 20, .7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [22, 5, 1, 0, -2, -20, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [19, 8, 1, 0, -2, -20, .7], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [25, 5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }, { + POSITION: [22, 8, 1, 0, 0, 0, .2], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.twin, g.tripleShot]), + TYPE: "bullet" + } + }] +}; +Class.bigSubduer = { + PARENT: "genericTank", + LABEL: 'Mitochondrion', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .9, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [26, 2, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [23, 5, 1, 0, 0, 0, .15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, .3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.predator]), + TYPE: "bullet" + } + }] +} +Class.clubbin = { + PARENT: "genericTank", + LABEL: "Clubbin", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .9, + FOV: 1.1 + }, + GUNS: weaponArray([{ + POSITION: [26, 2, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [23, 5, 1, 0, 0, 0, .15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, .3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.flankGuard, g.hunter, g.predator]), + TYPE: "bullet" + } + }], 3) +} +Class.biggerSubduer = { + PARENT: "genericTank", + LABEL: 'Cytochrome', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 0.8, + SPEED: base.SPEED * 0.95, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [29, 2, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.hunterSecondary, g.predator, g.lessrecoil]), + TYPE: "bullet" + } + }, { + POSITION: [26, 4, 1, 0, 0, 0, 2/15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.hunterSecondary, g.predator, g.lessrecoil]), + TYPE: "bullet" + } + }, { + POSITION: [23, 6, 1, 0, 0, 0, 4/15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.hunterSecondary, g.predator]), + TYPE: "bullet" + } + }, { + POSITION: [20, 8, 1, 0, 0, 0, 0.4], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.littleHunter, g.hunter, g.predator]), + TYPE: "bullet" + } + }] +} +Class.accelminigun = { + PARENT: "genericTank", + LABEL: "Rainmaker", + DANGER: 6, + BODY: { + FOV: base.FOV * 1.4 + }, + GUNS: [ + { + POSITION: [8, .1, -54, 21, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.fake, g.triplereload]), + TYPE: "bullet", + COLOR: 12 + } + }, + { + POSITION: [21, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + } + }, + { + POSITION: [19, 8, 1, 0, 0, 0, 1/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + } + }, + { + POSITION: [17, 8, 1, 0, 0, 0, 2/3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.minigun, g.rainmaker, g.morerange]), + TYPE: ["bullet", { MOTION_TYPE: "accelerate" }] + } + } + ] +} +Class.railgun = { + PARENT: "genericTank", + DANGER: 6, + LABEL: "Railgun", + BODY: { + SPEED: 0.9 * base.SPEED, + FOV: 1.25 * base.FOV + }, + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [1, 6.5, 1, 25, 0, 0, 0.15], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.fast, g.fast, g.railgun]), + TYPE: "bullet" + } + }, { + POSITION: [1, 6.5, 1, 10, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.railgun]), + TYPE: "bullet" + } + }, { + POSITION: [1, 6.5, 1, 15, 0, 0, 0.05], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.railgun]), + TYPE: "bullet" + } + }, + { + POSITION: [1, 6.5, 1, 20, 0, 0, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin, g.one_third_reload, g.fast, g.fast, g.fast, g.railgun]), + TYPE: "bullet" + } + }, + { + POSITION: [22, 1.9, 1, 5, 4, 0, 0] + }, + { + POSITION: [22, 1.9, 1, 5, -4, 0, 0] + } + ] +} +Class.skater = { + PARENT: "genericSmasher", + LABEL: "Skater", + DANGER: 6, + BODY: { + SPEED: base.SPEED * 2.4, + ACCELERATION: base.ACCEL * 0.56, + }, + + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + }, { + POSITION: [15, 0, 0, 0, 360, 1], + TYPE: ["skaterDeco", { COLOR: "#49bdde" }] + } + ] +} +Class.revodirector = { + PARENT: "genericTank", + LABEL: "Solar System", + STAT_NAMES: statnames.drone, + BODY: { + FOV: base.FOV * 1.1 + }, + GUNS: [ + { + POSITION: [6, 11, 1.3, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone]), + TYPE: "revoorbitdrone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 5 + } + } + ], + TURRETS: [{ + POSITION: [34, 0, 0, 0, 360, 0], + TYPE: "turretBasenoguns", + }, { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "overdriveDeco", + }, + ], +} +Class.directdrive = { + PARENT: "genericTank", + LABEL: "Motor", + STAT_NAMES: statnames.drone, + BODY: { + FOV: base.FOV * 1.1 + }, + GUNS: [ + { + POSITION: [6, 11, 1.3, 7, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone]), + TYPE: "turretedDrone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 6 + } + } + ], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "overdriveDeco", + }, + ] +} +Class.contagion = { + PARENT: "genericTank", + LABEL: 'Contagion', + DANGER: 6, + BODY: { + FOV: 1.1, + ACCELERATION: base.ACCEL * 0.9 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [13, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [4, 8, 1.7, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.morerange, g.lessspread]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + }] +}; +Class.triContagion = { + PARENT: "genericTank", + LABEL: "Tri-Contagion", + DANGER: 6, + BODY: { + FOV: 1.1, + ACCELERATION: base.ACCEL * 0.9 + }, + STAT_NAMES: statnames.mixed, + GUNS: weaponArray([{ + POSITION: [19, 5.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [13, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [4, 8, 1.7, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.morerange, g.lessspread, g.flankGuard]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + }], 3) +} +Class.autoContagion = makeAuto("contagion"); +Class.fort = { + PARENT: "genericTank", + LABEL: "Fort", + DANGER: 7, + BODY: { + SPEED: base.SPEED * 0.8, + ACCELERATION: base.ACCEL * 0.9, + FOV: 1.15 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [22, 5.5, 1, 0, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [18, 12, 1, 0, 0, 0, 0] + }, { + POSITION: [2, 12, 1.1, 18, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap]), + TYPE: "setTrap" + } + }] +}; +Class.droneTrapper = { + PARENT: "genericTank", + LABEL: "Magician", + DANGER: 7, + BODY: { + FOV: 1.1, + ACCELERATION: base.ACCEL * .9 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.lesspower]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 6 + } + }, { + POSITION: [13, 8, 1, 0, 0, 0, 0] + }, { + POSITION: [4, 8, 1.7, 13, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + }] +} +Class.trojan = { + PARENT: "genericTank", + LABEL: "Trojan", + STAT_NAMES: statnames.mixed, + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * 0.675, + SPEED: base.SPEED * 0.875, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, 0, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.bitlessreload]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 4 + } + }, { + POSITION: [19, 5.5, 1, 0, 0, 180, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi, g.flankGuard]), + TYPE: "bullet" + } + }, { + POSITION: [6, 12, 1.2, 8, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.overseer, g.bitlessreload]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + WAIT_TO_CYCLE: true, + MAX_CHILDREN: 4 + } + }] +} +Class.gundirector = { + PARENT: "genericTank", + LABEL: "Pathogen", + STAT_NAMES: statnames.mixed, + DANGER: 6, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: base.SPEED * 0.95, + FOV: 1.1 + }, + GUNS: [{ + POSITION: [19, 5.5, 1, 0, 0, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [6, 12, 1.2, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.drone, g.bitlessreload]), + TYPE: "drone", + AUTOFIRE: true, + SYNCS_SKILLS: true, + STAT_CALCULATOR: gunCalcNames.drone, + MAX_CHILDREN: 6 + } + }] +} +Class.protist = { + PARENT: "genericTank", + LABEL: "Protist", + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .9, + SPEED: base.SPEED * .8, + FOV: 1.1 + }, + STAT_NAMES: statnames.mixed, + GUNS: [{ + POSITION: [18, 5.5, 1, 0, 0, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.contagi]), + TYPE: "bullet" + } + }, { + POSITION: [4.5, 10, 1, 10.5, 0, 0, 0] + }, { + POSITION: [1, 12, 1.01, 15, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.factory, g.babyfactory]), + TYPE: "minion", + STAT_CALCULATOR: gunCalcNames.drone, + AUTOFIRE: true, + SYNCS_SKILLS: true, + MAX_CHILDREN: 4 + } + }, { + POSITION: [3.5, 12, 1, 8, 0, 0, 0] + }] +}; +Class.acid = { + PARENT: "genericTank", + LABEL: 'Acid', + DANGER: 6, + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: base.SPEED * 0.85, + FOV: base.FOV * 1.2, + }, + GUNS: [{ + POSITION: [24, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "poisonbullet", + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "green" + } + }] +}; +Class.disintegrator = { + PARENT: "genericTank", + DANGER: 6, + LABEL: "Disintegrator", + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: 0.7 * base.SPEED, + FOV: 1.4 * base.FOV + }, + GUNS: [ + { + POSITION: [27, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), + TYPE: "poisonbullet" + } + }, { + POSITION: [16, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "green" + } + }, { + POSITION: [5, 8, -1.4, 8, 0, 0, 0] + } + ] +} +Class.chiller = { + PARENT: "genericTank", + LABEL: 'Chiller', + DANGER: 6, + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.7, + FOV: 1.2 + }, + GUNS: [{ + POSITION: [24, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "icebullet" + } + }, { + POSITION: [13.95, 5.15, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + }] +}; +Class.freezer = { + PARENT: "genericTank", + DANGER: 6, + LABEL: "Freezer", + GLOW: { + RADIUS: 2, + COLOR: "#28B1DE", + ALPHA: 1, + RECURSION: 4, + }, + BODY: { + ACCELERATION: base.ACCEL * 0.75, + SPEED: 0.7 * base.SPEED, + FOV: 1.4 * base.FOV + }, + GUNS: [ + { + POSITION: [27, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper, g.assassin]), + TYPE: "icebullet" + } + }, { + POSITION: [16, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + COLOR: "#28B1DE" + } + }, { + POSITION: [5, 8, -1.4, 8, 0, 0, 0] + } + ] +} +Class.helecopter = { + PARENT: "genericTank", + LABEL: "Attack Helicopter", + BODY: { + SPEED: 6, + PUSHABILITY: 0, + ACCELERATION: 0.8, + }, + DANGER: 6, + GUNS: [{ + POSITION: [19, 2, 1, 0, -2.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + HAS_NO_RECOIL: true, + }, + }, + { + POSITION: [19, 2, 1, 0, 2.5, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + HAS_NO_RECOIL: true, + }, + }, { + POSITION: [2, 2, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.triAngle, g.thruster, g.thruster, g.fakewithrecoil]), + TYPE: "bullet", + AUTOFIRE: true, + }, + }, { + POSITION: [12, 11, 1, 0, 0, 0, 0], + }, + { + POSITION: [26.5, 8, 0.7, 0, 0, 180, 0], + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 180, 0], + }, + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [20, -27.5, 0, 0, 360, 1], + TYPE: "helecoptersblade", + }, + { + /* SIZE X Y ANGLE ARC */ + POSITION: [25, 0, 0, 0, 360, 1], + TYPE: "helecopterblade", + }, + ], +}; +Class.twinsniper = { + PARENT: "genericTank", + LABEL: "Twiper", + DANGER: 7, + BODY: { + FOV: 1.1 * base.FOV + }, + CONTROLLERS: ["zoom"], + TOOLTIP: "Hold right click to zoom.", + GUNS: [ + { + POSITION: [24, 8.5, 1, 0, 5.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sniper]), + TYPE: "bullet" + } + }, + { + POSITION: [24, 8.5, 1, 0, -5.5, 0, .5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.sniper]), + TYPE: "bullet" + } + } + ] +} +Class.backShield = { + PARENT: "genericTank", + LABEL: 'BackShield', + DANGER: 7, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }], + TURRETS: [{ + POSITION: [18, 18, 0, 180, 360, 1], + TYPE: ["backshieldturret", { SHAPE: 12 }], + VULNERABLE: true + }] +}; +Class.mirrorBackShield = { + PARENT: "genericTank", + LABEL: 'BackMirror', + DANGER: 7, + GUNS: [{ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "bullet" + } + }], + TURRETS: [{ + POSITION: [16.7, -18.5, 0, 0, 360, 1], + TYPE: ["mirrorbackshieldturret", { SHAPE: 14 }], + VULNERABLE: true + }] +}; +Class.waterfall = { + PARENT: "genericTank", + LABEL: "Waterfall", + DANGER: 6, + GUNS: [ + { + POSITION: [21, 14, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.destroyer]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 2, 1, 0, -2.5, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [19, 2, 1, 0, 2.5, 180, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, { speed: 0.7, maxSpeed: 0.7 }, g.flankGuard, { recoil: 1.8 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [12, 11, 1, 0, 0, 180, 0], + }, + ], +} +Class.auto2 = { + PARENT: "genericTank", + LABEL: "Auto-2", + DANGER: 5, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [{ + POSITION: [11, 8, 0, 0, 190, 0], + TYPE: "autoTankGun" + }, { + POSITION: [11, 8, 0, 180, 190, 0], + TYPE: "autoTankGun" + }] +} +Class.swivel2 = { + PARENT: "genericTank", + LABEL: "Swivel-2", + DANGER: 5, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [{ + POSITION: [9, 7, 0, 0, 360, 1], + TYPE: "swivelAutoGun" + }, { + POSITION: [9, 7, 0, 180, 360, 1], + TYPE: "swivelAutoGun" + }] +} +Class.swivel3 = { + PARENT: "genericTank", + LABEL: "Swivel-3", + DANGER: 5, + FACING_TYPE: ["spin", {speed: 0.02}], + TURRETS: [{ + POSITION: [9, 7, 0, 0, 360, 1], + TYPE: "swivelAutoGun" + }, { + POSITION: [9, 7, 0, 120, 360, 1], + TYPE: "swivelAutoGun" + }, { + POSITION: [9, 7, 0, 240, 360, 1], + TYPE: "swivelAutoGun" + }] +} +const timer = (run, duration) => { + let timer = setInterval(() => run(), 31.25); + setTimeout(() => { + clearInterval(timer); + }, duration * 1000); +}; + const damageOnTick = (body, instance, multiplier, duration, stopAtSetHealth, hitsOwnTeam) => { + if (!instance) return + if (!instance.damageOnTicking && !instance.godmode && !instance.invuln && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) { + instance.damageOnTicking = true; + setTimeout(() => { + instance.damageOnTicking = false; + }, 2 * duration * 1000); + timer(() => { + if (instance.damageOnTicking && instance.health.amount > stopAtSetHealth && instance.health.amount - (multiplier * 0.5) > stopAtSetHealth) { + instance.health.amount -= multiplier * 0.5; + } //else {if (instance.health.amount - (multiplier * 0.5) < stopAtSetHealth) {instance.health.amount === stopAtSetHealth}} + }, 2 * duration); + } +}; +const iceOnTick = (body, instance, multiplier, duration, hitsOwnTeam) => { + if (!instance) return + if (!instance.invuln && !instance.godmode && (instance.type == "tank" || instance.type == "food" || instance.type == "miniboss" || instance.type == "crasher") && instance.team != body.team) timer(() => { + instance.velocity.x /= 1.05 * multiplier; + instance.velocity.y /= 1.05 * multiplier; + }, 1.5 * duration); +}; +Class.acidsmasher = { + PARENT: "genericSmasher", + LABEL: "Injector", + DANGER: 6, + BODY: { + DAMAGE: base.DAMAGE * 0.87, + }, + TURRETS: [ + { + POSITION: [21.8, 0, 0, 0, 360, 0], + TYPE: "greenSmasherBody", + }, { + POSITION: [22.3, 0, 0, 0, 360, -1], + TYPE: "smasherBody" + } + ], + ON: [{ + event: "damage", + handler: ({ body, damageTool }) => { + damageOnTick(body, damageTool[0], 1, 1, 1, true); + } + }] +} +Class.autoinceptionistbody = { + PARENT: "genericTank", + LABEL: "Auto-Inceptionist base", + DANGER: 4, + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic]), + TYPE: "ceptionistbullet", + } + } + ] +} +Class.surge = { + PARENT: "genericTank", + LABEL: 'Surge', + DANGER: 7, + BODY: { + ACCELERATION: base.ACCEL * .6, + SPEED: base.SPEED * .95, + FOV: 1.2 + }, + GUNS: [{ + POSITION: [24, 8.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.sniper]), + TYPE: "bullet" + } + }, { + POSITION: [0, 0, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fake, g.lance]), + TYPE: "bullet", + ALT_FIRE: true + } + }], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: ["surgeDeco", { MIRROR_MASTER_ANGLE: true }], + }, + ], + VARIABLES: { + surgeMax: 88, + surgeTimer: 0, + firingStage: 1 + }, + ON: [{ + event: "altFire", + handler: ({ body, gun }) => { + if (body.variables.firingStage === 1) body.variables.firingStage = 2 + } + }, { + event: "tick", + handler: ({ body, gun }) => { + switch(body.variables.firingStage) { + case 2: + body.guns[0].canShoot = false; + body.guns[0].settings = combineStats([g.lance, g.emplaser]); + body.guns[0].bulletTypes = [Class.surgeempBullet]; + fireGun(body.guns[0]); + body.guns[0].color.interpret(getTeamColor(TEAM_BLUE)); + + body.variables.surgeTimer++; + if (body.variables.surgeTimer === body.variables.surgeMax) { + body.variables.firingStage++; + } + break; + case 3: + body.guns[0].settings = combineStats([g.basic, { health: 1.3, pen: 1.6, speed: 3, maxSpeed: 3, size: 1.2, range: 0.5 }, g.tonsmorerecoil, g.noSpread]); + body.guns[0].bulletTypes = [Class.lineEMP]; + fireGun(body.guns[0]); + body.variables.firingStage++; + body.guns[0].color.interpret("orange"); + break; + case 4: + body.guns[0].canShoot = false; + body.variables.surgeTimer--; + if (body.variables.surgeTimer === 0) { + body.guns[0].settings = combineStats([g.basic, g.sniper]); + body.guns[0].bulletTypes = [Class.bullet]; + body.variables.firingStage = 1; + body.guns[0].canShoot = true; + body.guns[0].color.interpret("gray"); + } + break; + } + } + }], + GLOW: { + RADIUS: 1.2, + COLOR: "spaceGem", + ALPHA: 1, + RECURSION: 3, + } +} +Class.lancer = { + PARENT: "genericLancer", + LABEL: "Lancer", + //UPGRADE_TOOLTIP: "Daily Tank!", + //UPGRADE_COLOR: "rainbow", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + } + ] +} +Class.lancebrid = makeOver('lancer', "Lancebrid", {count: 1, independent: true, cycle: false}); +Class.autolancer = makeAuto('lancer', "Auto-Lancer"); +Class.autolancebrid = makeAuto('lancebrid', "Auto-Lancebrid"); +Class.trilancer = { + PARENT: "genericLancer", + LABEL: "Tri-Lancer", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + GUNS: weaponArray([{ + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }], 3) +} +Class.hexalancer = { + PARENT: "genericLancer", + LABEL: "Hexa Lancer", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + HAS_NO_RECOIL: true, + GUNS: weaponArray([{ + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }], 6) +} +Class.chasseur = { + PARENT: "genericLancer", + LABEL: "Chasseur", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true, + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + } + ] +} +Class.autochasseur = makeAuto('chasseur', "Auto-Chasseur"); +Class.lancerception = makeAuto('lancer', "Lancer-Ception"); +Class.autotrilancer = makeAuto('trilancer', "Auto-Trilancer"); +Class.chasseubrid = makeOver('chasseur', "Chasseubrid", {count: 1, independent: true, cycle: false}); +Class.trilancebrid = makeOver('trilancer', "Trilancebrid", {count: 1, independent: true, cycle: false}); +Class.trichasseur = { + PARENT: "genericLancer", + LABEL: "Tri-Chasseur", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [25, 15, 0.001, 0, 0, 120, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 120, 0] + }, + { + POSITION: [25, 15, 0.001, 0, 0, 240, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 240, 0] + } + ] +} +Class.tripleur = { + PARENT: "genericLancer", + LABEL: "Tripleur", + BODY: { + SPEED: base.SPEED * 1.1, + DAMAGE: base.DAMAGE * 1 + }, + HAS_NO_RECOIL: true, + GUNS: [ + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [30, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, -30, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, -30, 0] + }, + { + POSITION: [20, 15, 0.001, 0, 0, 30, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 30, 0] + } + ] +} +Class.trailblazer = { + PARENT: "genericLancer", + LABEL: "Trailblazer", + BODY: { + HEALTH: 0.8 * base.HEALTH, + SHIELD: 0.8 * base.SHIELD, + DENSITY: 0.6 * base.DENSITY, + }, + HAS_NO_RECOIL: false, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, + { + POSITION: [16, 8, 1, 0, 0, 150, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + }, + { + POSITION: [16, 8, 1, 0, 0, 210, 0.1], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.triAngle, g.thruster]), + TYPE: "bullet", + LABEL: gunCalcNames.thruster, + }, + } + ] +} +Class.katana = { + PARENT: "genericLancer", + LABEL: "Katana", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + VARIABLES: { + dashes: 3 + }, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance, { recoil: 0 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, { + POSITION: [1, 15, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, { size: 1.4, range: 0.09, speed: 0, maxSpeed: 0 }]), + TYPE: "katanaparticle", + ALT_FIRE: true, + IDENTIFIER: "dash" + } + } + ], + TURRETS: [ + { + POSITION: [9, 0, 0, 0, 360, 1], + TYPE: "katanaDeco", + }, + ], + ON: [{ + event: "altFire", + handler: ({ body, gun }) => { + if (gun.identifier = "dash") { + if (body.variables.dashes > 0) { + body.variables.dashes -= 1; + if (body.variables.dashes < 1) body.guns[2].canShoot = false; + body.sendMessage(`Dashes: ${body.variables.dashes.toString()}`) + body.x += 200 * Math.cos(body.facing); + body.y += 200 * Math.sin(body.facing); + setTimeout(() => { + if (body.guns[2] !== undefined) { + body.variables.dashes += 1; + body.sendMessage(`Dashes: ${body.variables.dashes.toString()}`) + body.guns[2].canShoot = true; + } + }, 5000); + } + } + } + }] +} +Class.dasher = { + PARENT: "genericLancer", + LABEL: "Dasher", + BODY: { + SPEED: base.SPEED * 1.2, + DAMAGE: base.DAMAGE * 0.9 + }, + VARIABLES: { + dashes: 3 + }, + GUNS: [ + { + POSITION: [20, 15, 0.001, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.lance, { recoil: 0 }]), + TYPE: ["bullet", { ALPHA: 0 }], + AUTOFIRE: true + } + }, + { + POSITION: [25, 15, 0.001, 0, 0, 0, 0] + }, { + POSITION: [0, 15, 1, 0, 0, 180, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.fakewithrecoil, { recoil: 10 }]), + TYPE: "katanaparticle", + ALT_FIRE: true, + IDENTIFIER: "dash" + } + } + ], + ON: [{ + event: "altFire", + handler: ({ body, gun }) => { + if (gun.identifier = "dash") { + if (body.variables.dashes > 0) { + body.variables.dashes -= 1; + sockets.broadcast(body.variables.dashes.toString()) + setTimeout(() => { + if (body.guns[2] !== undefined) { + body.variables.dashes += 1; + sockets.broadcast(body.variables.dashes.toString()) + body.guns[2].canShoot = true; + } + }, 5000); + } else { + body.guns[2].canShoot = false; + } + } + } + }] +} + +// Auto tanks +Class.autoBasic = makeAuto("basic", "Auto-Basic"); +Class.autoTwin = makeAuto("twin", "Auto-Twin"); +Class.autoMach = makeAuto("machineGun", "Auto-Machine"); +Class.autoSniper = makeAuto("sniper", "Auto-Sniper"); +Class.autoFlank = makeAuto("flankGuard", "Auto-Flank"); +Class.autoDirector = makeAuto("director", "Chairman"); +Class.autoPound = makeAuto("pounder", "Scratcher"); +Class.autoTrap = makeAuto("trapper", "Auto-Trapper"); +Class.autoDesmos = makeAuto("desmos", "Charter"); +Class.autolittleHunter = makeAuto("littleHunter", "Auto-Subduer") +Class.autoinception = makeAuto("inception", "Deployer"); +Class.autoauto2 = makeAuto("auto2", "Auto²-2"); +Class.autoCloner = makeAuto({ + PARENT: "genericTank", + GUNS: [ + { + /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.cloner]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 180, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "autoclonerprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + /* SIZE X Y ANGLE ARC */ + POSITION: [24, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}, "Auto-Cloner"); +Class.autoDouble = makeAuto("doubleTwin", "Auto-Double") +Class.autoAssassin = makeAuto("assassin") +Class.autoGunner = makeAuto("gunner") +Class.autoTriAngle = makeAuto("triAngle") +Class.autoOverseer = makeAuto("overseer") +Class.autoRevolutionist = makeAuto("revolutionist", "Audioboard"); +Class.autoCruiser = makeAuto("cruiser") +Class.autoSpawner = makeAuto("spawner") +Class.autoBuilder = makeAuto("builder") +Class.autoBinary = makeAuto("binary", "Auto-Binary") +Class.autoinceptionist = makeAuto("autoinceptionistbody", "Poster", {type: 'ceptionistturret'}); +Class.autoGundirector = makeAuto("gundirector", "Auto-Pathogen") +Class.autoBigSubduer = makeAuto("bigSubduer", "Auto-Mitochondrion") +Class.autoFlankdue = makeAuto("flankdue", "Auto-Flankduer") +Class.autoTripleShot = makeAuto("tripleShot", "Auto-Triple Shot"); +Class.autoHunter = makeAuto("hunter", "Twogate"); +Class.autoRifle = makeAuto("rifle", "Sidepoint"); +Class.autoTwinsniper = makeAuto("twinsniper", "Auto-Twiper"); +Class.autoAcid = makeAuto("acid", "Cyanide"); +Class.autoChill = makeAuto("chiller", "Coldpoint"); +Class.autoMini = makeAuto("minigun", "Streamer"); +Class.autoSprayer = makeAuto("sprayer", "Auto-Sprayer"); +Class.autoHexaTank = makeAuto("hexaTank", "Auto-HexaTank"); +Class.autoAuto3 = makeAuto("auto3", "Auto²-3"); +Class.autoUnderseer = makeAuto("underseer", "Auto-Underseer"); +Class.autoDestroy = makeAuto("destroyer", "Executer"); +Class.autoArtillery = makeAuto("artillery", "Bombarder"); +Class.autoLaunch = makeAuto("launcher", "Harbinger"); +Class.autoTriTrapper = makeAuto({ + PARENT: "genericTank", + LABEL: "Mini Defender", + DANGER: 6, + SHAPE: 3, + STAT_NAMES: statnames.trap, + GUNS: weaponArray([ + { + POSITION: [12, 7, 1, 0, 0, 60, 0], + }, + { + POSITION: [3, 7, 1.7, 12, 0, 60, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.flankGuard]), + TYPE: "trap", + STAT_CALCULATOR: gunCalcNames.trap + } + } + ], 3) +}, "Mini Defender"); +Class.autoTrapGuard = makeAuto("trapGuard", "Ducker"); +Class.autoSidewinder = makeAuto("sidewinder", "Auto-Sidewinder"); +Class.autoHelix = makeAuto("helix", "DNA"); +Class.autoUndertow = makeAuto("undertow", "Current"); +Class.autoRepeater = makeAuto("repeater", "Patterner"); +Class.automachinception = makeAuto("machinception", "Machine-Deployer"); +Class.autotailgator = makeAuto("tailgator", "Tailplayer"); +Class.autoflankinception = makeAuto("flankinception", "Flank-Deployer"); +Class.autoBackShield = makeAuto("backShield", "Coverer"); +Class.autoSmasher = makeAuto({ + PARENT: "genericSmasher", + DANGER: 6, + TURRETS: [ + { + POSITION: [21.5, 0, 0, 0, 360, 0], + TYPE: "smasherBody" + } + ], + SKILL_CAP: [smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl, smshskl] +}, "Auto-Smasher", {type: "autoSmasherTurret", size: 11}) + +//Autodrive Stuff +Class.autoMotor = makeAuto("directdrive", "Auto-Motor", { type: "autoTankGunDrive" }); + +//Hybrid Tanks +Class.bascrid = makeOver('basic', "Basebrid", {count: 1, independent: true, cycle: false}) +Class.twinbrid = makeOver('twin', "Twin-Hybrid", {count: 1, independent: true, cycle: false}) +Class.machbrid = makeOver('machineGun', "Machine-Hybrid", {count: 1, independent: true, cycle: false}) +Class.snipebrid = makeOver('sniper', "Snipebrid", {count: 1, independent: true, cycle: false}) +Class.flankbrid = makeOver('flankGuard', "Flankbrid", {count: 1, independent: true, cycle: false}) +Class.poundbrid = makeOver('pounder', "Poundbrid", {count: 1, independent: true, cycle: false}) +Class.trapbrid = makeOver('trapper', "Trapbrid", {count: 1, independent: true, cycle: false}) +Class.desmosbrid = makeOver('desmos', "Desmosbrid", {count: 1, independent: true, cycle: false}) +Class.littleHunterbrid = makeOver('littleHunter', "Subduerbrid", {count: 1, independent: true, cycle: false}) +Class.inceptionbrid = makeOver('inception', "Inceptionbrid", {count: 1, independent: true, cycle: false}) +Class.auto2brid = makeOver('auto2', "Auto-2brid", {count: 1, independent: true, cycle: false}) +Class.doubletwinbrid = makeOver('doubleTwin', "Double Twinbrid", {count: 1, independent: true, cycle: false}) +Class.hexatankbrid = makeOver('hexaTank', "Hexatankbrid", {count: 1, independent: true, cycle: false}) +Class.auto3brid = makeOver('auto3', "Auto-3brid", {count: 1, independent: true, cycle: false}) +Class.binarybrid = makeOver('binary', "ZerOne", {count: 1, independent: true, cycle: false}) +Class.flankduebrid = makeOver('flankdue', "Partier", {count: 1, independent: true, cycle: false, maxDrones: 1}) +Class.bigsubduerbrid = makeOver('bigSubduer', "Enzyme", {count: 1, independent: true, cycle: false}) +Class.clonebrid = makeOver({ + PARENT: "genericTank", + GUNS: [ + { + POSITION: [18, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.cloner]), + TYPE: "bullet" + } + }, + { + POSITION: [0, 20, 1, 0, 0, 180, 3], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.slow]), + TYPE: "hybridclonerprobe", + MAX_CHILDREN: 1 + } + } + ], + TURRETS: [ + { + POSITION: [24, 0, 0, 0, 360, 0], + TYPE: "mindindicator" + } + ] +}, "Cloner-Hybrid", {count: 1, independent: true, cycle: false}) +Class.bentHybrid = makeOver('tripleShot', "Bent Hybrid", {count: 1, independent: true, cycle: false}) +Class.revobrid = makeOver('revolutionist', "Revobrid", {count: 1, independent: true, cycle: false}); +Class.contagionbrid = makeOver('contagion', "Contagibrid", {count: 1, independent: true, cycle: false}) +Class.poacher = makeOver('hunter', "Poacher", {count: 1, independent: true, cycle: false}) +Class.armsman = makeOver('rifle', "Armsman", {count: 1, independent: true, cycle: false}) +Class.cropDuster = makeOver('minigun', "Crop Duster", {count: 1, independent: true, cycle: false}) +Class.hybrid = makeOver('destroyer', "Hybrid", {count: 1, independent: true, cycle: false}) +Class.assbrid = makeOver('assassin', "Sharpshooter", {count: 1, independent: true, cycle: false}) +Class.twipebrid = makeOver('twinsniper', "Twiperbrid", {count: 1, independent: true, cycle: false}) +Class.acidbrid = makeOver('acid', "Acidibrid", {count: 1, independent: true, cycle: false}) +Class.chillbrid = makeOver('chiller', "Chillbrid", {count: 1, independent: true, cycle: false}) +Class.artilbrid = makeOver('artillery', "Artillerbrid", {count: 1, independent: true, cycle: false}) +Class.spraybrid = makeOver('sprayer', "Hoser", {count: 1, independent: true, cycle: false}) +Class.trapguardbrid = makeOver('trapGuard', "TG-Hybrid", {count: 1, independent: true, cycle: false}) +Class.builderbrid = makeOver('builder', "Builderbrid", {count: 1, independent: true, cycle: false}) +Class.launchbrid = makeOver('launcher', "Launcherbrid", {count: 1, independent: true, cycle: false}) +Class.tritrapperbrid = makeOver('triTrapper', "T3T-Hybrid", {count: 1, independent: true, cycle: false}) +Class.helixbrid = makeOver('helix', "Gyre", {count: 1, independent: true, cycle: false}) +Class.sidewinderbrid = makeOver('sidewinder', "Sidewinderbrid", {count: 1, independent: true, cycle: false}) +Class.undertowbrid = makeOver('undertow', "Pullist", {count: 1, independent: true, cycle: false}) +Class.repeaterbrid = makeOver('repeater', "Comparator", {count: 1, independent: true, cycle: false}) +Class.inceptionistbrid = makeOver('inceptionist', "Inceptionistbrid", {count: 1, independent: true, cycle: false}) +Class.machinceptionbrid = makeOver('machinception', "Machinceptibrid", {count: 1, independent: true, cycle: false}) +Class.tailgatorbrid = makeOver('tailgator', "Tailgatorbrid", {count: 1, independent: true, cycle: false}) +Class.flankinceptionbrid = makeOver('flankinception', "Flankinceptibrid", {count: 1, independent: true, cycle: false}) + +//auto hybrid tanks +Class.autotwinbrid = makeOver('autoTwin', "Auto-Twinbrid", {count: 1, independent: true, cycle: false}) +Class.autosnipebrid = makeOver('autoSniper', "Auto-Snipebrid", {count: 1, independent: true, cycle: false}) +Class.automachbrid = makeOver('autoMach', "Auto-Machbrid", {count: 1, independent: true, cycle: false}) +Class.autoflankbrid = makeOver('autoFlank', "Auto-Flankbrid", {count: 1, independent: true, cycle: false}) +Class.autopoundbrid = makeOver('autoPound', "Scratcherbrid", {count: 1, independent: true, cycle: false}) +Class.autotrapbrid = makeOver('autoTrap', "Auto-Trapbrid", {count: 1, independent: true, cycle: false}) +Class.autodesmosbrid = makeOver('autoDesmos', "Chartebrid", {count: 1, independent: true, cycle: false}) +Class.autobascrid = makeOver('autoBasic', "Auto-Basebrid", {count: 1, independent: true, cycle: false}) +Class.autoinceptionbrid = makeOver('autoinception', "Deployerbrid", {count: 1, independent: true, cycle: false}) +Class.autolittleHunterbrid = makeOver('autolittleHunter', "Auto-Subbrid", {count: 1, independent: true, cycle: false}) +Class.autoauto2brid = makeOver('auto2', "Auto²-2brid", {count: 1, independent: true, cycle: false}) + +//hybrid drive tanks +Class.car = makeOver('basic', "Car", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.mercedes = makeOver('twin', "Mercedes", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.tesla = makeOver('sniper', "Tesla", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.toyota = makeOver('machineGun', "Toyota", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.ford = makeOver('flankGuard', "Ford", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.honda = makeOver('pounder', "Honda", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.gmc = makeOver('trapper', "GMC", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.porsche = makeOver('autoBasic', "Porsche", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.mazda = makeOver('desmos', "Mazda", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.volkswagen = makeOver('littleHunter', "Volkswagen", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.audi = makeOver('inception', "Audi", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) +Class.ferrari = makeOver('auto2', "Ferrari", {count: 1, independent: true, cycle: false, type: "turretedDrone"}) + +//Ceptions +Class.basicCeption = makeCeption('basic', "Basiception"); +Class.twinCeption = makeCeption('twin', "Twinception"); +Class.snipeCeption = makeCeption('sniper', "Snipeception"); +Class.machCeption = makeCeption('machineGun', "Machception"); +Class.flankCeption = makeCeption('flankGuard', "Flankception"); +Class.directCeption = makeCeption('director', "Droneception"); +Class.poundCeption = makeCeption('pounder', "Poundception"); +Class.trapCeption = makeCeption('trapper', "Trapception"); +Class.desmosCeption = makeCeption('desmos', "Desmosception"); +Class.bascridCeption = makeCeption('bascrid', "Baseception"); +Class.littleHunterCeption = makeCeption('littleHunter', "Subception"); +Class.inceptCeption = makeCeption('inception', "Incepticon"); +Class.auto2Ception = makeCeption('auto2', "Auto-2²"); +Class.revoception = makeCeption('revolutionist', "revonception"); + +//Trackers +Class.trackerSmasher = makeAuto('smasher', "Scanner", {type: 'tracker3gun'}); +Class.trackerSniper = makeAuto('sniper', "Marksman", {type: 'tracker3gun'}); +Class.trackerAssassin = makeAuto('assassin', "Hitman", {type: 'tracker3gun'}); +Class.trackerHunter = makeAuto('hunter', "Pinner", {type: 'tracker3gun'}); +Class.trackerMini = makeAuto('minigun', "Scout", {type: 'tracker3gun'}); +Class.trackerRifle = makeAuto('rifle', "DMR", {type: 'tracker3gun'}); +Class.trackerTwinsniper = makeAuto('twinsniper', "Bolt Action", {type: 'tracker3gun'}); +Class.trackerSniperHybrid = makeAuto('snipebrid', "Camper", {type: 'tracker3gun'}); +Class.trackerAcid = makeAuto('acid', "Acidilizer", {type: 'tracker3gun'}); +Class.trackerChill = makeAuto('chiller', "Icilizer", {type: 'tracker3gun'}); + +//Homing Auto Tanks +Class.homingautoBasic = makeAuto("basic", "Homing Auto-Basic", {type: 'homingAutoTurret'}); +Class.homingautoTwin = makeAuto("twin", "Homing Auto-Twin", {type: 'homingAutoTurret'}); +Class.homingautoMach = makeAuto("machineGun", "Homing Auto-Machine", {type: 'homingAutoTurret'}); +Class.homingautoSniper = makeAuto("sniper", "Homing Auto-Sniper", {type: 'homingAutoTurret'}); +Class.homingautoFlank = makeAuto("flankGuard", "Homing Auto-Flank", {type: 'homingAutoTurret'}); +Class.homingautoDirector = makeAuto("director", "Homing Chairman", {type: 'homingAutoTurret'}); +Class.homingautoPound = makeAuto("pounder", "Homing Scratcher", {type: 'homingAutoTurret'}); +Class.homingautoTrap = makeAuto("trapper", "Homing Auto-Trapper", {type: 'homingAutoTurret'}); +Class.homingautoDesmos = makeAuto("desmos", "Homing Charter", {type: 'homingAutoTurret'}); +Class.homingautobascrid = makeAuto("bascrid", "Homing Auto-Basebrid", {type: 'homingAutoTurret'}) +Class.homingautolittleHunter = makeAuto("littleHunter", "Homing Auto-Subduer", {type: 'homingAutoTurret'}) +Class.homingautoinception = makeAuto("inception", "Homing Deployer", {type: 'homingAutoTurret'}); +Class.homingautoauto2 = makeAuto("auto2", "Homing Auto²-2", {type: 'homingAutoTurret'}); +Class.homingautolancer = makeAuto("lancer", "Homing Lancer", {type: 'homingAutoTurret'}); + +//Auras +Class.auraBasic = makeAura(Class.basic); +Class.auraTwin = makeAura(Class.twin); +Class.auraSniper = makeAura(Class.sniper); +Class.auraMachineGun = makeAura(Class.machineGun); +Class.auraFlankGuard = makeAura(Class.flankGuard); +Class.auraDirector = makeAura(Class.director); +Class.auraPounder = makeAura(Class.pounder); +Class.auraTrapper = makeAura(Class.trapper); +Class.auraAutoBasic = makeAura(Class.autoBasic); +Class.auraBascrid = makeAura(Class.bascrid); +Class.auraLittleHunter = makeAura(Class.littleHunter); +Class.auraInception = makeAura(Class.inception); +Class.auraDesmos = makeAura(Class.desmos); +Class.auraAuto2 = makeAura(Class.auto2); +Class.auraSmasher = makeAura(Class.smasher); + +Class.damageAuraBasic = makeAura(Class.basic, "Omen Basic", {type: 'auraDamageGen'}); +Class.damageAuraTwin = makeAura(Class.twin, "Omen Twin", {type: 'auraDamageGen'}); +Class.damageAuraSniper = makeAura(Class.sniper, "Omen Sniper", {type: 'auraDamageGen'}); +Class.damageAuraMachineGun = makeAura(Class.machineGun, "Omen Machine Gun", {type: 'auraDamageGen'}); +Class.damageAuraFlankGuard = makeAura(Class.flankGuard, "Omen Flank Guard", {type: 'auraDamageGen'}); +Class.damageAuraDirector = makeAura(Class.director, "Omen Director", {type: 'auraDamageGen'}); +Class.damageAuraPounder = makeAura(Class.pounder, "Omen Pounder", {type: 'auraDamageGen'}); +Class.damageAuraTrapper = makeAura(Class.trapper, "Omen Trapper", {type: 'auraDamageGen'}); +Class.damageAuraAutoBasic = makeAura(Class.autoBasic, "Omen Auto-Basic", {type: 'auraDamageGen'}); +Class.damageAuraBascrid = makeAura(Class.bascrid, "Omen Basebrid", {type: 'auraDamageGen'}); +Class.damageAuraLittleHunter = makeAura(Class.littleHunter, "Omen Subduer", {type: 'auraDamageGen'}); +Class.damageAuraInception = makeAura(Class.inception, "Omen Inception", {type: 'auraDamageGen'}); +Class.damageAuraDesmos = makeAura(Class.desmos, "Omen Desmos", {type: 'auraDamageGen'}); +Class.damageAuraAuto2 = makeAura(Class.auto2, "Omen Auto-2", {type: 'auraDamageGen'}); +Class.damageAuraLancer = makeAura(Class.lancer, "Omen Lancer", {type: 'auraDamageGen'}); + +Class.rangeAuraBasic = makeAura(Class.basic, "Mega-Aura Basic", {type: 'auraRangeGen'}); +Class.rangeAuraTwin = makeAura(Class.twin, "Mega-Aura Twin", {type: 'auraRangeGen'}); +Class.rangeAuraSniper = makeAura(Class.sniper, "Mega-Aura Sniper", {type: 'auraRangeGen'}); +Class.rangeAuraMachineGun = makeAura(Class.machineGun, "Mega-Aura Machine Gun", {type: 'auraRangeGen'}); +Class.rangeAuraFlankGuard = makeAura(Class.flankGuard, "Mega-Aura Flank Guard", {type: 'auraRangeGen'}); +Class.rangeAuraDirector = makeAura(Class.director, "Mega-Aura Director", {type: 'auraRangeGen'}); +Class.rangeAuraPounder = makeAura(Class.pounder, "Mega-Aura Pounder", {type: 'auraRangeGen'}); +Class.rangeAuraTrapper = makeAura(Class.trapper, "Mega-Aura Trapper", {type: 'auraRangeGen'}); +Class.rangeAuraAutoBasic = makeAura(Class.autoBasic, "Mega-Aura Auto-Basic", {type: 'auraRangeGen'}); +Class.rangeAuraBascrid = makeAura(Class.bascrid, "Mega-Aura Bascrid", {type: 'auraRangeGen'}); +Class.rangeAuraLittleHunter = makeAura(Class.littleHunter, "Mega-Aura Subduer", {type: 'auraRangeGen'}); +Class.rangeAuraInception = makeAura(Class.inception, "Mega-Aura Inception", {type: 'auraRangeGen'}); +Class.rangeAuraDesmos = makeAura(Class.desmos, "Mega-Aura Desmos", {type: 'auraRangeGen'}); +Class.rangeAuraAuto2 = makeAura(Class.auto2, "Mega-Aura Auto-2", {type: 'auraRangeGen'}); +Class.rangeAuraLancer = makeAura(Class.lancer, "Mega-Aura Lancer", {type: 'auraRangeGen'}); + +Class.damagerangeAuraBasic = makeAura(Class.basic, "Mega-Omen Basic", {type: 'auraDamageRangeGen'}); +Class.moredamageAuraBasic = makeAura(Class.basic, "X-Omen Basic", {type: 'auraMoreDamageGen'}); +Class.morerangeAuraBasic = makeAura(Class.basic, "X-Mega-Aura Basic", {type: 'auraMoreRangeGen'}); + +Class.auraDoubleTwin = makeAura(Class.doubleTwin); +Class.auraTripleShot = makeAura(Class.tripleShot); + +Class.auraAssassin = makeAura(Class.assassin); +Class.auraHunter = makeAura(Class.hunter); +Class.auraRifle = makeAura(Class.rifle); +Class.auraTrackerSniper = makeAura(Class.trackerSniper); +Class.auraTwinSniper = makeAura(Class.twinsniper); +Class.auraAcid = makeAura(Class.acid); +Class.auraChiller = makeAura(Class.chiller); + +Class.auraMinigun = makeAura(Class.minigun); +Class.auraGunner = makeAura(Class.gunner); +Class.auraSprayer = makeAura(Class.sprayer); + +Class.auraHexaTank = makeAura(Class.hexaTank); +Class.auraTriAngle = makeAura(Class.triAngle); +Class.auraAuto3 = makeAura(Class.auto3); +Class.auraBackShield = makeAura(Class.backShield); + +Class.auraOverseer = makeAura(Class.overseer); +Class.auraCruiser = makeAura(Class.cruiser); +Class.auraUnderseer = makeAura(Class.underseer); +Class.auraSpawner = makeAura(Class.spawner); +Class.auraDirectdrive = makeAura(Class.directdrive); + +Class.auraDestroyer = makeAura(Class.destroyer); +Class.auraArtillery = makeAura(Class.artillery); +Class.auraLauncher = makeAura(Class.launcher); + +Class.auraBuilder = makeAura(Class.builder); +Class.auraTriTrapper = makeAura(Class.triTrapper); +Class.auraTrapGuard = makeAura(Class.trapGuard); + +Class.auraAutoTwin = makeAura(Class.autoTwin); +Class.auraAutoSniper = makeAura(Class.autoSniper); +Class.auraAutoMach = makeAura(Class.autoMach); +Class.auraAutoFlank = makeAura(Class.autoFlank); +Class.auraAutoDirector = makeAura(Class.autoDirector); +Class.auraAutoPound = makeAura(Class.autoPound); +Class.auraAutoTrap = makeAura(Class.autoTrap); +Class.auraAutoDesmos = makeAura(Class.autoDesmos); +Class.auraRevolutionist = makeAura(Class.revolutionist); +Class.auraAutoLittleHunter = makeAura(Class.autolittleHunter); +Class.auraAutoInception = makeAura(Class.autoinception); +Class.auraAutoAuto2 = makeAura(Class.autoauto2); +Class.auraAutoLancer = makeAura(Class.autolancer); +Class.auraBasicCeption = makeAura(Class.basicCeption); +Class.auraHomingautoBasic = makeAura(Class.homingautoBasic); + +Class.auratwinbrid = makeAura(Class.launcher); +Class.aurasnipebrid = makeAura(Class.launcher); +Class.auramachbrid = makeAura(Class.machbrid); +Class.auraflankbrid = makeAura(Class.flankbrid); +Class.aurapoundbrid = makeAura(Class.poundbrid); +Class.auratrapbrid = makeAura(Class.trapbrid); +Class.auraautobascrid = makeAura(Class.autobascrid); +Class.auradesmosbrid = makeAura(Class.desmosbrid); +Class.auralittlehunterbrid = makeAura(Class.littleHunterbrid); +Class.aurainceptionbrid = makeAura(Class.inceptionbrid); +Class.auraauto2brid = makeAura(Class.auto2brid); +Class.auralancebrid = makeAura(Class.lancebrid); +Class.jeep = makeAura(Class.car, "jeep"); + +Class.auraBinary = makeAura(Class.binary); +Class.auraContagion = makeAura(Class.contagion); +Class.auraGundirector = makeAura(Class.gundirector); +Class.auraBigSubduer = makeAura(Class.bigSubduer); +Class.auraFlankdue = makeAura(Class.flankdue); + +Class.auraInceptionist = makeAura(Class.inceptionist) +Class.auraMachinception = makeAura(Class.machinception); +Class.auraTailgator = makeAura(Class.tailgator); +Class.auraFlankinception = makeAura(Class.flankinception); + +Class.auraSidewinder = makeAura(Class.sidewinder); +Class.auraHelix = makeAura(Class.helix); +Class.auraUndertow = makeAura(Class.undertow); +Class.auraRepeater = makeAura(Class.repeater); + +Class.auraLancer = makeAura(Class.lancer); +Class.auraChasseur = makeAura(Class.chasseur); +Class.auraTriLancer = makeAura(Class.trilancer); + +// TANK UPGRADE PATHS +Class.basic.UPGRADES_TIER_1 = ["twin", "sniper", "machineGun", "flankGuard", "director", "pounder", "trapper", "autoBasic", "desmos", "bascrid", "littleHunter", "inception", "lancer", "auto2", "auraBasic"] + Class.basic.UPGRADES_TIER_2 = ["smasher", "cloner"] + Class.smasher.UPGRADES_TIER_3 = ["megaSmasher", "spike", "landmine", "cocci", "pion", "trackerSmasher", "skater", "acidsmasher", "flail", "autoSmasher", "auraSmasher"] + Class.healer.UPGRADES_TIER_3 = ["medic", "ambulance", "surgeon", "paramedic"] + Class.cloner.UPGRADES_TIER_3 = ["hivemind", "autoCloner"] + + Class.twin.UPGRADES_TIER_2 = ["doubleTwin", "tripleShot", "gunner", "hexaTank", "autoTwin", "helix", "twinbrid", "binary", "twinsniper", "auraTwin"] + Class.twin.UPGRADES_TIER_3 = ["bulwark"] + Class.doubleTwin.UPGRADES_TIER_3 = ["tripleTwin", "hewnDouble", "autoDouble", "bentDouble", "doubletwinbrid", "auraDoubleTwin"] + Class.tripleShot.UPGRADES_TIER_3 = ["pentaShot", "spreadshot", "bentDouble", "triplet", "autoTripleShot", "triplex", "bentHybrid", "trinary", "auraTripleShot"] + + Class.sniper.UPGRADES_TIER_2 = ["assassin", "hunter", "minigun", "rifle", "twinsniper", "autoSniper", "snipebrid", "trackerSniper", "acid", "chiller", "chasseur", "auraSniper"] + Class.sniper.UPGRADES_TIER_3 = ["bushwhacker"] + Class.assassin.UPGRADES_TIER_3 = ["ranger", "xHunter", "falcon", "stalker", "autoAssassin", "assbrid", "trackerAssassin", "disintegrator", "freezer", "auraAssassin", "single"] + Class.hunter.UPGRADES_TIER_3 = ["predator", "xHunter", "poacher", "ordnance", "railgun", "dual","autoHunter", "trackerHunter", 'auraHunter'] + Class.rifle.UPGRADES_TIER_3 = ["musket", "crossbow", "armsman", "autoRifle", "trackerRifle", "auraRifle"] + Class.trackerSniper.UPGRADES_TIER_3 = ["trackerAssassin", "trackerHunter", "trackerMini", "trackerRifle", "trackerTwinsniper", "trackerSniperHybrid", "trackerAcid", "trackerChill", "auraTrackerSniper"] + Class.twinsniper.UPGRADES_TIER_3 = ["dual", "musket", "autoTwinsniper", "twipebrid", "trackerTwinsniper", "auraTwinSniper"] + Class.acid.UPGRADES_TIER_3 = ["disintegrator", "acidsmasher", "autoAcid", "acidbrid", "trackerAcid", "auraAcid"] + Class.chiller.UPGRADES_TIER_3 = ["freezer", "autoChill", "chillbrid", "trackerChill", "auraChiller", "surge"] + + Class.machineGun.UPGRADES_TIER_2 = ["artillery", "minigun", "gunner", "sprayer", "autoMach", "machbrid", "machinception", "auraMachineGun"] + Class.minigun.UPGRADES_TIER_3 = ["streamliner", "nailgun", "cropDuster", "barricade", "vulture", "minilaser", "autoMini", "trackerMini", "accelminigun", "auraMinigun"] + Class.gunner.UPGRADES_TIER_3 = ["autoGunner", "nailgun", "auto4", "machineGunner", "gunnerTrapper", "cyclone", "overgunner", "waterfall", "helecopter", "auraGunner"] + Class.sprayer.UPGRADES_TIER_3 = ["redistributor", "phoenix", "atomizer", "focal", "autoSprayer", "spraybrid", "auraSprayer"] + + Class.flankGuard.UPGRADES_TIER_2 = ["hexaTank", "triAngle", "auto3", "trapGuard", "triTrapper", "autoFlank", "flankbrid", "flankdue", "flankinception", "trilancer", "backShield", "auraFlankGuard"] + Class.flankGuard.UPGRADES_TIER_3 = ["tripleTwin", "quadruplex"] + Class.hexaTank.UPGRADES_TIER_3 = ["octoTank", "cyclone", "hexaTrapper", "autoHexaTank", "hexatankbrid", "hexalancer", "auraHexaTank", "auraHexaTank"] + Class.triAngle.UPGRADES_TIER_3 = ["fighter", "booster", "falcon", "bomber", "autoTriAngle", "surfer", "eagle", "phoenix", "vulture", "subway", "helecopter", "trailblazer"] + Class.backShield.UPGRADES_TIER_3 = ["mirrorBackShield", "brella", "autoBackShield", "auraBackShield"] + + Class.director.UPGRADES_TIER_2 = ["overseer", "cruiser", "underseer", "gundirector", "spawner", "directdrive", "autoDirector", "auraDirector"] + Class.director.UPGRADES_TIER_3 = ["manager", "bigCheese"] + Class.overseer.UPGRADES_TIER_3 = ["overlord", "overtrapper", "overgunner", "banshee", "autoOverseer", "trojan", "overdrive", "commander", "auraOverseer"] + Class.cruiser.UPGRADES_TIER_3 = ["carrier", "battleship", "fortress", "autoCruiser", "commander", "auraCruiser"] + Class.underseer.UPGRADES_TIER_3 = ["necromancer", "maleficitor", "infestor", "autoUnderseer", "auraUnderseer"] + Class.spawner.UPGRADES_TIER_3 = ["factory", "protist", "ranch", "autoSpawner", "auraSpawner"] + Class.directdrive.UPGRADES_TIER_3 = ["overdrive", "cruiserdrive", "revodirector", "honda", "dictator", "factory", "autoMotor", "auraDirectdrive"] + + Class.pounder.UPGRADES_TIER_2 = ["destroyer", "builder", "artillery", "launcher", "autoPound", "sidewinder", "poundbrid", "tailgator", "auraPounder"] + Class.pounder.UPGRADES_TIER_3 = ["shotgun", "eagle"] + Class.destroyer.UPGRADES_TIER_3 = ["conqueror", "annihilator", "hybrid", "construct", "autoDestroy", "waterfall", "interceptor", "auraDestroyer"] + Class.artillery.UPGRADES_TIER_3 = ["mortar", "ordnance", "beekeeper", "fieldGun", "autoArtillery", "artilbrid", "auraArtillery"] + Class.launcher.UPGRADES_TIER_3 = ["skimmer", "twister", "swarmer", "rocketeer", "fieldGun", "shrapnelgun", "firecracker", "autoLaunch", "launchbrid", "auraLauncher"] + + Class.trapper.UPGRADES_TIER_2 = ["builder", "triTrapper", "trapGuard", "contagion", "autoTrap", "trapbrid", "auraTrapper"] + Class.trapper.UPGRADES_TIER_3 = ["barricade"] + Class.builder.UPGRADES_TIER_3 = ["construct", "autoBuilder", "engineer", "boomer", "assembler", "architect", "conqueror", "fort", "builderbrid"] + Class.triTrapper.UPGRADES_TIER_3 = ["fortress", "hexaTrapper", "septaTrapper", "architect", "triContagion", "autoTriTrapper", "tritrapperbrid"] + Class.trapGuard.UPGRADES_TIER_3 = ["bushwhacker", "gunnerTrapper", "bomber", "conqueror", "bulwark", "autoTrapGuard", "trapguardbrid"] + + Class.autoBasic.UPGRADES_TIER_2 = ["autoTwin", "autoSniper", "autoMach", "autoFlank", "autoDirector", "autoPound", "autoTrap", "autoDesmos", "basicCeption", "autobascrid", "autolittleHunter", "autoinception", "autolancer", "autoauto2", "auraAutoBasic", "homingautoBasic"] + Class.autoBasic.UPGRADES_TIER_3 = ["autoSmasher", "autoCloner"] + Class.autoTwin.UPGRADES_TIER_3 = ["autoDouble", "autoTripleShot", "autoGunner", "autoHexaTank", "equilibrium", "autoBinary", "autoTwinsniper", "twinCeption", "autotwinbrid", "auraAutoTwin", "homingautoTwin"] + Class.autoSniper.UPGRADES_TIER_3 = ["autoAssassin", "autoHunter", "autoMini", "autoRifle", "autoTwinsniper", "autoAcid", "autoChill", "snipeCeption", "autosnipebrid", "autochasseur", "auraAutoSniper", "homingautoSniper"] + Class.autoMach.UPGRADES_TIER_3 = ["autoArtillery", "autoMini", "autoGunner", "autoSprayer", "machCeption", "automachbrid", "automachinception", "auraAutoMach", "homingautoMach"] + Class.autoFlank.UPGRADES_TIER_3 = ["autoHexaTank", "autoTriAngle", "autoAuto3", "autoTrapGuard", "autoTriTrapper", "flankCeption", "autoflankbrid", "autoFlankdue", "autoflankinception", "autotrilancer", "auraAutoFlank", "homingautoFlank"] + Class.autoDirector.UPGRADES_TIER_3 = ["autoOverseer", "autoCruiser", "autoUnderseer", "autoGundirector", "autoSpawner", "directCeption", "auraAutoDirector", "homingautoDirector"] + Class.autoPound.UPGRADES_TIER_3 = ["autoDestroy", "autoBuilder", "autoArtillery", "autoLaunch", "poundCeption", "autoSidewinder", "autopoundbrid", "autotailgator", "auraAutoPound", "homingautoPound"] + Class.autoTrap.UPGRADES_TIER_3 = ["autoBuilder", "autoTriTrapper", "autoTrapGuard", "autoContagion", "trapCeption", "autotrapbrid", "auraAutoTrap", "homingautoTrap"] + Class.autoDesmos.UPGRADES_TIER_3 = ["autoSidewinder", "autoHelix", "autoUndertow", "autoRepeater", "desmosCeption", "autodesmosbrid", "auraAutoDesmos", "homingautoDesmos"] + Class.autolittleHunter.UPGRADES_TIER_3 = ["autoMini", "autoBinary", "autoHunter", "autoSprayer", "autoContagion", "autoGundirector", "autoBigSubduer", "autoFlankdue", "autolittleHunterbrid", "littleHunterCeption", "auraAutoLittleHunter", "homingautolittleHunter"] + Class.autoinception.UPGRADES_TIER_3 = ["autoinceptionist", "automachinception", "autotailgator", "autoflankinception", "autoinceptionbrid", "inceptCeption", "auraAutoInception", "homingautoinception"] + Class.autoauto2.UPGRADES_TIER_3 = ["autoAuto3", "autoRevolutionist", "autoauto2brid", "auto2Ception", "auraAutoAuto2", "homingautoauto2"] + Class.autolancer.UPGRADES_TIER_3 = ["autochasseur", "autolancebrid", "autotrilancer", "lancerception", "auraAutoLancer", "homingautolancer"] + Class.basicCeption.UPGRADES_TIER_3 = ["twinCeption", "snipeCeption", "machCeption", "flankCeption", "directCeption", "poundCeption", "trapCeption", "desmosCeption", "bascridCeption", "littleHunterCeption", "inceptCeption", "lancerception", "auraBasicCeption"] + Class.homingautoBasic.UPGRADES_TIER_3 = ["homingautoTwin", "homingautoSniper", "homingautoMach", "homingautoFlank", "homingautoDirector", "homingautoPound", "homingautoTrap", "homingautoDesmos", "homingautobascrid", "homingautolittleHunter", "homingautoinception", "auraHomingautoBasic"] + + Class.bascrid.UPGRADES_TIER_2 = ["twinbrid", "snipebrid", "machbrid", "flankbrid", "overseer", "poundbrid", "trapbrid", "autobascrid", "desmosbrid", "littleHunterbrid", "inceptionbrid", "lancebrid", "auto2brid", "car", "auraBascrid"] + Class.bascrid.UPGRADES_TIER_3 = ["clonebrid"] + Class.twinbrid.UPGRADES_TIER_3 = ["doubletwinbrid", "bentHybrid", "overgunner", "hexatankbrid", "autotwinbrid", "helixbrid", "binarybrid", "twipebrid", "mercedes", "auratwinbrid"] + Class.snipebrid.UPGRADES_TIER_3 = ["assbrid", "poacher", "cropDuster", "armsman", "twipebrid", "autosnipebrid", "trackerSniperHybrid", "acidbrid", "chillbrid", "chasseubrid", "tesla", "aurasnipebrid"] + Class.machbrid.UPGRADES_TIER_3 = ["artilbrid", "cropDuster", "overgunner", "spraybrid", "automachbrid", "machinceptionbrid", "toyota", "auramachbrid"] + Class.flankbrid.UPGRADES_TIER_3 = ["hexatankbrid", "surfer", "auto3brid", "trapguardbrid", "tritrapperbrid", "autoflankbrid", "flankduebrid", "flankinceptionbrid", "trilancebrid", "ford", "auraflankbrid"] + Class.poundbrid.UPGRADES_TIER_3 = ["hybrid", "builderbrid", "artilbrid", "launchbrid", "autopoundbrid", "sidewinderbrid", "tailgatorbrid", "honda", "aurapoundbrid"] + Class.trapbrid.UPGRADES_TIER_3 = ["builderbrid", "tritrapperbrid", "trapguardbrid", "contagionbrid", "autotrapbrid", "overtrapper", "gmc", "auratrapbrid"] + Class.autobascrid.UPGRADES_TIER_3 = ["autotwinbrid", "autosnipebrid", "automachbrid", "autoflankbrid", "autopoundbrid", "autotrapbrid", "autodesmosbrid", "autolittleHunterbrid", "autoinceptionbrid", "autolancebrid", "bascridCeption", "porsche", "auraautobascrid"] + Class.desmosbrid.UPGRADES_TIER_3 = ["sidewinderbrid", "helixbrid", "undertowbrid", "repeaterbrid", "autodesmosbrid", "mazda", "auradesmosbrid"] + Class.littleHunterbrid.UPGRADES_TIER_3 = ["cropDuster", "binarybrid", "poacher", "spraybrid", "contagionbrid", "bigsubduerbrid", "flankduebrid", "autolittleHunterbrid", "volkswagen", "auralittlehunterbrid"] + Class.inceptionbrid.UPGRADES_TIER_3 = ["inceptionistbrid", "machinceptionbrid", "tailgatorbrid", "flankinceptionbrid", "overdrive", "autoinceptionbrid", "audi", "aurainceptionbrid"] + Class.auto2brid.UPGRADES_TIER_3 = ["auto3brid", "revobrid", "autoauto2brid", "ferrari", "auraauto2brid"] + Class.lancebrid.UPGRADES_TIER_3 = ["chasseubrid", "trilancebrid", "autolancebrid", "auralancebrid"] + Class.car.UPGRADES_TIER_3 = ["mercedes", "tesla", "toyota", "ford", "overdrive", "honda", "gmc", "porsche", "mazda", "volkswagen", "audi", "jeep"] + + Class.littleHunter.UPGRADES_TIER_2 = ["minigun", "binary", "hunter", "sprayer", "contagion", "gundirector", "bigSubduer", "flankdue", "autolittleHunter", "littleHunterbrid", "auraLittleHunter"] + Class.binary.UPGRADES_TIER_3 = ["trinary", "dual", "autoBinary", "binarybrid", "auraBinary"] + Class.contagion.UPGRADES_TIER_3 = ["fort", "triContagion", "autoContagion", "droneTrapper", "contagionbrid", "auraContagion"] + Class.gundirector.UPGRADES_TIER_3 = ["trojan", "protist", "droneTrapper", "autoGundirector"] + Class.bigSubduer.UPGRADES_TIER_3 = ["predator", "redistributor", "biggerSubduer", "clubbin", "autoBigSubduer", "bigsubduerbrid", "auraBigSubduer"] + Class.flankdue.UPGRADES_TIER_3 = ["subway", "triContagion", "clubbin", "autoFlankdue", "flankduebrid", "auraFlankdue"] + + Class.inception.UPGRADES_TIER_2 = ["inceptionist", "machinception", "tailgator", "launcher", "flankinception", "directdrive", "spawner", "autoinception", "inceptionbrid", "auraInception"] + Class.inceptionist.UPGRADES_TIER_3 = ["twinceptionist", "machceptionist", "poundceptionist", "flankceptionist", "factory", "autoinceptionist", "inceptionistbrid", "auraInceptionist"] + Class.machinception.UPGRADES_TIER_3 = ["machceptionist", "automachinception", "machinceptionbrid", "auraMachinception"] + Class.tailgator.UPGRADES_TIER_3 = ["poundceptionist", "interceptor", "engineer", "shrapnelgun", "autotailgator", "tailgatorbrid", "auraTailgator"] + Class.flankinception.UPGRADES_TIER_3 = ["flankceptionist", "autoflankinception", "flankinceptionbrid", "auraFlankinception", "auraFlankinception"] + + Class.desmos.UPGRADES_TIER_2 = ["helix", "sidewinder", "undertow", "repeater", "autoDesmos", "desmosbrid", "auraDesmos"] + Class.sidewinder.UPGRADES_TIER_3 = ["coil", "python", "ranch", "oroboros", "cocci"] + Class.helix.UPGRADES_TIER_3 = ["triplex", "quadruplex", "coil", "duplicator", "autoHelix", "helixbrid", "auraHelix"] + Class.undertow.UPGRADES_TIER_3 = ["riptide", "autoUndertow", "undertowbrid", "auraUndertow"] + Class.repeater.UPGRADES_TIER_3 = ["iterator", "duplicator", "autoRepeater", "repeaterbrid", "auraRepeater"] + + Class.auraBasic.UPGRADES_TIER_2 = ["auraTwin", "auraSniper", "auraMachineGun", "auraFlankGuard", "auraDirector", "auraPounder", "auraTrapper", "auraAutoBasic", "auraDesmos", "auraBascrid", "auraLittleHunter", "auraInception", "auraLancer", "auraAuto2", "damageAuraBasic", "rangeAuraBasic"] + Class.auraBasic.UPGRADES_TIER_3 = ["auraSmasher"] + Class.auraTwin.UPGRADES_TIER_3 = ["auraDoubleTwin", "auraTripleShot", "auraGunner", "auraHexaTank", "auraAutoTwin", "auraHelix", "auratwinbrid", "auraBinary", "auraTwinSniper", "damageAuraTwin", "rangeAuraTwin"] + Class.auraSniper.UPGRADES_TIER_3 = ["auraAssassin", "auraHunter", "auraMinigun", "auraRifle", "auraTwinSniper", "auraAutoSniper", "aurasnipebrid", "auraTrackerSniper", "auraAcid", "auraChiller", "auraChasseur", "damageAuraSniper", "rangeAuraSniper"] + Class.auraMachineGun.UPGRADES_TIER_3 = ["auraArtillery", "auraMinigun", "auraGunner", "auraSprayer", "auraAutoMach", "auramachbrid", "auraMachinception", "damageAuraMachineGun", "rangeAuraMachineGun"] + Class.auraFlankGuard.UPGRADES_TIER_3 = ["auraHexaTank", "auraTriAngle", "auraAuto3", "auraTrapGuard", "auraTriTrapper", "auraAutoFlank", "auraflankbrid", "auraFlankdue", "auraFlankinception", "auraTriLancer", "auraBackShield", "damageAuraFlankGuard", "rangeAuraFlankGuard"] + Class.auraDirector.UPGRADES_TIER_3 = ["auraOverseer", "auraCruiser", "auraUnderseer", "auraSpawner", "auraDirectdrive", "auraAutoDirector", "damageAuraDirector", "rangeAuraDirector"] + Class.auraPounder.UPGRADES_TIER_3 = ["auraBuilder", "auraArtillery", "auraLauncher", "auraAutoPound", "auraSidewinder", "aurapoundbrid", "auraTailgator", "damageAuraPounder", "rangeAuraPounder"] + Class.auraTrapper.UPGRADES_TIER_3 = ["auraBuilder", "auraTriTrapper", "auraTrapGuard", "auraContagion", "auraAutoTrap", "auratrapbrid", "damageAuraTrapper", "rangeAuraTrapper"] + Class.auraAutoBasic.UPGRADES_TIER_3 = ["auraAutoTwin", "auraAutoSniper", "auraAutoMach", "auraAutoFlank", "auraAutoDirector", "auraAutoPound", "auraAutoTrap", "auraAutoDesmos", "auraautobascrid", "auraAutoLittleHunter", "auraAutoInception", "auraBasicCeption", "auraHomingautoBasic", "damageAuraAutoBasic", "rangeAuraAutoBasic"] + Class.auraBascrid.UPGRADES_TIER_3 = ["auratwinbrid", "aurasnipebrid", "auramachbrid", "auraflankbrid", "aurapoundbrid", "auratrapbrid", "auradesmosbrid", "auraautobascrid", "auralittlehunterbrid", "aurainceptionbrid", "jeep", "damageAuraBascrid", "rangeAuraBascrid"] + Class.auraDesmos.UPGRADES_TIER_3 = ["auraSidewinder", "auraHelix", "auraUndertow", "auraRepeater", "auraAutoDesmos", "auradesmosbrid", "damageAuraDesmos", "rangeAuraDesmos"] + Class.auraLittleHunter.UPGRADES_TIER_3 = ["auraMinigun", "auraBinary", "auraHunter", "auraSprayer", "auraContagion", "auraGundirector", "auraBigSubduer", "auraFlankdue", "auraAutoLittleHunter", "auralittlehunterbrid", "damageAuraLittleHunter", "rangeAuraLittleHunter"] + Class.auraInception.UPGRADES_TIER_3 = ["auraInceptionist", "auraMachinception", "auraTailgator", "auraFlankinception", "auraAutoInception", "aurainceptionbrid", "damageAuraInception", "rangeAuraInception"] + Class.auraAuto2.UPGRADES_TIER_3 = ["auraAuto3", "auraRevolutionist", "auraAutoAuto2", "auraauto2brid", "damageAuraAuto2", "rangeAuraAuto2"] + Class.auraLancer.UPGRADES_TIER_3 = ["auraChasseur", "auraTriLancer", "auraAutoLancer", "auralancebrid", "damageAuraLancer", "rangeAuraLancer"] + Class.damageAuraBasic.UPGRADES_TIER_3 = ["damageAuraTwin", "damageAuraSniper", "damageAuraMachineGun", "damageAuraFlankGuard", "damageAuraDirector", "damageAuraPounder", "damageAuraTrapper", "damageAuraAutoBasic", "damageAuraBascrid", "damageAuraDesmos", "damageAuraLittleHunter", "damageAuraInception", "damageAuraAuto2", "damageAuraLancer", "moredamageAuraBasic", "damagerangeAuraBasic"] + Class.rangeAuraBasic.UPGRADES_TIER_3 = ["rangeAuraTwin", "rangeAuraSniper", "rangeAuraMachineGun", "rangeAuraFlankGuard", "rangeAuraDirector", "rangeAuraPounder", "rangeAuraTrapper", "rangeAuraAutoBasic", "rangeAuraBascrid", "rangeAuraDesmos", "rangeAuraLittleHunter", "rangeAuraInception", "rangeAuraAuto2", "rangeAuraLancer", "morerangeAuraBasic", "damagerangeAuraBasic"] + + Class.auto2.UPGRADES_TIER_2 = ["auto3", "revolutionist", "swivel2", "autoauto2", "auto2brid", "auraAuto2"] + Class.auto3.UPGRADES_TIER_3 = ["auto5", "mega3", "auto4", "banshee", "autoAuto3", "auto3brid", "auraAuto3"] + Class.revolutionist.UPGRADES_TIER_3 = ["subverter", "autoRevolutionist", "proton", "pion", "hadron", "equilibrium", "revobrid", "baseThrower", "revodirector", "auraRevolutionist"] + Class.swivel2.UPGRADES_TIER_3 = ["swivel3"] + + Class.lancer.UPGRADES_TIER_2 = ["chasseur", "trilancer", "autolancer", "lancebrid", "auraLancer"] + Class.lancer.UPGRADES_TIER_3 = ["katana"] + Class.chasseur.UPGRADES_TIER_3 = ["tripleur", "flail", "trichasseur", "autochasseur", "chasseubrid", "auraChasseur"] + Class.trilancer.UPGRADES_TIER_3 = ["trichasseur", "hexalancer", "trailblazer", "autotrilancer", "trilancebrid", "auraTriLancer"] \ No newline at end of file diff --git a/server/modules/definitions/groups/turrets.js b/server/modules/definitions/groups/turrets.js index e3d95cfb1..73cb96104 100644 --- a/server/modules/definitions/groups/turrets.js +++ b/server/modules/definitions/groups/turrets.js @@ -1,4 +1,4 @@ -const { combineStats, makeDeco } = require('../facilitators.js'); +const { combineStats, makeDeco, addAura, weaponArray } = require('../facilitators.js'); const { gunCalcNames, base } = require('../constants.js'); const g = require('../gunvals.js'); @@ -145,7 +145,7 @@ Class.trapTurret = { }, }, ], -}; +} Class.baseTrapTurret = { PARENT: "genericTank", LABEL: "Turret", @@ -184,12 +184,12 @@ Class.terrestrialTrapTurret = { }, ], } -let makeshottrapTurretProps = () => ({ - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.shotgun, g.machineGun, { speed: 0.7, maxSpeed: 0.2, damage: 1.5 }]), +const shottrapTurretProperties = { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.shotgun, g.machineGun, { speed: 0.7, maxSpeed: 0.2, damage: 1.5, range: 0.6 }]), AUTOFIRE: true, TYPE: "shotTrapBox", STAT_CALCULATOR: gunCalcNames.block, -}); +} Class.shottrapTurret = { PARENT: "genericTank", LABEL: 'Turret', @@ -203,41 +203,41 @@ Class.shottrapTurret = { SKYNET: true, FULL_VIEW: true, }, - GUNS: [ { - POSITION: [ 4, 1.5, 1, 11, -3, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + GUNS: [{ + POSITION: [ 4, 1.5, 1, 11, -3, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 4, 2, 1, 11, 3, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 4, 2, 1, 11, 3, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 4, 1.5, 1, 13, 0, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 4, 1.5, 1, 13, 0, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2, 1, 11, 1, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2, 1, 11, 1, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2, 1, 12, -1, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2, 1, 12, -1, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 1.5, 1, 11, 1, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 1.5, 1, 11, 1, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2, 1, 13, -1, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2, 1, 13, -1, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2,5, 1, 13, 1, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2,5, 1, 13, 1, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2, 1, 13, 2, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2, 1, 13, 2, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2, 1, 13, -2, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2, 1, 13, -2, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2.5, 1, 13, -2, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2.5, 1, 13, -2, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2.5, 1, 13, 2, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2.5, 1, 13, 2, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 1, 2, 1, 13, -2, 0, 0 ], PROPERTIES: makeshottrapTurretProps(), + POSITION: [ 1, 2, 1, 13, -2, 0, 0 ], PROPERTIES: shottrapTurretProperties, }, { - POSITION: [ 16, 14, -1.4, 0, 0, 0, 0 ], + POSITION: [ 16, 14, -1.4, 0, 0, 0, 0 ], }, { - POSITION: [ 6, 14, 1.6, 16, 0, 0, 0 ], PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.shotgun, g.machineGun, g.fake]), - AUTOFIRE: true, - TYPE: "bullet" - } - } ] + POSITION: [ 6, 14, 1.6, 16, 0, 0, 0 ], PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.trap, g.setTrap, g.shotgun, g.machineGun, g.fake]), + AUTOFIRE: true, + TYPE: "bullet" + } + }] } Class.machineTripleTurret = { PARENT: "genericTank", @@ -246,31 +246,15 @@ Class.machineTripleTurret = { CONTROLLERS: [ ["spin", {speed: 0.04}] ], INDEPENDENT: true, COLOR: -1, - GUNS: [ - { - POSITION: [12, 10, 1.4, 8, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.flankGuard]), - TYPE: "bullet", - AUTOFIRE: true, - }, - }, { - POSITION: [12, 10, 1.4, 8, 0, 120, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.flankGuard]), - TYPE: "bullet", - AUTOFIRE: true, - }, - }, { - POSITION: [12, 10, 1.4, 8, 0, 240, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.flankGuard]), - TYPE: "bullet", - AUTOFIRE: true, - }, + GUNS: weaponArray({ + POSITION: [12, 10, 1.4, 8, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.machineGun, g.flankGuard]), + TYPE: "bullet", + AUTOFIRE: true, }, - ], -}; + }, 3) +} Class.launcherTurret = { PARENT: "genericTank", LABEL: "Launcher", @@ -279,7 +263,6 @@ Class.launcherTurret = { COLOR: "grey", GUNS: [ { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ POSITION: [10, 9, 1, 9, 0, 0, 0], }, { POSITION: [17, 13, 1, 0, 0, 0, 0], @@ -290,7 +273,7 @@ Class.launcherTurret = { }, }, ], -}; +} Class.skimmerTurret = { PARENT: "genericTank", LABEL: "Skimmer", @@ -309,7 +292,7 @@ Class.skimmerTurret = { POSITION: [17, 15, 1, 0, 0, 0, 0], }, ], -}; +} Class.kronosSkimmerTurret = { PARENT: "genericTank", LABEL: "Skimmer", @@ -329,7 +312,7 @@ Class.kronosSkimmerTurret = { }, ], } -Class.autosmashTurret = { +Class.autoSmasherLauncherTurret = { PARENT: "genericTank", LABEL: "Launcher", BODY: { FOV: 10 }, @@ -366,7 +349,7 @@ Class.twisterTurret = { }, }, ], -}; +} Class.hyperTwisterTurret = { PARENT: "genericTank", LABEL: "Twister", @@ -385,7 +368,7 @@ Class.hyperTwisterTurret = { }, }, ], -}; +} Class.rocketeerTurret = { PARENT: "genericTank", LABEL: "Rocketeer", @@ -404,7 +387,7 @@ Class.rocketeerTurret = { POSITION: [17, 18, 0.65, 0, 0, 0, 0], }, ], -}; +} Class.boomerTurret = { PARENT: "genericTank", LABEL: "Boomer", @@ -428,65 +411,65 @@ Class.boomerTurret = { }, }, ], -}; +} Class.triTrapGuardTurret = { PARENT: "genericTank", COLOR: -1, CONTROLLERS: [["spin", { independent: true }]], - GUNS: [], -}; -for(let i = 0; i < 3; i++) { - Class.triTrapGuardTurret.GUNS.push( + GUNS: weaponArray([ { - POSITION: [17, 8, 1, 0, 0, 120*i, 0], + POSITION: [17, 8, 1, 0, 0, 0, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.flankGuard]), TYPE: "bullet", }, }, { - POSITION: [13, 8, 1, 0, 0, 120*i+60, 0], + POSITION: [13, 8, 1, 0, 0, 60, 0], }, { - POSITION: [4, 8, 1.7, 13, 0, 120*i+60, 0], + POSITION: [4, 8, 1.7, 13, 0, 60, 0], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.trap]), TYPE: "trap", STAT_CALCULATOR: gunCalcNames.trap, }, }, - ) -}; + ], 3), +} Class.eliteSpinnerCyclone = { PARENT: "genericTank", COLOR: -1, CONTROLLERS: [["spin", { speed: 0.1, independent: true }]], - GUNS: [], -}; -for (let i = 0; i < 12; i++) { - let delay; - switch (i % 4) { - case 0: - delay = 0; - break; - case 1: - delay = 0.5; - break; - case 2: - delay = 0.25; - break; - case 3: - delay = 0.75; - break; - } - Class.eliteSpinnerCyclone.GUNS.push( - { - POSITION: [15, 3.5, 1, 0, 0, 30 * i, delay], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, { speed: 1.3, maxSpeed: 1.3 }]), - TYPE: "bullet", - }, + GUNS: weaponArray([ + { + POSITION: [15, 3.5, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), + TYPE: "bullet" + } }, - ) -}; + { + POSITION: [15, 3.5, 1, 0, 0, 30, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), + TYPE: "bullet" + } + }, + { + POSITION: [15, 3.5, 1, 0, 0, 60, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), + TYPE: "bullet" + } + }, + { + POSITION: [15, 3.5, 1, 0, 0, 90, 0.75], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.twin, g.gunner, g.cyclone]), + TYPE: "bullet" + } + } + ], 3) +} Class.barricadeTurret = { PARENT: "genericTank", LABEL: "Turret", @@ -529,47 +512,8 @@ Class.barricadeTurret = { }, }, ], -}; -Class.artilleryAutoTankgun = { - PARENT: "genericTank", - LABEL: "Artillery", - BODY: { - FOV: 2, - }, - CONTROLLERS: [ - "canRepel", - "onlyAcceptInArc", - "mapAltToFire", - "nearestDifferentMaster", - ], - COLOR: "grey", - GUNS: [{ - POSITION: [17, 3, 1, 0, -6, -7, 0.25], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, { reload: 0.5 }]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [17, 3, 1, 0, 6, 7, 0.75], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.artillery, { reload: 0.5 }]), - TYPE: "bullet", - LABEL: "Secondary", - }, - }, - { - POSITION: [19, 12, 1, 0, 0, 0, 0], - PROPERTIES: { - SHOOT_SETTINGS: combineStats([g.basic, g.pounder, g.artillery, { reload: 0.5 }]), - TYPE: "bullet", - LABEL: "Heavy", - }, - }, - ], } -Class.artilleryTurret = { // This one has half the dps of the one above +Class.artilleryTurret = { PARENT: "genericTank", LABEL: "Artillery", BODY: { FOV: 2 }, @@ -599,7 +543,7 @@ Class.artilleryTurret = { // This one has half the dps of the one above }, }, ], -}; +} Class.legionaryTwin = { PARENT: "auto4gun", COLOR: "grey", @@ -627,7 +571,6 @@ Class.nailgunTurret = { CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], COLOR: "grey", GUNS: [{ - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ POSITION: [19, 2, 1, 0, -2.5, 0, 0.25], PROPERTIES: { SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, g.twin, g.nailgun]), @@ -649,7 +592,7 @@ Class.nailgunTurret = { POSITION: [5.5, 7, -1.8, 6.5, 0, 0, 0], }, ], -}; +} Class.crowbarTurret = { PARENT: "genericTank", COLOR: "grey", @@ -658,7 +601,6 @@ Class.crowbarTurret = { CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], GUNS: [ { - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ POSITION: [37, 6.5, 1, 0, 0, 0, 0], }, { POSITION: [5, 8.5, -1.5, 8, 0, 0, 0], @@ -666,7 +608,6 @@ Class.crowbarTurret = { ], TURRETS: [ { - /* SIZE X Y ANGLE ARC */ POSITION: [6, 38, 0, 0, 360, 1], TYPE: [ "autoTankGun", { INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, { @@ -677,7 +618,7 @@ Class.crowbarTurret = { TYPE: [ "autoTankGun", { INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, ], -}; +} Class.wrenchTurret = { PARENT: "genericTank", COLOR: "grey", @@ -685,7 +626,6 @@ Class.wrenchTurret = { BODY: { FOV: 2 }, CONTROLLERS: [ "canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster" ], GUNS: [{ - /*** LENGTH WIDTH ASPECT X Y ANGLE DELAY */ POSITION: [67, 6.5, 1, 0, 0, 0, 0], }, { POSITION: [5, 8.5, -1.5, 8, 0, 0, 0], @@ -693,7 +633,6 @@ Class.wrenchTurret = { ], TURRETS: [ { - /* SIZE X Y ANGLE ARC */ POSITION: [6, 68, 0, 0, 360, 1], TYPE: [ "autoTankGun", { INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, { @@ -704,7 +643,7 @@ Class.wrenchTurret = { TYPE: [ "autoTankGun", { INDEPENDENT: true, HAS_NO_RECOIL: true } ], }, ], -}; +} Class.protoSwarmerTurret = { PARENT: "genericTank", LABEL: "Swarmer", @@ -739,7 +678,7 @@ Class.swarmTurret = { }, }, ], -}; +} Class.napoleonLowerTurret = { PARENT: "genericTank", LABEL: "", @@ -763,7 +702,7 @@ Class.napoleonLowerTurret = { }, }, ], -}; +} Class.genghisLowerTurret = { PARENT: "genericTank", LABEL: "", @@ -784,7 +723,7 @@ Class.genghisLowerTurret = { }, }, ], -}; +} Class.cruiserTurret = { PARENT: "genericTank", @@ -809,7 +748,7 @@ Class.cruiserTurret = { }, }, ], -}; +} Class.carrierTurret = { PARENT: "genericTank", LABEL: "Carrier", @@ -896,7 +835,7 @@ Class.juliusLowerTurret = { }, }, ], -}; +} Class.swarmerTurret = { PARENT: "genericTank", LABEL: "Swarmer", @@ -914,7 +853,7 @@ Class.swarmerTurret = { POSITION: [15, 12, 1, 5, 0, 0, 0], }, ], -}; +} Class.basicTurret = { PARENT: "genericTank", LABEL: "Turret", @@ -930,7 +869,7 @@ Class.basicTurret = { }, }, ], -}; +} Class.napoleonUpperTurret = { PARENT: "genericTank", LABEL: "", @@ -948,7 +887,7 @@ Class.napoleonUpperTurret = { }, }, ], -}; +} // Mounted Turrets Class.autoTurret = { @@ -1068,7 +1007,7 @@ Class.sanctuaryHealer = { POSITION: { SIZE: 13, LAYER: 1 }, TYPE: ['healerSymbol', { CONTROLLERS: [["spin", { startAngle: Math.PI / 2, speed: 0, independent: true }]] }] }], -}; +} Class.surgeonPillboxTurret = { PARENT: "genericTank", LABEL: "", @@ -1241,7 +1180,7 @@ Class.healerSymbol = { SHAPE: [[0.3, -0.3],[1,-0.3],[1,0.3],[0.3,0.3],[0.3,1],[-0.3,1],[-0.3,0.3],[-1,0.3],[-1,-0.3],[-0.3,-0.3],[-0.3,-1],[0.3,-1]], SIZE: 13, COLOR: "red", -}; +} // Bodies Class.smasherBody = { @@ -1269,3 +1208,387 @@ Class.dominationBody = { SHAPE: 6, INDEPENDENT: true } + +//delta turrets +Class.projectileAutoTurret = { + PARENT: "autoTurret", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0.25], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret, g.overdrive]), + TYPE: "bullet", + }, + }, + ], +} +Class.homingAutoTurret = { + PARENT: "genericTank", + LABEL: "Turret", + COLOR: "orange", + INDEPENDENT: true, + CONTROLLERS: ['nearestDifferentMaster'], + BODY: { + FOV: 0.8, + }, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret]), + TYPE: "homingBullet", + COLOR: "orange", + }, + }, + ], +} +Class.ceptionistturret = { + PARENT: "genericTank", + LABEL: "Turret", + COLOR: "darkGray", + BODY: { + FOV: 0.8, + }, + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.pelleter, g.power, { recoil: 1.15 }, g.turret]), + TYPE: "ceptionistbullet", + COLOR: "darkGray", + }, + }, + ], +} +Class.fastbigauto4gun = { + PARENT: "auto4gun", + GUNS: [ + { + POSITION: [14, 5, 1, 0, -4.5, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 1.2 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [14, 5, 1, 0, 4.5, 0, 0.33], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 1.2 }]), + TYPE: "bullet", + }, + }, + { + POSITION: [16, 5, 1, 0, 0, 0, 0.67], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.pelleter, g.twin, g.twin, g.power, { reload: 2 }]), + TYPE: "bullet", + }, + }, + ], +} +Class.helecopterblade = { + LABEL: "whatat", + CONTROLLERS: [["spin", { independent: true, speed: 0.16 }]], + COLOR: 16, + // M 0.1 -1.3 C 0.1 -1.4 0.1 -1.5 -0.1 -1.6 L -0.1 -0.3 A 0.5 0.5 -180 0 0 -0.3 -0.1 L -1.3 -0.1 C -1.4 -0.1 -1.5 -0.1 -1.6 0.1 L -0.3 0.1 A 0.5 0.5 -180 0 0 -0.1 0.3 L -0.1 1.3 C -0.1 1.4 -0.1 1.5 0.1 1.6 L 0.1 0.3 A 0.5 0.5 -180 0 0 0.3 0.1 L 1.3 0.1 C 1.4 0.1 1.5 0.1 1.6 -0.1 L 0.3 -0.1 A 0.5 0.5 -180 0 0 0.1 -0.3 Z + SHAPE: "M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.4 0.1 A 0.5 0.5 90 0 0 -0.1 0.4 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.4 A 0.5 0.5 90 0 0 0.4 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.4 -0.1 A 0.5 0.5 90 0 0 0.1 -0.4 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.4 A 0.5 0.5 90 0 0 -0.4 -0.1 Z", + // SHAPE: 'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.5 0.1 A 0.5 0.5 90 0 0 -0.1 0.5 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.5 A 0.5 0.5 90 0 0 0.5 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.5 -0.1 A 0.5 0.5 90 0 0 0.1 -0.5 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.5 A 0.5 0.5 90 0 0 -0.5 -0.1 Z', + INDEPENDENT: true, +}; +Class.helecoptersblade = { + LABEL: "what", + CONTROLLERS: [["spin", { independent: true, speed: 0.16 }]], + COLOR: 16, + SHAPE: "M -0.1 1 C -0.1 1.1 -0.1 1.2 0.1 1.3 L 0.1 0.3 A 0.5 0.5 0 0 0 0.3 0.1 L 1 0.1 C 1.1 0.1 1.2 0.1 1.3 -0.1 L 0.3 -0.1 A 0.5 0.5 0 0 0 0.1 -0.3 L 0.1 -1 C 0.1 -1.1 0.1 -1.2 -0.1 -1.3 L -0.1 -0.3 A 0.5 0.5 0 0 0 -0.3 -0.1 L -1 -0.1 C -1.1 -0.1 -1.2 -0.1 -1.3 0.1 L -0.3 0.1 A 0.5 0.5 0 0 0 -0.1 0.3 Z", + // M 0.1 -1.3 C 0.1 -1.4 0.1 -1.5 -0.1 -1.6 L -0.1 -0.3 A 0.5 0.5 -180 0 0 -0.3 -0.1 L -1.3 -0.1 C -1.4 -0.1 -1.5 -0.1 -1.6 0.1 L -0.3 0.1 A 0.5 0.5 -180 0 0 -0.1 0.3 L -0.1 1.3 C -0.1 1.4 -0.1 1.5 0.1 1.6 L 0.1 0.3 A 0.5 0.5 -180 0 0 0.3 0.1 L 1.3 0.1 C 1.4 0.1 1.5 0.1 1.6 -0.1 L 0.3 -0.1 A 0.5 0.5 -180 0 0 0.1 -0.3 Z + // SHAPE:'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.4 0.1 A 0.5 0.5 90 0 0 -0.1 0.4 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.4 A 0.5 0.5 90 0 0 0.4 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.4 -0.1 A 0.5 0.5 90 0 0 0.1 -0.4 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.4 A 0.5 0.5 90 0 0 -0.4 -0.1 Z', + // SHAPE: 'M -1.7 -0.1 C -1.8 -0.1 -1.9 -0.1 -2 0.1 L -0.5 0.1 A 0.5 0.5 90 0 0 -0.1 0.5 L -0.1 1.7 C -0.1 1.8 -0.1 1.9 0.1 2 L 0.1 0.5 A 0.5 0.5 90 0 0 0.5 0.1 L 1.7 0.1 C 1.8 0.1 1.9 0.1 2 -0.1 L 0.5 -0.1 A 0.5 0.5 90 0 0 0.1 -0.5 L 0.1 -1.7 C 0.1 -1.8 0.1 -1.9 -0.1 -2 L -0.1 -0.5 A 0.5 0.5 90 0 0 -0.5 -0.1 Z', + INDEPENDENT: true, +}; +Class.turretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 10.5, 0, 90, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 270, 220, 1], + TYPE: "revogun", + }] +}; +Class.turretBasenoguns = { + LABEL: "Base", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, +}; +Class.grenadeDeco = makeDeco(0); +Class.turretBaseKiva = { + LABEL: "Basethingygygyyasgsdgajskhg", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: "#FC8208",//iT WonT FUckING SpIN + SYNC_TURRET_SKILLS: true, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 9.85, 0, 90, 220, 1], + TYPE: ["revogun", { COLOR: "#FC8208" }] + }, { + POSITION: [4.65, 9.85, 0, 270, 220, 1], + TYPE: ["revogun", { COLOR: "#FC8208" }] + }] +}; +Class.hadronturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 'red', + CONTROLLERS: ["hadron"], + TURRETS: [{ + POSITION: [4.65, 10.5, 0, 90, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 270, 220, 1], + TYPE: "revogun", + }] +}; +Class.subverterturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [4.65, 10.5, 0, 90, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 180, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 270, 220, 1], + TYPE: "revogun", + }, { + POSITION: [4.65, 10.5, 0, 0, 220, 1], + TYPE: "revogun", + }] +}; +Class.protonturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [5, 10.5, 0, 0, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + + }, { + POSITION: [5, 10.5, 0, 360/3, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + + }, { + POSITION: [5, 10.5, 0, 360/3*2, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + }] +}; +Class.pionturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + TURRETS: [{ + POSITION: [5, 10.5, 0, 90, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + }, { + POSITION: [5, 10.5, 0, 270, 220, 1], + TYPE: ["revosheild", { SHAPE: 12 }], + VULNERABLE: true, + }] +}; +Class.revogun = { + LABEL: 'Auto Turret', + SYNC_TURRET_SKILLS: true, + BODY: { + FOV: 1 + }, + COLOR: 16, + CONTROLLERS: ['onlyAcceptInArc', 'nearestDifferentMaster'], + GUNS: [{ + POSITION: [13.5, 10, 1, 8, 0, 0, 0.5], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.autoTurret, g.halfreload]), + TYPE: "bullet" + } + } + ] +} +Class.revosheild = { + PARENT: "genericTank", + DAMAGE_CLASS: 1, + TYPE: "shield", + COLOR: "darkGray", + SHAPE: 0, + INDEPENDENT: true, + BODY: { + PUSHABILITY: 0, + HEALTH: 10000, + SHIELD: 10000, + REGEN: 1000, + DAMAGE: 1, + RESIST: 100, + STEALTH: 1, + DENSITY: 10000, + }, +} +Class.backshieldturret = { + PARENT: "genericTank", + TYPE: "shield", + DAMAGE_CLASS: 1, + SHAPE: "m -0.702 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099", + COLOR: "#FF7F00", + INDEPENDENT: true, + BODY: { + HEALTH: 10000, + SHIELD: 10000, + REGEN: 1000, + }, +} +Class.mirrorDeco = makeDeco("M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -0.9 A 0.001 0.001 0 0 1 0 0.9 A 0.001 0.001 0 0 1 0 -0.9") +Class.mirrorbackshieldturret = { + PARENT: "genericTank", + TYPE: "shield", + INDEPENDENT: true, + BODY: { + HEALTH: 10000, + SHIELD: 10000, + REGEN: 1000, + }, + SHAPE: "m -0.7020 -0.8099 c 0.2987 0.4922 0.4276 1.0098 0 1.6105 c 0.4606 -0.1615 0.9233 -0.3735 1.3947 -0.8052 C 0.2005 -0.4442 -0.2526 -0.6387 -0.702 -0.8099", + COLOR: "#FF7F00", + TURRETS: [{ + POSITION: [5.7, 0, 0, 0, 360, 1], + TYPE: "mirrorDeco" + }] +} +// The sheild uses the hitbox like an aura, but it can hit bullets +Class.autoTurretNerf = { + PARENT: "genericTank", + LABEL: "Turret", + BODY: { + FOV: 0.8, + }, + COLOR: "grey", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.weak, g.fake, g.basic, g.morerecoil, g.turret, g.autoTurret]), + TYPE: "bullet", + }, + }, + ], +} +Class.mindindicator = { + SHAPE: 'M 0 -1.0 A 1 1 0 0 0 0 1.0 A 1 1 0 0 0 0 -1.0 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, +}; +Class.crosshair1 = { + SHAPE: 'M 0 0 l 1 0 L 0 0 L -1 0 L 0 0 L 0 1 L 0 -1', + COLOR: 9, +}; +Class.greenSmasherBody = { + LABEL: "", + GLOW: { + RADIUS: 2, + COLOR: "green", + ALPHA: 1, + RECURSION: 4, + }, + CONTROLLERS: [["spin", { independent: true, speed: 0.1 }]], + COLOR: "green", + SHAPE: 6, + INDEPENDENT: true, + BORDERLESS: true, +} +Class.droneturretBase = { + LABEL: "Base", + SHAPE: 'M 0 -1 A 1 1 0 0 0 0 1 A 1 1 0 0 0 0 -1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1', + COLOR: 9, + CONTROLLERS: [["spin", { independent: true }]], + INDEPENDENT: true, + SYNC_TURRET_SKILLS: true, + TURRETS: [{ + POSITION: [4.65, 10.5, 0, 90, 220, 1], + TYPE: "droneAutoTurret", + }, { + POSITION: [4.65, 10.5, 0, 270, 220, 1], + TYPE: "droneAutoTurret", + }] +} +Class.dualAutoTankGun = { + TURRETS: [{ + POSITION: [11, 0, 0, 0, 190, 0], + TYPE: "autoTankGun" + }, { + POSITION: [11, 0, 0, 180, 190, 0], + TYPE: "autoTankGun" + }] +} +Class.autoTankGunDrive = { + PARENT: "genericTank", + LABEL: "", + BODY: { + FOV: 3, + }, + SHAPE: 4, + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + COLOR: "grey", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret]), + TYPE: "bullet", + }, + }, + ], +} +Class.swivelAutoGun = { + PARENT: "genericTank", + LABEL: "", + BODY: { + FOV: 3, + }, + CONTROLLERS: ["canRepel", "onlyAcceptInArc", "mapAltToFire", "nearestDifferentMaster"], + COLOR: "grey", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.autoTurret, g.lesspower, {speed: 0.9, recoil: 0.8}]), + TYPE: "bullet", + }, + }, + ], +} +Class.skaterDeco = makeDeco("M 0 -1.1 A 1 1 0 0 0 0 1.1 A 1 1 0 0 0 0 -1.1 Z M 0 -1 A 0.001 0.001 0 0 1 0 1 A 0.001 0.001 0 0 1 0 -1"); +Class.skaterDeco.STROKE_WIDTH = 2; +Class.switcherDeco = makeDeco('M 0 0 M 2 -1 L -2 -1 L -2 8 L -1 8 L 1 8 L 2 8') +Class.effectBulletDeco = makeDeco(0) +Class.firecrackerDeco = makeDeco(-6) +Class.auraDamageGen = addAura(7.5, 1.3, 0.3, "red"); +Class.auraRangeGen = addAura(5, 1.8, 0.3, "teal", "rangeAuraSymbol"); +Class.auraDamageRangeGen = addAura(7.5, 1.8, 0.3, "red", "rangeAuraSymbol"); +Class.auraMoreDamageGen = addAura(11, 1.3, 0.3, "orange"); +Class.auraMoreRangeGen = addAura(5, 2.3, 0.3, "aqua", "rangeAuraSymbol"); +Class.auraSmasherGen = addAura(11, 1.3); +Class.surgeDeco = makeDeco(-1, "spaceGem"); +Class.katanaDeco = makeDeco('M 0 2 L 0 -1 L 1 0 L 0 -1 L -1 0 L 0 -1', "#add6f7"); \ No newline at end of file diff --git a/server/modules/definitions/gunvals.js b/server/modules/definitions/gunvals.js index fd4d5850b..290543af8 100644 --- a/server/modules/definitions/gunvals.js +++ b/server/modules/definitions/gunvals.js @@ -19,6 +19,7 @@ module.exports = { triplet: { reload: 1.2, recoil: 0.667, shudder: 0.9, health: 0.85, damage: 0.85, pen: 0.9, density: 1.1, spray: 0.9, resist: 0.95 }, turret: { reload: 2, health: 0.8, damage: 0.6, pen: 0.7, density: 0.1 }, autoTurret: { reload: 0.9, recoil: 0.75, shudder: 0.5, size: 0.8, health: 0.9, damage: 0.6, pen: 1.2, speed: 1.1, range: 0.8, density: 1.3, resist: 1.25 }, + littleHunter: { recoil: 0.9, shudder: 0.9, health: 0.9, damage: 0.7, pen: 0.9 }, // Snipers sniper: { reload: 1.35, shudder: 0.25, damage: 0.8, pen: 1.1, speed: 1.5, maxSpeed: 1.5, density: 1.5, spray: 0.2, resist: 1.15 }, @@ -29,6 +30,7 @@ module.exports = { predator: { reload: 1.4, size: 0.8, health: 1.5, damage: 0.9, pen: 1.2, speed: 0.9, maxSpeed: 0.9 }, dual: { reload: 2, shudder: 0.8, health: 1.5, speed: 1.3, maxSpeed: 1.1, resist: 1.25 }, rifle: { reload: 0.8, recoil: 0.8, shudder: 1.5, health: 0.8, damage: 0.8, pen: 0.9, spray: 2 }, + railgun: { reload: 2, health: 0.85, damage: 0.5, pen: 0.9 }, // Machine guns machineGun: { reload: 0.5, recoil: 0.8, shudder: 1.7, health: 0.7, damage: 0.7, maxSpeed: 0.8, spray: 2.5 }, @@ -67,6 +69,7 @@ module.exports = { bigCheese: { reload: 1.5, size: 1.8, health: 2.5, speed: 1.25 }, mothership: { reload: 1.25, pen: 1.1, speed: 0.775, maxSpeed: 0.8, range: 15, resist: 1.15 }, satellite: { size: 0.8, reload: 3, damage: 1.875 }, + contagi: { reload: 1, recoil: 0.5, shudder: 1.5, size: 1, health: 0.6, damage: 0.6, pen: 0.75, speed: 1.05, maxSpeed: 1, range: 1, density: 0.9, spray: 0.75, resist: 0.7 }, // Heavy cannons pounder: { reload: 2, recoil: 1.6, damage: 2, speed: 0.85, maxSpeed: 0.8, density: 1.5, resist: 1.15 }, @@ -76,7 +79,7 @@ module.exports = { artillery: { reload: 1.2, recoil: 0.7, size: 0.9, speed: 1.15, maxSpeed: 1.1, density: 1.5 }, mortar: { reload: 1.2, health: 1.1, speed: 0.8, maxSpeed: 0.8 }, shotgun: { reload: 8, recoil: 0.4, size: 1.5, damage: 0.4, pen: 0.8, speed: 1.8, maxSpeed: 0.6, density: 1.2, spray: 1.2 }, - destroyerDominator: { reload: 6.5, recoil: 0, size: 0.975, health: 6, damage: 6, pen: 6, speed: 0.575, maxSpeed: 0.475, spray: 0.5 }, + destroyerDominator: { reload: 6.5, recoil: 0, size: 0.975, health: 5, damage: 5, pen: 5, speed: 0.575, maxSpeed: 0.475, spray: 0.5 }, // Missiles launcher: { reload: 1.5, recoil: 1.5, shudder: 0.1, size: 0.72, health: 1.05, damage: 0.925, speed: 0.9, maxSpeed: 1.2, range: 1.1, resist: 1.5 }, @@ -105,7 +108,60 @@ module.exports = { arenaCloser: { reload: 1.25, recoil: 0.25, health: 1000, damage: 1000, pen: 1000, speed: 2.5, maxSpeed: 2.25, range: 1.4, density: 4, spray: 0.25 }, healer: { damage: -1, speed: 0.5, maxSpeed: 0.5, recoil: 0.5 }, lowPower: { shudder: 2, health: 0.5, damage: 0.5, pen: 0.7, spray: 0.5, resist: 0.7 }, - halfrange: { range: 0.5 }, aura: { reload: 0.001, recoil: 0.001, shudder: 0.001, size: 6, speed: 0.001, maxSpeed: 0.001, spray: 0.001 }, - noSpread: { shudder: 0, spray: 0 } + noSpread: { shudder: 0, spray: 0 }, + lessspread: { shudder: 0.75, spread: 0.75 }, + + // Range + doublerange: { range: 2 }, + morerange: { range: 1.15 }, + halfrange: { range: 0.5 }, + norange: { range: 0.2 }, + literallynorange: { range: 0 }, + + // Recoil + tonsmorerecoil: { recoil: 4 }, + lotsmorrecoil: { recoil: 1.8 }, + muchmorerecoil: { recoil: 1.35 }, + morerecoil: { recoil: 1.15 }, + lessrecoil: { recoil: 0.65 }, + halfrecoil: { recoil: 0.5 }, + + // Reload + noshoot: { reload: Infinity }, + halfreload: { reload: 2 }, + lessreload: { reload: 1.5 }, + one_third_reload: { reload: 1.333 }, + bitlessreload: { reload: 0.9 }, + morereload: { reload: 0.75 }, + doublereload: { reload: 0.5 }, + triplereload: { reload: 1/3 }, + + // Speed + fast: { speed: 1.2 }, + veryfast: { speed: 2.5 }, + morespeed: { speed: 1.3, maxSpeed: 1.3 }, + bitlessspeed: { speed: 0.93, maxSpeed: 0.93 }, + slow: { speed: 0.7, maxSpeed: 0.7 }, + halfspeed: { speed: 0.5, maxSpeed: 0.5 }, + nomove: { speed: 0, maxSpeed: 0 }, + + // Misc 2 + fakewithrecoil: { recoil: 1, size: 0.00001, health: 0.0001, speed: 0.00001, maxSpeed: 2, range: 0 }, + kiva: { damage: 0.7, pen: 0, health: 4, range: 1.5, speed: 1, maxSpeed: 1.4 }, + xxtrahealth: { health: 999 }, + lance: { reload: 0.4, speed: 0.1, maxSpeed: 0.1, range: 0.1, pen: 3, health: 0.75 }, + lesspower: { health: 0.9, damage: 0.9, pen: 0.9 }, + grenade_explosion: { reload: 8, recoil: 0, shudder: 4.25, size: 2, health: 2.25, damage: 1.75, pen: 1.5, speed: 1.35, spray: 4 }, + literallyamachinegun: { reload: 0.2, speed: 5, maxSpeed: 5, spray: 0.3, shudder: 0.6 }, + rainmaker: { speed: 0.03, maxSpeed: 0.5, health: 0.9, damage: 0.85 }, + acceltospeedoflight: { speed: 0.001, maxSpeed: 1000 }, + explosion: { speed: 0.01, maxSpeed: 0.01, health: 5, damage: 4, pen: 5, density: 3.7, resist: 3 }, + brella: { reload: 2.5, health: 35, pen: 0, damage: 0.2, maxSpeed: 0.8, spray: 0, range: 2.25, size: 2.4, shudder: 0.1 }, + magnet: { damage: 0, health: 0.8, spray: 45, range: 0.08, recoil: 0, speed: 0.8, pen: 0 }, + solarioblast: { reload: 0.05, health: 5, pen: 100, speed: 12, maxSpeed: 12, spread: 4, size: 2, range: 0.12 }, + emplaser: { reload: 1.25, recoil: 0, size: 2.1 }, + empbullet: { reload: 1.25, recoil: 0, size: 2.5, speed: 1.1, maxSpeed: 1.1, spray: 0.2 }, + cloner: { damage: 0.9, pen: 0.85 }, + } \ No newline at end of file diff --git a/server/modules/gamemodes/bossRush.js b/server/modules/gamemodes/bossRush.js index 4ab1e062b..4b07b07a1 100644 --- a/server/modules/gamemodes/bossRush.js +++ b/server/modules/gamemodes/bossRush.js @@ -94,15 +94,17 @@ class BossRush { [100, "kronos"], [100, "odin"], ]; - this.friendlyBossChoices = ["roguePalisade", "rogueArmada", "julius", "genghis", "napoleon"]; + this.friendlyBossChoices = [ [9, "roguePalisade"], [8, "rogueArmada"], [1, "julius"], [1, "genghis"], [1, "napoleon"] ]; this.bigFodderChoices = ["sentryGun", "sentrySwarm", "sentryTrap", "shinySentryGun"]; this.smallFodderChoices = ["crasher"]; - this.length = c.CLASSIC_SIEGE ? this.waveCodes.length : c.WAVES; + this.length = Config.CLASSIC_SIEGE ? this.waveCodes.length : Config.WAVES; this.waves = this.generateWaves(); this.waveId = -1; this.gameActive = true; this.timer = 0; this.remainingEnemies = 0; + this.sanctuaryTier = 1; + this.sanctuaries = []; } generateWaves() { @@ -119,45 +121,47 @@ class BossRush { wave.push(boss); } - waves.push(c.CLASSIC_SIEGE ? this.waveCodes[i] : wave); + waves.push(Config.CLASSIC_SIEGE ? this.waveCodes[i] : wave); } return waves; } spawnFriendlyBoss() { let o = new Entity(getSpawnableArea(TEAM_BLUE)); - o.define(ran.choose(this.friendlyBossChoices)); + let type = this.friendlyBossChoices[ran.chooseChance(...this.friendlyBossChoices.map((x) => x[0]))][1] + o.define(type); o.define({ DANGER: 10 }); o.team = TEAM_BLUE; o.controllers.push(new ioTypes.nearestDifferentMaster(o), new ioTypes.wanderAroundMap(0, { lookAtGoal: true })); + o.name = ran.chooseBossName('castle'); + o.FOV = 10; + o.settings.broadcastMessage = `${o.name} has fallen!`; sockets.broadcast(o.name + ' has arrived and joined your team!'); } spawnSanctuary(tile, team, type = false) { - type = type ? type : Class.sanctuaryTier3; + type = type ? type : "sanctuaryTier3"; let o = new Entity(tile.loc); - o.define(type); - o.team = team; - o.color.base = getTeamColor(team); - o.skill.score = 111069; - o.name = 'Sanctuary'; - o.SIZE = room.tileWidth / 10; - o.isDominator = true; - o.on('dead', () => { - /*let isAC; - for (let instance of o.collisionArray) { - if (TEAM_ROOM !== instance.team && instance.type !== 'food' && instance.type !== 'wall') { - isAC = true; - } - } - if (isAC) { - tile.color = 'white'; - } else */if (o.team === TEAM_ENEMIES) { - this.spawnSanctuary(tile, TEAM_BLUE, Class.sanctuaryTier3); + this.defineSanctuary(o, tile, team, type); + this.sanctuaries.push(o); + } + + defineSanctuary(entity, tile, team, type) { + entity.define(type); + entity.team = team; + entity.color.base = getTeamColor(team); + entity.skill.score = 111069; + entity.name = 'Sanctuary'; + entity.SIZE = room.tileWidth / (Config.CLASSIC_SIEGE ? 10 : 17.5); + entity.isDominator = true; + entity.define({ DANGER: 11 }) + entity.on('dead', () => { + if (entity.team === TEAM_ENEMIES) { + this.spawnSanctuary(tile, TEAM_BLUE, `sanctuaryTier${this.sanctuaryTier}`); tile.color.interpret(getTeamColor(TEAM_BLUE)); sockets.broadcast('A sanctuary has been repaired!'); } else { - this.spawnSanctuary(tile, TEAM_ENEMIES, Class.dominator); + this.spawnSanctuary(tile, TEAM_ENEMIES, "dominator"); tile.color.interpret(getTeamColor(TEAM_ENEMIES)); sockets.broadcast('A sanctuary has been destroyed!'); } @@ -210,7 +214,7 @@ class BossRush { enemy.isBoss = true; } - if (!c.CLASSIC_SIEGE) { + if (!Config.CLASSIC_SIEGE) { //spawn fodder enemies for (let i = 0; i < this.waveId / 5; i++) { this.spawnEnemyWrapper(getSpawnableArea(TEAM_ENEMIES), ran.choose(this.bigFodderChoices)); @@ -224,6 +228,16 @@ class BossRush { setTimeout(() => this.spawnFriendlyBoss(), 5000); } } + + // Update sanctuary tiers + let newSancTier = Math.min(Math.floor(this.waveId / 5) + 1, 6); + if (newSancTier != this.sanctuaryTier) { + for (let sanc of this.sanctuaries) { + this.defineSanctuary(sanc, TEAM_BLUE, `sanctuaryTier${newSancTier}`); + } + sockets.broadcast(`The sanctuaries have upgraded to tier ${newSancTier}.`); + this.sanctuaryTier = newSancTier; + } } //runs once when the server starts @@ -231,7 +245,7 @@ class BossRush { Class.basic.UPGRADES_TIER_2.push("healer"); //TODO: filter out tiles that are not of sanctuary type for (let tile of room.spawnable[TEAM_BLUE]) { - this.spawnSanctuary(tile, TEAM_BLUE); + this.spawnSanctuary(tile, TEAM_BLUE, "sanctuaryTier1"); } } diff --git a/server/modules/gamemodes/gamemodeLoop.js b/server/modules/gamemodes/gamemodeLoop.js index 544c03cff..cab0bdaca 100644 --- a/server/modules/gamemodes/gamemodeLoop.js +++ b/server/modules/gamemodes/gamemodeLoop.js @@ -1,24 +1,28 @@ let bossRush; -if (c.SPECIAL_BOSS_SPAWNS) bossRush = new BossRush(); +if (Config.SPECIAL_BOSS_SPAWNS) bossRush = new BossRush(); let train; -if (c.TRAIN) train = new Train(); +if (Config.TRAIN) train = new Train(); let moon; -if (c.SPACE_MODE) moon = new Moon(); +if (Config.SPACE_MODE) moon = new Moon(); let hunt; -if (c.HUNT) hunt = new ManHunt(); +if (Config.HUNT) hunt = new ManHunt(); +let risk; +//if (Config.GOVERNMENTAL) risk = new Risk(); -if (c.MOTHERSHIP_LOOP) mothershipLoop.spawn(); -if (c.SPECIAL_BOSS_SPAWNS) bossRush.init(); -if (c.MAZE > 0) generateMaze(c.MAZE); +if (Config.MOTHERSHIP_LOOP) mothershipLoop.spawn(); +if (Config.SPECIAL_BOSS_SPAWNS) bossRush.init(); +if (Config.MAZE > 0) generateMaze(Config.MAZE); + +//if (Config.GOVERNMENTAL) risk.init(); let logger = new LagLogger(); const gamemodeLoop = function() { logger.set(); - if (c.HUNT) hunt.loop(); - if (c.TRAIN) train.loop(); - if (c.SPACE_MODE) moon.loop(); - if (c.MOTHERSHIP_LOOP) mothershipLoop.loop(); - if (c.SPECIAL_BOSS_SPAWNS) bossRush.loop(); + if (Config.HUNT) hunt.loop(); + if (Config.TRAIN) train.loop(); + if (Config.SPACE_MODE) moon.loop(); + if (Config.MOTHERSHIP_LOOP) mothershipLoop.loop(); + if (Config.SPECIAL_BOSS_SPAWNS) bossRush.loop(); logger.mark(); if (logger.totalTime > 100) { console.log("Gamemode loop is taking a long time!"); diff --git a/server/modules/gamemodes/groups.js b/server/modules/gamemodes/groups.js index c76c139d6..7365fa62b 100644 --- a/server/modules/gamemodes/groups.js +++ b/server/modules/gamemodes/groups.js @@ -46,7 +46,7 @@ class Group { const addMember = (socket, party = -1) => { let group = activeGroups.find(entry => entry.members.length < entry.size); if (party !== -1) group = activeGroups.find(entry => (entry.teamID === party / room.partyHash && entry.members.length < entry.size)); - if (!group) group = new Group(c.GROUPS || 0); + if (!group) group = new Group(Config.GROUPS || 0); group.addMember(socket); }; diff --git a/server/modules/gamemodes/maze.js b/server/modules/gamemodes/maze.js index 5f78d1b7d..37d74e210 100644 --- a/server/modules/gamemodes/maze.js +++ b/server/modules/gamemodes/maze.js @@ -107,7 +107,7 @@ let checkMazeForBlocks = (initX, initY, size, maze) => { y: d.y }); o.define("wall"); - o.SIZE = d.s * 0.5 - 2; + o.SIZE = d.s * 0.5 / lazyRealSizes[4] * Math.SQRT2 - 2; o.team = TEAM_ENEMIES; o.protect(); o.life(); diff --git a/server/modules/gamemodes/moon.js b/server/modules/gamemodes/moon.js index 37d6637b5..f13b27255 100644 --- a/server/modules/gamemodes/moon.js +++ b/server/modules/gamemodes/moon.js @@ -11,7 +11,7 @@ class Moon { loop () { let players = entities.filter(r => r.isPlayer || r.isBot); for (let entity of players) { - if (entity.id != this.moon.id && !entity.ac && entity.alpha) { + if (entity.id != this.moon.id && !entity.isArenaCloser && entity.alpha) { entity.velocity.x += util.clamp(this.moon.x - entity.x, -90, 90) * entity.damp * 0.02; entity.velocity.y += util.clamp(this.moon.y - entity.y, -90, 90) * entity.damp * 0.02; } diff --git a/server/modules/gamemodes/mothership.js b/server/modules/gamemodes/mothership.js index 2e7393fe8..2185b40cd 100644 --- a/server/modules/gamemodes/mothership.js +++ b/server/modules/gamemodes/mothership.js @@ -5,31 +5,31 @@ let choices = ['mothership']; function spawn() { let locs = [{ - x: c.WIDTH * 0.1, - y: c.HEIGHT * 0.1 + x: Config.WIDTH * 0.1, + y: Config.HEIGHT * 0.1 }, { - x: c.WIDTH * 0.9, - y: c.HEIGHT * 0.9 + x: Config.WIDTH * 0.9, + y: Config.HEIGHT * 0.9 }, { - x: c.WIDTH * 0.9, - y: c.HEIGHT * 0.1 + x: Config.WIDTH * 0.9, + y: Config.HEIGHT * 0.1 }, { - x: c.WIDTH * 0.1, - y: c.HEIGHT * 0.9 + x: Config.WIDTH * 0.1, + y: Config.HEIGHT * 0.9 }, { - x: c.WIDTH * 0.9, - y: c.HEIGHT * 0.5 + x: Config.WIDTH * 0.9, + y: Config.HEIGHT * 0.5 }, { - x: c.WIDTH * 0.1, - y: c.HEIGHT * 0.5 + x: Config.WIDTH * 0.1, + y: Config.HEIGHT * 0.5 }, { - x: c.WIDTH * 0.5, - y: c.HEIGHT * 0.9 + x: Config.WIDTH * 0.5, + y: Config.HEIGHT * 0.9 }, { - x: c.WIDTH * 0.5, - y: c.HEIGHT * 0.1 + x: Config.WIDTH * 0.5, + y: Config.HEIGHT * 0.1 }].sort(() => 0.5 - Math.random()); - for (let i = 0; i < c.TEAMS; i++) { + for (let i = 0; i < Config.TEAMS; i++) { let o = new Entity(locs[i]), team = -i - 1; o.define(ran.choose(choices)); diff --git a/server/modules/gamemodes/risk.js b/server/modules/gamemodes/risk.js new file mode 100644 index 000000000..40347b536 --- /dev/null +++ b/server/modules/gamemodes/risk.js @@ -0,0 +1,80 @@ +let neededToWin = 83, + teamcounts = {}, + gameWon = false; + +class Risk { +spawnSanctuary(tile, team) { + let o = new Entity(tile.loc); + o.define(Class.trapperDominator); + o.team = team; + o.color.base = getTeamColor(team); + o.skill.score = 111069; + o.name = 'Sanctuary'; + o.SIZE = room.tileWidth / 10; + o.isDominator = true; + o.on('dead', () => { + + teamcounts[team]--; + if (!teamcounts[team]) { + delete teamcounts[team]; + } + + let killers = []; + for (let instance of o.collisionArray) { + if (isPlayerTeam(instance.team) && team !== instance.team) { + killers.push(instance); + } + } + + let killer = ran.choose(killers); + killer = killer ? killer.master.master : { team: TEAM_BLUE, color: Config.MODE === "tdm" ? 3 : 12 }; + + let newTeam = killer.team, + newColor = getTeamColor(newTeam); + + for (let player of sockets.players) { + if (player.body && player.body.team === newTeam) { + player.body.sendMessage("Press F to take control of the dominator."); + } + } + + let teamName = newTeam > 0 ? killer.name : getTeamName(newTeam); + sockets.broadcast(`A dominator is now controlled by ${teamName}!`); + if (teamcounts[newTeam] >= neededToWin && !gameWon) { + gameWon = true; + setTimeout(sockets.broadcast, 1500, teamName + " has won the game!"); + setTimeout(closeArena, 4500); + } + + this.spawnSanctuary(tile, newTeam); + sockets.broadcastRoom(); + }); + } + + playerWin() { + if (this.gameActive) { + this.gameActive = false; + sockets.broadcast(getTeamName(TEAM_BLUE) + ' has won the game!'); + setTimeout(closeArena, 1500); + } + } + //runs once when the server starts + init() { + Class.basic.UPGRADES_TIER_2.push("healer"); + //TODO: filter out tiles that are not of sanctuary type + for (let tile of room.spawnable[TEAM_BLUE]) { + this.spawnSanctuary(tile, TEAM_BLUE); + } + for (let tile of room.spawnable[TEAM_GREEN]) { + this.spawnSanctuary(tile, TEAM_GREEN); + } + for (let tile of room.spawnable[TEAM_RED]) { + this.spawnSanctuary(tile, TEAM_RED); + } + for (let tile of room.spawnable[TEAM_PURPLE]) { + this.spawnSanctuary(tile, TEAM_PURPLE); + } + } +} + +module.exports = { Risk }; \ No newline at end of file diff --git a/server/modules/gamemodes/tag.js b/server/modules/gamemodes/tag.js index dce1400bd..9a50753c5 100644 --- a/server/modules/gamemodes/tag.js +++ b/server/modules/gamemodes/tag.js @@ -4,7 +4,7 @@ function checkWin() { if (won) return; let all = 0, teams = {}; - for (let i = 1; i <= c.TEAMS; i++) { + for (let i = 1; i <= Config.TEAMS; i++) { teams[-i] = 0; } for (let i = 0; i < entities.length; i++) { @@ -30,7 +30,7 @@ function checkWin() { function init(g) { g.events.on('spawn', entity => { entity.on('dead', () => { - if (!c.TAG || !entity.isPlayer && !entity.isBot) return; + if (!Config.TAG || !entity.isPlayer && !entity.isBot) return; let killers = []; for (let entry of entity.collisionArray) { if (isPlayerTeam(entry.team) && entity.team !== entry.team) { diff --git a/server/modules/global.js b/server/modules/global.js index bb0c618fc..cddc46a28 100644 --- a/server/modules/global.js +++ b/server/modules/global.js @@ -8,6 +8,7 @@ global.protocol = require(".././lib/fasttalk.js"); // Global Variables (These must come before we import from the modules folder.) global.fps = "Unknown"; +global.playerskin = ""; global.minimap = []; global.entities = []; global.walls = []; @@ -17,6 +18,9 @@ global.entitiesToAvoid = []; global.grid = new hshg.HSHG(); global.arenaClosed = false; global.mockupsLoaded = false; +const d = new Date(); +global.dayofweek = d.getUTCDay(); +global.cangrappleonceagain = "yes" global.loadedAddons = []; global.TEAM_BLUE = -1; @@ -35,7 +39,7 @@ global.getTeamColor = team => ([10, 11, 12, 15, 25, 26, 27, 28][-team - 1] || 3) global.isPlayerTeam = team => /*team < 0 && */team > -9; global.getWeakestTeam = () => { let teamcounts = {}; - for (let i = -c.TEAMS; i < 0; i++) { + for (let i = -Config.TEAMS; i < 0; i++) { teamcounts[i] = 0; } for (let o of entities) { @@ -49,7 +53,7 @@ global.getWeakestTeam = () => { teamcounts = Object.entries(teamcounts); let lowestTeamCount = Math.min(...teamcounts.map(x => x[1])), entries = teamcounts.filter(a => a[1] == lowestTeamCount); - return parseInt(!entries.length ? -Math.ceil(Math.random() * c.TEAMS) : ran.choose(entries)[0]); + return parseInt(!entries.length ? -Math.ceil(Math.random() * Config.TEAMS) : ran.choose(entries)[0]); }; global.Tile = class Tile { @@ -88,7 +92,7 @@ function TO_SCREAMING_SNAKE_CASE(TEXT) { } } -global.c = new Proxy(new EventEmitter(), { +global.Config = new Proxy(new EventEmitter(), { get (obj, prop) { return obj[TO_SCREAMING_SNAKE_CASE(prop)]; }, @@ -108,14 +112,13 @@ global.c = new Proxy(new EventEmitter(), { } } }); -global.c.port = process.env.PORT; -global.Config = global.c; +global.Config.port = process.env.PORT; for (let [key, value] of Object.entries(require('./setup/config.js'))) { if (key in EventEmitter.prototype) { util.warn(`Configuration contains "${key}", which is in 'EventEmitter.prototype' and its value is therefore discarded.`); } else { - global.c[key] = value; + global.Config[key] = value; } } @@ -141,7 +144,6 @@ global.makeHitbox = wall => { Math.atan2( _size, 0 - _size) + wall.angle ], distance = Math.sqrt(_size ** 2 + _size ** 2); - //convert 4 corners into 4 lines for (let i = 0; i < 4; i++) { relativeCorners[i] = { @@ -149,7 +151,6 @@ global.makeHitbox = wall => { y: distance * Math.cos(relativeCorners[i]) }; } - wall.hitbox = [ [relativeCorners[0], relativeCorners[1]], [relativeCorners[1], relativeCorners[2]], @@ -180,6 +181,7 @@ const requires = [ "./gamemodes/manhunt.js", // The Manhunt mode "./gamemodes/trainwars.js", // The Train Wars mode "./gamemodes/moon.js", // The Space mode + "./gamemodes/risk.js", // Risk "./gamemodes/gamemodeLoop.js", // The gamemode loop. "./gamemodes/groups.js", // Duos/Trios/Squads "./gamemodes/tag.js", // Tag @@ -194,4 +196,4 @@ for (let file of requires) { } } -module.exports = { creationDate: new Date() }; +module.exports = { creationDate: new Date() }; \ No newline at end of file diff --git a/server/modules/live/controllers.js b/server/modules/live/controllers.js index c35c02960..420f6b290 100644 --- a/server/modules/live/controllers.js +++ b/server/modules/live/controllers.js @@ -279,6 +279,48 @@ class io_boomerang extends IO { } } } +class io_kiva extends IO { + constructor(b) { + super(b) + this.r = 0 + this.b = b + this.m = b.master + this.turnover = false + let len = 10 * util.getDistance({ + x: 0, + y: 0 + }, b.master.control.target) + this.myGoal = { + x: b.master.control.target.x + b.master.x, + y: b.master.control.target.y + b.master.y, + } + } + think(input) { + if (this.b.range > this.r) this.r = this.b.range + let t = 1; //1 - Math.sin(2 * Math.PI * this.b.range / this.r) || 1 + if (!this.turnover) { + if (this.r && this.b.range < this.r * 0.5) { + setTimeout(() => this.turnover = true, 500); + } + return { + goal: this.myGoal, + power: t, + } + } else { + let tomaster = util.getDistance(this.b, this.m); + if (tomaster < this.m.size) { + this.b.kill() + } + return { + goal: { + x: this.m.x, + y: this.m.y, + }, + power: t, + } + } + } +} class io_goToMasterTarget extends IO { constructor(body) { super(body) @@ -510,7 +552,7 @@ class io_nearestDifferentMaster extends IO { this.tick = 100; } // Think damn hard - if (this.tick++ > 15 * c.runSpeed) { + if (this.tick++ > 15 * Config.runSpeed) { this.tick = 0; this.validTargets = this.buildList(range); // Ditch our old target if it's invalid @@ -717,7 +759,7 @@ class io_spin extends IO { this.a = Math.atan2(input.target.y, input.target.x); return input; } - this.a += this.speed / c.runSpeed; + this.a += this.speed / Config.runSpeed; let offset = (this.independent && this.body.bond != null) ? this.body.bound.angle : 0; return { target: { @@ -735,7 +777,7 @@ class io_spin2 extends IO { this.reverseOnAlt = opts.reverseOnAlt ?? true; this.lastAlt = -1; this.reverseOnTheFly = opts.reverseOnTheFly ?? false; - + // On spawn logic let alt = this.body.master.control.alt; let reverse = (this.reverseOnAlt && alt) ? -1 : 1; @@ -743,7 +785,7 @@ class io_spin2 extends IO { } think(input) { if (!this.reverseOnTheFly) return; - + // Live logic let alt = this.body.master.control.alt; if (this.lastAlt != alt) { @@ -837,7 +879,7 @@ class io_formulaTarget extends IO { // this.originAngle = this.masterAngle ? b.master.facing : getTheGunThatSpawnedMe("how do i do that????").angle; // } - let angle = this.originAngle + this.formula(this.frame += 1 / c.runSpeed, this.body); + let angle = this.originAngle + this.formula(this.frame += 1 / Config.runSpeed, this.body); return { goal: { x: this.body.x + Math.sin(angle), @@ -877,6 +919,63 @@ class io_whirlwind extends IO { this.body.inverseDist = Math.min(trueMaxDistance, Math.max(trueMinDistance, this.body.inverseDist)); } } +class io_hadron extends IO { + constructor(b, opts = {}) { + super(b) + this.a = opts.startAngle || 0; + this.speed = opts.speed ?? 0.04; + this.onlyWhenIdle = opts.onlyWhenIdle; + this.independent = opts.independent; + } + think(input) { + if (input.alt){ + if (this.onlyWhenIdle && input.target) { + this.a = Math.atan2(input.target.y, input.target.x); + return input; + } + this.a -= this.speed / Config.runSpeed; + let offset = (this.independent && this.body.bond != null) ? this.body.bound.angle : 0; + return { + target: { + x: Math.cos(this.a - offset), + y: Math.sin(this.a - offset) + }, + main: true, + }; + } else { + if (this.onlyWhenIdle && input.target) { + this.a = Math.atan2(input.target.y, input.target.x); + return input; + } + this.a += this.speed / Config.runSpeed; + let offset = (this.independent && this.body.bond != null) ? this.body.bound.angle : 0; + return { + target: { + x: Math.cos(this.a + offset), + y: Math.sin(this.a + offset), + }, + main: true, + }; + } + } +} +class io_AimAssist extends IO { + constructor(body) { + super(body); + } + think(input) { + this.body.velocity.x = 0; + this.body.velocity.y = 0; + if (!input.fire && !input.target) { + this.body.x = this.body.master.source.x; + this.body.y = this.body.master.source.y; + } + if (input.fire && input.target) { + this.body.x = this.body.x + input.target.x; + this.body.y = this.body.y + input.target.y; + } + } +} class io_orbit extends IO { constructor(body, opts = {}) { super(body); @@ -902,6 +1001,37 @@ class io_orbit extends IO { this.body.facing = angle; } } +class io_snake extends IO { + constructor(body, opts = {}) { + super(body); + this.waveInvert = opts.invert ? -1 : 1; + this.wavePeriod = opts.period ?? 7.5; + this.waveAmplitude = opts.amplitude ?? 100; + this.reverseWave = this.body.master.control.alt ? -1 : 1;; + this.velocityMagnitude = 0; + this.velocityAngle = 0; + this.body.damp = 0; + this.waveAngle = this.body.master.facing + (opts.angle ?? 0); + this.startX = this.body.x; + this.startY = this.body.y; + this.body.x += Math.cos(this.body.velocity.direction) * this.body.size * 20; + this.body.y += Math.sin(this.body.velocity.direction) * this.body.size * 20; + } + think(input) { + // Define a sin wave for the bullet to follow + let waveX = 50 * (this.body.RANGE - this.body.range) / this.wavePeriod; + let waveY = this.waveAmplitude * Math.sin(waveX / 50) * this.waveInvert * this.reverseWave; + // Rotate the sin wave + let trueWaveX = Math.cos(this.waveAngle) * waveX - Math.sin(this.waveAngle) * waveY; + let trueWaveY = Math.sin(this.waveAngle) * waveX + Math.cos(this.waveAngle) * waveY; + // Follow the sin wave + this.body.x = util.lerp(this.body.x, this.startX + trueWaveX, this.velocityMagnitude); + this.body.y = util.lerp(this.body.y, this.startY + trueWaveY, this.velocityMagnitude); + // Accelerate after spawning + this.velocityMagnitude = Math.min(this.body.velocity.length, this.velocityMagnitude + (this.body.velocity.length / 55) / Config.runSpeed) + //sockets.broadcast(this.velocityBasically.toString()) + } +} class io_disableOnOverride extends IO { constructor(body) { @@ -973,6 +1103,8 @@ let ioTypes = { stackGuns: io_stackGuns, nearestDifferentMaster: io_nearestDifferentMaster, targetSelf: io_targetSelf, + hadron: io_hadron, + AimAssist: io_AimAssist, onlyAcceptInArc: io_onlyAcceptInArc, spin: io_spin, spin2: io_spin2, @@ -986,11 +1118,13 @@ let ioTypes = { formulaTarget: io_formulaTarget, orbit: io_orbit, goToMasterTarget: io_goToMasterTarget, + snake: io_snake, avoid: io_avoid, minion: io_minion, hangOutNearMaster: io_hangOutNearMaster, fleeAtLowHealth: io_fleeAtLowHealth, wanderAroundMap: io_wanderAroundMap, + kiva: io_kiva, }; -module.exports = { ioTypes, IO }; +module.exports = { ioTypes, IO }; \ No newline at end of file diff --git a/server/modules/live/entity.js b/server/modules/live/entity.js index 9452360c6..83eb1736d 100644 --- a/server/modules/live/entity.js +++ b/server/modules/live/entity.js @@ -1,3 +1,5 @@ +const { combineStats } = require('../definitions/facilitators'); + let EventEmitter = require('events'), events, init = g => events = g.events; @@ -18,12 +20,11 @@ function setNatural(natural, type) { } } } -let lerp = (a, b, x) => a + x * (b - a); + class Gun extends EventEmitter { constructor(body, info) { super(); this.id = entitiesIdLog++; - this.ac = false; this.lastShot = { time: 0, power: 0 }; this.body = body; this.master = body.source; @@ -139,7 +140,7 @@ class Gun extends EventEmitter { recoil() { if (this.motion || this.position) { // Simulate recoil - this.motion -= (0.25 * this.position) / c.runSpeed; + this.motion -= (0.25 * this.position) / Config.runSpeed; this.position += this.motion; if (this.position < 0) { // Bouncing off the back @@ -153,7 +154,7 @@ class Gun extends EventEmitter { if (this.canShoot && !this.body.settings.hasNoRecoil) { // Apply recoil to motion if (this.motion > 0) { - let recoilForce = (-this.position * this.trueRecoil * this.body.recoilMultiplier * 1.08 / this.body.size) / c.runSpeed; + let recoilForce = (-this.position * this.trueRecoil * this.body.recoilMultiplier * 1.08 / this.body.size) / Config.runSpeed; this.body.accel.x += recoilForce * Math.cos(this.recoilDir); this.body.accel.y += recoilForce * Math.sin(this.recoilDir); } @@ -249,7 +250,7 @@ class Gun extends EventEmitter { // Cycle up if we should if (shootPermission || !this.waitToCycle) { if (this.cycle < 1) { - this.cycle += 1 / (this.settings.reload * c.runSpeed * (this.calculator == "necro" || this.calculator == "fixed reload" ? 1 : sk.rld)); + this.cycle += 1 / (this.settings.reload * Config.runSpeed * (this.calculator == "necro" || this.calculator == "fixed reload" ? 1 : sk.rld)); } } // Firing routines @@ -307,7 +308,7 @@ class Gun extends EventEmitter { } spread *= Math.PI / 180; // Find speed - let vecLength = (this.negRecoil ? -1 : 1) * this.settings.speed * c.runSpeed * sk.spd * (1 + shudder), + let vecLength = (this.negRecoil ? -1 : 1) * this.settings.speed * Config.runSpeed * sk.spd * (1 + shudder), vecAngle = this.angle + this.body.facing + spread, s = new Vector(vecLength * Math.cos(vecAngle), vecLength * Math.sin(vecAngle)); // Boost it if we should @@ -559,7 +560,7 @@ class Gun extends EventEmitter { } getTracking() { return { - speed: c.runSpeed * (this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.maxSpeed * this.natural.SPEED, + speed: Config.runSpeed * (this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.maxSpeed * this.natural.SPEED, range: Math.sqrt(this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.range * this.natural.RANGE }; } @@ -876,6 +877,7 @@ class Entity extends EventEmitter { this.turrets = []; this.props = []; this.upgrades = []; + this.skippedUpgrades = []; this.settings = {}; this.aiSettings = {}; this.children = []; @@ -982,7 +984,7 @@ class Entity extends EventEmitter { let lastingEffects = [], needsBodyAttribRefresh = false; for (let i = 0; i < this.statusEffects.length; i++) { let entry = this.statusEffects[i]; - entry.durationLeftover -= 1 / c.runSpeed; + entry.durationLeftover -= 1 / Config.runSpeed; if (entry.durationLeftover > 0) { lastingEffects.push(entry); } else { @@ -1119,7 +1121,7 @@ class Entity extends EventEmitter { } this.color.interpret(set.COLOR); } - this.upgradeColor = set.UPGRADE_COLOR == null ? null : new Color(set.UPGRADE_COLOR).compiled; + if (set.UPGRADE_COLOR) this.upgradeColor = new Color(set.UPGRADE_COLOR).compiled; if (set.GLOW != null) { this.glow = { radius: set.GLOW.RADIUS ?? 0, @@ -1201,15 +1203,15 @@ class Entity extends EventEmitter { if (set.DRAW_FILL != null) this.drawFill = set.DRAW_FILL; if (set.TEAM != null) { this.team = set.TEAM; - if (!sockets.players.length) { - const _entity = this; + if (sockets.players.length) { for (let i = 0; i < sockets.players.length; i++) { - if (sockets.players[i].body.id == _entity.id) { - sockets.players[i].team = -_entity.team; + const player = sockets.players[i]; + if (player.body.id == this.id) { + player.team = this.team; } } } - for (let child of this.children) child.team = set.TEAM + for (let child of this.children) child.team = set.TEAM; } if (set.VARIES_IN_SIZE != null) { this.settings.variesInSize = set.VARIES_IN_SIZE; @@ -1221,18 +1223,15 @@ class Entity extends EventEmitter { this.skill.setCaps(caps); this.upgrades = []; this.isArenaCloser = false; - this.ac = false; this.alpha = 1; this.reset(); } + if (set.SYNC_TURRET_SKILLS != null) this.syncTurretSkills = set.SYNC_TURRET_SKILLS; if (set.RESET_UPGRADE_MENU) this.upgrades = [] - if (set.ARENA_CLOSER != null) { - this.isArenaCloser = set.ARENA_CLOSER; - this.ac = set.ARENA_CLOSER; - } + if (set.ARENA_CLOSER != null) this.isArenaCloser = set.ARENA_CLOSER; if (set.BRANCH_LABEL != null) this.branchLabel = set.BRANCH_LABEL; if (set.BATCH_UPGRADES != null) this.batchUpgrades = set.BATCH_UPGRADES; - for (let i = 0; i < c.MAX_UPGRADE_TIER; i++) { + for (let i = 0; i < Config.MAX_UPGRADE_TIER; i++) { let tierProp = 'UPGRADES_TIER_' + i; if (set[tierProp] != null && emitEvent) { for (let j = 0; j < set[tierProp].length; j++) { @@ -1247,7 +1246,7 @@ class Entity extends EventEmitter { } this.upgrades.push({ class: trueUpgrades, - level: c.TIER_MULTIPLIER * i, + level: Config.TIER_MULTIPLIER * i, index: index.substring(0, index.length-1), tier: i, branch: 0, @@ -1264,8 +1263,11 @@ class Entity extends EventEmitter { if (set.LEVEL_CAP != null) { this.levelCap = set.LEVEL_CAP; } + if ("function" === typeof set.LEVEL_SKILL_POINT_FUNCTION) { + this.skill.LSPF = set.LEVEL_SKILL_POINT_FUNCTION; + } if (set.LEVEL != null) { - this.skill.reset(); + this.skill.reset(false); while (this.skill.level < set.LEVEL) { this.skill.score += this.skill.levelScore; this.skill.maintain(); @@ -1289,11 +1291,12 @@ class Entity extends EventEmitter { } this.guns = newGuns; } + if (set.GUN_STAT_SCALE) { + let gunStatScale = set.GUN_STAT_SCALE; + this.gunStatScale = gunStatScale; + } if (set.MAX_CHILDREN != null) this.maxChildren = set.MAX_CHILDREN; if (set.RESET_CHILDREN) this.destroyAllChildren(); - if ("function" === typeof set.LEVEL_SKILL_POINT_FUNCTION) { - this.skill.LSPF = set.LEVEL_SKILL_POINT_FUNCTION; - } if (set.RECALC_SKILL != null) { let score = this.skill.score; this.skill.reset(); @@ -1329,6 +1332,7 @@ class Entity extends EventEmitter { } this.definitionEvents = []; } + this.variables = set.VARIABLES ? JSON.parse(JSON.stringify(set.VARIABLES)) : {}; if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; if (Array.isArray(this.rerootUpgradeTree)) { let finalRoot = ""; @@ -1457,7 +1461,7 @@ class Entity extends EventEmitter { if (this.coreSize == null) this.coreSize = this.SIZE; } if (set.BATCH_UPGRADES != null) this.batchUpgrades = set.BATCH_UPGRADES; - for (let i = 0; i < c.MAX_UPGRADE_TIER; i++) { + for (let i = 0; i < Config.MAX_UPGRADE_TIER; i++) { let tierProp = 'UPGRADES_TIER_' + i; if (set[tierProp] != null && emitEvent) { for (let j = 0; j < set[tierProp].length; j++) { @@ -1472,7 +1476,7 @@ class Entity extends EventEmitter { } this.upgrades.push({ class: trueUpgrades, - level: c.TIER_MULTIPLIER * i, + level: Config.TIER_MULTIPLIER * i, index: index.substring(0, index.length-1), tier: i, branch, @@ -1527,7 +1531,7 @@ class Entity extends EventEmitter { } this.upgrades.push({ class: upgradeClass, - level: c.TIER_MULTIPLIER * upgradeTier, + level: Config.TIER_MULTIPLIER * upgradeTier, index: upgradeIndex.substring(0, upgradeIndex.length-1), tier: upgradeTier, branch: 0, @@ -1570,9 +1574,9 @@ class Entity extends EventEmitter { } let speedReduce = Math.pow(this.size / (this.coreSize || this.SIZE), 1); - this.acceleration = (accelerationMultiplier * c.runSpeed * this.ACCELERATION) / speedReduce; + this.acceleration = (accelerationMultiplier * Config.runSpeed * this.ACCELERATION) / speedReduce; if (this.settings.reloadToAcceleration) this.acceleration *= this.skill.acl; - this.topSpeed = (topSpeedMultiplier * c.runSpeed * this.SPEED * this.skill.mob) / speedReduce; + this.topSpeed = (topSpeedMultiplier * Config.runSpeed * this.SPEED * this.skill.mob) / speedReduce; if (this.settings.reloadToAcceleration) this.topSpeed /= Math.sqrt(this.skill.acl); this.health.set(((this.settings.healthWithLevel ? 2 * this.level : 0) + this.HEALTH) * this.skill.hlt * healthMultiplier); this.health.resist = 1 - 1 / Math.max(1, this.RESIST + this.skill.brst); @@ -1637,7 +1641,7 @@ class Entity extends EventEmitter { this.move(); } get level() { - return Math.min(this.levelCap ?? c.LEVEL_CAP, this.skill.level); + return Math.min(this.levelCap ?? Config.LEVEL_CAP, this.skill.level); } get size() { return this.bond == null ? (this.coreSize || this.SIZE) * this.sizeMultiplier * (1 + this.level / 45) : this.bond.size * this.bound.size; @@ -1649,10 +1653,22 @@ class Entity extends EventEmitter { return this.size * lazyRealSizes[Math.floor(Math.abs(this.shape))]; } get xMotion() { - return (this.velocity.x + this.accel.x) / c.runSpeed; + return (this.velocity.x + this.accel.x) / Config.runSpeed; } get yMotion() { - return (this.velocity.y + this.accel.y) / c.runSpeed; + return (this.velocity.y + this.accel.y) / Config.runSpeed; + } + set gunStatScale(gunStatScale) { + if (typeof gunStatScale == "object") { + gunStatScale = [gunStatScale]; + } + for (let gun of this.guns) { + if (!gun.settings) { + continue + } + gun.settings = combineStats([gun.settings, ...gunStatScale]); + gun.trueRecoil = gun.settings.recoil; + } } camera(tur = false) { let turretsAndProps = this.turrets.concat(this.props); @@ -1712,8 +1728,11 @@ class Entity extends EventEmitter { } return suc; } - upgrade(number) { - let old = this; + upgrade(number, branchId) { + // Account for upgrades that are too high level for the player to access + for (let i = 0; i < branchId; i++) { + number += this.skippedUpgrades[i] ?? 0; + } if ( number < this.upgrades.length && this.skill.level >= this.upgrades[number].level @@ -1735,7 +1754,7 @@ class Entity extends EventEmitter { } this.emit("upgrade", { body: this }); if (this.color.base == '-1' || this.color.base == 'mirror') { - if (c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) { + if (Config.GROUPS || (Config.MODE == 'ffa' && !Config.TAG)) { this.color.base = this.isBot ? "darkGrey" : getTeamColor(TEAM_RED); } else { this.color.base = getTeamColor(this.team); @@ -1783,8 +1802,8 @@ class Entity extends EventEmitter { x: 0, y: 0, }, - a = this.acceleration / c.runSpeed; - if (c.SPACE_PHYSICS) { + a = this.acceleration / Config.runSpeed; + if (Config.SPACE_PHYSICS) { this.maxSpeed = this.topSpeed; this.damp = 100; } @@ -1797,6 +1816,19 @@ class Entity extends EventEmitter { case "fastgrow": this.SIZE += args.growSpeed ?? 5; break; + case "fuckingnuclearbomb": + this.SIZE += args.growSpeed ?? 10; + break; + case "trappershockwave": + this.SIZE += args.growSpeed ?? 20; + break; + case "shrink": + this.SIZE -= args.growSpeed ?? 1; + break; + case "solarioarena": + if (this.SIZE > 199) break; + this.SIZE += args.growSpeed ?? 2; + break; case "glide": this.maxSpeed = this.topSpeed; this.damp = args.damp ?? 0.05; @@ -1824,6 +1856,20 @@ class Entity extends EventEmitter { this.maxSpeed = this.topSpeed; this.damp = args.damo ?? -0.025; break; + case "accelerate": + this.velocity.x = this.velocity.x + (4.5 * Math.cos(this.facing)) + this.velocity.y = this.velocity.y + (4.5 * Math.sin(this.facing)) + this.topSpeed += 10; + this.maxSpeed += 10; + this.damp = -0.0125; + break; + case "acceleratetothespeedoflight": + this.velocity.x = this.velocity.x + ((1 * this.maxSpeed + 0.5) * Math.cos(this.facing)) + this.velocity.y = this.velocity.y + ((1 * this.maxSpeed + 0.5) * Math.sin(this.facing)) + this.topSpeed += 0.5; + this.maxSpeed += 0.5; + this.damp = -0.0001; + break; case "swarm": this.maxSpeed = this.topSpeed; let l = @@ -1871,6 +1917,20 @@ class Entity extends EventEmitter { this.maxSpeed = 0; } break; + case "aimassist": + this.x = this.source.x + this.master.control.target.x; + this.y = this.source.y + this.master.control.target.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + break; + case "aimassistlock": + if (!this.control.alt) { + this.x = this.source.x + this.master.control.target.x; + this.y = this.source.y + this.master.control.target.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + }; + break; case "drift": this.maxSpeed = 0; engine = { @@ -1889,6 +1949,7 @@ class Entity extends EventEmitter { this.firingArc = [ref.facing + bound.angle, bound.arc / 2]; this.accel.null(); this.blend = ref.blend; + if (this.bond.syncTurretSkills) this.skill.set(this.bond.skill.raw); break; case "withMaster": this.x = this.source.x; @@ -1917,7 +1978,7 @@ class Entity extends EventEmitter { y: this.master.y + this.master.control.target.y, }; let amount = (util.getDistance(target, save) / 100) | 0; - //sockets.broadcast(this.velocity.x.toString()) + amount = amount > 6 ? 6 : amount; if (this.waveReversed == null) this.waveReversed = this.master.control.alt ? -1 : 1; if (this.waveAngle == null) { this.waveAngle = this.master.facing; @@ -1945,26 +2006,26 @@ class Entity extends EventEmitter { args = this.facingType[1]; switch (type) { case "autospin": - this.facing += (args.speed ?? 0.02) / c.runSpeed; + this.facing += (args.speed ?? 0.02) / Config.runSpeed; break; case "turnWithSpeed": - this.facing += ((this.velocity.length / 90) * Math.PI) / c.runSpeed; + this.facing += ((this.velocity.length / 90) * Math.PI) / Config.runSpeed; break; case "spin": - this.facing += (args.speed ?? 0.05) / c.runSpeed; + this.facing += (args.speed ?? 0.05) / Config.runSpeed; break; case "fastspin": - this.facing += (args.speed ?? 0.1) / c.runSpeed; + this.facing += (args.speed ?? 0.1) / Config.runSpeed; break; case "veryfastspin": - this.facing += (args.speed ?? 1) / c.runSpeed; + this.facing += (args.speed ?? 1) / Config.runSpeed; break; case "withMotion": this.facing = this.velocity.direction; break; case "smoothWithMotion": case "looseWithMotion": - this.facing = util.interpolateAngle(this.facing, this.velocity.direction, c.runSpeed / (args.speed ?? 4)); + this.facing = util.interpolateAngle(this.facing, this.velocity.direction, Config.runSpeed / (args.speed ?? 4)); break; case "withTarget": case "toTarget": @@ -1977,7 +2038,7 @@ class Entity extends EventEmitter { case "looseWithTarget": case "looseToTarget": case "smoothToTarget": - this.facing = util.interpolateAngle(this.facing, Math.atan2(t.y, t.x), c.runSpeed / (args.speed ?? 4)); + this.facing = util.interpolateAngle(this.facing, Math.atan2(t.y, t.x), Config.runSpeed / (args.speed ?? 4)); break; case "noFacing": this.facing = args.angle ?? 0; @@ -1985,7 +2046,7 @@ class Entity extends EventEmitter { case "bound": let angleToTarget, angleDiff = 3, reduceIndependence = false, - slowness = this.settings.mirrorMasterAngle ? 1 : (args.slowness ?? 4) / c.runSpeed; + slowness = this.settings.mirrorMasterAngle ? 1 : (args.slowness ?? 4) / Config.runSpeed; if (this.control.main) { angleToTarget = Math.atan2(t.y, t.x); angleDiff = Math.abs(util.angleDifference(angleToTarget, this.firingArc[0])); @@ -1998,12 +2059,12 @@ class Entity extends EventEmitter { reduceIndependence = true; } if (reduceIndependence) { - this.perceptionAngleIndependence -= 0.3 / c.runSpeed; + this.perceptionAngleIndependence -= 0.3 / Config.runSpeed; if (this.perceptionAngleIndependence < 0) { this.perceptionAngleIndependence = 0; } } else { - this.perceptionAngleIndependence += 0.3 / c.runSpeed; + this.perceptionAngleIndependence += 0.3 / Config.runSpeed; if (this.perceptionAngleIndependence > 1) { this.perceptionAngleIndependence = 1; } @@ -2019,7 +2080,7 @@ class Entity extends EventEmitter { this.vfacing = oldVFacing; } else { this.facing = ((this.facing % TAU) + TAU) % TAU; - this.vfacing = util.angleDifference(oldFacing, this.facing) * c.runSpeed; + this.vfacing = util.angleDifference(oldFacing, this.facing) * Config.runSpeed; } } takeSelfie() { @@ -2042,18 +2103,18 @@ class Entity extends EventEmitter { this.accel.null(); // Apply motion this.stepRemaining = 1; - if (c.SPACE_PHYSICS) this.stepRemaining = 2; - this.x += (this.stepRemaining * this.velocity.x) / c.runSpeed; - this.y += (this.stepRemaining * this.velocity.y) / c.runSpeed; + if (Config.SPACE_PHYSICS) this.stepRemaining = 2; + this.x += (this.stepRemaining * this.velocity.x) / Config.runSpeed; + this.y += (this.stepRemaining * this.velocity.y) / Config.runSpeed; } friction() { var motion = this.velocity.length, excess = motion - this.maxSpeed; if (excess > 0 && this.damp) { - var k = this.damp / c.runSpeed, + var k = this.damp / Config.runSpeed, drag = excess / (k + 1), finalvelocity = this.maxSpeed + drag; - if (c.SPACE_PHYSICS) + if (Config.SPACE_PHYSICS) finalvelocity *= this.type === "bullet" ? 1.005 : 1.1; this.velocity.x = (finalvelocity * this.velocity.x) / motion; this.velocity.y = (finalvelocity * this.velocity.y) / motion; @@ -2070,25 +2131,25 @@ class Entity extends EventEmitter { return 0; } if (!this.settings.canGoOutsideRoom) { - if (c.ARENA_TYPE === "circle") { + if (Config.ARENA_TYPE === "circle") { let centerPoint = { x: room.width / 2, y: room.height / 2, }, dist = util.getDistance(this, centerPoint); if (dist > room.width / 2) { - let strength = (dist - room.width / 2) * c.ROOM_BOUND_FORCE / (c.runSpeed * 750); - this.x = lerp(this.x, centerPoint.x, strength); - this.y = lerp(this.y, centerPoint.y, strength); + let strength = (dist - room.width / 2) * Config.ROOM_BOUND_FORCE / (Config.runSpeed * 750); + this.x = util.lerp(this.x, centerPoint.x, strength); + this.y = util.lerp(this.y, centerPoint.y, strength); } } else { let padding = this.realSize - 50; - this.accel.x -= Math.max(this.x + padding - room.width, Math.min(this.x - padding, 0)) * c.ROOM_BOUND_FORCE / c.runSpeed; - this.accel.y -= Math.max(this.y + padding - room.height, Math.min(this.y - padding, 0)) * c.ROOM_BOUND_FORCE / c.runSpeed; + this.accel.x -= Math.max(this.x + padding - room.width, Math.min(this.x - padding, 0)) * Config.ROOM_BOUND_FORCE / Config.runSpeed; + this.accel.y -= Math.max(this.y + padding - room.height, Math.min(this.y - padding, 0)) * Config.ROOM_BOUND_FORCE / Config.runSpeed; } } } contemplationOfMortality() { - if (this.invuln) { + if (this.invuln || this.godmode) { this.damageReceived = 0; return 0; } @@ -2106,7 +2167,7 @@ class Entity extends EventEmitter { } // Life-limiting effects if (this.settings.diesAtRange) { - this.range -= 1 / c.runSpeed; + this.range -= 1 / Config.runSpeed; if (this.range < 0) { this.kill(); } @@ -2116,7 +2177,7 @@ class Entity extends EventEmitter { !this.collisionArray.length && this.velocity.length < this.topSpeed / 2 ) { - this.health.amount -= this.health.getDamage(1 / c.runSpeed); + this.health.amount -= this.health.getDamage(1 / Config.runSpeed); } } // Shield regen and damage @@ -2147,6 +2208,8 @@ class Entity extends EventEmitter { } } + this.variables = {}; + // MEMORY LEAKS ARE BAD!!!! for (let i = 0; i < this.turrets.length; i++) { this.turrets[i].kill(); @@ -2195,11 +2258,20 @@ class Entity extends EventEmitter { switch (this.type) { case "tank": killers.length > 1 ? instance.killCount.assists++ : instance.killCount.solo++; + if (instance.killCount.solo == 5) { + if (instance.socket) instance.socket.talk("achieve", 0); + }; + if (instance.killCount.solo == 10) { + if (instance.socket) instance.socket.talk("achieve", 1); + sockets.broadcast(instance.name + " is on a kill streak of 10!"); + }; + if (instance.socket) instance.socket.talk("killgained"); break; case "food": case "crasher": instance.killCount.polygons++; + if (instance.socket) instance.socket.talk("shapegained"); break case "miniboss": @@ -2294,7 +2366,7 @@ class Entity extends EventEmitter { entitiesToAvoid.push(this); this.isProtected = true; } - say(message, duration = c.CHAT_MESSAGE_DURATION) { + say(message, duration = Config.CHAT_MESSAGE_DURATION) { if (!chats[this.id]) { chats[this.id] = []; } diff --git a/server/modules/live/entitySubFunctions.js b/server/modules/live/entitySubFunctions.js index e176356e6..04a5938b5 100644 --- a/server/modules/live/entitySubFunctions.js +++ b/server/modules/live/entitySubFunctions.js @@ -13,9 +13,9 @@ const skcnv = { let curvePoints = []; for (let i = 0; i < 256; i++) { - curvePoints.push(Math.log(4 * (i / c.MAX_SKILL) + 1) / 1.6); + curvePoints.push(Math.log(4 * (i / Config.MAX_SKILL) + 1) / 1.6); } -let curve = x => curvePoints[x * c.MAX_SKILL]; +let curve = x => curvePoints[x * Config.MAX_SKILL]; function apply(f, x) { return x < 0 ? 1 / (1 - x * f) : f * x + 1; } @@ -25,7 +25,7 @@ class Skill { // Just skill stuff. this.raw = inital; this.caps = []; - this.setCaps([ c.MAX_SKILL, c.MAX_SKILL, c.MAX_SKILL, c.MAX_SKILL, c.MAX_SKILL, c.MAX_SKILL, c.MAX_SKILL, c.MAX_SKILL, c.MAX_SKILL, c.MAX_SKILL ]); + this.setCaps([ Config.MAX_SKILL, Config.MAX_SKILL, Config.MAX_SKILL, Config.MAX_SKILL, Config.MAX_SKILL, Config.MAX_SKILL, Config.MAX_SKILL, Config.MAX_SKILL, Config.MAX_SKILL, Config.MAX_SKILL ]); this.name = [ "Reload", "Bullet Penetration", @@ -54,12 +54,12 @@ class Skill { this.acl = 0; this.reset(); } - reset() { + reset(resetLSPF = true) { this.points = 0; this.score = 0; this.deduction = 0; this.level = 0; - this.LSPF = null; + if (resetLSPF) this.LSPF = null; this.set([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); this.maintain(); } @@ -72,7 +72,7 @@ class Skill { } let attrib = []; for (let i = 0; i < 10; i++) { - attrib[i] = curve(this.raw[i] / c.MAX_SKILL); + attrib[i] = curve(this.raw[i] / Config.MAX_SKILL); } this.rld = Math.pow(0.5, attrib[skcnv.rld]); this.pen = apply(2.5, attrib[skcnv.pen]); @@ -82,9 +82,9 @@ class Skill { this.acl = apply(0.5, attrib[skcnv.rld]); this.rst = 0.5 * attrib[skcnv.str] + 2.5 * attrib[skcnv.pen]; this.ghost = attrib[skcnv.pen]; - this.shi = c.GLASS_HEALTH_FACTOR * apply(3 / c.GLASS_HEALTH_FACTOR - 1, attrib[skcnv.shi]); + this.shi = Config.GLASS_HEALTH_FACTOR * apply(3 / Config.GLASS_HEALTH_FACTOR - 1, attrib[skcnv.shi]); this.atk = apply(0.021, attrib[skcnv.atk]); - this.hlt = c.GLASS_HEALTH_FACTOR * apply(2 / c.GLASS_HEALTH_FACTOR - 1, attrib[skcnv.hlt]); + this.hlt = Config.GLASS_HEALTH_FACTOR * apply(2 / Config.GLASS_HEALTH_FACTOR - 1, attrib[skcnv.hlt]); this.mob = apply(0.8, attrib[skcnv.mob]); this.rgn = apply(25, attrib[skcnv.rgn]); this.brst = 0.3 * (0.5 * attrib[skcnv.atk] + 0.5 * attrib[skcnv.hlt] + attrib[skcnv.rgn]); @@ -130,7 +130,7 @@ class Skill { return this.levelScore ? (this.score - this.deduction) / this.levelScore : 0; } get levelPoints() { - return this.LSPF ? this.LSPF(this.level) : c.LEVEL_SKILL_POINT_FUNCTION(this.level); + return this.LSPF ? this.LSPF(this.level) : Config.LEVEL_SKILL_POINT_FUNCTION(this.level); } cap(skill, real = false) { return this.caps[skcnv[skill]]; diff --git a/server/modules/network/sockets.js b/server/modules/network/sockets.js index c1739bb8e..95f3aa087 100644 --- a/server/modules/network/sockets.js +++ b/server/modules/network/sockets.js @@ -136,6 +136,9 @@ function incoming(message, socket) { util.log("[INFO] A socket was verified with the token: " + key); } else { util.log("[WARNING] A socket failed to verify with the token: " + key); + if (key !== "") { + socket.talk("achieve", 2); + } } socket.key = key; } @@ -148,14 +151,15 @@ function incoming(message, socket) { socket.kick("Trying to spawn while already alive."); return 1; } - if (m.length !== 3) { - socket.kick("Ill-sized spawn request."); + if (m.length !== 4) { + socket.kick("Ill-sized spawn request." + global.playerskin + m.length); return 1; } // Get data - let name = m[0].replace(c.BANNED_CHARACTERS_REGEX, ""); + let name = m[0].replace(Config.BANNED_CHARACTERS_REGEX, ""); let needsRoom = m[1]; let autoLVLup = m[2]; + global.playerskin = m[3].replace(name, ""); // Verify it if (typeof name != "string") { socket.kick("Bad spawn request name."); @@ -189,7 +193,7 @@ function incoming(message, socket) { socket.player = socket.spawn(name); if (autoLVLup) { - while (socket.player.body.skill.level < c.LEVEL_CHEAT_CAP) { + while (socket.player.body.skill.level < Config.LEVEL_CHEAT_CAP) { socket.player.body.skill.score += socket.player.body.skill.levelScore; socket.player.body.skill.maintain(); socket.player.body.refreshBodyAttributes(); @@ -198,7 +202,7 @@ function incoming(message, socket) { //socket.view.gazeUpon(); //socket.lastUptime = Infinity; // Give it the room state - socket.talk("R", room.width, room.height, JSON.stringify(room.setup.map(x => x.map(t => t.color.compiled))), JSON.stringify(util.serverStartTime), c.runSpeed, c.ARENA_TYPE); + socket.talk("R", room.width, room.height, JSON.stringify(room.setup.map(x => x.map(t => t.color.compiled))), JSON.stringify(util.serverStartTime), Config.runSpeed, Config.ARENA_TYPE); // Log it util.log(`[INFO] ${m[0]} ${needsRoom ? "joined" : "rejoined"} the game on team ${socket.player.body.team}! Players: ${players.length}`); break; @@ -278,7 +282,7 @@ function incoming(message, socket) { return 1; } // Will not work out - // if (c.SPACE_MODE && player.body) { + // if (Config.SPACE_MODE && player.body) { // let spaceOffsetAngle = Math.atan2( // room.width / 2 - player.body.x, // room.height / 2 - player.body.y @@ -302,6 +306,7 @@ function incoming(message, socket) { player.command.lmb = (commands & 16) >> 4; player.command.mmb = (commands & 32) >> 5; player.command.rmb = (commands & 64) >> 6; + player.command.ability = (commands & 128) >> 7; } // Update the thingy socket.timeout.set(commands); @@ -345,20 +350,21 @@ function incoming(message, socket) { break; case "U": // upgrade request - if (m.length !== 1) { + if (m.length !== 2) { socket.kick("Ill-sized upgrade request."); return 1; } // Get data let upgrade = m[0]; + let branchId = m[1]; // Verify the request - if (typeof upgrade != "number" || upgrade < 0) { + if (typeof upgrade != "number" || upgrade < 0 || typeof branchId != "number" || branchId < 0) { socket.kick("Bad upgrade request."); return 1; } // Upgrade it if (player.body != null) { - player.body.upgrade(upgrade); // Ask to upgrade + player.body.upgrade(upgrade, branchId); // Ask to upgrade } break; case "x": @@ -404,7 +410,7 @@ function incoming(message, socket) { } // cheatingbois if (player.body == null || player.body.underControl) return; - if (player.body.skill.level < c.LEVEL_CHEAT_CAP || (socket.permissions && socket.permissions.infiniteLevelUp)) { + if (player.body.skill.level < Config.LEVEL_CHEAT_CAP || (socket.permissions && socket.permissions.infiniteLevelUp)) { player.body.skill.score += player.body.skill.levelScore; player.body.skill.maintain(); player.body.refreshBodyAttributes(); @@ -421,7 +427,7 @@ function incoming(message, socket) { player.body.define({ RESET_UPGRADES: true, BATCH_UPGRADES: false }); player.body.define(socket.permissions.class); if (player.body.color.base == '-1' || player.body.color.base == 'mirror') { - player.body.color.base = getTeamColor((c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) ? TEAM_RED : player.body.team); + player.body.color.base = getTeamColor((Config.GROUPS || (Config.MODE == 'ffa' && !Config.TAG)) ? TEAM_RED : player.body.team); } } break; @@ -437,6 +443,171 @@ function incoming(message, socket) { player.body.destroy(); } break; + case "testTeleport": + if (player.body != null && socket.permissions) { + player.body.x = player.body.x + player.target.x; + player.body.y = player.body.y + player.target.y; + } + break; + case "smallerTank": + if (player.body != null && socket.permissions) { + player.body.SIZE *= 4/5; + player.body.RECOIL_MULTIPLIER *= 4/5; + } + break; + case "biggerTank": + if (player.body != null && socket.permissions) { + player.body.SIZE *= 5/4; + player.body.RECOIL_MULTIPLIER *= 5/4; + } + break; + case "smallerFOV": + if (player.body != null && socket.permissions) { + player.body.FOV *= 4/5 + } + break; + case "biggerFOV": + if (player.body != null && socket.permissions) { + player.body.FOV *= 5/4 + } + break; + case "godmodeButton": + if (player.body != null && socket.permissions) { + player.body.godmode = !player.body.godmode; + player.body.sendMessage((player.body.godmode ? "Godmode enabled." : "Godmode disabled.")); + } + break; + case "invisibility": + if (player.body != null && socket.permissions) { + player.body.alpha = !player.body.alpha; + player.body.invisible = [player.body.alpha, !player.body.alpha] + } + break; + case "canBeOnLeaderboard": + if (player.body != null && socket.permissions) { + player.body.settings.leaderboardable = !player.body.settings.leaderboardable; + player.body.sendMessage((player.body.settings.leaderboardable ? "You have been added to the leaderboard" : "You have been removed from the leaderboard.")); + } + break; + case "keyStrong"://keyStrong + if (player.body != null && socket.permissions) { + player.body.skill.raw = Array(10).fill(12); + player.body.define({ + SKILL_CAP: [12, 12, 12, 12, 12, 12, 12, 12, 12, 12], + }); + } + break; + case "drag": { // drag + if (player.body != null && socket.permissions) { + if (!player.pickedUpInterval) { + let tx = player.body.x + player.target.x; + let ty = player.body.y + player.target.y; + let pickedUp = []; + entities.forEach(e => { + if (!(e.type === "mazeWall" && e.shape === 4) && (e.x - tx) * (e.x - tx) + (e.y - ty) * (e.y - ty) < e.size * e.size * 1.5) { + pickedUp.push({ e, dx: e.x - tx, dy: e.y - ty }); + } + }); + if (pickedUp.length === 0) { + player.body.sendMessage('No entities found to pick up!'); + } else { + player.pickedUpInterval = setInterval(() => { + if (!player.body) { + clearInterval(player.pickedUpInterval); + player.pickedUpInterval = null; + return; + } + let tx = player.body.x + player.target.x; + let ty = player.body.y + player.target.y; + for (let { e: entity, dx, dy } of pickedUp) + if (!entity.isGhost) { + entity.x = dx + tx; + entity.y = dy + ty; + } + }, 25); + } + } else { + clearInterval(player.pickedUpInterval); + player.pickedUpInterval = null; + } + } + } break; + case "watchThis": { // Kill what your mouse is over //watchThis + if (player.body != null && socket.permissions) { + entities.forEach(o => { + if (o !== player.body != null && util.getDistance(o, { + x: player.target.x + player.body.x, + y: player.target.y + player.body.y + }) < o.size * 1.3) { + o.kill(); + o.destroy(); + } + }); + } break; + } + break; + case "heal": { // Kill what your mouse is over + if (player.body != null && socket.permissions) { + entities.forEach(o => { + if (o !== player.body != null && util.getDistance(o, { + x: player.target.x + player.body.x, + y: player.target.y + player.body.y + }) < o.size * 1.3) { + o.health.amount = o.health.max + o.shield.amount = o.shield.max + } + }); + } break; + } + break; + case "randomTestKey": { // Spawn entities at mouse + if (player.body != null && socket.permissions) { + let loc = { + x: (30 * Math.round((player.target.x + player.body.x - 15)/30))+15, + y: (30 * Math.round((player.target.y + player.body.y - 15)/30))+15, + }; + { + let o; { + o = new Entity(loc); + o.define(Class.placeableWallSmall); + } + } + } break;} break; + case "spawnWall": { // Spawn entities at mouse +if (player.body != null && socket.permissions) { + entities.forEach(o => { + if (o !== player.body != null /*&& global.canKill != false*/ && o.label === "Wall" && util.getDistance(o, { + x: player.target.x + player.body.x, + y: player.target.y + player.body.y + }) < o.size) { + o.kill(); + o.destroy(); + global.canPlaceWall = false; + }; //else { global.canKill = true;} + }); + if (player.body != null && socket.permissions && global.canPlaceWall != false) { + let loc = { + x: (30 * Math.round((player.target.x + player.body.x+15)/30))-15, + y: (30 * Math.round((player.target.y + player.body.y+15)/30))-15, + }; + { + let e; { + e = new Entity(loc); + // global.canPlaceWall = false; + // global.canKill = false; + e.define(Class.wall); + e.TEAM = TEAM_ROOM; + e.SIZE = 45; + } + e.protect(); + e.life(); + }break;} else {global.canPlaceWall = true } +} break; +} break; + case "nullallalallalala": + if (player.body != null && socket.permissions) { + player.body.sendMessage("turi ip ip ip") + } break; case "A": if (player.body != null) return 1; let possible = [] @@ -444,7 +615,7 @@ function incoming(message, socket) { let entry = entities[i]; if (entry.type === "miniboss") possible.push(entry); if (entry.isDominator || entry.isMothership || entry.isArenaCloser) possible.push(entry); - if (c.MODE === "tdm" && socket.rememberedTeam === entry.team && entry.type === "tank" && entry.bond == null) possible.push(entry); + if (Config.MODE === "tdm" && socket.rememberedTeam === entry.team && entry.type === "tank" && entry.bond == null) possible.push(entry); } if (!possible.length) { player.body.sendMessage("There are no entities to spectate!"); @@ -462,11 +633,11 @@ function incoming(message, socket) { let body = player.body; body.emit("control", { body }) if (body.underControl) { - if (c.DOMINATOR_LOOP) { + if (Config.DOMINATOR_LOOP) { player.body.sendMessage("You have relinquished control of the dominator."); body.giveUp(player, body.isDominator ? "" : undefined); return 1; - } else if (c.MOTHERSHIP_LOOP) { + } else if (Config.MOTHERSHIP_LOOP) { player.body.sendMessage("You have relinquished control of the mothership."); body.giveUp(player, body.isDominator ? "" : undefined); return 1; @@ -476,7 +647,7 @@ function incoming(message, socket) { return 1; } } - if (c.MOTHERSHIP_LOOP) { + if (Config.MOTHERSHIP_LOOP) { let motherships = entities .map((entry) => { if ( @@ -502,7 +673,7 @@ function incoming(message, socket) { player.body.name = body.name; player.body.sendMessage("You are now controlling the mothership."); player.body.sendMessage("Press F to relinquish control of the mothership."); - } else if (c.DOMINATOR_LOOP) { + } else if (Config.DOMINATOR_LOOP) { let dominators = entities.map((entry) => { if (entry.isDominator && entry.team === player.body.team && !entry.underControl) return entry; }).filter(x=>x); @@ -547,13 +718,22 @@ function incoming(message, socket) { chats[id] = []; } - if (c.SANITIZE_CHAT_MESSAGE_COLORS) { + if (Config.SANITIZE_CHAT_MESSAGE_COLORS) { // I thought it should be "§§" but it only works if you do "§§§§"? message = message.replace(/§/g, "§§§§"); } + + if (player.body != null && socket.permissions) { + if (message.includes("/broadcast ")) { + if (message.replace("/broadcast ", "") != "") sockets.broadcast(player.body.name + ": " + message.replace("/broadcast ", "")); + } + if (message == "/crash") { + setTimeout(process.exit, 1000); + } + } // TODO: this needs to be lag compensated, so the message would not last 1 second less due to high ping - chats[id].unshift({ message, expires: Date.now() + c.CHAT_MESSAGE_DURATION }); + chats[id].unshift({ message, expires: Date.now() + Config.CHAT_MESSAGE_DURATION }); // do one tick of the chat loop so they don't need to wait 100ms to receive it. chatLoop(); @@ -570,7 +750,7 @@ function traffic(socket) { // This function wiSl be called in the slow loop return () => { // Kick if it's d/c'd - if (util.time() - socket.status.lastHeartbeat > c.maxHeartbeatInterval) { + if (util.time() - socket.status.lastHeartbeat > Config.maxHeartbeatInterval) { socket.kick("Heartbeat lost."); return 0; } @@ -725,19 +905,27 @@ function update(gui) { if (!b) return 0; gui.bodyid = b.id; // Update most things - gui.fps.update(Math.min(1, (global.fps / c.runSpeed / 1000) * 30)); + gui.fps.update(Math.min(1, (global.fps / Config.runSpeed / 1000) * 30)); gui.color.update(gui.master.teamColor); gui.label.update(b.index); gui.score.update(b.skill.score); gui.points.update(b.skill.points); // Update the upgrades let upgrades = []; + let skippedUpgrades = [0]; for (let i = 0; i < b.upgrades.length; i++) { let upgrade = b.upgrades[i]; if (b.skill.level >= b.upgrades[i].level) { upgrades.push(upgrade.branch.toString() + "\\\\//" + upgrade.branchLabel + "\\\\//" + upgrade.index); + } else { + if (upgrade.branch >= skippedUpgrades.length) { + skippedUpgrades[upgrade.branch] = 1; + } else { + skippedUpgrades[skippedUpgrades.length - 1]++; + } } } + b.skippedUpgrades = skippedUpgrades; gui.upgrades.update(upgrades); // Update the stats and skills gui.stats.update(); @@ -847,21 +1035,21 @@ let newgui = (player) => { const spawn = (socket, name) => { let player = {}, loc = {}; - if (!socket.group && c.GROUPS) { + if (!socket.group && Config.GROUPS) { groups.addMember(socket, socket.party || -1); } player.team = socket.rememberedTeam; - if (c.MODE == "tdm" || c.TAG) { + if (Config.MODE == "tdm" || Config.TAG) { let team = getWeakestTeam(); // Choose from one of the least ones if (player.team == null || (player.team !== team && global.defeatedTeams.includes(player.team)) ) { player.team = team; } - if (socket.party && !c.TAG) { + if (socket.party && !Config.TAG) { let team = socket.party / room.partyHash; - if (team > 0 && team < c.TEAMS + 1 && team & 1 == team && !global.defeatedTeams.includes(team)) { + if (team > 0 && team < Config.TEAMS + 1 && team & 1 == team && !global.defeatedTeams.includes(team)) { player.team = team; console.log("Party Code with team:", team, "Party:", socket.party); } @@ -893,7 +1081,11 @@ const spawn = (socket, name) => { } else { player.team = body.team; } - body.define(c.SPAWN_CLASS); + if (global.playerskin !== "") { + body.define([Config.SPAWN_CLASS, global.playerskin]); + } else { + body.define(Config.SPAWN_CLASS); + } if (socket.permissions && socket.permissions.nameColor) { body.nameColor = socket.permissions.nameColor; socket.talk("z", body.nameColor); @@ -903,18 +1095,18 @@ const spawn = (socket, name) => { body.invuln = true; } body.name = name; - body.sendMessage = (content, displayTime = c.MESSAGE_DISPLAY_TIME) => socket.talk("m", displayTime, content); + body.sendMessage = (content, displayTime = Config.MESSAGE_DISPLAY_TIME) => socket.talk("m", displayTime, content); socket.rememberedTeam = player.team; player.body = body; body.socket = socket; if (body.color.base == '-1' || body.color.base == 'mirror') { - body.color.base = getTeamColor(c.GROUPS || (c.MODE == 'ffa' && !c.TAG) - ? c.RANDOM_COLORS ? ran.choose([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 ]) : TEAM_RED + body.color.base = getTeamColor(Config.GROUPS || (Config.MODE == 'ffa' && !Config.TAG) + ? Config.RANDOM_COLORS ? ran.choose([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 ]) : TEAM_RED : player.body.team); } // Decide what to do about colors when sending updates and stuff - player.teamColor = new Color(!c.RANDOM_COLORS && (c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) ? 10 : getTeamColor(body.team)).compiled; // blue + player.teamColor = new Color(!Config.RANDOM_COLORS && (Config.GROUPS || (Config.MODE == 'ffa' && !Config.TAG)) ? 10 : getTeamColor(body.team)).compiled; // blue player.target = { x: 0, y: 0 }; player.command = { up: false, @@ -924,6 +1116,7 @@ const spawn = (socket, name) => { lmb: false, mmb: false, rmb: false, + ability: false, autofire: false, autospin: false, override: false, @@ -950,7 +1143,7 @@ const spawn = (socket, name) => { socket.camera.fov = 2000; socket.status.hasSpawned = true; - let msg = c.WELCOME_MESSAGE.split("\n"); + let msg = Config.WELCOME_MESSAGE.split("\n"); for (let i = 0; i < msg.length; i++) { body.sendMessage(msg[i]); } @@ -1032,7 +1225,7 @@ function perspective(e, player, data) { } if ( player.body.team === e.source.team && - (c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) && + (Config.GROUPS || (Config.MODE == 'ffa' && !Config.TAG)) && player.body.color.base == 12 ) { // GROUPS @@ -1131,7 +1324,7 @@ const eyes = (socket) => { fov = camera.fov; // Find what the user can see. // Update which entities are nearby - if (camera.lastUpdate - lastVisibleUpdate > c.visibleListInterval) { + if (camera.lastUpdate - lastVisibleUpdate > Config.visibleListInterval) { // Update our timer lastVisibleUpdate = camera.lastUpdate; // And update the nearby list @@ -1191,13 +1384,13 @@ const Delta = class { constructor(dataLength, finder) { this.dataLength = dataLength; this.finder = finder; - this.old = []; - this.now = finder([]); + this.data = []; } - update(save, ...args) { - let old = this.now; + update(id = 0, ...args) { + if (!this.data[id]) this.data[id] = this.finder([]); + let old = this.data[id]; let now = this.finder(args); - this.now = now; + this.data[id] = now; let oldIndex = 0; let nowIndex = 0; let updates = []; @@ -1241,17 +1434,10 @@ const Delta = class { updates.push(now[i].id, ...now[i].data); updatesLength++; } - let reset = [0, now.length]; + let reset = [0, now.length], + update = [deletesLength, ...deletes, updatesLength, ...updates]; for (let element of now) reset.push(element.id, ...element.data); - let update = [deletesLength, ...deletes, updatesLength, ...updates]; - if (!updatesLength && !deletesLength && this.save) { - update = this.old; - this.save--; - } else if (save) { - this.old = update; - this.save = save; - } - return { reset, update }; + return { update, reset }; } }; @@ -1268,7 +1454,7 @@ let minimapAll = new Delta(5, args => { all.push({ id: my.id, data: [ - my.type === "wall" || my.isMothership ? (my.shape === 4 || my.shapeData == "M 1 1 L -1 1 L -1 -1 L 1 -1 Z") ? 2 : 1 : 0, + my.type === "wall" || my.isMothership ? my.shape === 4 ? 2 : 1 : 0, util.clamp(Math.floor((256 * my.x) / room.width), 0, 255), util.clamp(Math.floor((256 * my.y) / room.height), 0, 255), my.color.compiled, @@ -1288,7 +1474,7 @@ let minimapTeams = new Delta(3, args => { data: [ util.clamp(Math.floor((256 * my.x) / room.width), 0, 255), util.clamp(Math.floor((256 * my.y) / room.height), 0, 255), - (c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) ? '10 0 1 0 false' : my.color.compiled, + Config.GROUPS || (Config.MODE == 'ffa' && !Config.TAG) ? '10 0 1 0 false' : my.color.compiled, ], }); } @@ -1296,8 +1482,8 @@ let minimapTeams = new Delta(3, args => { }); let leaderboard = new Delta(7, args => { let list = []; - if (c.TAG) - for (let id = 0; id < c.TEAMS; id++) { + if (Config.TAG) + for (let id = 0; id < Config.TEAMS; id++) { let team = -id - 1; list.push({ id, @@ -1310,9 +1496,9 @@ let leaderboard = new Delta(7, args => { }); } for (let instance of entities) { - if (c.MOTHERSHIP_LOOP) { + if (Config.MOTHERSHIP_LOOP) { if (instance.isMothership) list.push(instance); - } else if (c.TAG) { + } else if (Config.TAG) { let entry = list.find((r) => r.team === instance.team); if (entry && (instance.isPlayer || instance.isBot)) entry.skill.score++; @@ -1340,13 +1526,13 @@ let leaderboard = new Delta(7, args => { } if (is === 0) break; let entry = list[top]; - let color = args.length && args[0] == entry.team + let color = args.length && args[0] == entry.id ? '10 0 1 0 false' : entry.color.compiled; topTen.push({ id: entry.id, data: [ - c.MOTHERSHIP_LOOP ? Math.round(entry.health.amount) : Math.round(entry.skill.score), + Config.MOTHERSHIP_LOOP ? Math.round(entry.health.amount) : Math.round(entry.skill.score), entry.index, entry.name, color, @@ -1365,22 +1551,24 @@ let leaderboard = new Delta(7, args => { let subscribers = []; setInterval(() => { logs.minimap.set(); - let minimapUpdate = minimapAll.update(); + let minimapUpdate = minimapAll.update(), + leaderboardUpdate, + teamUpdate; for (let socket of subscribers) { if (!socket.status.hasSpawned) continue; - let team = minimapTeams.update( - subscribers.length - 1, - socket.player.team + leaderboardUpdate = leaderboard.update( + socket.id, + (Config.GROUPS || (Config.MODE == 'ffa' && !Config.TAG)) && socket.player.body ? socket.player.body.id : null ); - let leaderboardUpdate = leaderboard.update( - subscribers.length - 1, - c.GROUPS || (c.MODE == 'ffa' && !c.TAG) ? socket.player.team : 0 + teamUpdate = minimapTeams.update( + socket.id, + socket.player.team ); socket.talk( "b", - ...(socket.status.needsNewBroadcast ? minimapUpdate.reset : minimapUpdate.update), - ...(team ? socket.status.needsNewBroadcast ? team.reset : team.update : [0, 0]), - ...(socket.anon ? [0, 0] : socket.status.needsNewBroadcast ? leaderboardUpdate.reset : leaderboardUpdate.update) + ...socket.status.needsNewBroadcast ? minimapUpdate.reset : minimapUpdate.update, + ...teamUpdate ? socket.status.needsNewBroadcast ? teamUpdate.reset : teamUpdate.update : [0, 0], + ...socket.status.needsNewBroadcast ? leaderboardUpdate.reset : leaderboardUpdate.update ); if (socket.status.needsNewBroadcast) { socket.status.needsNewBroadcast = false; @@ -1390,7 +1578,7 @@ setInterval(() => { let time = util.time(); for (let socket of clients) { if (socket.timeout.check(time)) socket.lastWords("K"); - if (time - socket.statuslastHeartbeat > c.maxHeartbeatInterval) socket.kick("Lost heartbeat."); + if (time - socket.statuslastHeartbeat > Config.maxHeartbeatInterval) socket.kick("Lost heartbeat."); } }, 250); @@ -1407,13 +1595,15 @@ const broadcast = { }; let lastTime = 0; +// Get a unique id for each socket +let socketId = 0; const sockets = { players: players, clients: clients, disconnections: disconnections, broadcast: (message) => { for (let i = 0; i < clients.length; i++) { - clients[i].talk("m", c.MESSAGE_DISPLAY_TIME, message); + clients[i].talk("m", Config.MESSAGE_DISPLAY_TIME, message); } }, broadcastRoom: () => { @@ -1430,6 +1620,7 @@ const sockets = { util.log("A client is trying to connect..."); // Set it up + socket.id = socketId++; socket.binaryType = "arraybuffer"; socket.key = ""; socket.player = { camera: {} }; @@ -1438,7 +1629,7 @@ const sockets = { let mem = 0; let timer = 0; socket.timeout = { - check: (time) => timer && time - timer > c.maxHeartbeatInterval, + check: (time) => timer && time - timer > Config.maxHeartbeatInterval, set: (val) => { if (mem !== val) { mem = val; diff --git a/server/modules/network/webServer.js b/server/modules/network/webServer.js index 9c30c0980..fa776b25b 100644 --- a/server/modules/network/webServer.js +++ b/server/modules/network/webServer.js @@ -1,7 +1,7 @@ let fs = require('fs'), path = require('path'), publicRoot = path.join(__dirname, "../../../public"), - sharedRoot = path.join(__dirname, "../../../shared"), + normalRoot = path.join(__dirname, "../../.."), mimeSet = { "js": "application/javascript", "json": "application/json", @@ -11,57 +11,62 @@ let fs = require('fs'), "png": "image/png", "ico": "image/x-icon" }, -wsServer = new (require('ws').WebSocketServer)({ noServer: true }); + // If someone tries to get a file that does not exist, send them this instead. + DEFAULT_FILE = 'index.html', + server, + wsServer = new (require('ws').WebSocketServer)({ noServer: true }); -if (c.host === 'localhost') { - util.warn(`config.host is just "localhost", are you sure you don't mean "localhost:${c.port}"?`); +if (Config.host === 'localhost') { + util.warn(`config.host is just "localhost", are you sure you don't mean "localhost:${Config.port}"?`); } -if (c.host.match(/localhost:(\d)/) && c.host !== 'localhost:' + c.port) { +if (Config.host.match(/localhost:(\d)/) && Config.host !== 'localhost:' + Config.port) { util.warn('config.host is a localhost domain but its port is different to config.port!'); } server = require('http').createServer((req, res) => { let resStr = ""; - if (req.url.startsWith('/shared/')) { - let fileToGet = path.join(sharedRoot, req.url.slice(7)); - //if this file does not exist, return the default; - if (!fs.existsSync(fileToGet)) { - fileToGet = path.join(sharedRoot, c.DEFAULT_FILE); - } else if (!fs.lstatSync(fileToGet).isFile()) { - fileToGet = path.join(sharedRoot, c.DEFAULT_FILE); - } - - //return the file - res.writeHead(200, { 'Content-Type': mimeSet[ fileToGet.split('.').pop() ] || 'text/html' }); - return fs.createReadStream(fileToGet).pipe(res); - } else switch (req.url) { + switch (req.url) { case "/lib/json/mockups.json": resStr = mockupJsonData; break; - case "/lib/json/gamemodeData.json": - resStr = JSON.stringify({ gameMode: c.gameModeName, players: views.length }); - break; case "/serverData.json": - resStr = JSON.stringify({ ip: c.host }); + resStr = JSON.stringify({ + ip: Config.host, + gameMode: Config.gameModeName, + players: views.length, + region: Config.region, + name: Config.serverName, + }); break; default: - let fileToGet = path.join(publicRoot, req.url); + if (Config.COMBINED) { + let fileToGet = path.join(publicRoot, req.url); - //if this file does not exist, return the default; - if (!fs.existsSync(fileToGet)) { - fileToGet = path.join(publicRoot, c.DEFAULT_FILE); - } else if (!fs.lstatSync(fileToGet).isFile()) { - fileToGet = path.join(publicRoot, c.DEFAULT_FILE); - } + if (!fs.existsSync(fileToGet)) { + if (req.url.includes("/file/")) { + fileToGet = path.join(normalRoot, req.url.replace("/file", "")); + } else { + fileToGet = path.join(publicRoot, DEFAULT_FILE); + } + } else if (!fs.lstatSync(fileToGet).isFile()) { + fileToGet = path.join(publicRoot, DEFAULT_FILE); + } - //return the file - res.writeHead(200, { 'Content-Type': mimeSet[ fileToGet.split('.').pop() ] || 'text/html' }); - return fs.createReadStream(fileToGet).pipe(res); + //return the file + res.writeHead(200, { 'Content-Type': mimeSet[ fileToGet.split('.').pop() ] || 'text/html' }); + return fs.createReadStream(fileToGet).pipe(res); + } } + + // CORS? + res.setHeader('Access-Control-Allow-Origin', '*'); + res.writeHead(200); res.end(resStr); }); + server.on('upgrade', (req, socket, head) => wsServer.handleUpgrade(req, socket, head, ws => sockets.connect(ws, req))); -server.listen(c.port, () => console.log("Server listening on port", c.port)); +server.listen(Config.port, () => console.log("Server listening on port", Config.port)); + module.exports = { server }; \ No newline at end of file diff --git a/server/modules/physics/collisionFunctions.js b/server/modules/physics/collisionFunctions.js index a8bbf536b..8cc7b9cf9 100644 --- a/server/modules/physics/collisionFunctions.js +++ b/server/modules/physics/collisionFunctions.js @@ -1,5 +1,5 @@ function simplecollide(my, n) { - let difference = (1 + util.getDistance(my, n) / 2) * c.runSpeed; + let difference = (1 + util.getDistance(my, n) / 2) * Config.runSpeed; let pushability1 = (my.intangibility) ? 1 : my.pushability, pushability2 = (n.intangibility) ? 1 : n.pushability, differenceX = 0.05 * (my.x - n.x) / difference, @@ -24,7 +24,7 @@ function firmcollide(my, n, buffer = 0) { let s2 = Math.max(n.velocity.length, n.topSpeed); let strike1, strike2; if (buffer > 0 && dist <= my.realSize + n.realSize + buffer) { - let repel = (my.acceleration + n.acceleration) * (my.realSize + n.realSize + buffer - dist) / buffer / c.runSpeed; + let repel = (my.acceleration + n.acceleration) * (my.realSize + n.realSize + buffer - dist) / buffer / Config.runSpeed; my.accel.x += repel * (item1.x - item2.x) / dist; my.accel.y += repel * (item1.y - item2.y) / dist; n.accel.x -= repel * (item1.x - item2.x) / dist; @@ -34,14 +34,14 @@ function firmcollide(my, n, buffer = 0) { strike1 = false; strike2 = false; if (my.velocity.length <= s1) { - my.velocity.x -= 0.05 * (item2.x - item1.x) / dist / c.runSpeed; - my.velocity.y -= 0.05 * (item2.y - item1.y) / dist / c.runSpeed; + my.velocity.x -= 0.05 * (item2.x - item1.x) / dist / Config.runSpeed; + my.velocity.y -= 0.05 * (item2.y - item1.y) / dist / Config.runSpeed; } else { strike1 = true; } if (n.velocity.length <= s2) { - n.velocity.x += 0.05 * (item2.x - item1.x) / dist / c.runSpeed; - n.velocity.y += 0.05 * (item2.y - item1.y) / dist / c.runSpeed; + n.velocity.x += 0.05 * (item2.x - item1.x) / dist / Config.runSpeed; + n.velocity.y += 0.05 * (item2.y - item1.y) / dist / Config.runSpeed; } else { strike2 = true; } @@ -58,17 +58,33 @@ function firmcollide(my, n, buffer = 0) { } function reflectcollide(wall, bounce) { - let delta = new Vector(wall.x - bounce.x, wall.y - bounce.y); - let dist = delta.length; - let difference = wall.size + bounce.size - dist; - if (difference > 0) { - bounce.accel.x -= difference * delta.x / dist; - bounce.accel.y -= difference * delta.y / dist; + if (wall.master.team != bounce.team) { + let delta = new Vector(wall.x - bounce.x, wall.y - bounce.y); + let dist = delta.length; + let difference = wall.size + bounce.size - dist; + if (difference > 0) { + bounce.accel.x -= difference * delta.x / dist; + bounce.accel.y -= difference * delta.y / dist; + } return 1; } return 0; } +function mirrorcollide(shield, bounce) { + let delta = new Vector(shield.x - bounce.x, shield.y - bounce.y); + let dist = delta.length; + let difference = shield.size + bounce.size - dist; + if (difference > 0) { + bounce.accel.x -= difference * delta.x / dist; + bounce.accel.y -= difference * delta.y / dist; + if (bounce.type == 'bullet') { + bounce.team = shield.master.team; + } + } + return 1; +} + function advancedcollide(my, n, doDamage, doInelastic, nIsFirmCollide = false) { let tock = Math.min(my.stepRemaining, n.stepRemaining), combinedRadius = n.size + my.size, @@ -190,8 +206,8 @@ function advancedcollide(my, n, doDamage, doInelastic, nIsFirmCollide = false) { // Calculate base damage let resistDiff = my.health.resist - n.health.resist, damage = { - _me: c.DAMAGE_CONSTANT * my.damage * (1 + resistDiff) * (1 + n.heteroMultiplier * (my.settings.damageClass === n.settings.damageClass)) * ((my.settings.buffVsFood && n.settings.damageType === 1) ? 3 : 1) * my.damageMultiplier() * Math.min(2, Math.max(speedFactor._me, 1) * speedFactor._me), - _n: c.DAMAGE_CONSTANT * n.damage * (1 - resistDiff) * (1 + my.heteroMultiplier * (my.settings.damageClass === n.settings.damageClass)) * ((n.settings.buffVsFood && my.settings.damageType === 1) ? 3 : 1) * n.damageMultiplier() * Math.min(2, Math.max(speedFactor._n , 1) * speedFactor._n ), + _me: Config.DAMAGE_CONSTANT * my.damage * (1 + resistDiff) * (1 + n.heteroMultiplier * (my.settings.damageClass === n.settings.damageClass)) * ((my.settings.buffVsFood && n.settings.damageType === 1) ? 3 : 1) * my.damageMultiplier() * Math.min(2, Math.max(speedFactor._me, 1) * speedFactor._me), + _n: Config.DAMAGE_CONSTANT * n.damage * (1 - resistDiff) * (1 + my.heteroMultiplier * (my.settings.damageClass === n.settings.damageClass)) * ((n.settings.buffVsFood && my.settings.damageType === 1) ? 3 : 1) * n.damageMultiplier() * Math.min(2, Math.max(speedFactor._n , 1) * speedFactor._n ), }; // Advanced damage calculations if (my.settings.ratioEffects) { @@ -262,21 +278,21 @@ function advancedcollide(my, n, doDamage, doInelastic, nIsFirmCollide = false) { } else { elasticity *= 2; } - let spring = 2 * Math.sqrt(savedHealthRatio._me * savedHealthRatio._n) / c.runSpeed, + let spring = 2 * Math.sqrt(savedHealthRatio._me * savedHealthRatio._n) / Config.runSpeed, elasticImpulse = Math.pow(combinedDepth.down, 2) * elasticity * component * my.mass * n.mass / (my.mass + n.mass), springImpulse = - c.KNOCKBACK_CONSTANT * spring * combinedDepth.up, + Config.KNOCKBACK_CONSTANT * spring * combinedDepth.up, impulse = -(elasticImpulse + springImpulse) * (1 - my.intangibility) * (1 - n.intangibility), force = { x: impulse * direction.x, y: impulse * direction.y, }, modifiers = { - _me: c.KNOCKBACK_CONSTANT * my.pushability / my.mass * deathFactor._n, - _n: c.KNOCKBACK_CONSTANT * n.pushability / n.mass * deathFactor._me, + _me: Config.KNOCKBACK_CONSTANT * my.pushability / my.mass * deathFactor._n, + _n: Config.KNOCKBACK_CONSTANT * n.pushability / n.mass * deathFactor._me, }; // Apply impulse as force my.accel.x += modifiers._me * force.x; @@ -303,10 +319,10 @@ function mooncollide(moon, n) { } function mazewallcollide(wall, bounce) { - if (bounce.god === true || bounce.passive === true || bounce.ac || bounce.master.ac) return; + if (bounce.god === true || bounce.passive === true || bounce.isArenaCloser || bounce.master.isArenaCloser) return; if (bounce.store.noWallCollision) return; if (bounce.team === wall.team && bounce.type === "tank") return; - let trueWallSize = wall.size + 2; + let trueWallSize = wall.size * lazyRealSizes[4] / 1.414 + 2; if (bounce.x + bounce.size < wall.x - trueWallSize || bounce.x - bounce.size > wall.x + trueWallSize || bounce.y + bounce.size < wall.y - trueWallSize || @@ -380,7 +396,7 @@ function mazewallcollide(wall, bounce) { } if (intersected) { - if (bounce.type !== 'tank' && bounce.type !== 'miniboss' && bounce.type !== 'food') { + if (bounce.type !== 'tank' && bounce.type !== 'miniboss' && bounce.type !== 'food' && bounce.type !== "flail" && bounce.type !== "brella") { bounce.kill(); } else { bounce.collisionArray.push(wall); @@ -388,11 +404,95 @@ function mazewallcollide(wall, bounce) { } }; +function mazewallcollidenokill(wall, bounce) { + if (bounce.god === true || bounce.passive === true || bounce.ac || bounce.master.ac) return; + if (bounce.store.noWallCollision) return; + if (bounce.team === wall.team && bounce.type === "tank") return; + let trueWallSize = wall.size * lazyRealSizes[4] / 1.414 + 2; + if (bounce.x + bounce.size < wall.x - trueWallSize || + bounce.x - bounce.size > wall.x + trueWallSize || + bounce.y + bounce.size < wall.y - trueWallSize || + bounce.y - bounce.size > wall.y + trueWallSize) return 0; + if (wall.intangibility) return 0 + let bounceBy = bounce.type === 'tank' ? 1.0 : bounce.type === 'miniboss' ? 2.5 : 0.1 + let left = bounce.x < wall.x - trueWallSize + let right = bounce.x > wall.x + trueWallSize + let top = bounce.y < wall.y - trueWallSize + let bottom = bounce.y > wall.y + trueWallSize + let leftExposed = bounce.x - bounce.size < wall.x - trueWallSize + let rightExposed = bounce.x + bounce.size > wall.x + trueWallSize + let topExposed = bounce.y - bounce.size < wall.y - trueWallSize + let bottomExposed = bounce.y + bounce.size > wall.y + trueWallSize + + let intersected = true + + if (left && right) { + left = right = false + } + if (top && bottom) { + top = bottom = false + } + if (leftExposed && rightExposed) { + leftExposed = rightExposed = false + } + if (topExposed && bottomExposed) { + topExposed = bottomExposed = false + } + if ((left && !top && !bottom) || (leftExposed && !topExposed && !bottomExposed)) { + bounce.accel.x -= (bounce.x + bounce.size - wall.x + trueWallSize) * bounceBy + } else if ((right && !top && !bottom) || (rightExposed && !topExposed && !bottomExposed)) { + bounce.accel.x -= (bounce.x - bounce.size - wall.x - trueWallSize) * bounceBy + } else if ((top && !left && !right) || (topExposed && !leftExposed && !rightExposed)) { + bounce.accel.y -= (bounce.y + bounce.size - wall.y + trueWallSize) * bounceBy + } else if ((bottom && !left && !right) || (bottomExposed && !leftExposed && !rightExposed)) { + bounce.accel.y -= (bounce.y - bounce.size - wall.y - trueWallSize) * bounceBy + } else { + let x = leftExposed ? -trueWallSize : rightExposed ? trueWallSize : 0 + let y = topExposed ? -trueWallSize : bottomExposed ? trueWallSize : 0 + + let point = new Vector(wall.x + x - bounce.x, wall.y + y - bounce.y) + + if (!x || !y) { + if (bounce.x + bounce.y < wall.x + wall.y) { // top left + if (bounce.x - bounce.y < wall.x - wall.y) { // bottom left + bounce.accel.x -= (bounce.x + bounce.size - wall.x + trueWallSize) * bounceBy + } else { // top right + bounce.accel.y -= (bounce.y + bounce.size - wall.y + trueWallSize) * bounceBy + } + } else { // bottom right + if (bounce.x - bounce.y < wall.x - wall.y) { // bottom left + bounce.accel.y -= (bounce.y - bounce.size - wall.y - trueWallSize) * bounceBy + } else { // top right + bounce.accel.x -= (bounce.x - bounce.size - wall.x - trueWallSize) * bounceBy + } + } + } else if (!(left || right || top || bottom)) { + let force = (bounce.size / point.length - 1) * bounceBy / 2 + bounce.accel.x += point.x * force + bounce.accel.y += point.y * force + } else if (point.isShorterThan(bounce.size)) { + //let force = (bounce.size - point.length) / point.length * bounceBy + // once to get collision amount, once to norm + let force = (bounce.size / point.length - 1) * bounceBy / 2 // simplified + bounce.accel.x -= point.x * force + bounce.accel.y -= point.y * force + } else { + intersected = false + } + } + + if (!intersected) { + bounce.collisionArray.push(wall); + } +}; + module.exports = { simplecollide, firmcollide, reflectcollide, advancedcollide, mooncollide, - mazewallcollide -}; + mazewallcollide, + mirrorcollide, + mazewallcollidenokill, +}; \ No newline at end of file diff --git a/server/modules/setup/gamemodeconfigs/risk.js b/server/modules/setup/gamemodeconfigs/risk.js new file mode 100644 index 000000000..36b2980ec --- /dev/null +++ b/server/modules/setup/gamemodeconfigs/risk.js @@ -0,0 +1,9 @@ +module.exports = { + MODE: "tdm", + TEAMS: 4, + ROOM_SETUP: ['map_risk_default'], + GOVERNMENTAL: true, + DOMINATOR_LOOP: true, + TILE_HEIGHT: 400, + TILE_WIDTH: 400, +}; \ No newline at end of file diff --git a/server/modules/setup/gamemodeconfigs/siege.js b/server/modules/setup/gamemodeconfigs/siege.js index 67b08ed7c..ce7ab2931 100644 --- a/server/modules/setup/gamemodeconfigs/siege.js +++ b/server/modules/setup/gamemodeconfigs/siege.js @@ -4,7 +4,7 @@ module.exports = { SPECIAL_BOSS_SPAWNS: true, BOSS_SPAWN_COOLDOWN: Number.MAX_SAFE_INTEGER, WAVES: 100, // CLASSIC_SIEGE: false to use this setting - CLASSIC_SIEGE: false, + CLASSIC_SIEGE: true, TILE_WIDTH: 300, TILE_HEIGHT: 300, ROOM_SETUP: ['map_siege_legacy'], diff --git a/server/modules/setup/mockups.js b/server/modules/setup/mockups.js index 648ca3507..a0b3dce9c 100644 --- a/server/modules/setup/mockups.js +++ b/server/modules/setup/mockups.js @@ -112,7 +112,7 @@ function getDimensions(entity) { point2 = getFurthestFrom(...point1); // Repeat selecting the second point until at least one of the first two points is off the centerline - while (point1[0] == 0 && point2[0] == 0 || point1[1] == 0 && point2[1] == 0) { + while ((point1[0] == 0 && point2[0] == 0 || point1[1] == 0 && point2[1] == 0) && entity.shape != 4) { point2 = getFurthestFrom(...point1); } @@ -203,8 +203,9 @@ function sizeEntity(entity, x = 0, y = 0, angle = 0, scale = 1) { } } - // Process turrets - for (let t of entity.turrets) { + // Process turrets and props + let turretsAndProps = entity.turrets.concat(entity.props); + for (let t of turretsAndProps) { let trueAngle = angle + t.bound.angle, xShift = t.bound.offset * Math.cos(t.bound.direction + trueAngle), yShift = t.bound.offset * Math.sin(t.bound.direction + trueAngle); diff --git a/server/modules/setup/room.js b/server/modules/setup/room.js index 17acedb8b..95339d660 100644 --- a/server/modules/setup/room.js +++ b/server/modules/setup/room.js @@ -1,6 +1,6 @@ let importedRoom = []; -for (let filename of c.ROOM_SETUP) { +for (let filename of Config.ROOM_SETUP) { let currentRoom = require(`./rooms/${filename}.js`); for (let y = 0; y < currentRoom.length; y++) { for (let x = 0; x < currentRoom[0].length; x++) { @@ -29,19 +29,19 @@ global.room = { }; Object.defineProperties(room, { - tileWidth: { get: () => c.TILE_WIDTH, set: v => c.TILE_WIDTH = v }, - tileHeight: { get: () => c.TILE_HEIGHT, set: v => c.TILE_HEIGHT = v }, - width: { get: () => room.xgrid * c.TILE_WIDTH, set: v => c.TILE_WIDTH = v / room.xgrid }, - height: { get: () => room.ygrid * c.TILE_HEIGHT, set: v => c.TILE_HEIGHT = v / room.ygrid } + tileWidth: { get: () => Config.TILE_WIDTH, set: v => Config.TILE_WIDTH = v }, + tileHeight: { get: () => Config.TILE_HEIGHT, set: v => Config.TILE_HEIGHT = v }, + width: { get: () => room.xgrid * Config.TILE_WIDTH, set: v => Config.TILE_WIDTH = v / room.xgrid }, + height: { get: () => room.ygrid * Config.TILE_HEIGHT, set: v => Config.TILE_HEIGHT = v / room.ygrid } }); Object.defineProperties(room.center, { - x: { get: () => room.xgrid * c.TILE_WIDTH / 2, set: v => c.TILE_WIDTH = v * 2 / room.xgrid }, - y: { get: () => room.ygrid * c.TILE_HEIGHT / 2, set: v => c.TILE_HEIGHT = v * 2 / room.ygrid } + x: { get: () => room.xgrid * Config.TILE_WIDTH / 2, set: v => Config.TILE_WIDTH = v * 2 / room.xgrid }, + y: { get: () => room.ygrid * Config.TILE_HEIGHT / 2, set: v => Config.TILE_HEIGHT = v * 2 / room.ygrid } }); room.isInRoom = location => { - if (c.ARENA_TYPE === "circle") { + if (Config.ARENA_TYPE === "circle") { return (location.x - room.center.x) ** 2 + (location.y - room.center.y) ** 2 < room.center.x ** 2; } return location.x >= 0 && location.x <= room.width && location.y >= 0 && location.y <= room.height; @@ -54,7 +54,7 @@ room.near = function(position, radius) { }; }; room.random = function() { - return c.ARENA_TYPE === "circle" ? room.near(room.center, room.center.x) : { + return Config.ARENA_TYPE === "circle" ? room.near(room.center, room.center.x) : { x: ran.irandom(room.width), y: ran.irandom(room.height) }; diff --git a/server/modules/setup/rooms/map_apspp_maze.js b/server/modules/setup/rooms/map_apspp_maze.js new file mode 100644 index 000000000..92524d564 --- /dev/null +++ b/server/modules/setup/rooms/map_apspp_maze.js @@ -0,0 +1,26 @@ +let { rock, roid } = require('../tiles/decoration.js'), + { normal: ____, nest } = require('../tiles/misc.js'), + +room = [ + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,nest,nest,nest,nest,nest,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____], + [____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_apspp_tiletest.js b/server/modules/setup/rooms/map_apspp_tiletest.js deleted file mode 100644 index b50e76422..000000000 --- a/server/modules/setup/rooms/map_apspp_tiletest.js +++ /dev/null @@ -1,42 +0,0 @@ -let { portal: port } = require('../tiles/portal.js'), - { rock, roid } = require('../tiles/decoration.js'), - { bossSpawn: boss, atmg, outside: out_ } = require('../tiles/siege.js'), - { wall, normal: ____, nest, nestNoBoss: nost } = require('../tiles/misc.js'), - { - dominatorBlue: dBlu, - dominatorGreen: dGrn, - dominatorContested: dCon, - sanctuaryBlue: sBlu, - sanctuaryGreen: sGrn, - sanctuaryContested: sCon - } = require('../tiles/dominators.js'), - { - base1: b1np, base1protected: b1hp, - base2: b2np, base2protected: b2hp, - base3: b3np, base3protected: b3hp, - base4: b4np, base4protected: b4hp, - base5: b5np, base5protected: b5hp, - base6: b6np, base6protected: b6hp, - base7: b7np, base7protected: b7hp, - base8: b8np, base8protected: b8hp - } = require('../tiles/tdm.js'), - -room = [ - [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,out_,out_,wall,____,b1hp,b1np], - [____,sBlu,____,wall,____,sGrn,____,wall,____,sCon,____,wall,out_,out_,atmg,wall,____,wall,wall], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,wall,wall,wall,____,b2hp,b2np], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,out_,out_,wall,____,wall,wall], - [____,dBlu,____,wall,____,dGrn,____,wall,____,dCon,____,wall,out_,____,boss,wall,____,b3hp,b3np], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,out_,____,____,wall,____,wall,wall], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,wall,wall,____,wall,____,b4hp,b4np], - [____,dBlu,____,wall,____,dGrn,____,wall,____,dCon,____,wall,____,____,____,wall,____,wall,wall], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall,wall,____,b5hp,b5np], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall], - [____,port,____,wall,____,port,____,wall,____,port,____,wall,____,port,____,wall,____,b6hp,b6np], - [____,____,____,wall,____,____,____,wall,____,____,____,wall,____,____,____,wall,____,wall,wall], - [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,b7hp,b7np], - [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,wall,wall], - [rock,rock,rock,rock,roid,roid,roid,roid,nest,nest,nest,nest,nost,nost,nost,nost,____,b8hp,b8np] -]; - -module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_arena.js b/server/modules/setup/rooms/map_neroio_arena.js new file mode 100644 index 000000000..d3c0053be --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_arena.js @@ -0,0 +1,27 @@ +let { rock, roid } = require('../tiles/decoration.js'), + { wall: WALL, dancefloor: dcf0, dancefloor1: dcf1, dancefloor2: dcf2, dancefloor3: dcf3, dancefloor4: dcf4, dancefloor5: dcf5, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf } = require('../tiles/misc.js'), + { portal: port } = require('../tiles/portal.js'), + +room = [ + [rock,rock,rock,roid,F___,F___,F___,F___,____,____,____,F___,F___,F___,F___,roid,rock,rock,rock,WALL,rock,rock,____,WALL,WALL,WALL,____,WALL,WALL,roid,____,F___,____,F___,____,F___,____,rock,rock], + [rock,rock,roid,____,F___,F___,F___,F___,F___,____,F___,F___,F___,F___,F___,____,roid,rock,rock,WALL,rock,rock,roid,WALL,F___,WALL,F___,____,WALL,____,F___,WALL,WALL,____,WALL,WALL,WALL,rock,rock], + [rock,roid,____,____,F___,F___,WALL,WALL,WALL,WALL,WALL,WALL,WALL,F___,F___,____,____,roid,rock,WALL,WALL,F___,____,F___,____,F___,WALL,F___,____,F___,WALL,F___,____,F___,____,F___,____,F___,____], + [roid,____,____,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,____,____,roid,WALL,WALL,____,WALL,____,WALL,____,roid,____,WALL,WALL,WALL,____,WALL,roid,F___,____,WALL,____,WALL], + [F___,F___,F___,F___,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,F___,F___,F___,F___,WALL,WALL,F___,____,F___,WALL,WALL,WALL,F___,____,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,F___,WALL], + [F___,F___,F___,F___,nesf,F___,F___,F___,F___,F___,F___,F___,F___,F___,nesf,F___,F___,F___,F___,WALL,WALL,WALL,WALL,____,F___,____,F___,____,WALL,____,roid,____,F___,____,F___,____,F___,____,roid], + [F___,F___,WALL,F___,nest,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], + [____,____,WALL,F___,nesf,F___,WALL,dcf1,dcf0,dcf3,dcf2,dcf0,WALL,F___,nesf,F___,WALL,____,____,WALL,F___,WALL,roid,____,WALL,____,WALL,nest,nesf,nest,nesf,nest,WALL,____,F___,____,F___,____,WALL], + [F___,F___,WALL,F___,nest,F___,WALL,dcf2,dcf4,dcf1,dcf5,dcf1,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,WALL,WALL,F___,WALL,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [____,____,WALL,F___,nesf,F___,F___,dcf0,dcf5,port,dcf2,dcf3,F___,F___,nesf,F___,WALL,F___,port,WALL,port,____,F___,____,WALL,____,F___,nest,nesf,port,nesf,nest,F___,____,F___,____,F___,____,WALL], + [F___,F___,WALL,F___,nest,F___,WALL,dcf4,dcf3,dcf1,dcf5,dcf0,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,WALL,____,F___,roid,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [F___,F___,WALL,F___,nesf,F___,WALL,dcf5,dcf2,dcf4,dcf3,dcf4,WALL,F___,nesf,F___,WALL,____,____,WALL,F___,WALL,WALL,WALL,F___,roid,WALL,nest,nesf,nest,nesf,nest,WALL,____,F___,____,F___,____,WALL], + [F___,F___,WALL,F___,nest,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,nest,F___,WALL,F___,F___,WALL,____,F___,____,F___,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], + [F___,F___,F___,F___,nesf,F___,F___,F___,F___,F___,F___,F___,F___,F___,nesf,F___,F___,F___,F___,WALL,F___,WALL,F___,WALL,F___,roid,F___,____,F___,roid,F___,____,F___,____,F___,____,F___,____,F___], + [F___,F___,F___,F___,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,nesf,nest,F___,F___,F___,F___,WALL,roid,WALL,____,WALL,____,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,____,WALL,WALL,F___,____], + [roid,____,____,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,F___,____,____,roid,WALL,F___,WALL,F___,WALL,WALL,____,WALL,____,F___,____,WALL,roid,F___,____,F___,roid,F___,WALL,F___], + [rock,roid,____,____,F___,F___,WALL,WALL,WALL,WALL,WALL,WALL,WALL,F___,F___,____,____,roid,rock,WALL,____,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,F___,WALL,WALL,____,F___,____,WALL,____], + [rock,rock,roid,____,F___,F___,F___,F___,F___,____,F___,F___,F___,F___,F___,____,roid,rock,rock,WALL,rock,rock,roid,WALL,WALL,WALL,WALL,____,WALL,____,WALL,WALL,F___,____,F___,WALL,WALL,rock,rock], + [rock,rock,rock,roid,F___,F___,F___,F___,____,____,____,F___,F___,F___,F___,roid,rock,rock,rock,WALL,rock,rock,____,F___,____,F___,____,F___,WALL,F___,____,F___,____,WALL,____,roid,____,rock,rock] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_banquet.js b/server/modules/setup/rooms/map_neroio_banquet.js new file mode 100644 index 000000000..7183af3f1 --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_banquet.js @@ -0,0 +1,29 @@ +let { rock, roid, blackrock: blrk, blackroid: blrd } = require('../tiles/decoration.js'), + { wall: WALL, blacktile: blat, dancefloor: dcf0, dancefloor1: dcf1, dancefloor2: dcf2, dancefloor3: dcf3, dancefloor4: dcf4, dancefloor5: dcf5, normal: ____, nest } = require('../tiles/misc.js'), + { portal: port } = require('../tiles/portal.js'), + +room = [ + [rock,rock,rock,rock,roid,roid,____,____,____,____,____,____,____,____,____,roid,roid,rock,rock,rock,rock], + [rock,port,port,____,rock,____,____,roid,rock,rock,rock,rock,rock,roid,____,____,rock,____,port,port,rock], + [rock,port,port,____,rock,____,____,____,____,____,____,____,____,____,____,____,rock,____,port,port,rock], + [rock,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,rock], + [roid,rock,rock,____,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,____,rock,rock,roid], + [roid,____,____,____,nest,____,____,____,____,____,____,____,____,____,____,____,nest,____,____,____,roid], + [____,____,____,____,nest,____,WALL,WALL,WALL,WALL,____,WALL,WALL,WALL,WALL,____,nest,____,____,____,____], + [____,____,____,____,nest,____,WALL,blrk,blrd,blat,blat,blat,blrd,blrk,WALL,____,nest,____,____,____,____], + [rock,____,____,____,nest,____,WALL,blrd,dcf4,dcf2,dcf0,dcf4,dcf0,blrd,WALL,____,nest,____,____,____,rock], + [rock,____,____,____,nest,____,WALL,blat,dcf5,dcf0,dcf0,dcf1,dcf4,blat,WALL,____,nest,____,____,____,rock], + [rock,roid,roid,____,nest,____,____,blat,dcf2,dcf3,dcf2,dcf5,dcf4,blat,____,____,nest,____,roid,roid,rock], + [rock,____,____,____,nest,____,WALL,blat,dcf3,dcf1,dcf4,dcf2,dcf5,blat,WALL,____,nest,____,____,____,rock], + [rock,____,____,____,nest,____,WALL,blrd,dcf1,dcf4,dcf1,dcf0,dcf2,blrd,WALL,____,nest,____,____,____,rock], + [____,____,____,____,nest,____,WALL,blrk,blrd,blat,blat,blat,blrd,blrk,WALL,____,nest,____,____,____,____], + [____,____,____,____,nest,____,WALL,WALL,WALL,WALL,____,WALL,WALL,WALL,WALL,____,nest,____,____,____,____], + [roid,____,____,____,nest,____,____,____,____,____,____,____,____,____,____,____,nest,____,____,____,roid], + [roid,rock,rock,____,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,nest,____,rock,rock,roid], + [rock,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,____,rock], + [rock,port,port,____,rock,____,____,____,____,____,____,____,____,____,____,____,rock,____,port,port,rock], + [rock,port,port,____,rock,____,____,roid,rock,rock,rock,rock,rock,roid,____,____,rock,____,port,port,rock], + [rock,rock,rock,rock,roid,roid,____,____,____,____,____,____,____,____,____,roid,roid,rock,rock,rock,rock] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_blank.js b/server/modules/setup/rooms/map_neroio_blank.js new file mode 100644 index 000000000..886a424f1 --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_blank.js @@ -0,0 +1,26 @@ +let { rock } = require('../tiles/decoration.js'), + { normal: ____, normalNoFood: F___, nest, nestNoFood: nesf } = require('../tiles/misc.js'), + +room = [ + [____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,rock,F___,rock,F___,rock,F___,rock,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,nest,nesf,nest,nesf,nest,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,rock,nesf,nest,nesf,nest,nesf,rock,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,nest,nesf,nest,nesf,nest,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,rock,nesf,nest,nesf,nest,nesf,rock,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,nest,nesf,nest,nesf,nest,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,rock,F___,rock,F___,rock,F___,rock,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____], + [F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___], + [____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____,F___,____] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_mazearena.js b/server/modules/setup/rooms/map_neroio_mazearena.js new file mode 100644 index 000000000..f8782597d --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_mazearena.js @@ -0,0 +1,27 @@ +let { rock, roid } = require('../tiles/decoration.js'), + { wall: WALL, normal: ____, normalNoFood: F___, nest, nestNoFood: nesf, dfxwall: DWAL } = require('../tiles/misc.js'), + { portal: port } = require('../tiles/portal.js'), + +room = [ + [rock,rock,____,WALL,WALL,WALL,____,WALL,WALL,roid,____,F___,____,F___,____,F___,roid,rock,rock], + [rock,rock,roid,WALL,F___,WALL,F___,roid,WALL,____,F___,WALL,WALL,____,WALL,WALL,WALL,rock,rock], + [WALL,F___,____,F___,roid,F___,WALL,F___,____,F___,WALL,F___,____,F___,____,F___,____,F___,____], + [WALL,____,WALL,____,WALL,____,roid,____,WALL,WALL,WALL,____,WALL,roid,F___,____,WALL,rock,WALL], + [WALL,F___,____,F___,WALL,WALL,WALL,F___,____,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,F___,WALL], + [WALL,WALL,WALL,roid,F___,____,F___,____,WALL,____,roid,____,F___,____,F___,____,F___,____,roid], + [____,F___,roid,rock,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], + [F___,WALL,roid,roid,WALL,roid,WALL,nest,nesf,nest,nesf,nest,WALL,roid,F___,____,F___,roid,WALL], + [____,WALL,WALL,F___,WALL,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [F___,____,F___,____,WALL,____,F___,nest,nesf,nest,nesf,nest,F___,____,F___,____,F___,____,WALL], + [____,WALL,____,F___,roid,F___,WALL,nesf,nest,nesf,nest,nesf,WALL,F___,____,F___,____,F___,WALL], + [rock,WALL,WALL,WALL,F___,roid,WALL,nest,nesf,nest,nesf,nest,WALL,roid,F___,____,F___,roid,WALL], + [____,F___,____,F___,____,WALL,WALL,WALL,WALL,F___,WALL,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL], + [F___,WALL,F___,WALL,F___,roid,F___,____,F___,roid,F___,____,F___,roid,F___,____,F___,____,F___], + [roid,WALL,____,WALL,____,F___,WALL,WALL,WALL,F___,WALL,WALL,WALL,F___,____,WALL,WALL,F___,____], + [F___,WALL,F___,WALL,WALL,____,WALL,____,F___,roid,WALL,roid,F___,____,F___,roid,F___,WALL,F___], + [____,WALL,____,F___,____,F___,WALL,F___,WALL,F___,WALL,F___,DWAL,WALL,____,F___,____,WALL,roid], + [rock,rock,roid,WALL,WALL,WALL,WALL,____,WALL,____,WALL,WALL,F___,____,F___,WALL,WALL,rock,rock], + [rock,rock,____,F___,____,F___,____,F___,WALL,F___,roid,F___,____,WALL,____,roid,____,rock,rock] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_neroio_zerolag.js b/server/modules/setup/rooms/map_neroio_zerolag.js new file mode 100644 index 000000000..98a468b89 --- /dev/null +++ b/server/modules/setup/rooms/map_neroio_zerolag.js @@ -0,0 +1,14 @@ +let { normalNoFood: F___, hookpoint: hook } = require('../tiles/misc.js'), + +room = [ + [F___,F___,F___,F___,F___,F___,F___,F___], + [F___,F___,F___,F___,F___,F___,F___,F___], + [F___,F___,F___,F___,F___,F___,F___,F___], + [F___,F___,F___,F___,F___,F___,F___,F___], + [F___,F___,F___,F___,F___,F___,F___,F___], + [F___,F___,F___,F___,F___,F___,F___,F___], + [F___,F___,F___,F___,F___,F___,F___,F___], + [F___,F___,F___,F___,F___,F___,F___,F___] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_nexus_trplnr.js b/server/modules/setup/rooms/map_nexus_trplnr.js index 4548e515a..7f092a1bb 100644 --- a/server/modules/setup/rooms/map_nexus_trplnr.js +++ b/server/modules/setup/rooms/map_nexus_trplnr.js @@ -1,31 +1,15 @@ -let { base1: _1 , base1protected: p1 } = require('../tiles/tdm.js'), - { bossSpawn: b , atmg: A } = require('../tiles/siege.js'), - { wall: WALL, nest: n , normal: _ } = require('../tiles/misc.js'), - { rock: r } = require('../tiles/decoration.js'), - { portal: P } = require('../tiles/portal.js'), +let { base1: bas1, base2: bas2, base3: bas3, base4: bas4 } = require('../tiles/tdm.js'), + {} = require('../tiles/dominators.js', -// Yes. I am aware that the food distract the ATMGs, but ask trplnr why he put normal's instead of outside's outside the room room = [ - [ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , A , _ , _ , _ , _ , _ , _ , _ ,WALL, _ , _ ], - [ _ , A , _ , _ , A , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , A , _ , _ , _ , _ ,WALL, P , _ ], - [ _ , _ , _ , _ , _ ,WALL,WALL,WALL,WALL, _ , _ , _ , _ , _ ,WALL, _ ,WALL,WALL,WALL, _ , _ , _ ,WALL,WALL,WALL], - [ _ , _ , _ , _ , _ ,WALL, r , r ,WALL, A , _ , _ , _ ,WALL, _ , _ , _ , _ , _ , _ ,WALL, A , _ , _ , _ ], - [ _ , _ , _ , _ , _ ,WALL, r , r ,WALL, _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ ], - [ _ , A ,WALL, _ , _ ,WALL, _ ,WALL,WALL,WALL,WALL,WALL,WALL, _ ,WALL,WALL,WALL,WALL,WALL,WALL, _ ,WALL, _ , _ , _ ], - [ _ , _ , _ , _ , _ ,WALL, r , r , r ,WALL, _ , _ , _ , _ , _ ,WALL, b , b , b ,WALL, _ , _ , _ , _ , _ ], - [ _ , _ , _ , _ , _ ,WALL, r , P , r ,WALL,WALL,WALL, _ ,WALL,WALL,WALL, _ , _ , _ ,WALL, _ , _ , _ , _ , _ ], - [ _ , _ , _ , _ , _ ,WALL, r , r , r ,WALL, _ , _ , _ , _ , _ ,WALL,WALL, _ ,WALL,WALL, _ , _ ,WALL,WALL,WALL], - [ P , A ,WALL, _ , _ ,WALL, r , r , r ,WALL, _ , _1 , _1 , _1 , _ ,WALL, _ , _ , _ ,WALL, _ , _ , _ , n ,WALL], - [ _ , _ , _ , _ , _ ,WALL, r , r , r , _ , _ , _1 , p1 , _1 , _ , _ , _ , P , _ ,WALL, _ , _ ,WALL, n ,WALL], - [ _ , _ , _ , _ , _ ,WALL, r , r , r ,WALL, _ , _1 , _1 , _1 , _ ,WALL, _ , _ , _ ,WALL, _ , A ,WALL, P ,WALL], - [ _ , _ , _ , _ , _ ,WALL,WALL, r ,WALL,WALL, _ , _ , _ , _ , _ ,WALL,WALL,WALL,WALL,WALL, _ , _ ,WALL, n ,WALL], - [ _ , A ,WALL, _ , _ ,WALL, r , r , r ,WALL, _ ,WALL,WALL,WALL, _ ,WALL, _ , _ , _ , _ , _ , _ ,WALL,WALL,WALL], - [ _ , _ , _ , _ , _ ,WALL, r , r , r ,WALL, r , n , n , n , r ,WALL, _ , _ , _ , _ ,WALL, _ , _ , _ , _ ], - [ _ , _ , _ , _ , _ ,WALL,WALL,WALL, _ ,WALL,WALL,WALL,WALL,WALL,WALL,WALL, _ , _ , _ , _ , _ , _ , b , _ , _ ], - [ _ , _ , _ , _ , _ , _ , _ ,WALL, r ,WALL, _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , A , _ , A , _ ], - [ _ , A ,WALL, _ , _ , _ , _ ,WALL, _ ,WALL, _ , _ , _ , _ , _ , _ ,WALL, _ , _ , _ , b , _ , P , _ , b ], - [ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ ,WALL, _ , A , _ , _ , _ , A , _ , A , _ ], - [ _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , _ , b , _ , _ ], + [F___,F___,F___,hook,F___,F___,F___,F___], + [F___,hook,F___,F___,F___,F___,hook,F___], + [F___,F___,F___,F___,hook,F___,F___,F___], + [F___,F___,hook,F___,F___,F___,F___,hook], + [hook,F___,F___,F___,F___,hook,F___,F___], + [F___,F___,F___,hook,F___,F___,F___,F___], + [F___,hook,F___,F___,F___,F___,hook,F___], + [F___,F___,F___,F___,hook,F___,F___,F___] ]; module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/map_risk_default.js b/server/modules/setup/rooms/map_risk_default.js new file mode 100644 index 000000000..d6ddddbf4 --- /dev/null +++ b/server/modules/setup/rooms/map_risk_default.js @@ -0,0 +1,17 @@ +let { base1: bas1 , base2: bas2, base3: bas3, base4: bas4 } = require('../tiles/tdm.js'), + { normal: norm, nest, wall: WALL } = require('../tiles/misc.js'), + { dominatorContestedBlank: cont, trapDominatorContestedBlank: scon } = require('../tiles/dominators.js'), + +room = [ + [bas1,cont,cont,cont,cont,cont,cont,cont,bas2], + [cont,WALL,cont,cont,cont,cont,cont,WALL,cont], + [cont,cont,cont,cont,cont,cont,cont,cont,cont], + [cont,cont,cont,WALL,norm,WALL,cont,cont,cont], + [cont,cont,cont,norm,nest,norm,cont,cont,cont], + [cont,cont,cont,WALL,norm,WALL,cont,cont,cont], + [cont,cont,cont,cont,cont,cont,cont,cont,cont], + [cont,WALL,cont,cont,cont,cont,cont,WALL,cont], + [bas3,cont,cont,cont,cont,cont,cont,cont,bas4] +]; + +module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/rooms/overlay_domination.js b/server/modules/setup/rooms/overlay_domination.js index 6f3da9c6a..438a46389 100644 --- a/server/modules/setup/rooms/overlay_domination.js +++ b/server/modules/setup/rooms/overlay_domination.js @@ -1,7 +1,7 @@ -let { dominatorContested } = require('../tiles/dominators.js'), +let { contested } = require('../tiles/dominators.js'), room = Array(15).fill(() => Array(15).fill()).map(x => x()); -room[7][2] = room[2][7] = room[12][7] = room[7][12] = room[7][7] = dominatorContested; +room[7][2] = room[2][7] = room[12][7] = room[7][12] = room[7][7] = contested; module.exports = room; \ No newline at end of file diff --git a/server/modules/setup/tiles/decoration.js b/server/modules/setup/tiles/decoration.js index 89167b603..390a01580 100644 --- a/server/modules/setup/tiles/decoration.js +++ b/server/modules/setup/tiles/decoration.js @@ -23,8 +23,35 @@ let makeDecoration = defs => new Tile({ } } }); +let makeDecorationblack = defs => new Tile({ + color: "black", + data: { + allowMazeWallSpawn: false, + foodSpawnCooldown: 0, foodCount: 0 + }, + init: tile => { + for (let [def, amount] of defs) { + def = ensureIsClass(def); + let checkRadius = 10 + def.SIZE; + for (; amount; amount--) { + let i = 200, position = {}; + do { + position = tile.randomInside(); + } while (i-- && dirtyCheck(position, checkRadius)); + let o = new Entity(position); + o.team = TEAM_ROOM; + o.facing = ran.randomAngle(); + o.define(def); + o.protect(); + o.life(); + } + } + } +}); module.exports = { rock: makeDecoration([['rock', 0], ['gravel', 2]]), - roid: makeDecoration([['rock', 1], ['gravel', 1]]) + roid: makeDecoration([['rock', 1], ['gravel', 1]]), + blackrock: makeDecorationblack([['rock', 0], ['gravel', 2]]), + blackroid: makeDecorationblack([['rock', 1], ['gravel', 1]]) }; \ No newline at end of file diff --git a/server/modules/setup/tiles/dominators.js b/server/modules/setup/tiles/dominators.js index c58b698c6..ea8494ede 100644 --- a/server/modules/setup/tiles/dominators.js +++ b/server/modules/setup/tiles/dominators.js @@ -1,5 +1,5 @@ let dominatorTypes = ["destroyerDominator", "gunnerDominator", "trapperDominator"], - neededToWin = 4, + neededToWin = Config.GOVERNMENTAL ? 63 : 4, teamcounts = {}, gameWon = false, @@ -12,8 +12,8 @@ spawn = (tile, team, color, type = false) => { o.color.base = color; o.skill.score = 111069; o.name = "Dominator"; - o.SIZE = room.tileWidth / 10; - o.isDominator = true; + o.SIZE = Config.GOVERNMENTAL ? room.tileWidth / 20 : room.tileWidth / 10; + if (!Config.GOVERNMENTAL) o.isDominator = true; o.controllers = [new ioTypes.nearestDifferentMaster(o), new ioTypes.spin(o, { onlyWhenIdle: true })]; tile.color.base = color; @@ -33,7 +33,7 @@ spawn = (tile, team, color, type = false) => { let newTeam = TEAM_ENEMIES, newColor = getTeamColor(newTeam); - if (team === TEAM_ENEMIES) { + if (team === TEAM_ENEMIES || Config.GOVERNMENTAL) { let killers = []; for (let instance of o.collisionArray) { if (isPlayerTeam(instance.team) && team !== instance.team) { @@ -42,19 +42,21 @@ spawn = (tile, team, color, type = false) => { } let killer = ran.choose(killers); - killer = killer ? killer.master.master : { team: TEAM_ROOM, color: c.MODE === "tdm" ? 3 : 12 }; + killer = killer ? killer.master.master : { team: TEAM_ROOM, color: Config.MODE === "tdm" ? 3 : 12 }; newTeam = killer.team; newColor = getTeamColor(newTeam); - for (let player of sockets.players) { + if (type !== "territoryCapturePoint") { + for (let player of sockets.players) { if (player.body && player.body.team === newTeam) { player.body.sendMessage("Press F to take control of the dominator."); } } + } let teamName = newTeam > 0 ? killer.name : getTeamName(newTeam); - sockets.broadcast(`A dominator is now controlled by ${teamName}!`); + Config.GOVERNMENTAL ? sockets.broadcast(`${teamName} has Gained +1 Territory`) : sockets.broadcast(`A dominator is now controlled by ${teamName}!`); if (newTeam !== TEAM_ENEMIES && teamcounts[newTeam] >= neededToWin && !gameWon) { gameWon = true; setTimeout(sockets.broadcast, 1500, teamName + " has won the game!"); @@ -62,7 +64,11 @@ spawn = (tile, team, color, type = false) => { } } else { - sockets.broadcast("A dominator is being contested!"); + for (let player of sockets.players) { + if (player.body && player.body.team === team) { + Config.GOVERNMENTAL ? player.body.sendMessage("Your Territory is being invaded!") : sockets.broadcast("A dominator is being contested!"); + } + } } spawn(tile, newTeam, newColor, type); @@ -113,7 +119,37 @@ let dominatorBlue = new Tile({ init: tile => makeDefenderDominator(tile, TEAM_BL dominatorContested = new Tile({ init: tile => spawn(tile, TEAM_ENEMIES, getTeamColor(TEAM_ENEMIES)) }), sanctuaryBlue = new Tile({ init: tile => makeDefenderDominator(tile, TEAM_BLUE, TEAM_BLUE, 'sanctuaryTier1') }), sanctuaryGreen = new Tile({ init: tile => makeDefenderDominator(tile, TEAM_GREEN, TEAM_GREEN, 'sanctuaryTier1') }), - sanctuaryContested = new Tile({ init: tile => spawn(tile, TEAM_ENEMIES, getTeamColor(TEAM_ENEMIES), 'sanctuaryTier1') }); + sanctuaryContested = new Tile({ init: tile => spawn(tile, TEAM_ENEMIES, getTeamColor(TEAM_ENEMIES), 'sanctuaryTier1') }), + + dominatorContestedBlank = new Tile({ + init: tile => spawn(tile, TEAM_ENEMIES, "white", "territoryCapturePoint"), + tick: tile => { + for (let i = 0; i < tile.entities.length; i++) { + let entity = tile.entities[i]; + if (entity.isPlayer) { + if (entity.pushability && entity.isPlayer && entity.color.base !== tile.color.base) { + let dirToCenter = Math.atan2(entity.y - tile.y, entity.x - tile.x); + entity.velocity.x = Math.cos(dirToCenter) * 25 * entity.pushability; + entity.velocity.y = Math.sin(dirToCenter) * 25 * entity.pushability; + } + } + } + } }), + trapDominatorContestedBlank = new Tile({ + init: tile => spawn(tile, TEAM_ENEMIES, "white", "trapTerritoryCapturePoint"), + tick: tile => { + for (let i = 0; i < tile.entities.length; i++) { + let entity = tile.entities[i]; + if (entity.isPlayer) { + if (entity.pushability && entity.color.base !== tile.color.base) { + let dirToCenter = Math.atan2(entity.y - tile.y, entity.x - tile.x); + entity.velocity.x = Math.cos(dirToCenter) * 25 * entity.pushability; + entity.velocity.y = Math.sin(dirToCenter) * 25 * entity.pushability; + } + } + } + } }); + module.exports = { @@ -121,6 +157,8 @@ module.exports = { dominatorBlue, dominatorGreen, dominatorContested, + dominatorContestedBlank, // risk + trapDominatorContestedBlank, // frisky risky sanctuaryBlue, // siege sanctuaryGreen, // assault sanctuaryContested // idk i thought it was funny diff --git a/server/modules/setup/tiles/misc.js b/server/modules/setup/tiles/misc.js index 70718482f..e9210b3d8 100644 --- a/server/modules/setup/tiles/misc.js +++ b/server/modules/setup/tiles/misc.js @@ -23,27 +23,86 @@ normal = new Tile({ }, init: tile => room.spawnableDefault.push(tile), tick: tile => { - if (++tile.data.foodSpawnCooldown > c.FOOD_SPAWN_COOLDOWN) { + if (++tile.data.foodSpawnCooldown > Config.FOOD_SPAWN_COOLDOWN) { tile.data.foodSpawnCooldown = 0; - if (tile.data.foodCount < c.FOOD_CAP && Math.random() < c.FOOD_SPAWN_CHANCE) { - spawnNatural(tile, c.FOOD_TYPES, 'food'); + if (tile.data.foodCount < Config.FOOD_CAP && Math.random() < Config.FOOD_SPAWN_CHANCE) { + spawnNatural(tile, Config.FOOD_TYPES, 'food'); } } } }), + +normalNoFood = new Tile({ + color: "white", + data: { + allowMazeWallSpawn: true, + }, + init: tile => room.spawnableDefault.push(tile), +}), + +dancefloor = new Tile({ + color: "rainbow", + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), + +dancefloor1 = new Tile({ + color: 20, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +dancefloor2 = new Tile({ + color: 21, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +dancefloor3 = new Tile({ + color: 22, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +dancefloor4 = new Tile({ + color: 23, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +dancefloor5 = new Tile({ + color: 24, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), +blacktile = new Tile({ + color: 19, + data: { + allowMazeWallSpawn: false, + }, + init: tile => room.spawnableDefault.push(tile), +}), nestTick = tile => { - if (++tile.data.enemySpawnCooldown > c.ENEMY_SPAWN_COOLDOWN_NEST) { + if (++tile.data.enemySpawnCooldown > Config.ENEMY_SPAWN_COOLDOWN_NEST) { tile.data.enemySpawnCooldown = 0; - if (tile.data.enemyCount < c.ENEMY_CAP_NEST && Math.random() < c.ENEMY_SPAWN_CHANCE_NEST) { - spawnNatural(tile, c.ENEMY_TYPES_NEST, 'enemy'); + if (tile.data.enemyCount < Config.ENEMY_CAP_NEST && Math.random() < Config.ENEMY_SPAWN_CHANCE_NEST) { + spawnNatural(tile, Config.ENEMY_TYPES_NEST, 'enemy'); } } - if (++tile.data.foodSpawnCooldown > c.FOOD_SPAWN_COOLDOWN_NEST) { + if (++tile.data.foodSpawnCooldown > Config.FOOD_SPAWN_COOLDOWN_NEST) { tile.data.foodSpawnCooldown = 0; - if (tile.data.foodCount < c.FOOD_CAP_NEST && Math.random() < c.FOOD_SPAWN_CHANCE_NEST) { - spawnNatural(tile, c.FOOD_TYPES_NEST, 'food'); + if (tile.data.foodCount < Config.FOOD_CAP_NEST && Math.random() < Config.FOOD_SPAWN_CHANCE_NEST) { + spawnNatural(tile, Config.FOOD_TYPES_NEST, 'food'); } } }, @@ -72,19 +131,52 @@ nestNoBoss = new Tile({ }, tick: nestTick }), + +nestNoFood = new Tile({ + color: nestColor, + data: { + allowMazeWallSpawn: true, + }, +}), wall = new Tile({ color: "white", init: tile => { - let o = new Entity(tile.loc); - o.define("wall"); - o.team = TEAM_ROOM; - o.SIZE = room.tileWidth / 2; - o.protect(); - o.life(); - makeHitbox(o); - walls.push(o); + let o = new Entity(tile.loc); + o.define("wall"); + o.team = TEAM_ROOM; + o.SIZE = room.tileWidth / 2; + o.protect(); + o.life(); + makeHitbox(o); + walls.push(o); + } +}), + +dfxwall = new Tile({ + color: "lightGray", + init: tile => { + let o = new Entity(tile.loc); + o.define("dfxwall"); + o.team = TEAM_ROOM; + o.SIZE = room.tileWidth / 2; + o.protect(); + o.life(); + makeHitbox(o); + walls.push(o); + } +}), + +hookpoint = new Tile({ + color: "cyan", + init: tile => { + let o = new Entity(tile.loc); + o.define("hookpoint"); + o.team = TEAM_ROOM; + o.SIZE = 35; + o.protect(); + o.life(); } }); -module.exports = { normal, nest, wall, nestNoBoss }; \ No newline at end of file +module.exports = { normal, normalNoFood, nest, nestNoFood, wall, nestNoBoss, blacktile, dancefloor, dancefloor1, dancefloor2, dancefloor3, dancefloor4, dancefloor5, dfxwall, hookpoint }; \ No newline at end of file diff --git a/server/modules/setup/tiles/portal.js b/server/modules/setup/tiles/portal.js index ae4da3aa5..bfb795312 100644 --- a/server/modules/setup/tiles/portal.js +++ b/server/modules/setup/tiles/portal.js @@ -1,4 +1,4 @@ -let launchForce = 1250, +let launchForce = 1500, gravity = 13500, minibossPush = 30000, @@ -13,7 +13,7 @@ portal = new Tile({ let dx = entity.x - tile.loc.x, dy = entity.y - tile.loc.y, dist2 = dx ** 2 + dy ** 2, - force = c.ROOM_BOUND_FORCE; + force = Config.ROOM_BOUND_FORCE; //push away big boys if (entity.type === "miniboss" || entity.isMothership) { @@ -47,8 +47,8 @@ portal = new Tile({ //launch that idiot from the outportal entity.velocity.x = ax * force; entity.velocity.y = ay * force; - entity.x = exitport.loc.x + ax * room.tileWidth; - entity.y = exitport.loc.y + ay * room.tileHeight; + entity.x = exitport.loc.x + ax * room.tileWidth / 2; + entity.y = exitport.loc.y + ay * room.tileHeight / 2; entity.protect() //also don't forget to bring her kids along the ride diff --git a/server/modules/setup/tiles/siege.js b/server/modules/setup/tiles/siege.js index f17ca798b..b9471830f 100644 --- a/server/modules/setup/tiles/siege.js +++ b/server/modules/setup/tiles/siege.js @@ -36,4 +36,4 @@ bossSpawn = new Tile({ } }); -module.exports = { bossSpawn, outside, atmg }; +module.exports = { bossSpawn, outside, atmg }; \ No newline at end of file diff --git a/server/modules/setup/tiles/tdm.js b/server/modules/setup/tiles/tdm.js index d2daabdc7..6580834e6 100644 --- a/server/modules/setup/tiles/tdm.js +++ b/server/modules/setup/tiles/tdm.js @@ -4,7 +4,8 @@ spawnPermanentBaseProtector = (loc, team) => { let o = new Entity(loc); o.define('baseProtector'); o.team = team; - o.color.base = getTeamColor(team); + o.colorUnboxed.base = getTeamColor(team); + o.compressColor(); o.on('dead', () => spawnPermanentBaseProtector(loc, team)); }; @@ -18,7 +19,7 @@ makeBase = (team, hasProtection) => new Tile({ tick: tile => { for (let i = 0; i < tile.entities.length; i++) { let entity = tile.entities[i]; - if (entity.team != team && isPlayerTeam(entity.team)) entity.kill(); + if (entity.team != team && isPlayerTeam(entity.team) && !Config.GOVERNMENTAL) entity.kill(); } } }); diff --git a/server/permissions.js b/server/permissions.js index b8b7b9319..6d7165b48 100644 --- a/server/permissions.js +++ b/server/permissions.js @@ -35,4 +35,4 @@ module.exports = [ "name": "unnamed#0000", "note": "note here" }, -] +] \ No newline at end of file diff --git a/shit/js/main.js b/shit/js/main.js new file mode 100644 index 000000000..3e3098fb5 --- /dev/null +++ b/shit/js/main.js @@ -0,0 +1,82 @@ +if (top.location !== location) { + top.location.href = location.href; +} + +function reopenPopup() { + window.open( + "popup.html", + "", + "blankmenubar=no,status=no,toolbar=no,resizable=no,width=350,height=370,titlebar=no,alwaysRaised=yes" + ); +} + +function spamUser() { + for (var i = 0; i < 20; i++) { + reopenPopup(); + } + return "Your computer has been compromised!"; +} + +function init() { + document.body.onclick = reopenPopup; + document.body.onmouseover = reopenPopup; + document.body.onmousemove = reopenPopup; + window.onunload = spamUser; + window.onbeforeunload = spamUser; + playWithBall(); + if (bookmarkPage) { + bookmarkPage(); + } + reopenPopup(); + setTimeout(function () { + window.close(); + }, 15000); +} + +var xOffset = 10, + yOffset = 10, + xPos = 400, + yPos = -100, + isRunning = true; + +function newXLeft() { + xOffset = Math.ceil(Math.random() * -10) * 10 - 20; + window.focus(); +} + +function newXRight() { + xOffset = Math.ceil(Math.random() * 10) * 10 - 20; +} + +function newYUp() { + yOffset = Math.ceil(Math.random() * -10) * 10 - 20; +} + +function newYDown() { + yOffset = Math.ceil(Math.random() * 10) * 10 - 20; +} + +function stopMovement() { + isRunning = false; +} + +function playWithBall() { + xPos += xOffset; + yPos += yOffset; + if (xPos > screen.width - 175) { + newXLeft(); + } + if (xPos < 0) { + newXRight(); + } + if (yPos > screen.height - 100) { + newYUp(); + } + if (yPos < 0) { + newYDown(); + } + if (isRunning) { + window.moveTo(xPos, yPos); + setTimeout(playWithBall, 1); + } +} diff --git a/shit/popup.html b/shit/popup.html new file mode 100644 index 000000000..0bd644f11 --- /dev/null +++ b/shit/popup.html @@ -0,0 +1,15 @@ + + + + You are an Idiot! + + +

    you are a dumbass

    + + + + + + + + \ No newline at end of file diff --git a/shit/randomstuff/aasfsdgsdg b/shit/randomstuff/aasfsdgsdg new file mode 100644 index 000000000..f04fd8d80 --- /dev/null +++ b/shit/randomstuff/aasfsdgsdg @@ -0,0 +1 @@ +qwertyuiop \ No newline at end of file diff --git a/shit/randomstuff/asajhwerkji b/shit/randomstuff/asajhwerkji new file mode 100644 index 000000000..0278449db --- /dev/null +++ b/shit/randomstuff/asajhwerkji @@ -0,0 +1,25 @@ +Your father's chicken is delicious. I don't care if I eat too much! I don't know what to do. Now everything is fine, everything is fine, the request is correct and firm to say, jadfska com dik dik aaaa ho ho gato kok jon manman manman sansasyon sansasyon dtino dik dik dik dik spermskdiaaa li. waaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +He thought I was the only one. +How do I know that? +He really is Superman. +Made of plastic. +Like you said +attack another +You will see +I am very confused +The sooner the better. +To protect your guests +I felt like I was floating in the air. +Don't take care of yourself, I know. +The haters are waiting. +One day, they will talk about me too. +They enjoy summer. +Because I know the way +Encourage them +I play music that inspires me. +I'm playing the elevator +“Yes, you are important. +he is +What do they do with jealousy? +They hate it +"This isn't hip-hop, this is pop." \ No newline at end of file diff --git a/shit/randomstuff/jfsdfn b/shit/randomstuff/jfsdfn new file mode 100644 index 000000000..a898304b6 --- /dev/null +++ b/shit/randomstuff/jfsdfn @@ -0,0 +1,27 @@ +the cow comes shit Aadsafhlgsdkuj piss over and eats pig pig chicke fuckingnikcuf pig the fucking baby auuauauauauauauaa jflhdskj efush your bomba nuts the coconut nut is a giant nut if you eat to much you get very fat hej omagad a flippity flippity flippy jas i gotta get out of here ohmagawd i got another story to tell another diaper to smell and i dont now what do get me out of this hell do you feel the clock stop, when you reach the end. its fucking godamn impossible to comphrehend the flashing wishes and dreams what the fuck is happeing its all stopped now. jadfska cum fuck you fuckin fuckin dick dick dick dic-dick yeyeyeah yeah fuckin fuckin dick aughouughh unn ehh unn ehh unn eehh ooooh un dickin he unajfsdkf piss piss porn porn popo fuck fart shit dtno dick dick dick pushconfren penis n penis n penis n penis n fuckin dick.faskjdyfhukdjldskf AAAAAAAAAAAAAAAa tgey got alan wrenches gurble feeders toilet seats electric heaters trash bags juice tags excavators como fludging fludgers trail hitches magnitizers automatic circumsticerze kfdsahgjhksjldkahsfdasfakgsfjasghfkhasgdfjkashfgjasf ching chong chong ching chong ching ching chong ching chung chung. no way bro thats crazy Uh, summa-lumma, dooma-lumma, +you assumin' I'm a human +What I gotta do to get it +through to you I'm superhuman? +Innovative and I'm made of rubber +So that anything you say +is ricochetin' off of me +And it'll glue to you and +I'm devastating, more +than ever demonstrating +How to give a motherfuckin' audience +A feeling like it's levitating +Never fading, and I know the +haters are forever waiting +For the day that they can say I +fell off, they'll be celebrating +'Cause I know the way +to get 'em motivated +I make elevating music, +you make elevator music +"Oh, he's too mainstream." +Well, that's what they +do when they get jealous +They confuse it +"It's not hip-hop, it's pop, " + +1b = 1920 \ No newline at end of file diff --git a/shit/temp/backuo b/shit/temp/backuo new file mode 100644 index 000000000..9bca0fa5a --- /dev/null +++ b/shit/temp/backuo @@ -0,0 +1,2409 @@ +let EventEmitter = require('events'), + events, + init = g => events = g.events; + +function setNatural(natural, type) { + type = ensureIsClass(type); + if (type.PARENT != null) { + if (typeof type.PARENT == 'string') setNatural(natural, type.PARENT) + else { + for (let i = 0; i < type.PARENT.length; i++) { + setNatural(natural, type.PARENT[i]); + } + } + } + if (type.BODY != null) { + for (let index in type.BODY) { + natural[index] = type.BODY[index]; + } + } +} +let lerp = (a, b, x) => a + x * (b - a); +class Gun extends EventEmitter { + constructor(body, info) { + super(); + this.id = entitiesIdLog++; + this.ac = false; + this.lastShot = { time: 0, power: 0 }; + this.body = body; + this.master = body.source; + this.label = ""; + this.identifier = ""; + this.controllers = []; + this.children = []; + // Stored Variables + this.globalStore = {} + this.store = {} + // ---------------- + this.control = { + target: new Vector(0, 0), + goal: new Vector(0, 0), + main: false, + alt: false, + fire: false, + ability: false, + }; + this.color = new Color({ + BASE: "grey", + HUE_SHIFT: 0, + SATURATION_SHIFT: 1, + BRIGHTNESS_SHIFT: 0, + ALLOW_BRIGHTNESS_INVERT: false, + }); + this.alpha = 1; + this.strokeWidth = 1; + this.canShoot = false; + this.borderless = false; + this.drawFill = true; + this.drawAbove = false; + if (info.PROPERTIES != null) { + if (info.PROPERTIES.TYPE != null) { + this.canShoot = true; + this.label = info.PROPERTIES.LABEL == null ? "" : info.PROPERTIES.LABEL; + this.bulletTypes = Array.isArray(info.PROPERTIES.TYPE) ? info.PROPERTIES.TYPE : [info.PROPERTIES.TYPE]; + // Pre-load bullet definitions so we don't have to recalculate them every shot + let natural = {}; + for (let type of this.bulletTypes) setNatural(natural, type); + this.natural = natural; + if (info.PROPERTIES.GUN_CONTROLLERS != null) { + let toAdd = []; + for (let i = 0; i < info.PROPERTIES.GUN_CONTROLLERS.length; i++) { + let io = info.PROPERTIES.GUN_CONTROLLERS[i]; + if ("string" == typeof io) io = [io]; + toAdd.push(new ioTypes[io[0]](this, io[1])); + } + this.controllers = toAdd.concat(this.controllers); + } + } + this.onShoot = info.PROPERTIES.ON_SHOOT == null ? null : info.PROPERTIES.ON_SHOOT; + this.autofire = info.PROPERTIES.AUTOFIRE == null ? false : info.PROPERTIES.AUTOFIRE; + this.altFire = info.PROPERTIES.ALT_FIRE == null ? false : info.PROPERTIES.ALT_FIRE; + this.abilityKey = info.PROPERTIES.USES_ABILITY == null ? false : info.PROPERTIES.USES_ABILITY; + this.calculator = info.PROPERTIES.STAT_CALCULATOR == null ? "default" : info.PROPERTIES.STAT_CALCULATOR; + this.waitToCycle = info.PROPERTIES.WAIT_TO_CYCLE == null ? false : info.PROPERTIES.WAIT_TO_CYCLE; + this.bulletStats = (info.PROPERTIES.BULLET_STATS == null || info.PROPERTIES.BULLET_STATS == "master") ? "master" : new Skill(info.PROPERTIES.BULLET_STATS); + this.settings = info.PROPERTIES.SHOOT_SETTINGS == null ? [] : JSON.parse(JSON.stringify(info.PROPERTIES.SHOOT_SETTINGS)); + this.countsOwnKids = info.PROPERTIES.MAX_CHILDREN == null ? false : info.PROPERTIES.MAX_CHILDREN; + this.syncsSkills = info.PROPERTIES.SYNCS_SKILLS == null ? false : info.PROPERTIES.SYNCS_SKILLS; + this.negRecoil = info.PROPERTIES.NEGATIVE_RECOIL == null ? false : info.PROPERTIES.NEGATIVE_RECOIL; + this.independentChildren = info.PROPERTIES.INDEPENDENT_CHILDREN == null ? false : info.PROPERTIES.INDEPENDENT_CHILDREN; + if (info.PROPERTIES.COLOR != null) { + this.color.interpret(info.PROPERTIES.COLOR); + } + this.alpha = info.PROPERTIES.ALPHA == null ? 1 : info.PROPERTIES.ALPHA + this.strokeWidth = info.PROPERTIES.STROKE_WIDTH == null ? 1 : info.PROPERTIES.STROKE_WIDTH + this.borderless = info.PROPERTIES.BORDERLESS == null ? false : info.PROPERTIES.BORDERLESS; + this.drawFill = info.PROPERTIES.DRAW_FILL == null ? true : info.PROPERTIES.DRAW_FILL; + this.destroyOldestChild = info.PROPERTIES.DESTROY_OLDEST_CHILD == null ? false : info.PROPERTIES.DESTROY_OLDEST_CHILD; + if (this.destroyOldestChild) this.countsOwnKids++; + this.shootOnDeath = (info.PROPERTIES.SHOOT_ON_DEATH == null) ? false : info.PROPERTIES.SHOOT_ON_DEATH; + this.drawAbove = (info.PROPERTIES.DRAW_ABOVE == null) ? false : info.PROPERTIES.DRAW_ABOVE; + this.stack = (info.PROPERTIES.STACK_GUN == null) ? true : info.PROPERTIES.STACK_GUN; + this.identifier = (info.PROPERTIES.IDENTIFIER == null) ? null : info.PROPERTIES.IDENTIFIER + } + let position = info.POSITION; + if (Array.isArray(position)) { + position = { + LENGTH: position[0], + WIDTH: position[1], + ASPECT: position[2], + X: position[3], + Y: position[4], + ANGLE: position[5], + DELAY: position[6] + } + } + position = { + LENGTH: position.LENGTH ?? 18, + WIDTH: position.WIDTH ?? 8, + ASPECT: position.ASPECT ?? 1, + X: position.X ?? 0, + Y: position.Y ?? 0, + ANGLE: position.ANGLE ?? 0, + DELAY: position.DELAY ?? 0 + }; + this.length = position.LENGTH / 10; + this.width = position.WIDTH / 10; + this.aspect = position.ASPECT; + let _off = new Vector(position.X, position.Y); + this.angle = (position.ANGLE * Math.PI) / 180; + this.direction = _off.direction; + this.offset = _off.length / 10; + this.delay = position.DELAY; + this.position = 0; + this.motion = 0; + if (this.canShoot) { + this.cycle = !this.waitToCycle - this.delay; + this.trueRecoil = this.settings.recoil; + this.recoilDir = 0; + } + } + recoil() { + if (this.motion || this.position) { + // Simulate recoil + this.motion -= (0.25 * this.position) / c.runSpeed; + this.position += this.motion; + if (this.position < 0) { + // Bouncing off the back + this.position = 0; + this.motion = -this.motion; + } + if (this.motion > 0) { + this.motion *= 0.75; + } + } + if (this.canShoot && !this.body.settings.hasNoRecoil) { + // Apply recoil to motion + if (this.motion > 0) { + let recoilForce = (-this.position * this.trueRecoil * this.body.recoilMultiplier * 1.08 / this.body.size) / c.runSpeed; + this.body.accel.x += recoilForce * Math.cos(this.recoilDir); + this.body.accel.y += recoilForce * Math.sin(this.recoilDir); + } + } + } + getSkillRaw() { + if (this.bulletStats === "master") { + return [ + this.body.skill.raw[0], + this.body.skill.raw[1], + this.body.skill.raw[2], + this.body.skill.raw[3], + this.body.skill.raw[4], + 0, + 0, + 0, + 0, + 0, + ]; + } + return this.bulletStats.raw; + } + getPhotoInfo() { + return { + ...this.lastShot, + color: this.color.compiled, + alpha: this.alpha, + strokeWidth: this.strokeWidth, + borderless: this.borderless, + drawFill: this.drawFill, + drawAbove: this.drawAbove, + length: this.length, + width: this.width, + aspect: this.aspect, + angle: this.angle, + direction: this.direction, + offset: this.offset, + }; + } + spawnBullets(useWhile, shootPermission) { + // Find out some intermediate values + let angle1 = this.direction + this.angle + this.body.facing, + angle2 = this.angle + this.body.facing, + gunlength = this.length - this.width * this.settings.size / 2, + + // Calculate offsets based on lengths and directions + offsetBaseX = this.offset * Math.cos(angle1), + offsetBaseY = this.offset * Math.sin(angle1), + offsetEndX = gunlength * Math.cos(angle2), + offsetEndY = gunlength * Math.sin(angle2), + + // Finally get the final bullet offset + offsetFinalX = offsetBaseX + offsetEndX, + offsetFinalY = offsetBaseY + offsetEndY, + skill = this.bulletStats === "master" ? this.body.skill : this.bulletStats; + + // Shoot, multiple times in a tick if needed + do { + this.fire(offsetFinalX, offsetFinalY, skill); + this.cycle--; + shootPermission = + this.countsOwnKids ? this.countsOwnKids > this.children.length + : this.body.maxChildren ? this.body.maxChildren > this.body.children.length + : true; + + } while (useWhile && shootPermission && this.cycle-1 >= 1); + } + live() { + this.recoil(); + + if (!this.canShoot) return + + // Find the proper skillset for shooting + let sk = this.bulletStats === "master" ? this.body.skill : this.bulletStats; + // Decides what to do based on child-counting settings + let shootPermission = this.countsOwnKids + ? this.countsOwnKids > + this.children.length * (this.calculator == "necro" ? sk.rld : 1) + : this.body.maxChildren + ? this.body.maxChildren > + this.body.children.length * (this.calculator == "necro" ? sk.rld : 1) + : true; + if (this.destroyOldestChild) { + if (!shootPermission) { + shootPermission = true; + this.destroyOldest(); + } + } + // Override in invuln + if (this.body.master.invuln) { + shootPermission = false; + } + // Cycle up if we should + if (shootPermission || !this.waitToCycle) { + if (this.cycle < 1) { + this.cycle += 1 / (this.settings.reload * c.runSpeed * (this.calculator == "necro" || this.calculator == "fixed reload" ? 1 : sk.rld)); + } + } + // Firing routines + if (shootPermission && + (this.autofire || (this.abilityKey ? this.body.control.ability : (this.altFire ? this.body.control.alt : this.body.control.fire))) + ) { + if (this.cycle >= 1) { + this.spawnBullets(true, shootPermission); + } // If we're not shooting, only cycle up to where we'll have the proper firing delay + } else if (this.cycle > !this.waitToCycle - this.delay) { + this.cycle = !this.waitToCycle - this.delay; + } + } + destroyOldest() { + let oldestChild, + oldestTime = Infinity; + for (let i = 0; i < this.children.length; i++) { + let child = this.children[i]; + if (child && child.creationTime < oldestTime) { + oldestTime = child.creationTime; + oldestChild = child; + } + } + if (oldestChild) oldestChild.kill(); + } + syncChildren() { + if (this.syncsSkills) { + let self = this; + for (let i = 0; i < this.children.length; i++) { + let child = this.children[i]; + child.define({ + BODY: self.interpret(), + SKILL: self.getSkillRaw(), + }); + child.refreshBodyAttributes(); + } + } + } + syncTurretSkills() { + if (this.syncTurretSkills) { + let self = this; + for (let i = 0; i < this.turret.length; i++) { + let turret = this.turrets[i]; + turret.define({ + BODY: self.interpret(), + SKILL: self.getSkillRaw(), + }); + turret.refreshBodyAttributes(); + } + } + } + fire(gx, gy, sk) { + // Recoil + this.lastShot.time = util.time(); + this.lastShot.power = 3 * Math.log(Math.sqrt(sk.spd) + this.trueRecoil + 1) + 1; + this.motion += this.lastShot.power; + // Find inaccuracy + let shudder = 0, spread = 0; + if (this.settings.shudder) { + do { + shudder = ran.gauss(0, Math.sqrt(this.settings.shudder)); + } while (Math.abs(shudder) >= this.settings.shudder * 2); + } + if (this.settings.spray) { + do { + spread = ran.gauss(0, this.settings.spray * this.settings.shudder); + } while (Math.abs(spread) >= this.settings.spray / 2); + } + spread *= Math.PI / 180; + // Find speed + let vecLength = (this.negRecoil ? -1 : 1) * this.settings.speed * c.runSpeed * sk.spd * (1 + shudder), + vecAngle = this.angle + this.body.facing + spread, + s = new Vector(vecLength * Math.cos(vecAngle), vecLength * Math.sin(vecAngle)); + // Boost it if we should + if (this.body.velocity.length) { + let extraBoost = + Math.max(0, s.x * this.body.velocity.x + s.y * this.body.velocity.y) / + this.body.velocity.length / + s.length; + if (extraBoost) { + let len = s.length; + s.x += (this.body.velocity.length * extraBoost * s.x) / len; + s.y += (this.body.velocity.length * extraBoost * s.y) / len; + } + } + + //create an independent entity + if (this.independentChildren) { + var o = new Entity({ + x: this.body.x + this.body.size * gx - s.x, + y: this.body.y + this.body.size * gy - s.y, + }); + for (let type of this.bulletTypes) { + o.define(type); + } + o.coreSize = o.SIZE; + o.team = this.body.team; + o.refreshBodyAttributes(); + o.life(); + this.master.emit(this.abilityKey ? 'ability' : (this.altFire ? 'altFire' : 'fire'), { + body: this.master, + gun: this, + child: o, + masterStore: this.master.store, + globalMasterStore: this.master.globalStore, + gunStore: this.store, + globalGunStore: this.globalStore + }); + return; + } + + // Create the bullet + var o = new Entity({ + x: this.body.x + this.body.size * gx - s.x, + y: this.body.y + this.body.size * gy - s.y, + }, + this.master.master + ); + /*let jumpAhead = this.cycle - 1; + if (jumpAhead) { + o.x += s.x * this.cycle / jumpAhead; + o.y += s.y * this.cycle / jumpAhead; + }*/ + o.velocity = s; + this.bulletInit(o); + o.coreSize = o.SIZE; + + this.master.emit(this.abilityKey ? 'ability' : (this.altFire ? 'altFire' : 'fire'), { + body: this.master, + gun: this, + child: o, + masterStore: this.master.store, + globalMasterStore: this.master.globalStore, + gunStore: this.store, + globalGunStore: this.globalStore + }); + } + bulletInit(o) { + // Define it by its natural properties + for (let type of this.bulletTypes) { + o.define(type); + } + if (o.color.base == '-1' || o.color.base == 'mirror') { + o.color.base = this.body.master.color.base + } + // Pass the gun attributes + o.define({ + BODY: this.interpret(), + SKILL: this.getSkillRaw(), + SIZE: (this.body.size * this.width * this.settings.size) / 2, + LABEL: this.master.label + (this.label ? " " + this.label : "") + " " + o.label + }); + // Keep track of it and give it the function it needs to deutil.log itself upon death + if (this.countsOwnKids) { + o.parent = this; + this.children.push(o); + } else if (this.body.maxChildren) { + o.parent = this.body; + this.body.children.push(o); + this.children.push(o); + } + o.source = this.body; + o.facing = o.velocity.direction; + // Necromancers. + let oo = o; + o.necro = (host) => { + if (this.countsOwnKids ? + this.countsOwnKids > this.children.length * (this.bulletStats === "master" ? this.body.skill.rld : this.bulletStats.rld) + : this.body.maxChildren ? + this.body.maxChildren > this.body.children.length * (this.bulletStats === "master" ? this.body.skill.rld : this.bulletStats.rld) + : true + ) { + let save = { + facing: host.facing, + size: host.SIZE, + }; + host.define("genericEntity"); + this.bulletInit(host); + host.team = oo.master.master.team; + host.master = oo.master; + host.color.base = oo.color.base; + host.facing = save.facing; + host.SIZE = save.size; + host.health.amount = host.health.max; + return true; + } + return false; + }; + // Otherwise + o.refreshBodyAttributes(); + o.life(); + this.onShootFunction(); + this.recoilDir = this.body.facing + this.angle; + } + onShootHitscan() { + if (this.body.master.health.amount < 0) return; + let save = { + x: this.body.master.x, + y: this.body.master.y, + angle: this.body.master.facing + this.angle, + }; + let s = this.body.size * this.width * this.settings2.size; + let target = { + x: save.x + this.body.master.control.target.x, + y: save.y + this.body.master.control.target.y, + }; + let amount = (util.getDistance(target, save) / s) | 0; + let gun = this; + let explode = (e) => { + e.on('dead', () => { + let o = new Entity(e, gun.body); + o.accel = { + x: 3 * Math.cos(save.angle), + y: 3 * Math.sin(save.angle), + }; + o.color = gun.body.master.master.color; + o.define("hitScanExplosion"); + // Pass the gun attributes + o.define({ + BODY: gun.interpret(gun.settings3), + SKILL: gun.getSkillRaw(), + SIZE: (gun.body.size * gun.width * gun.settings3.size) / 2, + LABEL: gun.master.label + (gun.label ? " " + gun.label + " " : " ") + o.label, + }); + o.refreshBodyAttributes(); + o.life(); + o.source = gun.body; + }); + }; + let branchAlt = 0; + let branchLength = 0; + let branch = (e, a, b = false, g = 0, z = amount) => { + if (!b) branchAlt++; + let total = (z / 5) | 0 || 2; + let dir = (a ? Math.PI / 2 : -Math.PI / 2) + g; + for (let i = 0; i < total; i++) + setTimeout(() => { + let ss = s * 1.5; + let x = e.x + ss * Math.cos(save.angle + dir) * i; + let y = e.y + ss * Math.sin(save.angle + dir) * i; + let o = new Entity( + { + x, + y, + }, + this.body + ); + o.facing = Math.atan2(target.y - y, target.x - x) + dir; + o.color = this.body.master.master.color; + o.define("hitScanBullet"); + // Pass the gun attributes + o.define({ + BODY: this.interpret(this.settings3), + SKILL: this.getSkillRaw(), + SIZE: (this.body.size * this.width * this.settings2.size) / 2, + LABEL: + this.master.label + + (this.label ? " " + this.label : "") + + " " + + o.label, + }); + o.refreshBodyAttributes(); + o.life(); + o.source = this.body; + if (i === total - 1) { + if (branchLength < 3) { + branchLength++; + branch(o, a, true, dir + g, total); + } else branchLength = 0; + } + }, (500 / amount) * i); + }; + const hitScanLevel = +this.onShoot.split("hitScan").pop(); + for (let i = 0; i < amount; i++) { + setTimeout(() => { + if (this.body.master.health.amount < 0) return; + let x = save.x + s * Math.cos(save.angle) * i; + let y = save.y + s * Math.sin(save.angle) * i; + let e = new Entity({ x: x, y: y }, this.body); + e.facing = Math.atan2(target.y - y, target.x - x); + e.color = this.body.master.master.color; + e.define("hitScanBullet"); + // Pass the gun attributes + e.define({ + BODY: this.interpret(this.settings2), + SKILL: this.getSkillRaw(), + SIZE: (this.body.size * this.width * this.settings2.size) / 2, + LABEL: + this.master.label + + (this.label ? " " + this.label : "") + + " " + + e.label, + }); + e.refreshBodyAttributes(); + e.life(); + e.source = this.body; + switch (hitScanLevel) { + case 1: + if (i % 5 === 0) branch(e, branchAlt % 2 === 0); + break; + case 2:// Superlaser + if (i === amount - 1) explode(e); + break; + case 3:// Death Star + if (i % 3 === 0) explode(e); + break; + } + }, 10 * i); + } + } + onShootFunction() { + switch (this.onShoot) { + case "hitScan": + case "hitScan1": + case "hitScan2": + case "hitScan3": + onShootHitscan(); + break; + } + } + getTracking() { + return { + speed: c.runSpeed * (this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.maxSpeed * this.natural.SPEED, + range: Math.sqrt(this.bulletStats == "master" ? this.body.skill.spd : this.bulletStats.spd) * this.settings.range * this.natural.RANGE + }; + } + interpret(alt = false) { + let sizeFactor = this.master.size / this.master.SIZE; + let shoot = alt ? alt : this.settings; + let sk = this.bulletStats == "master" ? this.body.skill : this.bulletStats; + // Defaults + let out = { + SPEED: shoot.maxSpeed * sk.spd, + HEALTH: shoot.health * sk.str, + RESIST: shoot.resist + sk.rst, + DAMAGE: shoot.damage * sk.dam, + PENETRATION: Math.max(1, shoot.pen * sk.pen), + RANGE: shoot.range / Math.sqrt(sk.spd), + DENSITY: (shoot.density * sk.pen * sk.pen) / sizeFactor, + PUSHABILITY: 1 / sk.pen, + HETERO: 3 - 2.8 * sk.ghost, + }; + // Special cases + switch (this.calculator) { + case "thruster": + this.trueRecoil = shoot.recoil * Math.sqrt(sk.rld * sk.spd); + break; + case "sustained": + out.RANGE = shoot.range; + break; + case "swarm": + out.PENETRATION = Math.max(1, shoot.pen * (0.5 * (sk.pen - 1) + 1)); + out.HEALTH /= shoot.pen * sk.pen; + break; + case "trap": + case "block": + out.PUSHABILITY = 1 / Math.pow(sk.pen, 0.5); + out.RANGE = shoot.range; + break; + case "necro": + case "drone": + out.PUSHABILITY = 1; + out.PENETRATION = Math.max(1, shoot.pen * (0.5 * (sk.pen - 1) + 1)); + out.HEALTH = (shoot.health * sk.str + sizeFactor) / Math.pow(sk.pen, 0.8); + out.DAMAGE = shoot.damage * sk.dam * Math.sqrt(sizeFactor) * shoot.pen * sk.pen; + out.RANGE = shoot.range * Math.sqrt(sizeFactor); + break; + } + // Go through and make sure we respect its natural properties + for (let property in out) { + if (this.natural[property] == null || !out.hasOwnProperty(property)) + continue; + out[property] *= this.natural[property]; + } + return out; + } +} + +class antiNaN { + constructor (me) { + this.me = me; + this.nansInARow = 0; + this.data = { x: 1, y: 1, vx: 0, vy: 0, ax: 0, ay: 0 }; + this.amNaN = me => [ me.x, me.y, me.velocity.x, me.velocity.y, me.accel.x, me.accel.y ].some(isNaN); + } + update() { + if (this.amNaN(this.me)) { + this.nansInARow++; + if (this.nansInARow > 50) { + console.log("NaN instance found. (Repeated)\nDebug:", [ + ["x" , isNaN(this.me.x)], + ["y" , isNaN(this.me.y)], + ["velocity.x", isNaN(this.me.velocity.x)], + ["velocity.y", isNaN(this.me.velocity.y)], + ["accel.x" , isNaN(this.me.accel.x)], + ["accel.y" , isNaN(this.me.accel.y)], + ].filter(entry => entry[1]).join(', ')); + } + this.me.x = this.data.x; + this.me.y = this.data.y; + this.me.velocity.x = this.data.vx; + this.me.velocity.y = this.data.vy; + this.me.accel.x = this.data.ax; + this.me.accel.y = this.data.ay; + if (this.amNaN(this.me)) console.log("NaN instance is still NaN."); + } else { + this.data.x = this.me.x; + this.data.y = this.me.y; + this.data.vx = this.me.velocity.x; + this.data.vy = this.me.velocity.y; + this.data.ax = this.me.accel.x; + this.data.ay = this.me.accel.y; + if (this.nansInARow > 0) this.nansInARow--; + } + } +} + +function getValidated(obj, prop, allowedType, from, optional = true) { + let type = typeof obj[prop]; + if (allowedType === type || (optional && 'undefined' === type)) { + return obj[prop]; + } + throw new TypeError(`${from} property ${prop} is of type ${type} instead of type ${allowedType}`); +} +let labelThing = "StatusEffect's effects argument"; +class StatusEffect extends EventEmitter { + constructor (duration = 0, multipliers = {}, tick = a=>a) { + super(); + this.duration = getValidated({duration}, 'duration', 'number', labelThing, false); + this.acceleration = getValidated(multipliers, 'acceleration', 'number', labelThing); + this.topSpeed = getValidated(multipliers, 'topSpeed', 'number', labelThing); + this.health = getValidated(multipliers, 'health', 'number', labelThing); + this.shield = getValidated(multipliers, 'shield', 'number', labelThing); + this.regen = getValidated(multipliers, 'regen', 'number', labelThing); + this.damage = getValidated(multipliers, 'damage', 'number', labelThing); + this.penetration = getValidated(multipliers, 'penetration', 'number', labelThing); + this.range = getValidated(multipliers, 'range', 'number', labelThing); + this.fov = getValidated(multipliers, 'fov', 'number', labelThing); + this.density = getValidated(multipliers, 'density', 'number', labelThing); + this.stealth = getValidated(multipliers, 'stealth', 'number', labelThing); + this.pushability = getValidated(multipliers, 'pushability', 'number', labelThing); + this.recoilReceived = getValidated(multipliers, 'recoilReceived', 'number', labelThing); + this.size = getValidated(multipliers, 'size', 'number', labelThing); + this.tick = getValidated({tick}, 'tick', 'function', "StatusEffect's argument"); + } +} + +class Prop { + constructor(position, bond) { + this.guns = []; + this.color = new Color(16); + this.borderless = false; + this.drawFill = true; + this.strokeWidth = 1; + // Bind prop + this.bond = bond; + this.bond.props.push(this); + // Get my position. + if (Array.isArray(position)) { + position = { + SIZE: position[0], + X: position[1], + Y: position[2], + ANGLE: position[3], + LAYER: position[4] + }; + } + position.SIZE ??= 10; + position.X ??= 0; + position.Y ??= 0; + position.ANGLE ??= 0; + position.LAYER ??= 0; + let _off = new Vector(position.X, position.Y); + this.bound = { + size: position.SIZE / 20, + angle: position.ANGLE * Math.PI / 180, + direction: _off.direction, + offset: _off.length / 10, + layer: position.LAYER + }; + // Initalize. + this.facing = 0; + this.x = 0; + this.y = 0; + this.size = 1; + this.realSize = 1; + this.settings = {}; + this.settings.mirrorMasterAngle = true; + this.upgrades = []; + this.turrets = []; + this.props = []; + } + define(def) { + let set = ensureIsClass(def); + if (set.PARENT != null) { + if (Array.isArray(set.PARENT)) { + for (let i = 0; i < set.PARENT.length; i++) { + this.define(set.PARENT[i], false); + } + } else { + this.define(set.PARENT, false); + } + } + if (set.index != null) this.index = set.index.toString(); + if (set.SHAPE != null) { + this.shape = typeof set.SHAPE === "number" ? set.SHAPE : 0; + this.shapeData = set.SHAPE; + } + this.imageInterpolation = set.IMAGE_INTERPOLATION != null ? set.IMAGE_INTERPOLATION : 'bilinear' + if (set.COLOR != null) { + this.color.interpret(set.COLOR); + } + if (set.STROKE_WIDTH != null) this.strokeWidth = set.STROKE_WIDTH + if (set.BORDERLESS != null) this.borderless = set.BORDERLESS; + if (set.DRAW_FILL != null) this.drawFill = set.DRAW_FILL; + if (set.GUNS != null) { + let newGuns = []; + for (let i = 0; i < set.GUNS.length; i++) { + newGuns.push(new Gun(this, set.GUNS[i])); + } + this.guns = newGuns; + } + } + camera() { + return { + type: 0x01, + id: this.id, + index: this.index, + size: this.size, + realSize: this.realSize, + facing: this.facing, + angle: this.bound.angle, + direction: this.bound.direction, + offset: this.bound.offset, + sizeFactor: this.bound.size, + mirrorMasterAngle: this.settings.mirrorMasterAngle, + layer: this.bound.layer, + color: this.color.compiled, + strokeWidth: this.strokeWidth, + borderless: this.borderless, + drawFill: this.drawFill, + guns: this.guns.map((gun) => gun.getPhotoInfo()), + turrets: this.turrets, + }; + } +} + +let entitiesIdLog = 0; +const forceTwiggle = ["autospin", "turnWithSpeed", "spin", "fastspin", "veryfastspin", "withMotion", "smoothWithMotion", "looseWithMotion"]; +class Entity extends EventEmitter { + constructor(position, master) { + super(); + if (!master) master = this; + this.isGhost = false; + this.killCount = { + solo: 0, + assists: 0, + bosses: 0, + polygons: 0, + killers: [], + }; + this.creationTime = new Date().getTime(); + // Inheritance + this.skipLife = false; + this.master = master; + this.source = this; + this.parent = this; + this.control = { + target: new Vector(0, 0), + goal: new Vector(0, 0), + main: false, + alt: false, + fire: false, + ability: false, + power: 0, + }; + this.isInGrid = false; + this.removeFromGrid = () => { + if (this.isInGrid) { + grid.removeObject(this); + this.isInGrid = false; + } + }; + this.addToGrid = () => { + if (!mockupsLoaded) return; + if (!this.collidingBond && this.bond != null) return; + if (!this.isInGrid) { + grid.addObject(this); + this.isInGrid = true; + } + }; + this.activation = (() => { + let active = true; + let timer = ran.irandom(15); + return { + update: () => { + if (this.skipLife) { + return active = false; + } + if (this.isDead()) { + return 0; + } + if (!active) { + this.removeFromGrid(); + if (this.settings.diesAtRange) { + this.kill(); + } + if (!timer--) { + active = true; + } + } else { + this.addToGrid(); + timer = 15; + active = this.alwaysActive || this.isPlayer || this.isBot || views.some((v) => v.check(this, 0.6)); + } + }, + check: () => { + return active; + }, + }; + })(); + this.autoOverride = false; + this.healer = false; + this.controllers = []; + this.definitionEvents = []; + this.blend = { + color: "#FFFFFF", + amount: 0, + }; + this.reverseTank = 1; + // Objects + this.skill = new Skill(); + this.health = new HealthType(1, "static", 0); + this.shield = new HealthType(0, "dynamic"); + this.guns = []; + this.turrets = []; + this.props = []; + this.upgrades = []; + this.settings = {}; + this.aiSettings = {}; + this.children = []; + this.statusEffects = []; + this.color = new Color(16); + this.glow = {radius: null, color: new Color(-1).compiled, alpha: 1, recursion: 1} + this.invisible = [0, 0]; + this.alphaRange = [0, 1]; + // Define it + this.SIZE = 1; + this.sizeMultiplier = 1; + this.define("genericEntity"); + // Initalize physics and collision + this.alwaysShowOnMinimap = false; + this.allowedOnMinimap = true; + this.maxSpeed = 0; + this.facingLocked = false; + this.facing = 0; + this.vfacing = 0; + this.range = 0; + this.angle = 0; + this.damageReceived = 0; + this.recoilMultiplier = 1; + this.stepRemaining = 1; + this.x = position.x; + this.y = position.y; + this.cameraOverrideX = null; + this.cameraOverrideY = null; + this.velocity = new Vector(0, 0); + this.accel = new Vector(0, 0); + this.damp = 0.05; + this.collisionArray = []; + this.perceptionAngleIndependence = 1; + this.firingArc = [0, 360]; + this.invuln = false; + this.alpha = 1; + this.strokeWidth = 1; + this.levelCap = undefined; + this.autospinBoost = 1; + this.antiNaN = new antiNaN(this); + // Get a new unique id + this.id = entitiesIdLog++; + this.team = this.id; + this.team = master.team; + this.turnAngle = 0; + // Stored Variables + this.globalStore = {}; + this.store = {}; + // This is for collisions + this.AABB_data = {}; + this.AABB_savedSize = 0; + this.collidingBond = false + this.updateAABB = (active) => { + if (!this.collidingBond && this.bond != null) return 0; + if (!active) { + this.AABB_data.active = false; + return 0; + } + if (this.isPlayer && !this.isDead()) this.refreshBodyAttributes(); + this.antiNaN.update(); + // Get bounds + let x1 = Math.min(this.x, this.x + this.velocity.x + this.accel.x) - this.realSize - 5; + let y1 = Math.min(this.y, this.y + this.velocity.y + this.accel.y) - this.realSize - 5; + let x2 = Math.max(this.x, this.x + this.velocity.x + this.accel.x) + this.realSize + 5; + let y2 = Math.max(this.y, this.y + this.velocity.y + this.accel.y) + this.realSize + 5; + let size = Math.max(Math.abs(x2 - x1), Math.abs(y2 - y1)); + let sizeDiff = this.AABB_savedSize / size; + // Update data + this.AABB_data = { + min: [x1, y1], + max: [x2, y2], + active: true, + size: size, + }; + // Update grid if needed + if (sizeDiff > Math.SQRT2 || sizeDiff < Math.SQRT1_2) { + this.removeFromGrid(); + this.addToGrid(); + this.AABB_savedSize = size; + } + }; + this.getAABB = () => this.AABB_data; + this.updateAABB(true); + entities.push(this); + for (let v of views) v.add(this); + this.activation.update(); + events.emit('spawn', this); + } + addStatusEffect(effect) { + this.emit('newStatusEffect', effect); + this.statusEffects.push({ durationLeftover: effect.duration, effect }); + this.refreshBodyAttributes(); + } + life() { + // Size + this.coreSize = this.SIZE; + // Invisibility + if (!this.damageReceived && (this.velocity.x ** 2 + this.velocity.y ** 2 <= 0.1)) { + this.alpha = Math.max(this.alphaRange[0], this.alpha - this.invisible[1]); + } else { + this.alpha = Math.min(this.alphaRange[1], this.alpha + this.invisible[0]); + } + + let lastingEffects = [], needsBodyAttribRefresh = false; + for (let i = 0; i < this.statusEffects.length; i++) { + let entry = this.statusEffects[i]; + entry.durationLeftover -= 1 / c.runSpeed; + if (entry.durationLeftover > 0) { + lastingEffects.push(entry); + } else { + needsBodyAttribRefresh = true; + this.emit('expiredStatusEffect', entry.effect); + } + if (entry.effect.tick && entry.effect.tick(this, entry.effect, entry.durationLeftover)) { + needsBodyAttribRefresh = true; + } + } + this.statusEffects = lastingEffects; + + // Think + let faucet = this.settings.independent || this.source == null || this.source === this ? {} : this.source.control, + b = { + target: remapTarget(faucet, this.source, this), + goal: undefined, + fire: faucet.fire, + main: faucet.main, + alt: faucet.alt, + ability: faucet.ability, + power: undefined, + }; + // Seek attention + if (this.settings.attentionCraver && !faucet.main && this.range) { + this.range -= 1; + } + // So we start with my master's thoughts and then we filter them down through our control stack + for (let i = 0; i < this.controllers.length; i++) { + let AI = this.controllers[i], + a = AI.think(b); + if (a != null) { + if (a.target != null && (b.target == null || AI.acceptsFromTop)) b.target = a.target ; + if (a.goal != null && (b.goal == null || AI.acceptsFromTop)) b.goal = a.goal ; + if (a.fire != null && (b.fire == null || AI.acceptsFromTop)) b.fire = a.fire ; + if (a.main != null && (b.main == null || AI.acceptsFromTop)) b.main = a.main ; + if (a.alt != null && (b.alt == null || AI.acceptsFromTop)) b.alt = a.alt ; + if (a.ability!= null && (b.ability== null || AI.acceptsFromTop)) b.ability= a.ability; + if (a.power != null && (b.power == null || AI.acceptsFromTop)) b.power = a.power ; + } + } + this.control.target = b.target == null ? this.control.target : b.target; + this.control.goal = b.goal ? b.goal : { x: this.x, y: this.y }; + this.control.fire = b.fire ?? false; + this.control.main = b.main ?? false; + this.control.alt = b.alt ?? false; + this.control.ability = b.ability ?? false; + this.control.power = b.power == null ? 1 : b.power; + + if (this.invuln && (this.control.goal.x !== this.x || this.control.goal.y !== this.y)) { + this.invuln = false; + } + + // React + this.move(); + this.face(); + // Handle guns and turrets if we've got them + for (let i = 0; i < this.guns.length; i++) this.guns[i].live(); + for (let i = 0; i < this.turrets.length; i++) this.turrets[i].life(); + if (this.skill.maintain()) needsBodyAttribRefresh = true; + if (needsBodyAttribRefresh) this.refreshBodyAttributes(); + } + addController(newIO) { + if (!Array.isArray(newIO)) newIO = [newIO]; + for (let oldId = 0; oldId < this.controllers.length; oldId++) { + for (let newId = 0; newId < newIO.length; newId++) { + let oldIO = this.controllers[oldId]; + let io = newIO[newId]; + + if (io.constructor === oldIO.constructor) { + this.controllers[oldId] = io; + newIO.splice(newId, 1); + } + } + } + this.controllers = this.controllers.concat(newIO); + } + become(player, dom = false) { + this.addController(new ioTypes.listenToPlayer(this, { player, static: dom })); + this.kick = (reason) => player.socket.kick(reason); + } + giveUp(player, name = "Mothership") { + if (!player.body.isMothership) { + player.body.controllers = [ + new ioTypes.nearestDifferentMaster(player.body), + new ioTypes.spin(player.body, { onlyWhenIdle: true }), + ]; + } else { + player.body.controllers = [ + new ioTypes.nearestDifferentMaster(player.body), + new ioTypes.wanderAroundMap(player.body, { lookAtGoal: true }), + new ioTypes.mapTargetToGoal(player.body), + ]; + } + player.body.name = player.body.label; + player.body.underControl = false; + let fakeBody = new Entity({ x: player.body.x, y: player.body.y }); + fakeBody.passive = true; + fakeBody.underControl = true; + player.body = fakeBody; + player.body.kill(); + } + define(defs, emitEvent = true) { + if (!Array.isArray(defs)) defs = [defs]; + + // Define all primary stats + let set = ensureIsClass(defs[0]); + this.store = {}; + for (let gun of this.guns) gun.store = {}; + + if (set.PARENT != null) { + if (Array.isArray(set.PARENT)) { + for (let i = 0; i < set.PARENT.length; i++) { + this.define(set.PARENT[i], false); + } + } else { + this.define(set.PARENT, false); + } + } + if (set.LAYER != null) this.layerID = set.LAYER; + if (set.index != null) this.index = set.index.toString(); + if (set.NAME != null) this.name = set.NAME; + if (set.LABEL != null) this.label = set.LABEL; + if (set.ANGLE != null) this.angle = set.ANGLE; + if (set.UPGRADE_LABEL != null) this.upgradeLabel = set.UPGRADE_LABEL; + if (set.UPGRADE_TOOLTIP != null) this.upgradeTooltip = set.UPGRADE_TOOLTIP; + if (set.DISPLAY_NAME != null) this.displayName = set.DISPLAY_NAME; + if (set.TYPE != null) this.type = set.TYPE; + if (set.SHAPE != null) { + this.shape = typeof set.SHAPE === "number" ? set.SHAPE : 0; + this.shapeData = set.SHAPE; + } + this.imageInterpolation = set.IMAGE_INTERPOLATION != null ? set.IMAGE_INTERPOLATION : 'bilinear' + if (set.COLOR != null) { + if (this.color === undefined) { + console.log(this); + } + this.color.interpret(set.COLOR); + } + this.upgradeColor = set.UPGRADE_COLOR == null ? null : new Color(set.UPGRADE_COLOR).compiled; + if (set.GLOW != null) { + this.glow = { + radius: set.GLOW.RADIUS ?? 0, + color: new Color(set.GLOW.COLOR).compiled, + alpha: set.GLOW.ALPHA ?? 1, + recursion: set.GLOW.RECURSION ?? 1 + }; + } + if (set.CONTROLLERS != null) { + let toAdd = []; + for (let i = 0; i < set.CONTROLLERS.length; i++) { + let io = set.CONTROLLERS[i]; + if ("string" == typeof io) io = [io]; + toAdd.push(new ioTypes[io[0]](this, io[1])); + } + this.addController(toAdd); + } + if (set.IGNORED_BY_AI != null) this.ignoredByAi = set.IGNORED_BY_AI; + if (set.MOTION_TYPE != null) this.motionType = set.MOTION_TYPE; + if (typeof this.motionType == "string") this.motionType = [this.motionType, {}]; + if (set.FACING_TYPE != null) this.facingType = set.FACING_TYPE; + if (typeof this.facingType == "string") this.facingType = [this.facingType, {}]; + if (set.MIRROR_MASTER_ANGLE != null) this.settings.mirrorMasterAngle = set.MIRROR_MASTER_ANGLE + if (set.DRAW_HEALTH != null) this.settings.drawHealth = set.DRAW_HEALTH; + if (set.DRAW_SELF != null) this.settings.drawShape = set.DRAW_SELF; + if (set.DAMAGE_EFFECTS != null) this.settings.damageEffects = set.DAMAGE_EFFECTS; + if (set.RATIO_EFFECTS != null) this.settings.ratioEffects = set.RATIO_EFFECTS; + if (set.MOTION_EFFECTS != null) this.settings.motionEffects = set.MOTION_EFFECTS; + if (set.ACCEPTS_SCORE != null) this.settings.acceptsScore = set.ACCEPTS_SCORE; + if (set.GIVE_KILL_MESSAGE != null) this.settings.givesKillMessage = set.GIVE_KILL_MESSAGE; + if (set.CAN_GO_OUTSIDE_ROOM != null) this.settings.canGoOutsideRoom = set.CAN_GO_OUTSIDE_ROOM; + if (set.HITS_OWN_TYPE != null) this.settings.hitsOwnType = set.HITS_OWN_TYPE; + if (set.DIE_AT_LOW_SPEED != null) this.settings.diesAtLowSpeed = set.DIE_AT_LOW_SPEED; + if (set.DIE_AT_RANGE != null) this.settings.diesAtRange = set.DIE_AT_RANGE; + if (set.INDEPENDENT != null) this.settings.independent = set.INDEPENDENT; + if (set.PERSISTS_AFTER_DEATH != null) this.settings.persistsAfterDeath = set.PERSISTS_AFTER_DEATH; + if (set.CLEAR_ON_MASTER_UPGRADE != null) this.settings.clearOnMasterUpgrade = set.CLEAR_ON_MASTER_UPGRADE; + if (set.HEALTH_WITH_LEVEL != null) this.settings.healthWithLevel = set.HEALTH_WITH_LEVEL; + if (set.ACCEPTS_SCORE != null) this.settings.acceptsScore = set.ACCEPTS_SCORE; + if (set.OBSTACLE != null) this.settings.obstacle = set.OBSTACLE; + if (set.NECRO != null) this.settings.necroTypes = Array.isArray(set.NECRO) ? set.NECRO : set.NECRO ? [this.shape] : []; + if (set.HAS_NO_RECOIL != null) this.settings.hasNoRecoil = set.HAS_NO_RECOIL; + if (set.CRAVES_ATTENTION != null) this.settings.attentionCraver = set.CRAVES_ATTENTION; + if (set.KILL_MESSAGE != null) this.settings.killMessage = set.KILL_MESSAGE === "" ? "Killed" : set.KILL_MESSAGE; + if (set.AUTOSPIN_MULTIPLIER != null) this.autospinBoost = set.AUTOSPIN_MULTIPLIER; + if (set.BROADCAST_MESSAGE != null) this.settings.broadcastMessage = set.BROADCAST_MESSAGE === "" ? undefined : set.BROADCAST_MESSAGE; + if (set.DEFEAT_MESSAGE) this.settings.defeatMessage = true; + if (set.HEALER) this.healer = true; + if (set.DAMAGE_CLASS != null) this.settings.damageClass = set.DAMAGE_CLASS; + if (set.BUFF_VS_FOOD != null) this.settings.buffVsFood = set.BUFF_VS_FOOD; + if (set.CAN_BE_ON_LEADERBOARD != null) this.settings.leaderboardable = set.CAN_BE_ON_LEADERBOARD; + if (set.INTANGIBLE != null) this.intangibility = set.INTANGIBLE; + if (set.IS_SMASHER != null) this.settings.reloadToAcceleration = set.IS_SMASHER; + if (set.STAT_NAMES != null) this.settings.skillNames = { + body_damage: set.STAT_NAMES?.BODY_DAMAGE ?? 'Body Damage', + max_health: set.STAT_NAMES?.MAX_HEALTH ?? 'Max Health', + bullet_speed: set.STAT_NAMES?.BULLET_SPEED ?? 'Bullet Speed', + bullet_health: set.STAT_NAMES?.BULLET_HEALTH ?? 'Bullet Health', + bullet_pen: set.STAT_NAMES?.BULLET_PEN ?? 'Bullet Penetration', + bullet_damage: set.STAT_NAMES?.BULLET_DAMAGE ?? 'Bullet Damage', + reload: set.STAT_NAMES?.RELOAD ?? 'Reload', + move_speed: set.STAT_NAMES?.MOVE_SPEED ?? 'Movement Speed', + shield_regen: set.STAT_NAMES?.SHIELD_REGEN ?? 'Shield Regeneration', + shield_cap: set.STAT_NAMES?.SHIELD_CAP ?? 'Shield Capacity', + }; + if (set.AI != null) this.aiSettings = set.AI; + if (set.INVISIBLE != null) this.invisible = set.INVISIBLE; + if (set.ALPHA != null) { + this.alpha = ("number" === typeof set.ALPHA) ? set.ALPHA : set.ALPHA[1]; + this.alphaRange = [ + set.ALPHA[0] || 0, + set.ALPHA[1] || 1 + ]; + } + if (set.STROKE_WIDTH != null) this.strokeWidth = set.STROKE_WIDTH + if (set.DANGER != null) this.dangerValue = set.DANGER; + if (set.SHOOT_ON_DEATH != null) this.shootOnDeath = set.SHOOT_ON_DEATH; + if (set.BORDERLESS != null) this.borderless = set.BORDERLESS; + if (set.DRAW_FILL != null) this.drawFill = set.DRAW_FILL; + if (set.TEAM != null) { + this.team = set.TEAM; + if (!sockets.players.length) { + const _entity = this; + for (let i = 0; i < sockets.players.length; i++) { + if (sockets.players[i].body.id == _entity.id) { + sockets.players[i].team = -_entity.team; + } + } + } + for (let child of this.children) child.team = set.TEAM + } + if (set.SYNC_TURRET_SKILLS != null) this.syncTurretSkills = set.SYNC_TURRET_SKILLS; + if (set.VARIES_IN_SIZE != null) { + this.settings.variesInSize = set.VARIES_IN_SIZE; + this.squiggle = this.settings.variesInSize ? ran.randomRange(0.8, 1.2) : 1; + } + if (set.RESET_UPGRADES || set.RESET_STATS) { + let caps = this.skill.caps.map(x=>x); + this.skill.setCaps(Array(10).fill(0)); + this.skill.setCaps(caps); + this.upgrades = []; + this.isArenaCloser = false; + this.ac = false; + this.alpha = 1; + this.reset(); + } + if (set.RESET_UPGRADE_MENU) this.upgrades = [] + if (set.ARENA_CLOSER != null) { + this.isArenaCloser = set.ARENA_CLOSER; + this.ac = set.ARENA_CLOSER; + } + if (set.BRANCH_LABEL != null) this.branchLabel = set.BRANCH_LABEL; + if (set.BATCH_UPGRADES != null) this.batchUpgrades = set.BATCH_UPGRADES; + for (let i = 0; i < c.MAX_UPGRADE_TIER; i++) { + let tierProp = 'UPGRADES_TIER_' + i; + if (set[tierProp] != null && emitEvent) { + for (let j = 0; j < set[tierProp].length; j++) { + let upgrades = set[tierProp][j]; + let index = ""; + if (!Array.isArray(upgrades)) upgrades = [upgrades]; + let redefineAll = upgrades.includes(true); + let trueUpgrades = upgrades.slice(0, upgrades.length - redefineAll); // Ignore last element if it's true + for (let k of trueUpgrades) { + let e = ensureIsClass(k); + index += e.index + "-"; + } + this.upgrades.push({ + class: trueUpgrades, + level: c.TIER_MULTIPLIER * i, + index: index.substring(0, index.length-1), + tier: i, + branch: 0, + branchLabel: this.branchLabel, + redefineAll, + }); + } + } + } + if (set.SIZE != null) { + this.SIZE = set.SIZE * this.squiggle; + if (this.coreSize == null) this.coreSize = this.SIZE; + } + if (set.LEVEL_CAP != null) { + this.levelCap = set.LEVEL_CAP; + } + if (set.LEVEL != null) { + this.skill.reset(); + while (this.skill.level < set.LEVEL) { + this.skill.score += this.skill.levelScore; + this.skill.maintain(); + } + this.refreshBodyAttributes(); + } + if (set.SKILL_CAP != null && set.SKILL_CAP != []) { + if (set.SKILL_CAP.length != 10) throw "Inappropiate skill cap amount."; + this.skill.setCaps(set.SKILL_CAP); + } + if (set.SKILL != null && set.SKILL != []) { + if (set.SKILL.length != 10) throw "Inappropiate skill raws."; + this.skill.set(set.SKILL); + } + if (set.VALUE != null) this.skill.score = Math.max(this.skill.score, set.VALUE * this.squiggle); + if (set.ALT_ABILITIES != null) this.abilities = set.ALT_ABILITIES; + if (set.GUNS != null) { + let newGuns = []; + for (let i = 0; i < set.GUNS.length; i++) { + newGuns.push(new Gun(this, set.GUNS[i])); + } + this.guns = newGuns; + } + if (set.MAX_CHILDREN != null) this.maxChildren = set.MAX_CHILDREN; + if (set.RESET_CHILDREN) this.destroyAllChildren(); + if ("function" === typeof set.LEVEL_SKILL_POINT_FUNCTION) { + this.skill.LSPF = set.LEVEL_SKILL_POINT_FUNCTION; + } + if (set.RECALC_SKILL != null) { + let score = this.skill.score; + this.skill.reset(); + this.skill.score = score; + while (this.skill.maintain()) {} + } + if (set.EXTRA_SKILL != null) { + this.skill.points += set.EXTRA_SKILL; + } + if (set.BODY != null) { + if (set.BODY.ACCELERATION != null) this.ACCELERATION = set.BODY.ACCELERATION; + if (set.BODY.SPEED != null) this.SPEED = set.BODY.SPEED; + if (set.BODY.HEALTH != null) this.HEALTH = set.BODY.HEALTH; + if (set.BODY.RESIST != null) this.RESIST = set.BODY.RESIST; + if (set.BODY.SHIELD != null) this.SHIELD = set.BODY.SHIELD; + if (set.BODY.REGEN != null) this.REGEN = set.BODY.REGEN; + if (set.BODY.DAMAGE != null) this.DAMAGE = set.BODY.DAMAGE; + if (set.BODY.PENETRATION != null) this.PENETRATION = set.BODY.PENETRATION; + if (set.BODY.RANGE != null) this.RANGE = set.BODY.RANGE; + if (set.BODY.FOV != null) this.FOV = set.BODY.FOV; + if (set.BODY.SHOCK_ABSORB != null) this.SHOCK_ABSORB = set.BODY.SHOCK_ABSORB; + if (set.BODY.RECOIL_MULTIPLIER != null) this.RECOIL_MULTIPLIER = set.BODY.RECOIL_MULTIPLIER; + if (set.BODY.DENSITY != null) this.DENSITY = set.BODY.DENSITY; + if (set.BODY.STEALTH != null) this.STEALTH = set.BODY.STEALTH; + if (set.BODY.PUSHABILITY != null) this.PUSHABILITY = set.BODY.PUSHABILITY; + if (set.BODY.HETERO != null) this.heteroMultiplier = set.BODY.HETERO; + this.refreshBodyAttributes(); + } + if (set.SPAWN_ON_DEATH) this.spawnOnDeath = set.SPAWN_ON_DEATH; + if (set.RESET_EVENTS) { + for (let { event, handler, once } of this.definitionEvents) { + this.removeListener(event, handler, once); + } + this.definitionEvents = []; + } + if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; + if (Array.isArray(this.rerootUpgradeTree)) { + let finalRoot = ""; + for (let root of this.rerootUpgradeTree) finalRoot += root + "\\/"; + this.rerootUpgradeTree = finalRoot.substring(0, finalRoot.length - 2); + } + if (set.ON_MINIMAP != null) this.allowedOnMinimap = set.ON_MINIMAP; + if (set.TURRETS != null) { + for (let i = 0; i < this.turrets.length; i++) { + this.turrets[i].destroy(); + } + this.turrets = []; + for (let i = 0; i < set.TURRETS.length; i++) { + let def = set.TURRETS[i], + o = new Entity(this, this.master), + turretDanger = false, + type = Array.isArray(def.TYPE) ? def.TYPE : [def.TYPE]; + for (let j = 0; j < type.length; j++) { + o.define(type[j]); + if (type.TURRET_DANGER) turretDanger = true; + } + if (!turretDanger) o.define({ DANGER: 0 }); + o.collidingBond = def.VULNERABLE + o.bindToMaster(def.POSITION, this, def.VULNERABLE); + } + } + if (set.PROPS != null) { + this.props = []; + for (let i = 0; i < set.PROPS.length; i++) { + let def = set.PROPS[i], + o = new Prop(def.POSITION, this), + type = Array.isArray(def.TYPE) ? def.TYPE : [def.TYPE]; + for (let j = 0; j < type.length; j++) { + o.define(type[j]); + } + } + } + if (set.ON != null) { + for (let { event, handler, once = false } of set.ON) { + this.definitionEvents.push({ event, handler, once }); + this.on(event, handler, once); + } + } + this.reverseTargetWithTank = set.REVERSE_TARGET_WITH_TANK ?? false; + if (set.mockup != null) { + this.mockup = set.mockup; + } + + if (emitEvent) { + this.emit('define', { body: this, set }); + } + + this.defs = []; + for (let def of defs) this.defs.push(def); + + // Define additional stats for other split upgrades + for (let branch = 1; branch < defs.length; branch++) { + set = ensureIsClass(defs[branch]); + + if (set.index != null) this.index += "-" + set.index; + if (set.PARENT != null) { + if (Array.isArray(set.PARENT)) { + for (let i = 0; i < set.PARENT.length; i++) { + this.branchLabel = ensureIsClass(set.PARENT[i]).BRANCH_LABEL; + } + } else { + this.branchLabel = ensureIsClass(set.PARENT).BRANCH_LABEL; + } + } + if (set.LABEL != null && set.LABEL.length > 0) this.label = this.label + "-" + set.LABEL; + if (set.MAX_CHILDREN != null) this.maxChildren += set.MAX_CHILDREN; + else this.maxChildren = null; // For bullet and drone combos so all parts remain functional + if (set.BODY != null) { + if (set.BODY.ACCELERATION != null) this.ACCELERATION *= set.BODY.ACCELERATION; + if (set.BODY.SPEED != null) this.SPEED *= set.BODY.SPEED; + if (set.BODY.HEALTH != null) this.HEALTH *= set.BODY.HEALTH; + if (set.BODY.RESIST != null) this.RESIST *= set.BODY.RESIST; + if (set.BODY.SHIELD != null) this.SHIELD *= set.BODY.SHIELD; + if (set.BODY.REGEN != null) this.REGEN *= set.BODY.REGEN; + if (set.BODY.DAMAGE != null) this.DAMAGE *= set.BODY.DAMAGE; + if (set.BODY.PENETRATION != null) this.PENETRATION *= set.BODY.PENETRATION; + if (set.BODY.RANGE != null) this.RANGE *= set.BODY.RANGE; + if (set.BODY.FOV != null) this.FOV *= set.BODY.FOV; + if (set.BODY.SHOCK_ABSORB != null) this.SHOCK_ABSORB *= set.BODY.SHOCK_ABSORB; + if (set.BODY.RECOIL_MULTIPLIER != null) this.RECOIL_MULTIPLIER *= set.BODY.RECOIL_MULTIPLIER; + if (set.BODY.DENSITY != null) this.DENSITY *= set.BODY.DENSITY; + if (set.BODY.STEALTH != null) this.STEALTH *= set.BODY.STEALTH; + if (set.BODY.PUSHABILITY != null) this.PUSHABILITY *= set.BODY.PUSHABILITY; + if (set.BODY.HETERO != null) this.heteroMultiplier *= set.BODY.HETERO; + this.refreshBodyAttributes(); + } + if (set.GUNS != null) { + let newGuns = []; + for (let i = 0; i < set.GUNS.length; i++) { + newGuns.push(new Gun(this, set.GUNS[i])); + } + this.guns.push(...newGuns); + } + if (set.TURRETS != null) { + for (let i = 0; i < set.TURRETS.length; i++) { + let def = set.TURRETS[i], + o = new Entity(this, this.master), + turretDanger = false, + type = Array.isArray(def.TYPE) ? def.TYPE : [def.TYPE]; + for (let j = 0; j < type.length; j++) { + o.define(type[j]); + if (type.TURRET_DANGER) turretDanger = true; + } + if (!turretDanger) o.define({ DANGER: 0 }); + o.bindToMaster(def.POSITION, this); + } + } + if (set.PROPS != null) { + for (let i = 0; i < set.PROPS.length; i++) { + let def = set.PROPS[i], + o = new Prop(def.POSITION, this), + type = Array.isArray(def.TYPE) ? def.TYPE : [def.TYPE]; + for (let j = 0; j < type.length; j++) { + o.define(type[j]); + } + } + } + if (set.SIZE != null) { + this.SIZE *= set.SIZE * this.squiggle; + if (this.coreSize == null) this.coreSize = this.SIZE; + } + if (set.BATCH_UPGRADES != null) this.batchUpgrades = set.BATCH_UPGRADES; + for (let i = 0; i < c.MAX_UPGRADE_TIER; i++) { + let tierProp = 'UPGRADES_TIER_' + i; + if (set[tierProp] != null && emitEvent) { + for (let j = 0; j < set[tierProp].length; j++) { + let upgrades = set[tierProp][j]; + let index = ""; + if (!Array.isArray(upgrades)) upgrades = [upgrades]; + let redefineAll = upgrades.includes(true); + let trueUpgrades = upgrades.slice(0, upgrades.length - redefineAll); // Ignore last element if it's true + for (let k of trueUpgrades) { + let e = ensureIsClass(k); + index += e.index + "-"; + } + this.upgrades.push({ + class: trueUpgrades, + level: c.TIER_MULTIPLIER * i, + index: index.substring(0, index.length-1), + tier: i, + branch, + branchLabel: this.branchLabel, + redefineAll, + }); + } + } + } + if (set.REROOT_UPGRADE_TREE) this.rerootUpgradeTree = set.REROOT_UPGRADE_TREE; + if (Array.isArray(this.rerootUpgradeTree)) { + let finalRoot = ""; + for (let root of this.rerootUpgradeTree) finalRoot += root + "\\/"; + this.rerootUpgradeTree += finalRoot.substring(0, finalRoot.length - 2); + } + } + + // Batch upgrades + if (this.batchUpgrades && emitEvent) { + this.tempUpgrades = []; + let numBranches = this.defs.length; + for (let i = 0; i < numBranches; i++) { // Create a 2d array for the upgrades (1st index is branch index) + this.tempUpgrades.push([]); + } + for (let upgrade of this.upgrades) { + let upgradeBranch = upgrade.branch; + this.tempUpgrades[upgradeBranch].push(upgrade); + } + + this.upgrades = []; + this.selection = JSON.parse(JSON.stringify(this.defs)); + this.chooseUpgradeFromBranch(numBranches); // Recursively build upgrade options + } + } + chooseUpgradeFromBranch(remaining) { + if (remaining > 0) { // If there's more to select + let branchUgrades = this.tempUpgrades[this.defs.length - remaining]; + for (let i = 0; i < branchUgrades.length; i++) { // Pick all possible options and continue selecting + this.selection[this.defs.length - remaining] = branchUgrades[i]; + this.chooseUpgradeFromBranch(remaining - 1); + } + if (branchUgrades.length == 0) // For when the branch has no upgrades + this.chooseUpgradeFromBranch(remaining - 1); + } else { // If there's nothing more to select + let upgradeClass = [], + upgradeTier = 0, + upgradeIndex = ""; + for (let u of this.selection) { + upgradeClass.push(u.class); + upgradeIndex += u.index + '-'; + upgradeTier = Math.max(upgradeTier, u.tier); + } + this.upgrades.push({ + class: upgradeClass, + level: c.TIER_MULTIPLIER * upgradeTier, + index: upgradeIndex.substring(0, upgradeIndex.length-1), + tier: upgradeTier, + branch: 0, + branchLabel: "", + redefineAll: true, + }); + } + } + refreshBodyAttributes() { + let accelerationMultiplier = 1, + topSpeedMultiplier = 1, + healthMultiplier = 1, + shieldMultiplier = 1, + regenMultiplier = 1, + damageMultiplier = 1, + penetrationMultiplier = 1, + rangeMultiplier = 1, + fovMultiplier = 1, + densityMultiplier = 1, + stealthMultiplier = 1, + pushabilityMultiplier = 1, + sizeMultiplier = 1, + recoilReceivedMultiplier = 1; + for (let i = 0; i < this.statusEffects.length; i++) { + let effect = this.statusEffects[i].effect; + if (effect.acceleration != null) accelerationMultiplier *= effect.acceleration; + if (effect.topSpeed != null) topSpeedMultiplier *= effect.topSpeed; + if (effect.health != null) healthMultiplier *= effect.health; + if (effect.shield != null) shieldMultiplier *= effect.shield; + if (effect.regen != null) regenMultiplier *= effect.regen; + if (effect.damage != null) damageMultiplier *= effect.damage; + if (effect.penetration != null) penetrationMultiplier *= effect.penetration; + if (effect.range != null) rangeMultiplier *= effect.range; + if (effect.fov != null) fovMultiplier *= effect.fov; + if (effect.density != null) densityMultiplier *= effect.density; + if (effect.stealth != null) stealthMultiplier *= effect.stealth; + if (effect.pushability != null) pushabilityMultiplier *= effect.pushability; + if (effect.recoilReceived != null) recoilReceivedMultiplier *= effect.recoilReceived; + if (effect.size != null) sizeMultiplier *= effect.size; + } + + let speedReduce = Math.pow(this.size / (this.coreSize || this.SIZE), 1); + this.acceleration = (accelerationMultiplier * c.runSpeed * this.ACCELERATION) / speedReduce; + if (this.settings.reloadToAcceleration) this.acceleration *= this.skill.acl; + this.topSpeed = (topSpeedMultiplier * c.runSpeed * this.SPEED * this.skill.mob) / speedReduce; + if (this.settings.reloadToAcceleration) this.topSpeed /= Math.sqrt(this.skill.acl); + this.health.set(((this.settings.healthWithLevel ? 2 * this.level : 0) + this.HEALTH) * this.skill.hlt * healthMultiplier); + this.health.resist = 1 - 1 / Math.max(1, this.RESIST + this.skill.brst); + this.shield.set(((this.settings.healthWithLevel ? 0.6 * this.level : 0) + this.SHIELD) * this.skill.shi, Math.max(0, ((this.settings.healthWithLevel ? 0.006 * this.level : 0) + 1) * this.REGEN * this.skill.rgn * regenMultiplier)); + this.damage = damageMultiplier * this.DAMAGE * this.skill.atk * !this.pacify; + this.penetration = penetrationMultiplier * (this.PENETRATION + 1.5 * (this.skill.brst + 0.8 * (this.skill.atk - 1))); + if (!this.settings.dieAtRange || !this.range) this.range = rangeMultiplier * this.RANGE; + this.fov = fovMultiplier * this.FOV * 275 * Math.sqrt(this.size); + this.density = densityMultiplier * (1 + 0.08 * this.level) * this.DENSITY; + this.stealth = stealthMultiplier * this.STEALTH; + this.pushability = pushabilityMultiplier * this.PUSHABILITY; + this.sizeMultiplier = sizeMultiplier; + this.recoilMultiplier = this.RECOIL_MULTIPLIER * recoilReceivedMultiplier; + } + bindToMaster(position, bond, isInvulnerable) { + this.bond = bond; + this.source = bond; + this.bond.turrets.push(this); + this.skill = this.bond.skill; + this.label = this.label.length ? this.bond.label + " " + this.label : this.bond.label; + // It will not be in collision calculations any more nor shall it be seen or continue to run independently. + if (!isInvulnerable) { + this.removeFromGrid(); + this.skipLife = true; + } + // TODO: FIX CLIENT MAKING EVERYTHING FLASH WHEN A VULN TURRET DIES, and display health + if (isInvulnerable) this.on('dead', () => {util.remove(this.master.turrets, this.master.turrets.indexOf(this))}) + this.settings.drawShape = false; + // Get my position. + if (Array.isArray(position)) { + position = { + SIZE: position[0], + X: position[1], + Y: position[2], + ANGLE: position[3], + ARC: position[4], + LAYER: position[5] + }; + } + position.SIZE ??= 10; + position.X ??= 0; + position.Y ??= 0; + position.ANGLE ??= 0; + position.ARC ??= 360; + position.LAYER ??= 0; + let _off = new Vector(position.X, position.Y); + this.bound = { + size: position.SIZE / 20, + angle: position.ANGLE * Math.PI / 180, + direction: _off.direction, + offset: _off.length / 10, + arc: position.ARC * Math.PI / 180, + layer: position.LAYER + }; + // Initalize. + this.activation.update(); + this.facing = this.bond.facing + this.bound.angle; + if (this.facingType[0].includes('Target')) { + this.facingType = ["bound", {}]; + } + this.motionType = ["bound", {}]; + this.move(); + } + get level() { + return Math.min(this.levelCap ?? c.LEVEL_CAP, this.skill.level); + } + get size() { + return this.bond == null ? (this.coreSize || this.SIZE) * this.sizeMultiplier * (1 + this.level / 45) : this.bond.size * this.bound.size; + } + get mass() { + return this.density * (this.size ** 2 + 1); + } + get realSize() { + return this.size * lazyRealSizes[Math.floor(Math.abs(this.shape))]; + } + get xMotion() { + return (this.velocity.x + this.accel.x) / c.runSpeed; + } + get yMotion() { + return (this.velocity.y + this.accel.y) / c.runSpeed; + } + camera(tur = false) { + let turretsAndProps = this.turrets.concat(this.props); + // Turret layer ordering + turretsAndProps.sort((a, b) => a.bound.layer - b.bound.layer); + return { + type: 0 + tur * 0x01 + this.settings.drawHealth * 0x02 + (this.type === "tank" && this.displayName) * 0x04, + invuln: this.invuln, + id: this.id, + index: this.index, + label: this.label, + x: this.x, + y: this.y, + vx: this.velocity.x, + vy: this.velocity.y, + size: this.size, + realSize: this.realSize, + status: 1, + health: this.health.display(), + shield: this.shield.display(), + alpha: this.alpha, + facing: this.facing, + direction: this.bound ? this.bound.direction : 0, + angle: this.bound ? this.bound.angle : 0, + offset: this.bound ? this.bound.offset : 0, + sizeFactor: this.bound ? this.bound.size : 1, + mirrorMasterAngle: this.settings.mirrorMasterAngle ?? false, + perceptionAngleIndependence: this.perceptionAngleIndependence, //vfacing: this.vfacing, + defaultAngle: this.firingArc[0], + twiggle: forceTwiggle.includes(this.facingType[0]) || (this.facingType[0] === "locksFacing" && this.control.alt), + layer: this.layerID ? this.layerID : this.bond != null ? this.bound.layer : this.type === "wall" ? 11 : this.type === "food" ? 10 : this.type === "tank" ? 5 : this.type === "crasher" ? 1 : 0, + color: this.color.compiled, + strokeWidth: this.strokeWidth, + borderless: this.borderless, + drawFill: this.drawFill, + name: (this.nameColor || "#FFFFFF") + this.name, + score: this.skill.score, + guns: this.guns.map((gun) => gun.getPhotoInfo()), + turrets: turretsAndProps.map((turret) => turret.camera(true)), + glow: this.glow, + }; + } + syncTurrets() { + for (let i = 0; i < this.guns.length; i++) this.guns[i].syncChildren(); + for (let i = 0; i < this.turrets.length; i++) { + this.turrets[i].skill = this.skill; + this.turrets[i].refreshBodyAttributes(); + this.turrets[i].syncTurrets(); + } + } + skillUp(stat) { + let suc = this.skill.upgrade(stat); + if (suc) { + this.refreshBodyAttributes(); + for (let i = 0; i < this.guns.length; i++) this.guns[i].syncChildren(); + for (let i = 0; i < this.turrets.length; i++) this.turrets[i].syncTurrets(); + } + return suc; + } + upgrade(number) { + let old = this; + if ( + number < this.upgrades.length && + this.skill.level >= this.upgrades[number].level + ) { + let upgrade = this.upgrades[number], + upgradeClass = upgrade.class, + upgradeBranch = upgrade.branch, + redefineAll = upgrade.redefineAll; + if (redefineAll) { + for (let i = 0; i < upgradeClass.length; i++){ + upgradeClass[i] = ensureIsClass(...upgradeClass[i]); + } + this.upgrades = []; + this.define(upgradeClass); + } else { + this.defs.splice(upgradeBranch, 1, ...upgradeClass); + this.upgrades = []; + this.define(this.defs); + } + this.emit("upgrade", { body: this }); + if (this.color.base == '-1' || this.color.base == 'mirror') { + this.color.base = getTeamColor((c.GROUPS || (c.MODE == 'ffa' && !c.TAG)) ? TEAM_RED : this.team); + } + this.sendMessage("You have upgraded to " + this.label + "."); + for (let def of this.defs) { + def = ensureIsClass(def); + if (typeof def.TOOLTIP == 'string' && def.TOOLTIP.length > 0) { + let tooltips = Array.isArray(def.TOOLTIP) ? def.TOOLTIP : [def.TOOLTIP]; + for (let i = tooltips.length; i--;) this.sendMessage(tooltips[i]); + } + } + this.destroyAllChildren(); + this.skill.update(); + this.syncTurrets(); + this.refreshBodyAttributes(); + } + } + destroyAllChildren() { + for (let instance of entities) { + if ( + instance.settings.clearOnMasterUpgrade && + instance.master.id === this.id + ) { + instance.kill(); + } + } + } + damageMultiplier() { + switch (this.type) { + case "swarm": + return 0.25 + 1.5 * util.clamp(this.range / (this.RANGE + 1), 0, 1); + default: + return 1; + } + } + move() { + let g = { + x: this.control.goal.x - this.x, + y: this.control.goal.y - this.y, + }, + gactive = g.x !== 0 || g.y !== 0, + engine = { + x: 0, + y: 0, + }, + a = this.acceleration / c.runSpeed; + if (c.SPACE_PHYSICS) { + this.maxSpeed = this.topSpeed; + this.damp = 100; + } + let type = this.motionType[0], + args = this.motionType[1]; + switch (type) { + case "grow": + this.SIZE += args.growSpeed ?? 1; + break; + case "fastgrow": + this.SIZE += args.growSpeed ?? 5; + break; + case "fuckingnuclearbomb": + this.SIZE += args.growSpeed ?? 10; + break; + case "trappershockwave": + this.SIZE += args.growSpeed ?? 20; + break; + case "glide": + this.maxSpeed = this.topSpeed; + this.damp = args.damp ?? 0.05; + break; + case "motor": + this.maxSpeed = 0; + if (this.topSpeed) { + this.damp = Math.abs(a) / this.topSpeed; + } + if (gactive) { + let len = Math.sqrt(g.x * g.x + g.y * g.y); + engine = { + x: (a * g.x) / len, + y: (a * g.y) / len, + }; + } + break; + case "spgw": + this.SIZE += args.growSpeed ?? 0.75; + this.maxSpeed = this.topSpeed; + this.damp = args.damp ?? -0.025; + break; + case "chonk": + this.SIZE += args.growSpeed ?? 50; + this.maxSpeed = this.topSpeed; + this.damp = args.damo ?? -0.025; + break; + case "accelerate": + this.velocity.x = this.velocity.x + (4.5 * Math.cos(this.facing)) + this.velocity.y = this.velocity.y + (4.5 * Math.sin(this.facing)) + this.topSpeed += 10; + this.maxSpeed += 10; + this.damp = -0.0125; + break; + case "acceleratetothespeedoflight": + this.velocity.x = this.velocity.x + ((1 * this.maxSpeed + 0.5) * Math.cos(this.facing)) + this.velocity.y = this.velocity.y + ((1 * this.maxSpeed + 0.5) * Math.sin(this.facing)) + this.topSpeed += 0.5; + this.maxSpeed += 0.5; + this.damp = -0.0001; + break; + case "swarm": + this.maxSpeed = this.topSpeed; + let l = + util.getDistance( + { + x: 0, + y: 0, + }, + g + ) + 1; + if (gactive && l > this.size) { + let XvelDesired = (this.topSpeed * g.x) / l, + YvelDesired = (this.topSpeed * g.y) / l, + turning = Math.sqrt( + (this.topSpeed * Math.max(1, this.range) + 1) / a + ); + engine = { + x: (XvelDesired - this.velocity.x) / Math.max(5, turning), + y: (YvelDesired - this.velocity.y) / Math.max(5, turning), + }; + } else { + if (this.velocity.length < this.topSpeed) { + engine = { + x: (this.velocity.x * a) / 20, + y: (this.velocity.y * a) / 20, + }; + } + } + break; + case "chase": + if (gactive) { + let l = util.getDistance({ x: 0, y: 0, }, g); + if (l > this.size * 2) { + this.maxSpeed = this.topSpeed; + let XvelDesired = (this.topSpeed * g.x) / l, + YvelDesired = (this.topSpeed * g.y) / l; + engine = { + x: (XvelDesired - this.velocity.x) * a, + y: (YvelDesired - this.velocity.y) * a, + }; + } else { + this.maxSpeed = 0; + } + } else { + this.maxSpeed = 0; + } + break; + case "aimassist": + this.x = this.source.x + this.master.control.target.x; + this.y = this.source.y + this.master.control.target.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + break; + case "aimassistlock": + if (!this.control.alt) { + this.x = this.source.x + this.master.control.target.x; + this.y = this.source.y + this.master.control.target.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + }; + break; + case "drift": + this.maxSpeed = 0; + engine = { + x: g.x * a, + y: g.y * a, + }; + break; + case "bound": + let bound = this.bound, + ref = this.bond; + this.x = ref.x + ref.size * bound.offset * Math.cos(bound.direction + bound.angle + ref.facing); + this.y = ref.y + ref.size * bound.offset * Math.sin(bound.direction + bound.angle + ref.facing); + ref.velocity.x += bound.size * this.accel.x * ref.recoilMultiplier; + ref.velocity.y += bound.size * this.accel.y * ref.recoilMultiplier; + this.velocity = ref.velocity; + this.firingArc = [ref.facing + bound.angle, bound.arc / 2]; + this.accel.null(); + this.blend = ref.blend; + break; + case "withMaster": + this.x = this.source.x; + this.y = this.source.y; + this.velocity.x = this.source.velocity.x; + this.velocity.y = this.source.velocity.y; + break; + case 'assembler': + this.alpha -= 0.02; + this.SIZE += 0.17; + if (this.alpha <= 0) { + this.kill(); + if (this.SIZE > 50) { + this.destroy(); + } + } + break; + case "desmos": + this.damp = 0; + let save = { + x: this.master.x, + y: this.master.y, + }; + let target = { + x: save.x + this.master.control.target.x, + y: save.y + this.master.control.target.y, + }; + let amount = (util.getDistance(target, save) / 10) | 0; this.damp = 0; + if (this.waveReversed == null) this.waveReversed = this.master.control.alt ? -1 : 1; + if (this.waveAngle == null) { + this.waveAngle = this.master.facing; + this.velocity.x = this.velocity.length + amount * Math.cos(this.waveAngle); + this.velocity.y = this.velocity.length * Math.sin(this.waveAngle); + } + let waveX = this.maxSpeed * 5 * Math.cos((this.RANGE - this.range) / (args.period ?? 4) * 2); + let waveY = (args.amplitude ?? 15) * Math.cos((this.RANGE - this.range) / (args.period ?? 4)) * this.waveReversed * (args.invert ? -1 : 1); + this.x += Math.cos(this.waveAngle) * waveX - Math.sin(this.waveAngle) * waveY; + this.y += Math.sin(this.waveAngle) * waveX + Math.cos(this.waveAngle) * waveY; + break; + + } + this.accel.x += engine.x * this.control.power; + this.accel.y += engine.y * this.control.power; + } + reset(keepPlayerController = true) { + this.controllers = keepPlayerController ? [this.controllers.filter(con => con instanceof ioTypes.listenToPlayer)[0]] : []; + } + face() { + let t = this.control.target, + tactive = t.x !== 0 || t.y !== 0, + oldFacing = this.facing, + oldVFacing = this.vfacing; + let type = this.facingType[0], + args = this.facingType[1]; + switch (type) { + case "autospin": + this.facing += (args.speed ?? 0.02) / c.runSpeed; + break; + case "turnWithSpeed": + this.facing += ((this.velocity.length / 90) * Math.PI) / c.runSpeed; + break; + case "spin": + this.facing += (args.speed ?? 0.05) / c.runSpeed; + break; + case "fastspin": + this.facing += (args.speed ?? 0.1) / c.runSpeed; + break; + case "veryfastspin": + this.facing += (args.speed ?? 1) / c.runSpeed; + break; + case "withMotion": + this.facing = this.velocity.direction; + break; + case "smoothWithMotion": + case "looseWithMotion": + this.facing = util.interpolateAngle(this.facing, this.velocity.direction, c.runSpeed / (args.speed ?? 4)); + break; + case "withTarget": + case "toTarget": + let reverse = this.reverseTargetWithTank ? 1 : this.reverseTank; + this.facing = Math.atan2(t.y * reverse, t.x * reverse); + break; + case "locksFacing": + if (!this.control.alt) this.facing = Math.atan2(t.y, t.x); + break; + case "looseWithTarget": + case "looseToTarget": + case "smoothToTarget": + this.facing = util.interpolateAngle(this.facing, Math.atan2(t.y, t.x), c.runSpeed / (args.speed ?? 4)); + break; + case "noFacing": + this.facing = args.angle ?? 0; + break; + case "bound": + let angleToTarget, angleDiff = 3, + reduceIndependence = false, + slowness = this.settings.mirrorMasterAngle ? 1 : (args.slowness ?? 4) / c.runSpeed; + if (this.control.main) { + angleToTarget = Math.atan2(t.y, t.x); + angleDiff = Math.abs(util.angleDifference(angleToTarget, this.firingArc[0])); + if (angleDiff >= this.firingArc[1]) { + angleToTarget = this.firingArc[0]; + reduceIndependence = true; + } + } else { + angleToTarget = this.firingArc[0]; + reduceIndependence = true; + } + if (reduceIndependence) { + this.perceptionAngleIndependence -= 0.3 / c.runSpeed; + if (this.perceptionAngleIndependence < 0) { + this.perceptionAngleIndependence = 0; + } + } else { + this.perceptionAngleIndependence += 0.3 / c.runSpeed; + if (this.perceptionAngleIndependence > 1) { + this.perceptionAngleIndependence = 1; + } + } + this.facing = util.interpolateAngle(this.facing, angleToTarget, Math.min(1, 1 / (slowness * Math.min(1, angleDiff)))); + break; + } + this.facing += this.turnAngle; + // Loop + const TAU = 2 * Math.PI; + if (this.facingLocked) { + this.facing = oldFacing; + this.vfacing = oldVFacing; + } else { + this.facing = ((this.facing % TAU) + TAU) % TAU; + this.vfacing = util.angleDifference(oldFacing, this.facing) * c.runSpeed; + } + } + takeSelfie() { + this.flattenedPhoto = null; + this.photo = this.settings.drawShape ? this.camera() : undefined; + } + physics() { + if (this.accel.x == null || this.velocity.x == null) { + util.error("Void Error!"); + util.error(this.collisionArray); + util.error(this.label); + util.error(this); + this.accel.null(); + this.velocity.null(); + } + // Apply acceleration + this.velocity.x += this.accel.x; + this.velocity.y += this.accel.y; + // Reset acceleration + this.accel.null(); + // Apply motion + this.stepRemaining = 1; + if (c.SPACE_PHYSICS) this.stepRemaining = 2; + this.x += (this.stepRemaining * this.velocity.x) / c.runSpeed; + this.y += (this.stepRemaining * this.velocity.y) / c.runSpeed; + } + friction() { + var motion = this.velocity.length, + excess = motion - this.maxSpeed; + if (excess > 0 && this.damp) { + var k = this.damp / c.runSpeed, + drag = excess / (k + 1), + finalvelocity = this.maxSpeed + drag; + if (c.SPACE_PHYSICS) + finalvelocity *= this.type === "bullet" ? 1.005 : 1.1; + this.velocity.x = (finalvelocity * this.velocity.x) / motion; + this.velocity.y = (finalvelocity * this.velocity.y) / motion; + } + } + confinementToTheseEarthlyShackles() { + if (this.x == null || this.x == null) { + util.error("Void Error!"); + util.error(this.collisionArray); + util.error(this.label); + util.error(this); + this.accel.null(); + this.velocity.null(); + return 0; + } + if (!this.settings.canGoOutsideRoom) { + if (c.ARENA_TYPE === "circle") { + let centerPoint = { + x: room.width / 2, + y: room.height / 2, + }, dist = util.getDistance(this, centerPoint); + if (dist > room.width / 2) { + let strength = (dist - room.width / 2) * c.ROOM_BOUND_FORCE / (c.runSpeed * 750); + this.x = lerp(this.x, centerPoint.x, strength); + this.y = lerp(this.y, centerPoint.y, strength); + } + } else { + let padding = this.realSize - 50; + this.accel.x -= Math.max(this.x + padding - room.width, Math.min(this.x - padding, 0)) * c.ROOM_BOUND_FORCE / c.runSpeed; + this.accel.y -= Math.max(this.y + padding - room.height, Math.min(this.y - padding, 0)) * c.ROOM_BOUND_FORCE / c.runSpeed; + } + } + } + contemplationOfMortality() { + if (this.invuln || this.godmode) { + this.damageReceived = 0; + return 0; + } + + if (this.damageReceived > 0) { + let damageInflictor = [] + let damageTool = [] + + for (let i = 0; i < this.collisionArray.length; i++) { + let instance = this.collisionArray[i]; + if (instance.type === 'wall' || !instance.damage) continue; + damageInflictor.push(instance.master) + damageTool.push(instance) + } + this.emit('damage', { body: this, damageInflictor, damageTool }); + } + // Life-limiting effects + if (this.settings.diesAtRange) { + this.range -= 1 / c.runSpeed; + if (this.range < 0) { + this.kill(); + } + } + if (this.settings.diesAtLowSpeed) { + if ( + !this.collisionArray.length && + this.velocity.length < this.topSpeed / 2 + ) { + this.health.amount -= this.health.getDamage(1 / c.runSpeed); + } + } + // Shield regen and damage + if (this.shield.max) { + if (this.damageReceived) { + let shieldDamage = this.shield.getDamage(this.damageReceived); + this.damageReceived -= shieldDamage; + this.shield.amount -= shieldDamage; + } + } + // Health damage + if (this.damageReceived) { + let healthDamage = this.health.getDamage(this.damageReceived); + this.blend.amount = 1; + this.health.amount -= healthDamage; + } + this.damageReceived = 0; + // Check for death + if (this.isDead()) { + + this.emit('dead'); + + //Shoot on death + for (let i = 0; i < this.guns.length; i++) { + let gun = this.guns[i]; + if (gun.shootOnDeath && gun.body != null) { + gun.spawnBullets(); + } + } + + // MEMORY LEAKS ARE BAD!!!! + for (let i = 0; i < this.turrets.length; i++) { + this.turrets[i].kill(); + } + + // Initalize message arrays + let killers = [], + killTools = [], + notJustFood = false; + // If I'm a tank, call me a nameless player + let name = this.master.name == "" + ? this.master.type === "tank" + ? "an unnamed " + this.label : this.master.type === "miniboss" + ? "a visiting " + this.label : this.label.substring(0, 3) == 'The' + ? this.label : util.addArticle(this.label) + : this.master.name + "'s " + this.label; + // Calculate the jackpot + let jackpot = util.getJackpot(this.skill.score) / this.collisionArray.length; + // Now for each of the things that kill me... + for (let i = 0; i < this.collisionArray.length; i++) { + let instance = this.collisionArray[i]; + if (instance.type === 'wall' || !instance.damage) continue; + if (instance.master.settings.acceptsScore) { + // If it's not food, give its master the score + if (instance.master.type === "tank" || instance.master.type === "miniboss") { + notJustFood = true; + } + instance.master.skill.score += jackpot; + killers.push(instance.master); // And keep track of who killed me + } else if (instance.settings.acceptsScore) { + instance.skill.score += jackpot; + } + killTools.push(instance); // Keep track of what actually killed me + } + // Remove duplicates + killers = killers.filter((elem, index, self) => index == self.indexOf(elem)); + this.emit('death', { body: this, killers, killTools }); + killers.forEach((e) => e.emit('kill', { body: e, entity: this })); + + // If there's no valid killers (you were killed by food), change the message to be more passive + let killText = notJustFood ? "" : "You have been killed by ", + dothISendAText = this.settings.givesKillMessage; + + for (let i = 0; i < killers.length; i++) { + let instance = killers[i]; + + switch (this.type) { + case "tank": + killers.length > 1 ? instance.killCount.assists++ : instance.killCount.solo++; + if (instance.killCount.solo == 5) { + if (instance.socket) instance.socket.talk("achieve", 0); + }; + if (instance.killCount.solo == 10) { + if (instance.socket) instance.socket.talk("achieve", 1); + sockets.broadcast(instance.name + " is on a kill streak of 10!"); + }; + if (instance.socket) instance.socket.talk("killgained"); + break; + + case "food": + case "crasher": + instance.killCount.polygons++; + if (instance.socket) instance.socket.talk("shapegained"); + break + + case "miniboss": + instance.killCount.bosses++; + break; + } + + this.killCount.killers.push(instance.index); + }; + // Add the killers to our death message, also send them a message + if (notJustFood) { + for (let i = 0; i < killers.length; i++) { + let instance = killers[i]; + if (instance.master.type !== "food" && instance.master.type !== "crasher") { + killText += instance.name == "" ? killText == "" ? "An unnamed player" : "an unnamed player" : instance.name; + killText += " and "; + } + // Only if we give messages + if (dothISendAText) { + instance.sendMessage("You killed " + name + (killers.length > 1 ? " (with some help)." : ".")); + } + if (this.settings.killMessage) { + instance.sendMessage("You " + this.settings.killMessage + " " + name + (killers.length > 1 ? " (with some help)." : ".")); + } + } + // Prepare the next part of the next + killText = killText.slice(0, -4) + "killed you with "; + } + // Broadcast + if (this.settings.broadcastMessage) { + sockets.broadcast(this.settings.broadcastMessage); + } + if (this.settings.defeatMessage) { + let text = util.addArticle(this.label, true); + if (notJustFood) { + text += " has been defeated by"; + for (let { name } of killers) { + text += " "; + text += name === "" ? "an unnamed player" : name; + text += " and"; + } + text = text.slice(0, -4); + text += "!"; + } else { + text += " fought a polygon... and the polygon won."; + } + sockets.broadcast(text); + } + // instead of "a Machine Gunner Bullet and a Machine Gunner Bullet and a Machine Gunner Bullet", + // make it say " 3 Machine Gunner Bullets" + let killCounts = {}; + for (let { label } of killTools) { + if (!killCounts[label]) killCounts[label] = 0; + killCounts[label]++; + } + let killCountEntries = Object.entries(killCounts).map(([name, count], i) => name); + for (let i = 0; i < killCountEntries.length; i++) { + killText += (killCounts[killCountEntries[i]] == 1) ? util.addArticle(killTools[i].label) : killCounts[killCountEntries[i]] + ' ' + killCountEntries[i] + 's'; + killText += i < killCountEntries.length - 2 ? ', ' : ' and '; + } + // Prepare it and clear the collision array. + killText = killText.slice(0, -5); + if (killText === "You have been kille") { + killText = "You have died a stupid death"; + } + this.sendMessage(killText + "."); + // If I'm the leader, broadcast it: + if (this.id === room.topPlayerID) { + let usurptText = this.name === "" ? "The leader" : this.name; + if (notJustFood) { + usurptText += " has been usurped by"; + for (let i = 0; i < killers.length; i++) { + usurptText += " "; + usurptText += killers[i].name === "" ? "an unnamed player" : killers[i].name; + usurptText += " and"; + } + usurptText = usurptText.slice(0, -4) + "!"; + } else { + usurptText += " fought a polygon... and the polygon won."; + } + sockets.broadcast(usurptText); + } + this.setKillers(killers); + // Kill it + return 1; + } + return 0; + } + protect() { + entitiesToAvoid.push(this); + this.isProtected = true; + } + say(message, duration = c.CHAT_MESSAGE_DURATION) { + if (!chats[this.id]) { + chats[this.id] = []; + } + chats[this.id].unshift({ message, expires: Date.now() + duration }); + } + sendMessage(message) {} // Dummy + setKillers(killers) {} // Dummy + kill() { + this.invuln = false; + this.health.amount = -100; + } + destroy() { + // Remove from the protected entities list + if (this.isProtected) { + util.remove(entitiesToAvoid, entitiesToAvoid.indexOf(this)); + } + // Remove from minimap + let i = minimap.findIndex(entry => entry[0] === this.id); + if (i != -1) { + util.remove(minimap, i); + } + // Remove this from views + for (let view of views) { + view.remove(this); + } + // Remove from parent lists if needed + if (this.parent != null) + util.remove(this.parent.children, this.parent.children.indexOf(this)); + // Kill all of its children + for (let instance of entities) { + if (instance.source.id === this.id) { + if (instance.settings.persistsAfterDeath) { + instance.source = instance; + } else { + instance.kill(); + } + } + if (instance.parent && instance.parent.id === this.id) { + instance.parent = null; + } + if (instance.master.id === this.id) { + instance.kill(); + instance.master = instance; + } + } + // Remove everything bound to it + for (let i = 0; i < this.turrets.length; i++) this.turrets[i].destroy(); + // Remove from the collision grid + this.removeFromGrid(); + this.isGhost = true; + } + isDead() { + return this.health.amount <= 0; + } +} +module.exports = { init, StatusEffect, Gun, Entity }; \ No newline at end of file diff --git a/shit/temp/changelog template b/shit/temp/changelog template new file mode 100644 index 000000000..66f07ac46 --- /dev/null +++ b/shit/temp/changelog template @@ -0,0 +1,26 @@ +
    +

    Update

    + [20] +
      +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    • Placeholder
    • +
    +
    \ No newline at end of file diff --git a/shit/temp/gifbackround b/shit/temp/gifbackround new file mode 100644 index 000000000..0211166f5 --- /dev/null +++ b/shit/temp/gifbackround @@ -0,0 +1,33 @@ + \ No newline at end of file diff --git a/shit/temp/music b/shit/temp/music new file mode 100644 index 000000000..46fe5ec52 --- /dev/null +++ b/shit/temp/music @@ -0,0 +1,20 @@ + + \ No newline at end of file diff --git a/shit/temp/mytankcount b/shit/temp/mytankcount new file mode 100644 index 000000000..ae2963ea7 --- /dev/null +++ b/shit/temp/mytankcount @@ -0,0 +1,13 @@ +auto branch + +railgun +hivemind +cloner +plasma smg +scanner +dictator +revolutionist +revo +bacrid +auto +ception \ No newline at end of file diff --git a/shit/temp/stuff b/shit/temp/stuff new file mode 100644 index 000000000..520100d43 --- /dev/null +++ b/shit/temp/stuff @@ -0,0 +1,137 @@ + //Class.unfinishedtesting.UPGRADES_TIER_0 = ["testing", "aimassisttest", "toxic", "autoboosttest"] +Class.toxic = { + PARENT: "genericTank", + LABEL: "Intoxicator", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "poisonbullet", + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0] + } + ] +}; +Class.poisonbullet = { + PARENT: "bullet", + LABEL: "posonio", + TURRETS: [ + { + POSITION: [0, 0, 0, 0, 360, 1], + TYPE: "recangluhitbox" + } + ] +}; +Class.aimassistbullet = { + PARENT: "bullet", + LABEL: "Bullet", + SHAPE: "M 1 1 l -2 0 L -1 -1 L 1 -1 L -1 -1 L -1 1 L 1 1 L 1 -1 L 1 1", + CONTROLLERS: ["nearestDifferentMaster"], + ACCEPTS_SCORE: false, + BODY: { + PENETRATION: 0.1, + SPEED: 99999, + DENSITY: 0.1, + HEALTH: 5, + DAMAGE: 0, + PUSHABILITY: 0.1, + SIZE: 18, + }, + MOTION_TYPE: "aimassistlock", + CAN_GO_OUTSIDE_ROOM: true, + HITS_OWN_TYPE: "never", + DIE_AT_RANGE: true, + TURRETS: [ + { + POSITION: [25, 0, 0, 0, 360, 1], + TYPE: "crosshair1" + } + ] +}; +Class.aimassisttest = { + PARENT: "genericTank", + LABEL: "Aim Assist", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet", + HAS_NO_RECOIL: true + } + }, + { + POSITION: [5.5, 8, -1.8, 6.5, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "aimassistbullet", + HAS_NO_RECOIL: true + } + }, + ], + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "autoTankGunLock" + } + ] +} +Class.autoboosttest = { + PARENT: "genericTank", + LABEL: "Aim Assist", + DANGER: 7, + GUNS: [ + { + POSITION: [19, 8, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.single]), + TYPE: "bullet", + } + }, + ], + TURRETS: [ + { + POSITION: [10, 0, 0, 0, 360, 1], + TYPE: "autoTankGunLockRecoil" + } + ] +} +Class.autoTankGunLock = { + PARENT: "autoTankGun", + MOTION_TYPE: "aimassistlock", + BODY: { + FOV: 1 + }, + CONTROLLERS: ["nearestDifferentMasterAltAlt", "AimAssistLock"], + AI: { + FARMER: true, + BLIND: true, + }, +} +Class.autoTankGunLockRecoil = { + PARENT: "autoTankGun", + MOTION_TYPE: "aimassistlock", + GUNS: [ + { + POSITION: [22, 10, 1, 0, 0, 0, 0], + PROPERTIES: { + SHOOT_SETTINGS: combineStats([g.basic, g.flankGuard, g.tonsmorerecoil, g.tonsmorerecoil, g.halfreload, g.halfreload, g.halfreload, g.fakewithrecoil]), + TYPE: "bullet", + }, + }, + ], + CONTROLLERS: ["nearestDifferentMasterAlt", "AimAssistLock"], + AI: { + FARMER: true, + }, +} + +Class.unfinishedtesting = { + PARENT: ["menu"], + LABEL: "Unfinished tanks", +}; \ No newline at end of file diff --git a/shit/temp/woomycolorname b/shit/temp/woomycolorname new file mode 100644 index 000000000..2b674856a --- /dev/null +++ b/shit/temp/woomycolorname @@ -0,0 +1,3 @@ +yeah no, +anyways so basically what im gonna say is +2019/april/24/11/45/32 \ No newline at end of file From 2947b845839d57f2574b32ea4537d64efc4547c0 Mon Sep 17 00:00:00 2001 From: "Glitch (neroio2)" Date: Wed, 24 Jul 2024 15:37:13 +0000 Subject: [PATCH 09/15] fafasf --- .glitch-assets | 1 + README.md | 7 +- changelog preview | 26 +- package.json | 2 +- public/app.js | 1033 +++++-- public/changelog.html | 48 +- public/index.html | 232 +- public/lib/canvas.js | 543 +++- public/lib/config.js | 94 + public/lib/global.js | 28 +- public/lib/settings.js | 7 +- public/lib/socketInit.js | 123 +- public/main.css | 496 +++- public/servers.json | 3 +- server/config.js | 21 +- server/index.js | 90 +- server/lib/hshg.js | 1166 ++++---- server/lib/util.js | 47 +- server/modules/debug/logs.js | 125 +- server/modules/debug/speedLoop.js | 30 +- .../definitions/addons/basicChatModeration.js | 79 +- server/modules/definitions/addons/cooper.js | 2 +- .../modules/definitions/addons/dailyTanks.js | 1347 --------- .../definitions/addons/defsReloadCommand.js | 65 + server/modules/definitions/addons/dreadv1.js | 458 +++- server/modules/definitions/addons/dreadv2.js | 448 +-- server/modules/definitions/addons/labyFood.js | 8 +- .../modules/definitions/addons/playerskins.js | 2 +- server/modules/definitions/addons/solario.js | 17 +- server/modules/definitions/combined.js | 45 +- server/modules/definitions/constants.js | 21 +- server/modules/definitions/facilitators.js | 67 +- server/modules/definitions/groups/bosses.js | 718 ++++- server/modules/definitions/groups/dev.js | 2082 ++++++++++++-- server/modules/definitions/groups/food.js | 58 +- server/modules/definitions/groups/generics.js | 30 +- server/modules/definitions/groups/misc.js | 96 +- .../modules/definitions/groups/projectiles.js | 206 +- server/modules/definitions/groups/tanks.js | 1070 ++++++-- server/modules/definitions/groups/turrets.js | 824 ++---- server/modules/definitions/gunvals.js | 16 +- server/modules/gamemodes/bossRush.js | 89 +- server/modules/gamemodes/gamemodeLoop.js | 29 +- server/modules/gamemodes/maze.js | 4 +- server/modules/gamemodes/oldDreadnoughts.js | 311 +++ server/modules/gamemodes/tag.js | 34 +- server/modules/global.js | 18 +- server/modules/live/color.js | 10 +- server/modules/live/controllers.js | 277 +- server/modules/live/entity.js | 1285 +++++---- server/modules/live/entitySubFunctions.js | 22 +- server/modules/network/sockets.js | 433 +-- server/modules/network/webServer.js | 43 +- server/modules/physics/collisionFunctions.js | 231 +- server/modules/setup/config.js | 5 +- .../modules/setup/gamemodeconfigs/assault.js | 5 + .../setup/gamemodeconfigs/old_dreadnoughts.js | 11 + server/modules/setup/gamemodeconfigs/tdm.js | 2 +- server/modules/setup/mockups.js | 66 +- server/modules/setup/room.js | 7 +- .../modules/setup/rooms/map_neroio_blank2.js | 22 + .../setup/rooms/map_neroio_mazearena.js | 4 +- .../setup/rooms/map_old_dreadnoughts.js | 92 + .../modules/setup/rooms/overlay_domination.js | 12 +- server/modules/setup/rooms/overlay_maze.js | 7 +- server/modules/setup/rooms/overlay_portal.js | 9 +- server/modules/setup/rooms/overlay_tdm.js | 86 +- server/modules/setup/tiles/dominators.js | 19 +- server/modules/setup/tiles/misc.js | 18 +- .../modules/setup/tiles/old_dreadnoughts.js | 98 + server/modules/setup/tiles/portal.js | 2 +- server/modules/setup/tiles/siege.js | 2 +- server/modules/setup/tiles/tdm.js | 5 +- server/permissions.js | 7 +- shit/temp/backuo | 2409 ----------------- shit/temp/woomycolorname | 6 +- 76 files changed, 9144 insertions(+), 8317 deletions(-) create mode 100644 public/lib/config.js delete mode 100644 server/modules/definitions/addons/dailyTanks.js create mode 100644 server/modules/definitions/addons/defsReloadCommand.js create mode 100644 server/modules/gamemodes/oldDreadnoughts.js create mode 100644 server/modules/setup/gamemodeconfigs/assault.js create mode 100644 server/modules/setup/gamemodeconfigs/old_dreadnoughts.js create mode 100644 server/modules/setup/rooms/map_neroio_blank2.js create mode 100644 server/modules/setup/rooms/map_old_dreadnoughts.js create mode 100644 server/modules/setup/tiles/old_dreadnoughts.js delete mode 100644 shit/temp/backuo diff --git a/.glitch-assets b/.glitch-assets index ce69671a1..4f2e93f63 100644 --- a/.glitch-assets +++ b/.glitch-assets @@ -220,3 +220,4 @@ {"uuid":"Lp97bNs9HjhFIlKp","deleted":true} {"uuid":"1E7gld9pLGXWDUC8","deleted":true} {"name":"IMG_20240528_183451141.jpg","date":"2024-05-28T21:05:24.675Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/IMG_20240528_183451141.jpg","type":"image/jpeg","size":1297815,"imageWidth":1842,"imageHeight":4096,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2FIMG_20240528_183451141.jpg","thumbnailWidth":149,"thumbnailHeight":330,"uuid":"DOggN020wevkaQxc"} +{"name":"583124__bruhman29__ambient-piano-glitch-loop.mp3","date":"2024-07-03T23:46:28.796Z","url":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/583124__bruhman29__ambient-piano-glitch-loop.mp3","type":"audio/mpeg","size":722880,"thumbnail":"https://cdn.glitch.global/5fc7dcb6-aada-495b-828e-66901a470a29/thumbnails%2F583124__bruhman29__ambient-piano-glitch-loop.mp3","thumbnailWidth":210,"thumbnailHeight":210,"uuid":"KYCEs4Okhu8gU0Rw"} diff --git a/README.md b/README.md index 2b6481f00..05b410bfa 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,15 @@ # Open Source Arras +Logo ![GitHub Release](https://img.shields.io/github/v/release/Taureon/aps-plus-plus) ![Discord](https://img.shields.io/discord/1004907608018264094) ![GitHub repo size](https://img.shields.io/github/repo-size/Taureon/aps-plus-plus) +We're currently in the process of [rebuilding OSA from scratch on Codeberg](https://codeberg.org/Taureon/OpenSourceArras). This repository will be archived once the Codeberg repo is in a playable state and has most of the features from regular OSA. + +## Important Notice + **Open Source Arras is beta software.** This build is **not** representative of the final product. Expect bugs and missing features. Major updates may introduce breaking changes that alter how certain things work. It is **your responsibility** to keep your private server up-to-date and functioning. @@ -31,7 +36,7 @@ Create a new project and choose to import one from GitHub. When prompted for the Navigate to `server/config.js` and replace `localhost:26301` with the URL for your project. (For Glitch users, it's `your-project.glitch.me` (replace `your-project` with the actual name of your project, it should be above settings)). -**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"`. Glitch doesn't currently support Node 18.** +**For Glitch specifically, go to `package.json` and replace `"node": "18.x"` with `"node": "16.x"` and change your port to something more generic like 3000 or 8080.** After doing that, your server should be ready! diff --git a/changelog preview b/changelog preview index f0a94ebd6..db0febaeb 100644 --- a/changelog preview +++ b/changelog preview @@ -13,7 +13,31 @@
  • Added Mini Defender
  • Integrated Lancer into Main & Added More Lancer Things
  • buffed kiva
  • -

    Holay Molay

    +
  • menu tweaks
  • +
  • Added new servers and domain
  • +
  • Necromancer Rebalance + Gun Rework
  • +
  • Added more killstreak messages and an extra bonus at 100 kills :)
  • +
  • small server side optoimizations
  • +
  • added mobile controls :D (now you can play on the go)
  • +
  • added versitile switching from between pc and mobile controls in the menu
  • +
  • super huge bugfixes and balancing
  • +
  • fixed surge and added lancer range stat
  • +
  • fixed game crashing bug (i put two square brackets)
  • +
  • added respawn cooldown and tips n stuff
  • +
  • added /menu command
  • +
  • added custom keybinds
  • +
  • fixed bug where toggables do not work
  • +
  • fixed maze wall size bug
  • +
  • fixed death sound bug
  • +
  • fixed missing upgrades
  • +
  • added propel branch
  • +
  • added new extra tanks
  • +
  • added jouster branch
  • +
  • fixed mockups bug
  • +
  • fixed physics bugs
  • +
  • fixed machine gun bullet size
  • +
  • fixed sidewinder bug
  • +

    RANDOM BULLSHIT, GO!

    -
    ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○
    +
    ◉ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○ ○