Passage check bit

● ARCHIVED · READ-ONLY
Started by Napoleon 11 posts View original ↗
  1. #game_map #-------------------------------------------------------------------------- # * Check Passage # bit: Inhibit passage check bit #-------------------------------------------------------------------------- def check_passage(x, y, bit) all_tiles(x, y).each do |tile_id| flag = tileset.flags[tile_id] next if flag & 0x10 != 0 # [☆]: No effect on passage return true if flag & bit == 0 # [○] : Passable return false if flag & bit == bit # [×] : Impassable end return false # Impassable endSo what bit do I have to pass for no direction? Like I just want to know if the tile is not passable at all from any direction? The documentation says it only supports directions 2, 4, 6, 8. But I have no direction. Just pass 0?
  2. Passing in a 0 would not be right.  The flag & bit would always return 0, meaning everything is always passable. 

    You could iterate over all 4 directions, like this:

    passable=true

    [2, 4, 6, 8].each {

    |dir| if ($game_map.check_passage(x, y, dir) == false)

      passable=false

    }

    I'd imagine there's a more efficient way though.
  3. Remember that you have to divide the direction value by 2 to get the corresponding direction bit.

    [Removed some wrong statement of mine]
  4. Thanks that works. I did add a minor fix though to prevent it from crashing.

    def any_direction_passable?(x, y, directions = 0b1111) return 0 != all_tiles(x, y).inject(directions) { |res, tile_id| flags = tileset.flags[tile_id] # <<< changed tile to tile_id to prevent the crash next (flags & 0x10 == 0) ? res & ~flags : res }endYou removed your "wrong statement"? It seems to work for me?

    P.S.

    You don't mind if I add that method 1:1 into my core script?
  5. Argh, it seems I was too slow deleting my code fragment... ^^
    The method does return wrong results at the moment, as a direction is marked as unpassable when any tile is unpassable for that direction, even when a passable tile was already found...

    Sorry for that.

    Edit: I think this should do instead:

    def any_direction_passable?(x, y, directions = 0b1111) # Get the first non-star-tile:  tile = all_tiles(x, y).find { |tile_id| tileset.flags[tile_id] & 0x10 == 0 }  # Return true if any of the given direction bits of the first found tile is 0:  return (tile != nil and (directions & ~tileset.flags[tile]) != 0)endThis fragment should work correctly as long as the original check_passage method is not redefined.
  6. in that case I go with whitesphere's solution:

      def any_direction_passable?(x, y)    [2, 4, 6, 8].each { |d| return true if check_passage(x, y, (1 << (d / 2 - 1)) & 0x0f) }    return false  endUntil I find a more efficient solution.
  7. I think 10 checks for passability in ANY direction.


    I don't remember why I think that ...
  8. def any_direction_passable?(x, y) check_passage(x, y, 0x0F)endUntested, but this does do the job, doesn't it?
  9. The default definition of check_passage should not return usable results for multiple direction bits.

    When the result is true then at least one of these directions is actually passable, when the result is false at least one direction is impassable. If some of the directions are passable and some are not, then the result will be case dependent.

    However, in theory that issue should be easy to fix (did not test that yet either^^):

    Change line 10 to
    return true if flag & bit != bit  # [○] : Passable

    if the method shall return true when at least one of the given directions is passable...

    ...or change line 11 to
    return false if flag & bit != 0  # [×] : Impassable

    if the method shall only return true when all of the given directions are passable.

    After doing that cremnophobias suggestion should work.
  10. Wait, I think I'm confused. Could you clarify what you are looking for, Napoleon? If any (as in Enumerable#any?) direction or if all directions are passable?
  11. Any indeed is what I'm looking for.

    But AnotherFen's solution + your bit seems to do the job as far as I have tested. I also tested it with tiles with only a few passable directions including stars.