Advertisement
Guest User

Tilemap_XP

a guest
Mar 9th, 2019
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 30.11 KB | None | 0 0
  1. class CustomTilemapAutotiles
  2.   attr_accessor :changed
  3.  
  4.   def initialize
  5.     @changed=true
  6.     @tiles=[nil,nil,nil,nil,nil,nil,nil]
  7.   end
  8.  
  9.   def []=(i,value)
  10.     @tiles[i]=value
  11.     @changed=true
  12.   end
  13.  
  14.   def [](i)
  15.     return @tiles[i]
  16.   end
  17. end
  18.  
  19.  
  20.  
  21. #Console::setup_console
  22. class CustomTilemapSprite < Sprite
  23. end
  24.  
  25.  
  26.  
  27. class CustomTilemap
  28.   Animated_Autotiles_Frames = 15 # Frequency of updating an animated autotile
  29.   Autotiles = [
  30.      [ [27, 28, 33, 34], [ 5, 28, 33, 34], [27,  6, 33, 34], [ 5,  6, 33, 34],
  31.        [27, 28, 33, 12], [ 5, 28, 33, 12], [27,  6, 33, 12], [ 5,  6, 33, 12] ],
  32.      [ [27, 28, 11, 34], [ 5, 28, 11, 34], [27,  6, 11, 34], [ 5,  6, 11, 34],
  33.        [27, 28, 11, 12], [ 5, 28, 11, 12], [27,  6, 11, 12], [ 5,  6, 11, 12] ],
  34.      [ [25, 26, 31, 32], [25,  6, 31, 32], [25, 26, 31, 12], [25,  6, 31, 12],
  35.        [15, 16, 21, 22], [15, 16, 21, 12], [15, 16, 11, 22], [15, 16, 11, 12] ],
  36.      [ [29, 30, 35, 36], [29, 30, 11, 36], [ 5, 30, 35, 36], [ 5, 30, 11, 36],
  37.        [39, 40, 45, 46], [ 5, 40, 45, 46], [39,  6, 45, 46], [ 5,  6, 45, 46] ],
  38.      [ [25, 30, 31, 36], [15, 16, 45, 46], [13, 14, 19, 20], [13, 14, 19, 12],
  39.        [17, 18, 23, 24], [17, 18, 11, 24], [41, 42, 47, 48], [ 5, 42, 47, 48] ],
  40.      [ [37, 38, 43, 44], [37,  6, 43, 44], [13, 18, 19, 24], [13, 14, 43, 44],
  41.        [37, 42, 43, 48], [17, 18, 47, 48], [13, 18, 43, 48], [ 1,  2,  7,  8] ]
  42.   ]
  43.   FlashOpacity=[100,90,80,70,80,90]
  44.   attr_reader :tileset
  45.   attr_reader :autotiles
  46.   attr_reader :map_data
  47.   attr_reader :flash_data
  48.   attr_reader :priorities
  49.   attr_reader :terrain_tags
  50.   attr_reader :visible
  51.   attr_accessor :ox
  52.   attr_accessor :oy
  53.   attr_reader :viewport
  54.   attr_accessor :tone
  55.   attr_accessor :color
  56.  
  57.   def graphicsHeight
  58.     return @graphicsHeight
  59.   end
  60.  
  61.   def graphicsWidth
  62.     return @graphicsWidth
  63.   end
  64.  
  65.   def initialize(viewport)
  66.     @tileset      = nil  # Refers to Map Tileset Name
  67.     @autotiles    = CustomTilemapAutotiles.new
  68.     @map_data     = nil  # Refers to 3D Array Of Tile Settings
  69.     @flash_data   = nil  # Refers to 3D Array of Tile Flashdata
  70.     @priorities   = nil  # Refers to Tileset Priorities
  71.     @terrain_tags = nil  # Refers to Tileset Terrain Tags
  72.     @visible      = true # Refers to Tileset Visibleness
  73.     @ox           = 0    # Bitmap Offsets
  74.     @oy           = 0    # bitmap Offsets
  75.     @plane        = false
  76.     @haveGraphicsWH = (Graphics.width!=nil rescue false)
  77.     if @haveGraphicsWH
  78.       @graphicsWidth  = Graphics.width
  79.       @graphicsHeight = Graphics.height
  80.     else
  81.       @graphicsWidth  = 640
  82.       @graphicsHeight = 480
  83.     end
  84.     @tileWidth  = Game_Map::TILEWIDTH rescue 32
  85.     @tileHeight = Game_Map::TILEHEIGHT rescue 32
  86.     @tileSrcWidth  = 32
  87.     @tileSrcHeight = 32
  88.     @diffsizes=(@tileWidth!=@tileSrcWidth) || (@tileHeight!=@tileSrcHeight)
  89.     @tone=Tone.new(0,0,0,0)
  90.     @color=Color.new(0,0,0,0)
  91.     @oldtone=Tone.new(0,0,0,0)
  92.     @oldcolor=Color.new(0,0,0,0)
  93.     @selfviewport=Viewport.new(0,0,graphicsWidth,graphicsHeight)
  94.     @viewport=viewport ? viewport : @selfviewport
  95.     @tiles=[]
  96.     @autotileInfo=[]
  97.     @regularTileInfo=[]
  98.     @oldOx=0
  99.     @oldOy=0
  100.     @oldViewportOx=0
  101.     @oldViewportOy=0
  102.     @layer0=CustomTilemapSprite.new(viewport)
  103.     @layer0.visible=true
  104.     @nowshown=false
  105.     @layer0.bitmap=Bitmap.new([graphicsWidth+320,1].max,[graphicsHeight+320,1].max)
  106.     @flash=nil
  107.     @layer0.ox=0
  108.     @layer0.oy=0
  109.     @oxLayer0=0
  110.     @oyLayer0=0
  111.     @oxFlash=0
  112.     @oyFlash=0
  113.     @layer0.z=0
  114.     @priotiles=[]
  115.     @priotilesfast=[]
  116.     @prioautotiles=[]
  117.     @autosprites=[]
  118.     @framecount=[0,0,0,0,0,0,0,0]
  119.     @tilesetChanged=true
  120.     @flashChanged=false
  121.     @firsttime=true
  122.     @disposed=false
  123.     @usedsprites=false
  124.     @layer0clip=true
  125.     @firsttimeflash=true
  126.     @fullyrefreshed=false
  127.     @fullyrefreshedautos=false
  128.   end
  129.  
  130.   def disposed?
  131.     return @disposed
  132.   end
  133.  
  134.   def flash_data=(value)
  135.     @flash_data=value
  136.     @flashChanged=true
  137.   end
  138.  
  139.   def priorities=(value)
  140.     @priorities=value
  141.     @tilesetChanged=true
  142.   end
  143.  
  144.   def terrain_tags=(value)
  145.     @terrain_tags=value
  146.     @tilesetChanged=true
  147.   end
  148.  
  149.   def tileset=(value)
  150.     @tileset=value
  151.     @tilesetChanged=true
  152.   end
  153.  
  154.   def update
  155.     if @haveGraphicsWH
  156.       @graphicsWidth=Graphics.width
  157.       @graphicsHeight=Graphics.height
  158.     end
  159.     if @oldtone!=@tone
  160.       @layer0.tone=@tone
  161.       @flash.tone=@tone if @flash
  162.       for sprite in @autosprites
  163.         sprite.tone=@tone if sprite.is_a?(Sprite)
  164.       end
  165.       for sprite in @tiles
  166.         sprite.tone=@tone if sprite.is_a?(Sprite)
  167.       end
  168.       @oldtone=@tone.clone
  169.     end
  170.     if @oldcolor!=@color
  171.       @layer0.color=@color
  172.       @flash.color=@color if @flash
  173.       for sprite in @autosprites
  174.         sprite.color=@color if sprite.is_a?(Sprite)
  175.       end
  176.       for sprite in @tiles
  177.         sprite.color=@color if sprite.is_a?(Sprite)
  178.       end
  179.       @oldcolor=@color.clone
  180.     end
  181.     if @autotiles.changed
  182.       refresh_autotiles
  183.       repaintAutotiles
  184.     end
  185.     if @flashChanged
  186.       refresh_flash
  187.     end
  188.     if @tilesetChanged
  189.       refresh_tileset
  190.     end
  191.     if @flash
  192.       @flash.opacity=FlashOpacity[(Graphics.frame_count/2) % 6]
  193.     end
  194.     mustrefresh=!(@oldOx==@ox && @oldOy==@oy &&
  195.        !@tilesetChanged && !@autotiles.changed)
  196.     if @viewport.ox!=@oldViewportOx || @viewport.oy!=@oldViewportOy
  197.       mustrefresh=true
  198.       @oldViewportOx=@viewport.ox
  199.       @oldViewportOy=@viewport.oy
  200.     end
  201.     if mustrefresh
  202.       refresh
  203.     end
  204.     if (Graphics.frame_count % Animated_Autotiles_Frames == 0) || @nowshown
  205.       repaintAutotiles
  206.       refresh(true)
  207.     end
  208.     @nowshown=false
  209.     @autotiles.changed=false
  210.     @tilesetChanged=false
  211.   end
  212.  
  213.   def shown?
  214.     return false if !@visible
  215.     ysize=@map_data.ysize
  216.     xsize=@map_data.xsize
  217.     xStart=(@ox/@tileWidth)-1
  218.     xEnd=((@ox+@viewport.rect.width)/@tileWidth)+1
  219.     yStart=(@oy/@tileHeight)-1
  220.     yEnd=((@oy+@viewport.rect.height)/@tileHeight)+1
  221.     xStart=0 if xStart<0
  222.     xStart=xsize-1 if xStart>=xsize
  223.     xEnd=0 if xEnd<0
  224.     xEnd=xsize-1 if xEnd>=xsize
  225.     yStart=0 if yStart<0
  226.     yStart=ysize-1 if yStart>=ysize
  227.     yEnd=0 if yEnd<0
  228.     yEnd=ysize-1 if yEnd>=ysize
  229.     return (xStart<xEnd && yStart<yEnd)
  230.   end
  231.  
  232.   def dispose
  233.     return if disposed?
  234.     @help.dispose if @help
  235.     @help=nil
  236.     i=0;len=@autotileInfo.length;while i<len
  237.       if @autotileInfo[i]
  238.         @autotileInfo[i].dispose
  239.         @autotileInfo[i]=nil
  240.       end
  241.       i+=1
  242.     end
  243.     i=0;len=@regularTileInfo.length;while i<len
  244.       if @regularTileInfo[i]
  245.         @regularTileInfo[i].dispose
  246.         @regularTileInfo[i]=nil
  247.       end
  248.       i+=1
  249.     end
  250.     i=0;len=@tiles.length;while i<len
  251.       @tiles[i].dispose
  252.       @tiles[i]=nil
  253.       i+=2
  254.     end
  255.     i=0;len=@autosprites.length;while i<len
  256.       @autosprites[i].dispose
  257.       @autosprites[i]=nil
  258.       i+=2
  259.     end
  260.     if @layer0
  261.       @layer0.bitmap.dispose if !@layer0.disposed?
  262.       @layer0.bitmap=nil if !@layer0.disposed?
  263.       @layer0.dispose
  264.       @layer0=nil
  265.     end
  266.     if @flash
  267.       @flash.bitmap.dispose if !@flash.disposed?
  268.       @flash.bitmap=nil if !@flash.disposed?
  269.       @flash.dispose
  270.       @flash=nil
  271.     end
  272.     for i in 0...7
  273.       self.autotiles[i]=nil
  274.     end
  275.     @tiles.clear
  276.     @autosprites.clear
  277.     @autotileInfo.clear
  278.     @regularTileInfo.clear
  279.     @tilemap=nil
  280.     @tileset=nil
  281.     @priorities=nil
  282.     @selfviewport.dispose
  283.     @selfviewport=nil
  284.     @disposed=true
  285.   end
  286.  
  287.   def bltAutotile(bitmap,x,y,id,frame)
  288.     return if frame<0
  289.     autotile=@autotiles[id/48-1]
  290.     return if !autotile || autotile.disposed?
  291.     if autotile.height==@tileSrcHeight
  292.       anim=frame*@tileSrcWidth
  293.       src_rect=Rect.new(anim,0,@tileSrcWidth,@tileSrcHeight)
  294.       if @diffsizes
  295.         bitmap.stretch_blt(Rect.new(x,y,@tileWidth,@tileHeight),autotile,src_rect)
  296.       else
  297.         bitmap.blt(x,y,autotile,src_rect)
  298.       end
  299.     else
  300.       anim=frame*3*@tileSrcWidth
  301.       id%=48
  302.       tiles = Autotiles[id>>3][id&7]
  303.       src=Rect.new(0,0,0,0)
  304.       halfTileWidth=@tileWidth>>1
  305.       halfTileHeight=@tileHeight>>1
  306.       halfTileSrcWidth=@tileSrcWidth>>1
  307.       halfTileSrcHeight=@tileSrcHeight>>1
  308.       for i in 0...4
  309.         tile_position = tiles[i] - 1
  310.         src.set( (tile_position % 6)*halfTileSrcWidth + anim,
  311.            (tile_position / 6)*halfTileSrcHeight, halfTileSrcWidth, halfTileSrcHeight)
  312.         if @diffsizes
  313.           bitmap.stretch_blt(
  314.              Rect.new(i%2*halfTileWidth+x,i/2*halfTileHeight+y,halfTileWidth,halfTileHeight),
  315.              autotile,src)
  316.         else
  317.           bitmap.blt(i%2*halfTileWidth+x,i/2*halfTileHeight+y, autotile, src)
  318.         end
  319.       end
  320.     end
  321.   end
  322.  
  323.   def autotileNumFrames(id)
  324.     autotile=@autotiles[id/48-1]
  325.     return 0 if !autotile || autotile.disposed?
  326.     frames=1
  327.     if autotile.height==@tileHeight
  328.       frames=autotile.width/@tileWidth
  329.     else
  330.       frames=autotile.width/(3*@tileWidth)
  331.     end
  332.     return frames
  333.   end
  334.  
  335.   def autotileFrame(id)
  336.     autotile=@autotiles[id/48-1]
  337.     return -1 if !autotile || autotile.disposed?
  338.     frames=1
  339.     if autotile.height==@tileHeight
  340.       frames=autotile.width/@tileWidth
  341.     else
  342.       frames=autotile.width/(3*@tileWidth)
  343.     end
  344.     return (Graphics.frame_count/Animated_Autotiles_Frames)%frames
  345.   end
  346.  
  347.   def repaintAutotiles
  348.     for i in 0...@autotileInfo.length
  349.       next if !@autotileInfo[i]
  350.       frame=autotileFrame(i)
  351.       @autotileInfo[i].clear
  352.       bltAutotile(@autotileInfo[i],0,0,i,frame)
  353.     end
  354.   end
  355.  
  356.   def getAutotile(sprite,id)
  357.     frames=@framecount[id/48-1]
  358.     if frames<=1
  359.       anim=0
  360.     else
  361.       anim=(Graphics.frame_count/Animated_Autotiles_Frames)%frames
  362.     end
  363.     return if anim<0
  364.     bitmap=@autotileInfo[id]
  365.     if !bitmap
  366.        bitmap=Bitmap.new(@tileWidth,@tileHeight)
  367.        bltAutotile(bitmap,0,0,id,anim)
  368.        @autotileInfo[id]=bitmap
  369.     end
  370.     sprite.bitmap=bitmap if sprite.bitmap!=bitmap
  371.   end
  372.  
  373.   def getRegularTile(sprite,id)
  374.     if !@diffsizes
  375.       sprite.bitmap=@tileset if sprite.bitmap!=@tileset
  376.       sprite.src_rect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
  377.          @tileSrcWidth,@tileSrcHeight)
  378.     else
  379.       bitmap=@regularTileInfo[id]
  380.       if !bitmap
  381.         bitmap=Bitmap.new(@tileWidth,@tileHeight)
  382.         rect=Rect.new(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
  383.            @tileSrcWidth,@tileSrcHeight)
  384.         bitmap.stretch_blt(Rect.new(0,0,@tileWidth,@tileHeight),@tileset,rect)
  385.         @regularTileInfo[id]=bitmap
  386.       end
  387.       sprite.bitmap=bitmap if sprite.bitmap!=bitmap
  388.     end
  389.   end
  390.  
  391.   def addTile(tiles,count,xpos,ypos,id)
  392.     if id>=384
  393.       if count>=tiles.length
  394.         sprite=CustomTilemapSprite.new(@viewport)
  395.         tiles.push(sprite,0)
  396.       else
  397.         sprite=tiles[count]
  398.         tiles[count+1]=0
  399.       end
  400.       sprite.visible=@visible
  401.       sprite.x=xpos
  402.       sprite.y=ypos
  403.       sprite.tone=@tone
  404.       sprite.color=@color
  405.       getRegularTile(sprite,id)
  406.       spriteZ=(!@priorities[id] || @priorities[id]==0) ? 0 : ypos+@priorities[id]*32+32
  407.       spriteZ=1 if @priorities[id]==4 && $PokemonGlobal && $PokemonGlobal.bridge>0
  408.       spriteZ=-100 if PBTerrain.hasReflections?(@terrain_tags[id])
  409.       sprite.z=spriteZ
  410.       count+=2
  411.     else
  412.       if count>=tiles.length
  413.         sprite=CustomTilemapSprite.new(@viewport)
  414.         tiles.push(sprite,1)
  415.       else
  416.         sprite=tiles[count]
  417.         tiles[count+1]=1
  418.       end
  419.       sprite.visible=@visible
  420.       sprite.x=xpos
  421.       sprite.y=ypos
  422.       sprite.tone=@tone
  423.       sprite.color=@color
  424.       getAutotile(sprite,id)
  425.       spriteZ=(!@priorities[id] || @priorities[id]==0) ? 0 : ypos+@priorities[id]*32+32
  426.       spriteZ=1 if @priorities[id]==4 && $PokemonGlobal && $PokemonGlobal.bridge>0
  427.       spriteZ=-100 if PBTerrain.hasReflections?(@terrain_tags[id])
  428.       sprite.z=spriteZ
  429.       count+=2
  430.     end
  431.     return count
  432.   end
  433.  
  434.   def refresh_tileset
  435.     i=0; len=@regularTileInfo.length; while i<len
  436.       if @regularTileInfo[i]
  437.         @regularTileInfo[i].dispose
  438.         @regularTileInfo[i]=nil
  439.       end
  440.       i+=1
  441.     end
  442.     @regularTileInfo.clear
  443.     @priotiles.clear
  444.     ysize=@map_data.ysize
  445.     xsize=@map_data.xsize
  446.     zsize=@map_data.zsize
  447.     if xsize>100 || ysize>100
  448.       @fullyrefreshed=false
  449.     else
  450.       for z in 0...zsize
  451.         for y in 0...ysize
  452.           for x in 0...xsize
  453.             id = @map_data[x, y, z]
  454.             next if id==0 || !@priorities[id]
  455.             next if @priorities[id]==0 && !PBTerrain.hasReflections?(@terrain_tags[id])
  456.             @priotiles.push([x,y,z,id])
  457.           end
  458.         end
  459.       end
  460.       @fullyrefreshed=true
  461.     end
  462.   end
  463.  
  464.   def refresh_flash
  465.     if @flash_data && !@flash
  466.       @flash=CustomTilemapSprite.new(viewport)
  467.       @flash.visible=true
  468.       @flash.z=1
  469.       @flash.tone=tone
  470.       @flash.color=color
  471.       @flash.blend_type=1
  472.       @flash.bitmap=Bitmap.new([graphicsWidth*2,1].max,[graphicsHeight*2,1].max)
  473.       @firsttimeflash=true
  474.     elsif !@flash_data && @flash
  475.       @flash.bitmap.dispose if @flash.bitmap
  476.       @flash.dispose
  477.       @flash=nil
  478.       @firsttimeflash=false
  479.     end
  480.   end
  481.  
  482.   def refresh_autotiles
  483.     i=0;len=@autotileInfo.length;while i<len
  484.       if @autotileInfo[i]
  485.         @autotileInfo[i].dispose
  486.         @autotileInfo[i]=nil
  487.       end
  488.       i+=1
  489.     end
  490.     i=0;len=@autosprites.length;while i<len
  491.       if @autosprites[i]
  492.         @autosprites[i].dispose
  493.         @autosprites[i]=nil
  494.       end
  495.       i+=2
  496.     end
  497.     @autosprites.clear
  498.     @autotileInfo.clear
  499.     @prioautotiles.clear
  500.     @priorect=nil
  501.     @priorectautos=nil
  502.     hasanimated=false
  503.     for i in 0...7
  504.       numframes=autotileNumFrames(48*(i+1))
  505.       hasanimated=true if numframes>=2
  506.       @framecount[i]=numframes
  507.     end
  508.     if hasanimated
  509.       ysize=@map_data.ysize
  510.       xsize=@map_data.xsize
  511.       zsize=@map_data.zsize
  512.       if xsize>100 || ysize>100
  513.         @fullyrefreshedautos=false
  514.       else
  515.         for y in 0...ysize
  516.           for x in 0...xsize
  517.             haveautotile=false
  518.             for z in 0...zsize
  519.               id = @map_data[x, y, z]
  520.               next if id==0 || id>=384 || !@priorities[id]
  521.               next if @priorities[id]!=0 || PBTerrain.hasReflections?(@terrain_tags[id])
  522.               next if @framecount[id/48-1]<2
  523.               haveautotile=true
  524.               break
  525.             end
  526.             @prioautotiles.push([x,y]) if haveautotile
  527.           end
  528.         end
  529.         @fullyrefreshedautos=true
  530.       end
  531.     else
  532.       @fullyrefreshedautos=true
  533.     end
  534.   end
  535.  
  536.   def map_data=(value)
  537.     @map_data=value
  538.     @tilesetChanged=true
  539.   end
  540.  
  541.   def refreshFlashSprite
  542.     return if !@flash || @flash_data.nil?
  543.     ptX=@ox-@oxFlash
  544.     ptY=@oy-@oyFlash
  545.     if !@firsttimeflash && !@usedsprites &&
  546.        ptX>=0 && ptX+@viewport.rect.width<=@flash.bitmap.width &&
  547.        ptY>=0 && ptY+@viewport.rect.height<=@flash.bitmap.height
  548.       @flash.ox=0
  549.       @flash.oy=0
  550.       @flash.src_rect.set(ptX.round,ptY.round,
  551.          @viewport.rect.width,@viewport.rect.height)
  552.       return
  553.     end
  554.     width=@flash.bitmap.width
  555.     height=@flash.bitmap.height
  556.     bitmap=@flash.bitmap
  557.     ysize=@map_data.ysize
  558.     xsize=@map_data.xsize
  559.     zsize=@map_data.zsize
  560.     @firsttimeflash=false
  561.     @oxFlash=@ox-(width>>2)
  562.     @oyFlash=@oy-(height>>2)
  563.     @flash.ox=0
  564.     @flash.oy=0
  565.     @flash.src_rect.set(width>>2,height>>2,
  566.        @viewport.rect.width,@viewport.rect.height)
  567.     @flash.bitmap.clear
  568.     @oxFlash=@oxFlash.floor
  569.     @oyFlash=@oyFlash.floor
  570.     xStart=(@oxFlash/@tileWidth)
  571.     xStart=0 if xStart<0
  572.     yStart=(@oyFlash/@tileHeight)
  573.     yStart=0 if yStart<0
  574.     xEnd=xStart+(width/@tileWidth)+1
  575.     yEnd=yStart+(height/@tileHeight)+1
  576.     xEnd=xsize if xEnd>=xsize
  577.     yEnd=ysize if yEnd>=ysize
  578.     if xStart<xEnd && yStart<yEnd
  579.       yrange=yStart...yEnd
  580.       xrange=xStart...xEnd
  581.       tmpcolor=Color.new(0,0,0,0)
  582.       for y in yrange
  583.         ypos=(y*@tileHeight)-@oyFlash
  584.         for x in xrange
  585.           xpos=(x*@tileWidth)-@oxFlash
  586.           id = @flash_data[x, y, 0]
  587.           r=(id>>8)&15
  588.           g=(id>>4)&15
  589.           b=(id)&15
  590.           tmpcolor.set(r<<4,g<<4,b<<4)
  591.           bitmap.fill_rect(xpos,ypos,@tileWidth,@tileHeight,tmpcolor)
  592.         end
  593.       end
  594.     end
  595.   end
  596.  
  597.   def refreshLayer0(autotiles=false)
  598.     if autotiles
  599.       return true if !shown?
  600.     end
  601.     ptX=@ox-@oxLayer0
  602.     ptY=@oy-@oyLayer0
  603.     if !autotiles && !@firsttime && !@usedsprites &&
  604.        ptX>=0 && ptX+@viewport.rect.width<=@layer0.bitmap.width &&
  605.        ptY>=0 && ptY+@viewport.rect.height<=@layer0.bitmap.height
  606.       if @layer0clip && @viewport.ox==0 && @viewport.oy==0
  607.         @layer0.ox=0
  608.         @layer0.oy=0
  609.         @layer0.src_rect.set(ptX.round,ptY.round,
  610.            @viewport.rect.width,@viewport.rect.height)
  611.       else
  612.         @layer0.ox=ptX.round
  613.         @layer0.oy=ptY.round
  614.         @layer0.src_rect.set(0,0,@layer0.bitmap.width,@layer0.bitmap.height)
  615.       end
  616.       return true
  617.     end
  618.     width=@layer0.bitmap.width
  619.     height=@layer0.bitmap.height
  620.     bitmap=@layer0.bitmap
  621.     ysize=@map_data.ysize
  622.     xsize=@map_data.xsize
  623.     zsize=@map_data.zsize
  624.     twidth=@tileWidth
  625.     theight=@tileHeight
  626.     mapdata=@map_data
  627.     if autotiles
  628.       return true if @fullyrefreshedautos && @prioautotiles.length==0
  629.       xStart=(@oxLayer0/twidth)
  630.       xStart=0 if xStart<0
  631.       yStart=(@oyLayer0/theight)
  632.       yStart=0 if yStart<0
  633.       xEnd=xStart+(width/twidth)+1
  634.       yEnd=yStart+(height/theight)+1
  635.       xEnd=xsize if xEnd>xsize
  636.       yEnd=ysize if yEnd>ysize
  637.       return true if xStart>=xEnd || yStart>=yEnd
  638.       trans=Color.new(0,0,0,0)
  639.       temprect=Rect.new(0,0,0,0)
  640.       tilerect=Rect.new(0,0,twidth,theight)
  641.       zrange=0...zsize
  642.       overallcount=0
  643.       count=0
  644.       if !@fullyrefreshedautos
  645.         for y in yStart..yEnd
  646.           for x in xStart..xEnd
  647.             haveautotile=false
  648.             for z in zrange
  649.               id = mapdata[x, y, z]
  650.               next if !id || id<48 || id>=384
  651.               prioid=@priorities[id]
  652.               next if !prioid || prioid!=0 || PBTerrain.hasReflections?(@terrain_tags[id])
  653.               fcount=@framecount[id/48-1]
  654.               next if !fcount || fcount<2
  655.               if !haveautotile
  656.                 haveautotile=true
  657.                 overallcount+=1
  658.                 xpos=(x*twidth)-@oxLayer0
  659.                 ypos=(y*theight)-@oyLayer0
  660.                 bitmap.fill_rect(xpos,ypos,twidth,theight,trans) if overallcount<=2000
  661.                 break
  662.               end
  663.             end
  664.             for z in zrange
  665.               id = mapdata[x,y,z]
  666.               next if !id || id<48
  667.               prioid=@priorities[id]
  668.               next if !prioid || prioid!=0 || PBTerrain.hasReflections?(@terrain_tags[id])
  669.               if overallcount>2000
  670.                 xpos=(x*twidth)-@oxLayer0
  671.                 ypos=(y*theight)-@oyLayer0
  672.                 count=addTile(@autosprites,count,xpos,ypos,id)
  673.                 next
  674.               elsif id>=384
  675.                 temprect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
  676.                    @tileSrcWidth,@tileSrcHeight)
  677.                 xpos=(x*twidth)-@oxLayer0
  678.                 ypos=(y*theight)-@oyLayer0
  679.                 if @diffsizes
  680.                   bitmap.stretch_blt(Rect.new(xpos,ypos,twidth,theight),@tileset,temprect)
  681.                 else
  682.                   bitmap.blt(xpos,ypos,@tileset,temprect)
  683.                 end
  684.               else
  685.                 tilebitmap=@autotileInfo[id]
  686.                 if !tilebitmap
  687.                   anim=autotileFrame(id)
  688.                   next if anim<0
  689.                   tilebitmap=Bitmap.new(twidth,theight)
  690.                   bltAutotile(tilebitmap,0,0,id,anim)
  691.                   @autotileInfo[id]=tilebitmap
  692.                 end
  693.                 xpos=(x*twidth)-@oxLayer0
  694.                 ypos=(y*theight)-@oyLayer0
  695.                 bitmap.blt(xpos,ypos,tilebitmap,tilerect)
  696.               end
  697.             end
  698.           end
  699.         end
  700.         Graphics.frame_reset
  701.       else
  702.         if !@priorect || !@priorectautos || @priorect[0]!=xStart ||
  703.            @priorect[1]!=yStart ||
  704.            @priorect[2]!=xEnd ||
  705.            @priorect[3]!=yEnd
  706.           @priorectautos=@prioautotiles.find_all{|tile|
  707.              x=tile[0]
  708.              y=tile[1]
  709.              # "next" means "return" here
  710.              next !(x<xStart || x>xEnd || y<yStart || y>yEnd)
  711.           }
  712.           @priorect=[xStart,yStart,xEnd,yEnd]
  713.         end
  714.    #   echoln ["autos",@priorect,@priorectautos.length,@prioautotiles.length]
  715.         for tile in @priorectautos
  716.           x=tile[0]
  717.           y=tile[1]
  718.           overallcount+=1
  719.           xpos=(x*twidth)-@oxLayer0
  720.           ypos=(y*theight)-@oyLayer0
  721.           bitmap.fill_rect(xpos,ypos,twidth,theight,trans)
  722.           z=0
  723.           while z<zsize
  724.             id = mapdata[x,y,z]
  725.             z+=1
  726.             next if !id || id<48
  727.             prioid=@priorities[id]
  728.             next if !prioid || prioid!=0 || PBTerrain.hasReflections?(@terrain_tags[id])
  729.             if id>=384
  730.               temprect.set(((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
  731.                  @tileSrcWidth,@tileSrcHeight)
  732.               if @diffsizes
  733.                 bitmap.stretch_blt(Rect.new(xpos,ypos,twidth,theight),@tileset,temprect)
  734.               else
  735.                 bitmap.blt(xpos,ypos,@tileset,temprect)
  736.               end
  737.             else
  738.               tilebitmap=@autotileInfo[id]
  739.               if !tilebitmap
  740.                 anim=autotileFrame(id)
  741.                 next if anim<0
  742.                 tilebitmap=Bitmap.new(twidth,theight)
  743.                 bltAutotile(tilebitmap,0,0,id,anim)
  744.                 @autotileInfo[id]=tilebitmap
  745.               end
  746.               bitmap.blt(xpos,ypos,tilebitmap,tilerect)
  747.             end
  748.           end
  749.         end
  750.         Graphics.frame_reset if overallcount>500
  751.       end
  752.       @usedsprites=false
  753.       return true
  754.     end
  755.     return false if @usedsprites
  756.     @firsttime=false
  757.     @oxLayer0=@ox-(width>>2)
  758.     @oyLayer0=@oy-(height>>2)
  759.     if @layer0clip
  760.       @layer0.ox=0
  761.       @layer0.oy=0
  762.       @layer0.src_rect.set(width>>2,height>>2,
  763.          @viewport.rect.width,@viewport.rect.height)
  764.     else
  765.       @layer0.ox=(width>>2)
  766.       @layer0.oy=(height>>2)
  767.     end
  768.     @layer0.bitmap.clear
  769.     @oxLayer0=@oxLayer0.floor
  770.     @oyLayer0=@oyLayer0.floor
  771.     xStart=(@oxLayer0/twidth)
  772.     xStart=0 if xStart<0
  773.     yStart=(@oyLayer0/theight)
  774.     yStart=0 if yStart<0
  775.     xEnd=xStart+(width/twidth)+1
  776.     yEnd=yStart+(height/theight)+1
  777.     xEnd=xsize if xEnd>=xsize
  778.     yEnd=ysize if yEnd>=ysize
  779.     if xStart<xEnd && yStart<yEnd
  780.       tmprect=Rect.new(0,0,0,0)
  781.       yrange=yStart...yEnd
  782.       xrange=xStart...xEnd
  783.       for z in 0...zsize
  784.         for y in yrange
  785.           ypos=(y*theight)-@oyLayer0
  786.           for x in xrange
  787.             xpos=(x*twidth)-@oxLayer0
  788.             id = mapdata[x, y, z]
  789.             next if id==0 || !@priorities[id] || @priorities[id]!=0 ||
  790.                PBTerrain.hasReflections?(@terrain_tags[id])
  791.             if id>=384
  792.               tmprect.set( ((id - 384)&7)*@tileSrcWidth,((id - 384)>>3)*@tileSrcHeight,
  793.                  @tileSrcWidth,@tileSrcHeight)
  794.               if @diffsizes
  795.                 bitmap.stretch_blt(Rect.new(xpos,ypos,twidth,theight),@tileset,tmprect)
  796.               else
  797.                 bitmap.blt(xpos,ypos,@tileset,tmprect)
  798.               end
  799.             else
  800.               frames=@framecount[id/48-1]
  801.               if frames<=1
  802.                 frame=0
  803.               else
  804.                 frame=(Graphics.frame_count/Animated_Autotiles_Frames)%frames
  805.               end
  806.               bltAutotile(bitmap,xpos,ypos,id,frame)
  807.             end
  808.           end
  809.         end
  810.       end
  811.       Graphics.frame_reset
  812.     end
  813.     return true
  814.   end
  815.  
  816.   def getResizeFactor
  817.     return $ResizeFactor ? $ResizeFactor : 1.0
  818.   end
  819.  
  820.   def ox=(val)
  821.     rf=getResizeFactor
  822.     if rf!=1.0
  823.       val=(val*rf).to_i
  824.       val=(val/rf).to_i
  825.     end
  826.     wasshown=self.shown?
  827.     @ox=val.floor
  828.     @nowshown=(!wasshown && self.shown?)
  829.   end
  830.  
  831.   def oy=(val)
  832.     rf=getResizeFactor
  833.     if rf!=1.0
  834.       val=(val*rf).to_i
  835.       val=(val/rf).to_i
  836.     end
  837.     wasshown=self.shown?
  838.     @oy=val.floor
  839.     @nowshown=(!wasshown && self.shown?)
  840.   end
  841.  
  842.   def visible=(val)
  843.     wasshown=@visible
  844.     @visible=val
  845.     @nowshown=(!wasshown && val)
  846.   end
  847.  
  848.   def refresh(autotiles=false)
  849.     @oldOx=@ox
  850.     @oldOy=@oy
  851.     usesprites=false
  852.     if @layer0
  853.       @layer0.visible=@visible
  854.       usesprites=!refreshLayer0(autotiles)
  855.       if autotiles && !usesprites
  856.         return
  857.       end
  858.     else
  859.       usesprites=true
  860.     end
  861.     refreshFlashSprite
  862.     vpx=@viewport.rect.x
  863.     vpy=@viewport.rect.y
  864.     vpr=@viewport.rect.width+vpx
  865.     vpb=@viewport.rect.height+vpy
  866.     xsize=@map_data.xsize
  867.     ysize=@map_data.ysize
  868.     minX=(@ox/@tileWidth)-1
  869.     maxX=((@ox+@viewport.rect.width)/@tileWidth)+1
  870.     minY=(@oy/@tileHeight)-1
  871.     maxY=((@oy+@viewport.rect.height)/@tileHeight)+1
  872.     minX=0 if minX<0
  873.     minX=xsize-1 if minX>=xsize
  874.     maxX=0 if maxX<0
  875.     maxX=xsize-1 if maxX>=xsize
  876.     minY=0 if minY<0
  877.     minY=ysize-1 if minY>=ysize
  878.     maxY=0 if maxY<0
  879.     maxY=ysize-1 if maxY>=ysize
  880.     count=0
  881.     if minX<maxX && minY<maxY
  882.       @usedsprites=usesprites || @usedsprites
  883.       if @layer0
  884.         @layer0.visible=false if usesprites
  885.       end
  886.       if @fullyrefreshed
  887.         if !@priotilesrect || !@priotilesfast ||
  888.            @priotilesrect[0]!=minX ||
  889.            @priotilesrect[1]!=minY ||
  890.            @priotilesrect[2]!=maxX ||
  891.            @priotilesrect[3]!=maxY
  892.           @priotilesfast=@priotiles.find_all{|tile|
  893.              x=tile[0]
  894.              y=tile[1]
  895.              # "next" means "return" here
  896.              next !(x<minX || x>maxX || y<minY || y>maxY)
  897.           }
  898.           @priotilesrect=[minX,minY,maxX,maxY]
  899.         end
  900.         #   echoln [minX,minY,maxX,maxY,@priotilesfast.length,@priotiles.length]
  901.         for prio in @priotilesfast
  902.           xpos=(prio[0]*@tileWidth)-@ox
  903.           ypos=(prio[1]*@tileHeight)-@oy
  904.           count=addTile(@tiles,count,xpos,ypos,prio[3])
  905.         end
  906.       else
  907.         if !@priotilesrect || !@priotilesfast ||
  908.            @priotilesrect[0]!=minX ||
  909.            @priotilesrect[1]!=minY ||
  910.            @priotilesrect[2]!=maxX ||
  911.            @priotilesrect[3]!=maxY
  912.           @priotilesfast=[]
  913.           for z in 0...@map_data.zsize
  914.             for y in minY..maxY
  915.               for x in minX..maxX
  916.                 id = @map_data[x, y, z]
  917.                 next if id==0 || !@priorities[id]
  918.                 next if @priorities[id]==0 && !PBTerrain.hasReflections?(@terrain_tags[id])
  919.                 @priotilesfast.push([x,y,z,id])
  920.               end
  921.             end
  922.           end
  923.           @priotilesrect=[minX,minY,maxX,maxY]
  924.         end
  925.         for prio in @priotilesfast
  926.           xpos=(prio[0]*@tileWidth)-@ox
  927.           ypos=(prio[1]*@tileHeight)-@oy
  928.           count=addTile(@tiles,count,xpos,ypos,prio[3])
  929.         end
  930.       end
  931.     end
  932.     if count<@tiles.length
  933.       bigchange=(count<=(@tiles.length*2/3)) && (@tiles.length*2/3)>25
  934.       j=count; len=@tiles.length; while j<len
  935.         sprite=@tiles[j]
  936.         @tiles[j+1]=-1
  937.         if bigchange
  938.           sprite.dispose
  939.           @tiles[j]=nil
  940.           @tiles[j+1]=nil
  941.         elsif !@tiles[j].disposed?
  942.           sprite.visible=false if sprite.visible
  943.         end
  944.         j+=2
  945.       end
  946.       @tiles.compact! if bigchange
  947.     end
  948.   end
  949. end
  950.  
  951.  
  952.  
  953. class SynchronizedTilemapAutotilesInternal
  954.   def initialize(oldat)
  955.     @atdisposables=[[],[],[],[],[],[],[]]
  956.     @atframes=[[],[],[],[],[],[],[]]
  957.     @atframe=[-1,-1,-1,-1,-1,-1,-1]
  958.     @autotiles=[]
  959.     @oldat=oldat
  960.   end
  961.  
  962.   def dispose
  963.     for i in 0...7
  964.       for bitmap in @atdisposables[i]
  965.         bitmap.dispose
  966.       end
  967.       @atdisposables[i].clear
  968.       @atframes[i].clear
  969.     end
  970.   end
  971.  
  972.   def [](i)
  973.     return @autotiles[i]
  974.   end
  975.  
  976.   def []=(i,value)
  977.     for frame in @atdisposables[i]
  978.       frame.dispose
  979.     end
  980.     @atframe[i]=-1
  981.     @atframes[i].clear
  982.     @atdisposables[i].clear
  983.     if value && !value.disposed?
  984.       if value.height==32
  985.         frames=value.width/32
  986.         for j in 0...frames
  987.           @atdisposables[i][j]=Bitmap.new(32,32)
  988.           @atdisposables[i][j].blt(0,0,value,Rect.new(j*32,0,32,32))
  989.           @atframes[i][j]=@atdisposables[i][j]
  990.         end
  991.       elsif value.height==128
  992.         frames=value.width/96
  993.         for j in 0...frames
  994.           @atdisposables[i][j]=Bitmap.new(96,128)
  995.           @atdisposables[i][j].blt(0,0,value,Rect.new(j*96,0,96,128))
  996.           @atframes[i][j]=@atdisposables[i][j]
  997.         end
  998.       else
  999.         @atframes[i][0]=value
  1000.       end
  1001.     else
  1002.       @atframes[i][0]=value
  1003.     end
  1004.     @autotiles[i]=value
  1005.     sync
  1006.   end
  1007.  
  1008.   def sync
  1009.     frameused=[]
  1010.     for i in 0...7
  1011.       frames=[1,@atframes[i].length].max
  1012.       frame=(Graphics.frame_count/15)%frames
  1013.       if frames>1 && @atframe[i]!=frame
  1014.         @oldat[i]=@atframes[i][frame]
  1015.         @atframe[i]=frame
  1016.       end
  1017.     end
  1018.   end
  1019. end
  1020.  
  1021.  
  1022.  
  1023. class SynchronizedTilemapAutotiles
  1024.   def initialize(autotiles)
  1025.     @autotiles=autotiles
  1026.   end
  1027.  
  1028.   def [](i)
  1029.     @autotiles[i]
  1030.   end
  1031.  
  1032.   def []=(i,value)
  1033.     @autotiles[i]=value
  1034.   end
  1035. end
  1036.  
  1037.  
  1038.  
  1039. class SynchronizedTilemap < Tilemap
  1040.   # This class derives from Tilemap just to synchronize
  1041.   # the tilemap animation.
  1042.   attr_accessor :numupdates
  1043.  
  1044.   def initialize(viewport=nil)
  1045.     super(viewport)
  1046.     @updating=true
  1047.     @autotiles=SynchronizedTilemapAutotilesInternal.new(self.autotiles)
  1048.     @autos=SynchronizedTilemapAutotiles.new(@autotiles)
  1049.     @updating=false
  1050.   end
  1051.  
  1052.   def dispose
  1053.     @autotiles.dispose
  1054.     super
  1055.   end
  1056.  
  1057.   def autotiles
  1058.     if @updating
  1059.       super
  1060.     else
  1061.       return @autos
  1062.     end  
  1063.   end
  1064.  
  1065.   def update
  1066.    return if disposed?
  1067.    @autotiles.sync
  1068.    super
  1069.   end
  1070. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement