• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Invalid tile eraser

Maruno

Lead Dev of Pokémon Essentials
5,286
Posts
16
Years
    • Seen May 3, 2024
    Description​

    This script will scan all your maps, find any used tiles which do not exist in the map's tileset, and erase them. This checks tiles that are placed in the map as well as event graphics. It will erase tiles used from autotiles that do not exist in the tileset.

    The use of non-existent tiles is caused by bad map data, namely by creating a map using tiles from a long tileset before switching/editing it to a shorter tileset. Since Essentials v18, this bad tile data causes error messages, and this script will fix that.

    Only map files are affected by this script. The tileset data (as seen in the Database) is not changed.

    This script will be included in a later version of Essentials. It is provided now because it's useful.

    How to use​

    Paste the code below into a new script section just above "Main".

    The option to "Fix Invalid Tiles" will now appear in the Debug menu under "Other options...". Select it to run it.

    If any maps have been changed as a result of this script, you should close RPG Maker XP to ensure you don't re-save an unfixed copy of the map over the amended copy generated by this script.

    The script​

    Code:
    alias __errorTiles__pbDebugMenuCommands pbDebugMenuCommands
    
    def pbDebugMenuCommands(showall = true)
      commands = __errorTiles__pbDebugMenuCommands(showall)
      commands.add("othermenu","invalidtiles",_INTL("Fix Invalid Tiles"),
        _INTL("Scans all maps and erases non-existent tiles."))
      return commands
    end
    
    alias __errorTiles__pbDebugMenuActions pbDebugMenuActions
    
    def pbDebugMenuActions(cmd = "", sprites = nil, viewport = nil)
      if cmd == "invalidtiles"
        pbDebugFixInvalidTiles
        return false
      end
      return __errorTiles__pbDebugMenuActions(cmd, sprites, viewport)
    end
    
    def pbDebugFixInvalidTiles
      num_errors = 0
      num_error_maps = 0
      @tilesets = pbLoadRxData("Data/Tilesets")
      mapData = MapData.new
      t = Time.now.to_i
      Graphics.update
      for id in mapData.mapinfos.keys.sort
        if Time.now.to_i - t >= 5
          Graphics.update
          t = Time.now.to_i
        end
        changed = false
        map = mapData.getMap(id)
        next if !map || !mapData.mapinfos[id]
        Win32API.SetWindowText(_INTL("Processing map {1} ({2})", id, mapData.mapinfos[id].name))
        passages = mapData.getTilesetPassages(map, id)
        # Check all tiles in map for non-existent tiles
        for x in 0...map.data.xsize
          for y in 0...map.data.ysize
            for i in 0...map.data.zsize
              tile_id = map.data[x, y, i]
              next if pbCheckTileValidity(tile_id, map, @tilesets, passages)
              map.data[x, y, i] = 0
              changed = true
              num_errors += 1
            end
          end
        end
        # Check all events in map for page graphics using a non-existent tile
        for key in map.events.keys
          event = map.events[key]
          for page in event.pages
            next if page.graphic.tile_id <= 0
            next if pbCheckTileValidity(page.graphic.tile_id, map, @tilesets, passages)
            page.graphic.tile_id = 0
            changed = true
            num_errors += 1
          end
        end
        next if !changed
        # Map was changed; save it
        num_error_maps += 1
        mapData.saveMap(id)
      end
      if num_error_maps == 0
        pbMessage(_INTL("No invalid tiles were found."))
      else
        pbMessage(_INTL("{1} error(s) were found across {2} map(s) and fixed.", num_errors, num_error_maps))
        pbMessage(_INTL("Close RPG Maker XP to ensure the changes are applied properly."))
      end
    end
    
    def pbCheckTileValidity(tile_id, map, tilesets, passages)
      return false if !tile_id
      if tile_id > 0 && tile_id < 384
        # Check for defined autotile
        autotile_id = tile_id / 48 - 1
        autotile_name = tilesets[map.tileset_id].autotile_names[autotile_id]
        return true if autotile_name && autotile_name != ""
      else
        # Check for tileset data
        return true if passages[tile_id]
      end
      return false
    end
     
    Back
    Top