Tint_rect(target_rect)

● ARCHIVED · READ-ONLY
Started by Baibu 5 posts View original ↗
  1. Hi!
    I am trying to dynamically add a tone (similar to the 'Tint Screen' event command) to only a certain area (rectangle) of the map.
    Changing the tone of all characters within the rect was simple:
    Code:
    class Sprite_Character
    
      alias update_alias update
      def update #because characters can walk into or out of the area
        update_alias
        you_in?(@my_given_rect, @character.x, @character.y)
          tone.gray = 255 #take the color away
        else
          tone.gray = 0 #reset color
        end
      end
    
      def you_in?(target_rect, x, y)
        #returns true if x,y is within target_rect
       end
    end

    Maybe not the most beautiful solution, but does the trick for now.
    Now my problem is: $game_map.data (and therefore the Tilemap) contains integers, not sprites, so I can't simply change the tone of each tile.
    I think I'll have to check for each tile of the map while it is drawn, but I can't find where this happens. Any ideas?
  2. I've moved this thread to Script Support. Thank you.

  3. It would probably be best to use regions. Put regions onto the area you want to change the tone, then code to change the tone for the areas for the region. Maybe someone can code this for you.
  4. You may have better luck with making a new viewport on the map scene for this purpose.
    You can than move this viewport around, change it's size and change it's tone when needed.
    Just make sure to put this viewport above @viewport1, which is the default viewport for displaying characters.
    Anything displayed below this viewport should get the tone change effect.
    You won't even need to get the characters' position to compare it with the viewport's position, nor will you need to adjust the character sprite's tone, because this effect is automatic.
    The only thing you need to do is to move and resize this viewport to the correct position, and change it's tone to whatever you like.

    Figuring out the Tilemap class' methods would take quite some time, since that class is hidden in the DLL of the engine, and the help files contain very little about it.
  5. @mlogan: Sorry, my mistake.

    @Sixth: Currently working on this solution. Originally tried to cut out that part of the map and paste it into a lower z viewport, but had exactly the problem you described. Resizing and moving the new viewport is probably cleaner anyway. Thanks for the hint!

    Update: Well, curses! That was MUCH easier. I did not realize that viewport.tone worked this way. Ok, this problem is solved.
    Thanks again!

    Update 2: The only problem seems to be that the tones of overlapping viewports seem to be additive? So to exclude an area from a lower viewport's tone (so normal and specified area can be tinted independently of each other), I'll have to cut and paste after all.

    Update 3: Here's my solution so far. It's far from perfect but it works. I had to copy all the character sprites so they can exist in both viewports. For now, only $game_map.screen.tone affects the parallax background (because I didn't want to copy that as well) and I'm not sure what 'Spriteset_Map::create_shadow' etc. even does, so I didn't touch it either.
    Code:
    #==============================================================================
    # ■ Spriteset_Map
    #==============================================================================
    
    class Spriteset_Map
     
      #--------------------------------------------------------------------------
      # alias method: create_viewports
      #--------------------------------------------------------------------------
      alias mapAreaTint_create_viewports create_viewports
      def create_viewports
        mapAreaTint_create_viewports
        #---
        @nullRect = Rect.new(0,0,0,0)
        #---
        @viewport1b = Viewport.new
        @viewport1b.z = @viewport1.z + 10
        @viewport1b.rect = @nullRect
      end
     
      #--------------------------------------------------------------------------
      # alias method: create_tilemap
      #--------------------------------------------------------------------------
      alias mapAreaTint_create_tilemap create_tilemap
      def create_tilemap
        @tilemap_tinted = Tilemap.new(@viewport1b)
        @tilemap_tinted.map_data = Table.new(0)
        #---
        mapAreaTint_create_tilemap
      end
     
      #--------------------------------------------------------------------------
      # alias method: load_tileset
      #--------------------------------------------------------------------------
      alias mapAreaTint_load_tileset load_tileset
      def load_tileset
        mapAreaTint_load_tileset
        #---
        @tileset.tileset_names.each_with_index do |name, i|
          @tilemap_tinted.bitmaps[i] = Cache.tileset(name)
        end
        @tilemap_tinted.flags = @tileset.flags
      end
     
      #--------------------------------------------------------------------------
      # alias method: create_characters
      #--------------------------------------------------------------------------
      alias mapAreaTint_create_characters create_characters
      def create_characters
        mapAreaTint_create_characters
        @character_sprites_tinted = []
        $game_map.events.values.each do |event|
          @character_sprites_tinted.push(Sprite_Character.new(@viewport1b, event))
        end
        $game_map.vehicles.each do |vehicle|
          @character_sprites_tinted.push(Sprite_Character.new(@viewport1b, vehicle))
        end
        $game_player.followers.reverse_each do |follower|
          @character_sprites_tinted.push(Sprite_Character.new(@viewport1b, follower))
        end
        @character_sprites_tinted.push(Sprite_Character.new(@viewport1b, $game_player))
        @map_id = $game_map.map_id
      end
     
      #--------------------------------------------------------------------------
      # alias method: update
      #--------------------------------------------------------------------------
      alias mapAreaTint_update update
      def update
        update_viewports_rect
        mapAreaTint_update
      end
        
      #--------------------------------------------------------------------------
      # new method: update_viewports_rect
      #--------------------------------------------------------------------------
      def update_viewports_rect
        if $game_map.screen.area_tint?
          viewport_rect = $game_map.screen.area_tint_rect.clone
          viewport_rect.width   = (viewport_rect.width + 1) * 32
          viewport_rect.height  = (viewport_rect.height + 1) * 32
          viewport_rect.x       *= 32
          viewport_rect.y       *= 32
          viewport_rect.x       -= ($game_map.display_x * 32)
          viewport_rect.y       -= ($game_map.display_y * 32)
          #---
          @viewport1b.rect = viewport_rect
        end
      end
     
      #--------------------------------------------------------------------------
      # alias method: update_tilemap
      #--------------------------------------------------------------------------
      alias mapAreaTint_update_tilemap update_tilemap
      def update_tilemap
        mapAreaTint_update_tilemap
        #---
        if $game_map.screen.area_tint?
          inside, outside = cut_from_mapdata($game_map.screen.area_tint_rect.clone)
          #---
          @tilemap.map_data = outside
          @tilemap_tinted.map_data = inside
        end
        #---
        @tilemap.update
      end
     
      #--------------------------------------------------------------------------
      # alias method: update_viewports
      #--------------------------------------------------------------------------
      alias mapAreaTint_update_viewports update_viewports
      def update_viewports
        mapAreaTint_update_viewports
        #---
        if $game_map.screen.area_tint?
          @viewport1b.tone.set($game_map.screen.area_tone)
          @viewport1b.ox = $game_map.screen.shake
          @viewport1b.update
        else
          @viewport1b.rect = @nullRect
        end
      end
     
      #--------------------------------------------------------------------------
      # alias method: update_characters
      #--------------------------------------------------------------------------
      alias mapAreaTint_update_characters update_characters
      def update_characters
        mapAreaTint_update_characters
        #---
        @character_sprites_tinted.each {|sprite| sprite.update }
      end
     
      #--------------------------------------------------------------------------
      # new method: cut_from_mapdata(rect)
      #   rect : Rect
      #   returns inside:Table, outside:Table
      #--------------------------------------------------------------------------
      def cut_from_mapdata(rect)
        outside = $game_map.data.clone
        inside = Table.new(rect.width + 1, rect.height + 1, outside.zsize)
        #---
        width = 0
        loop do
          break if width >= inside.xsize
          height = 0
          loop do
            break if height >= inside.ysize
            depth = 0
            loop do
              break if depth >= inside.zsize
              x = rect.x + width
              y = rect.y + height
              if (x >= 0) && (y >= 0) && (x < outside.xsize) && (y < outside.ysize)
                inside[width,height,depth] = outside[x,y,depth]
                #outside[x,y,depth] = 0
              end
              #---
              depth += 1
            end #/loop depth
            height += 1
          end #/loop height
          width += 1
        end #/loop width
        #---
        return inside, outside
      end
     
      #--------------------------------------------------------------------------
      # alias method: dispose_tilemap
      #--------------------------------------------------------------------------
      alias mapAreaTint_dispose_tilemap dispose_tilemap
      def dispose_tilemap
        mapAreaTint_dispose_tilemap
        #---
        @tilemap_tinted.dispose
      end
     
      #--------------------------------------------------------------------------
      # alias method: dispose_characters
      #--------------------------------------------------------------------------
      alias mapAreaTint_dispose_characters dispose_characters
      def dispose_characters
        mapAreaTint_dispose_characters
        #---
        @character_sprites_tinted.each {|sprite| sprite.dispose }
      end
    end # /Spriteset_Map
    
    #==============================================================================
    # ■ Game_Screen
    #==============================================================================
    
    class Game_Screen
     
      #--------------------------------------------------------------------------
      # new accessor: area_tint_rect, area_tone (readonly)
      #--------------------------------------------------------------------------
      attr_reader :area_tint_rect
      attr_reader :area_tone
     
      #--------------------------------------------------------------------------
      # alias method: initialize
      #--------------------------------------------------------------------------
      alias mapAreaTint_initialize initialize
      def initialize
        mapAreaTint_initialize
        #---
        @area_tint_rect = nil
        @area_tone = nil
        @area_tone_target = nil
        @area_tone_duration = -1
      end
     
      #--------------------------------------------------------------------------
      # new method: set_area_tint(rect, tone, duration)
      #--------------------------------------------------------------------------
      def set_area_tint(rect, tone, duration)
        @area_tint_rect = rect
        @area_tone_target = tone.clone
        @area_tone_duration = duration
        #---
        @area_tone = @area_tone_target.clone if duration <= 0
      end
     
      #--------------------------------------------------------------------------
      # new method: reset_area_tint
      #--------------------------------------------------------------------------
      def reset_area_tint
        @area_tint_rect = nil
        @area_tone = nil
      end
     
      #--------------------------------------------------------------------------
      # new method: area_tint?
      #--------------------------------------------------------------------------
      def area_tint?
        @area_tint_rect != nil
      end
     
      #--------------------------------------------------------------------------
      # alias method: update_tone
      #--------------------------------------------------------------------------
      alias mapAreaTint_update_tone update_tone
      def update_tone
        mapAreaTint_update_tone
        #---
        if @area_tone_duration != nil && @area_tone_duration > 0
          d = @area_tone_duration
          #---
          @area_tone = Tone.new(0,0,0,0) if @area_tone == nil
          #---
          @area_tone.red = (@area_tone.red * (d - 1) + @area_tone_target.red) / d
          @area_tone.green = (@area_tone.green * (d - 1) + @area_tone_target.green) / d
          @area_tone.blue = (@area_tone.blue * (d - 1) + @area_tone_target.blue) / d
          @area_tone.gray = (@area_tone.gray * (d - 1) + @area_tone_target.gray) / d
          @area_tone_duration -= 1
        end
      end
    end # /Game_Screen
    
    #==============================================================================
    # ■ Sprite_Character
    #==============================================================================
    
    class Sprite_Character < Sprite_Base
     
      #--------------------------------------------------------------------------
      # alias method: update_position
      #--------------------------------------------------------------------------
      alias mapAreaTint_update_position update_position
      def update_position
        mapAreaTint_update_position
        #---
        self.x = @character.screen_x - viewport.rect.x
        self.y = @character.screen_y - viewport.rect.y
      end
    end # /Sprite_Character