Advertisement
ezmash

Large Sprite Fix (MV)

Dec 7th, 2015
3,325
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*:
  2. * @plugindesc Fixes issue with large sprites appearing over ☆ passability tiles
  3. * @author Shaz - rewrite of Neon Black's plugin
  4. *
  5. * @param Terrain Id
  6. * @desc This is the ID of the terrain to fix with ☆ tiles
  7. * @default 7
  8. *
  9. * @param Apply to Followers
  10. * @desc Enable this option to perform large sprite checking on followers
  11. * @default N
  12. *
  13. * @param Apply to Vehicles
  14. * @desc Enable this option to perform large sprite checking on vehicles
  15. * @default Y
  16. *
  17. * @param Apply to All Events
  18. * @desc Enable this option to perform large sprite checking on ALL events
  19. * @default N
  20. *
  21. * @help
  22. *
  23. * This plugin is a rewrite to fix some issues with Neon Black's Large Sprite
  24. * Fix plugin.  By default, tiles with a star passability appear in front of
  25. * character sprites, based on the assumption that character sprites will
  26. * follow MV's default size of 48x48 pixels.  This causes a problem when
  27. * sprites are larger, or are drawn higher than the grid, and may be partially
  28. * chopped off by the tile.
  29. *
  30. * Tiles marked with the specified terrain tag and a star passage setting will
  31. * only appear above the character sprite when the character is at the same
  32. * y coordinate, or higher, than the tile.  If the character is lower than the
  33. * tile, the character will appear in front.
  34. *
  35. * To perform large sprite checking only on specific events, set the Apply to
  36. * All Events parameter to N, and add a plugin call on each event page where
  37. * the effect is to be applied:
  38. *   LargeSprite
  39. * To maintain compatibility with Neon Black's previous plugin, you can also
  40. * use the tag <large sprite> in a comment box on an event.
  41. */
  42.  
  43. (function() {
  44.  
  45.   var parameters = PluginManager.parameters('ShazLargeSpriteFix');
  46.   var terrainId = Number(parameters['Terrain Id'] || 7);
  47.   var lsFollowers = (parameters['Apply to Followers'] || 'N').toUpperCase().substring(0,1) === 'Y';
  48.   var lsVehicles = (parameters['Apply to Vehicles'] || 'N').toUpperCase().substring(0,1) === 'Y';
  49.   var lsAllEvents = (parameters['Apply to All Events'] || 'N').toUpperCase().substring(0,1) === 'Y';
  50.  
  51.   Game_CharacterBase.prototype.largeSprite = function() { return false };
  52.   Game_Player.prototype.largeSprite = function() { return true };
  53.   Game_Follower.prototype.largeSprite = function() { return lsFollowers };
  54.   Game_Vehicle.prototype.largeSprite = function() { return lsVehicles };
  55.   Game_Event.prototype.largeSprite = function() { return lsAllEvents || this._largeSprite };
  56.  
  57.   var _Game_Event_setupPage = Game_Event.prototype.setupPage;
  58.   Game_Event.prototype.setupPage = function() {
  59.     _Game_Event_setupPage.call(this);
  60.     this._largeSprite = this.list().some(function(cmd) {
  61.       return (cmd.code === 356 && cmd.parameters[0].split(' ').shift().toUpperCase() === 'LARGESPRITE') ||
  62.       ([108,408].indexOf(cmd.code) > -1 && cmd.parameters[0].match(/<large sprite>/i));
  63.     });
  64.   };
  65.  
  66.   var _Game_Map_setup = Game_Map.prototype.setup;
  67.   Game_Map.prototype.setup = function(mapId) {
  68.     _Game_Map_setup.call(this, mapId);
  69.     this.setupLargeSpriteTiles();
  70.   };
  71.  
  72.   Game_Map.prototype.setupLargeSpriteTiles = function() {
  73.     this._largeSpriteTiles = [];
  74.     var flags = this.tilesetFlags();
  75.     for (var x = 0; x < $dataMap.width; x++) {
  76.       for (var y = 0; y < $dataMap.height; y++) {
  77.         var tiles = this.allTiles(x, y);
  78.         for (var i = 0; i < tiles.length; i++) {
  79.           var flag = flags[tiles[i]];
  80.           if ((flag & 0x10) !== 0 && (flag >> 12) === terrainId) {
  81.             this._largeSpriteTiles.push([x,y]);
  82.             break;
  83.           }
  84.         }
  85.       }
  86.     }
  87.   };
  88.  
  89.   Game_Map.prototype.largeSpriteTiles = function(x1, y1, x2, y2) {
  90.     return this._largeSpriteTiles.filter( function(key) {
  91.       return key[0] >= x1 && key[0] <= x2 && key[1] >= y1 && key[1] <= y2;
  92.     });
  93.   };
  94.  
  95.   var _Sprite_Character_update = Sprite_Character.prototype.update;
  96.   Sprite_Character.prototype.update = function() {
  97.     if (this.isImageChanged()) {
  98.       this._characterSpriteChanged = true;
  99.     }
  100.     _Sprite_Character_update.call(this);
  101.     this.updateUpperSprite();
  102.   };
  103.  
  104.   Sprite_Character.prototype.updateUpperSprite = function () {
  105.     if (this._character.largeSprite() && this._tileId === 0 && this.bitmap.isReady()) {
  106.       if (this._characterSpriteChanged) {
  107.         this.saveBitmap();
  108.       }
  109.       this.getMapInfo();
  110.       this.getEdgeRect();
  111.       if (this.isOnScreenCharacter()) {
  112.         this.getEdgeTiles();
  113.         this.overlayTiles = $gameMap.largeSpriteTiles(this.edgeTiles[0], this.edgeTiles[1],
  114.           this.edgeTiles[2], this.edgeTiles[3] - 1);
  115.         this.refreshBitmap();
  116.       }
  117.     }
  118.   };
  119.  
  120.   Sprite_Character.prototype.saveBitmap = function() {
  121.     this._characterSpriteChanged = false;
  122.     frame = new Rectangle(this._frame.x, this._frame.y, this._frame.width, this._frame.height);
  123.     this.oldBitmap = new Bitmap(this.bitmap.width, this.bitmap.height);
  124.     this.oldBitmap.blt(this.bitmap, 0, 0, this.bitmap.width, this.bitmap.height, 0, 0);
  125.     this.bitmap = new Bitmap(this.bitmap.width, this.bitmap.height);
  126.     this.bitmap.blt(this.oldBitmap, 0, 0, this.bitmap.width, this.bitmap.height, 0, 0);
  127.     this.setFrame(frame.x, frame.y, frame.width, frame.height);
  128.     if (this._upperSprite) {
  129.       this._upperSprite.bitmap = new Bitmap(this.patternWidth(), this.patternHeight());
  130.     }
  131.   };
  132.  
  133.   Sprite_Character.prototype.refreshBitmap = function() {
  134.     if (this._upperSprite) {
  135.       this.bitmap.clearRect(0, 0, this.bitmap.width, this.bitmap.height);
  136.       this.bitmap.blt(this.oldBitmap, 0, 0, this.bitmap.width, this.bitmap.height, 0, 0);
  137.     }
  138.     if (this.overlayTiles.length > 0) {
  139.       this.createUpperSprite();
  140.       this._upperSprite.bitmap.clear();
  141.       this._upperSprite.visible = this.visible;
  142.       this._upperSprite.opacity = this.opacity;
  143.       this._upperSprite.x = this.x;
  144.       this._upperSprite.y = this.y;
  145.       this._upperSprite.z = 8;
  146.       this._upperSprite.setBlendColor(this.getBlendColor());
  147.       this._upperSprite.setColorTone(this.getColorTone());
  148.       this.copyOverlaySegments();
  149.     } else if (this._upperSprite) {
  150.       this._upperSprite.visible = false;
  151.     }
  152.   };
  153.  
  154.   Sprite_Character.prototype.copyOverlaySegments = function() {
  155.     var pw = this.patternWidth();
  156.     var ph = this.patternHeight();
  157.     for (var x = 0; x < pw; ) {
  158.       for (var y = 0; y < ph; ) {
  159.         var w = Math.min(pw - x, this.tw - (this.mx + this.edge[0] + x) % this.tw);
  160.         var h = Math.min(ph - y, this.th - (this.my + this.edge[1] + y) % this.th);
  161.         if (this.isOverlaySegment(x, y)) {
  162.           this._upperSprite.bitmap.blt(this.bitmap, this._frame.x + x, this._frame.y + y, w, h, x, y, w, h);
  163.           this.bitmap.clearRect(this._frame.x + x, this._frame.y + y, w, h);
  164.         }
  165.         y += h;
  166.       }
  167.       x += w;
  168.     }
  169.   };
  170.  
  171.   Sprite_Character.prototype.isOverlaySegment = function(x, y) {
  172.     var tx = Math.floor((this.mx + this.edge[0] + x) / this.tw);
  173.     var ty = Math.floor((this.my + this.edge[1] + y) / this.th);
  174.     return this.overlayTiles.some(function(key) {
  175.       return key[0] === tx && key[1] === ty;
  176.     }.bind(this));
  177.   };
  178.  
  179.   Sprite_Character.prototype.createUpperSprite = function() {
  180.     if (!this._upperSprite) {
  181.       this._upperSprite = new Sprite()
  182.       this._upperSprite.bitmap = new Bitmap(this.patternWidth(), this.patternHeight());
  183.       this._upperSprite.anchor.x = this.anchor.x;
  184.       this._upperSprite.anchor.y = this.anchor.y;
  185.       this.parent.addChild(this._upperSprite);
  186.     }
  187.   };
  188.  
  189.   Sprite_Character.prototype.isOnScreenCharacter = function() {
  190.     return this._character.screenZ() <= 5 &&
  191.       this.edge[0] < Graphics._width && this.edge[2] > 0 &&
  192.       this.edge[1] < Graphics._height && this.edge[3] > 0;
  193.   };
  194.  
  195.   Sprite_Character.prototype.getEdgeRect = function() {
  196.     var x = this.x - Math.round(this.patternWidth() * this.anchor.x);
  197.     var y = this.y - Math.round(this.patternHeight() * this.anchor.y);
  198.     var w = x + this.patternWidth();
  199.     var h = y + this.patternHeight();
  200.     this.edge = [x, y, w, h];
  201.   };
  202.  
  203.   Sprite_Character.prototype.getEdgeTiles = function() {
  204.     var x = Math.floor((this.mx + this.edge[0]) / this.tw);
  205.     var y = Math.floor((this.my + this.edge[1]) / this.th);
  206.     var w = Math.floor((this.mx + this.edge[2]) / this.tw);
  207.     var h = Math.floor((this.my + this.edge[3]) / this.th);
  208.     this.edgeTiles = [x, y, w, h];
  209.   };
  210.  
  211.   Sprite_Character.prototype.getMapInfo = function() {
  212.     this.tw = $gameMap.tileWidth();
  213.     this.th = $gameMap.tileHeight();
  214.     this.mx = $gameMap.displayX() * this.tw;
  215.     this.my = $gameMap.displayY() * this.th;
  216.   };
  217. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement