Custom Flair Animator

Animate custom flair using a spritesheet

  1. // ==UserScript==
  2. // @name Custom Flair Animator
  3. // @version 1
  4. // @description Animate custom flair using a spritesheet
  5. // @include https://*.koalabeast.com/game
  6. // @include https://*.koalabeast.com/game?*
  7. // @author Bambi
  8. // @grant none
  9. // @namespace https://greasyfork.org/users/1089343
  10. // ==/UserScript==
  11.  
  12. console.log('START: ' + GM_info.script.name + ' (v' + GM_info.script.version + ' by ' + GM_info.script.author + ')');
  13.  
  14. tagpro.ready(function () {
  15. const flairSpritesheetURL = 'https://i.imgur.com/tnVHI5u.png'; // Replace with your spritesheet URL.
  16. const flairFrameWidth = 16; // Width of each frame in pixels.
  17. const flairFrameHeight = 16; // Height of each frame in pixels.
  18. const flairFramesPerSecond = 16; // Desired frames per second.
  19. const gridRows = 6; // Number of rows in the grid.
  20. const gridCols = 6; // Number of columns in the grid.
  21. const totalFrames = 36; // Total number of frames in your spritesheet.
  22.  
  23. let currentFrame = 0;
  24. let lastUpdateTime = 0;
  25.  
  26. const flairContainer = new PIXI.Container();
  27. const flairSprite = new PIXI.Sprite();
  28. flairContainer.addChild(flairSprite);
  29. flairContainer.scale.set(1.0); // Adjust the scale as needed.
  30.  
  31. const flairTexture = PIXI.Texture.from(flairSpritesheetURL);
  32.  
  33. function animateFlair() {
  34. const currentTime = Date.now();
  35. if (currentTime - lastUpdateTime >= 1000 / flairFramesPerSecond) {
  36. currentFrame = (currentFrame + 1) % totalFrames;
  37. const frameX = (currentFrame % gridCols) * flairFrameWidth;
  38. const frameY = Math.floor(currentFrame / gridCols) * flairFrameHeight;
  39. flairSprite.texture = new PIXI.Texture(flairTexture.baseTexture, new PIXI.Rectangle(frameX, frameY, flairFrameWidth, flairFrameHeight));
  40. lastUpdateTime = currentTime;
  41. }
  42. requestAnimationFrame(animateFlair);
  43. }
  44.  
  45. function changeFlair() {
  46. const player = tagpro.players[tagpro.playerId];
  47.  
  48. if (player.id === tagpro.playerId && !player.newFlair) {
  49. if (player.sprites.flair) {
  50. player.sprites.info.removeChild(player.sprites.flair);
  51. player.sprites.flair.destroy();
  52. player.sprites.flair = null;
  53. }
  54.  
  55. if (!player.sprites.flair) {
  56. player.sprites.flair = flairContainer;
  57. player.sprites.flair.anchor = new PIXI.Point(0.5, 0.5);
  58. player.sprites.flair.position = new PIXI.Point(15, -17); // (20, -9) is normal
  59. player.sprites.info.addChild(player.sprites.flair);
  60. player.flair = player.sprites.flair.flairName = 'shinyaxe';
  61. }
  62.  
  63. player.newFlair = true;
  64. }
  65. }
  66.  
  67. function waitForPlayer() {
  68. return new Promise(resolve => {
  69. let clearable;
  70.  
  71. clearable = setInterval(function () {
  72. if (tagpro && !tagpro.spectator && tagpro.players && tagpro.playerId && tagpro.players[tagpro.playerId] && tagpro.players[tagpro.playerId].hasOwnProperty('flair') && tagpro.players[tagpro.playerId].sprites) {
  73. clearInterval(clearable);
  74. resolve();
  75. }
  76. }, 100);
  77. });
  78. }
  79.  
  80. waitForPlayer().then(() => {
  81. changeFlair();
  82. animateFlair();
  83. });
  84. });