def METHOD_NAME(self, ctx: cairo.Context, action: FixedFloorActionRule, sx: int, sy: int):
    if isinstance(action, EntityRule):
        assert self.parent.entity_rule_container is not None
        item, monster, tile, stats = self.parent.entity_rule_container.get(action.entity_rule_id)
        # Has trap?
        if tile.trap_id < 25:
            self._draw_trap(ctx, tile.trap_id, sx, sy)
        # Has item?
        if item.item_id > 0:
            if item.item_id < self.parent.module.item_count():
                self._draw_item(ctx, item.item_id, sx, sy)
            else:
                ctx.arc(sx + DPCI_TILE_DIM * DPC_TILING_DIM / 2, sy + DPCI_TILE_DIM * DPC_TILING_DIM / 2,
                        DPCI_TILE_DIM * DPC_TILING_DIM / 2, 0, 2 * math.pi)
                ctx.set_source_rgba(*COLOR_ITEM)
                ctx.fill_preserve()
                ctx.set_source_rgba(*COLOR_OUTLINE)
                ctx.set_line_width(1)
                ctx.stroke()
        # Has Pokémon?
        if monster.md_idx > 0:
            self._draw_pokemon(ctx, monster.md_idx, action.direction, sx, sy)
    elif isinstance(action, TileRule):
        # Leader spawn tile
        if action.tr_type == TileRuleType.LEADER_SPAWN:
            self.parent.draw_placeholder(0, sx, sy, action.direction, ctx)
        # Attendant1 spawn tile
        if action.tr_type == TileRuleType.ATTENDANT1_SPAWN:
            self.parent.draw_placeholder(10, sx, sy, action.direction, ctx)
        # Attendant2 spawn tile
        if action.tr_type == TileRuleType.ATTENDANT2_SPAWN:
            self.parent.draw_placeholder(11, sx, sy, action.direction, ctx)
        # Attendant3 spawn tile
        if action.tr_type == TileRuleType.ATTENDANT3_SPAWN:
            self.parent.draw_placeholder(15, sx, sy, action.direction, ctx)
        # Key walls
        if action.tr_type == TileRuleType.FL_WA_ROOM_FLAG_0C or action.tr_type == TileRuleType.FL_WA_ROOM_FLAG_0D:
            sprite, x, y, w, h = self.parent.sprite_provider.get_for_trap(
                31,
                lambda: GLib.idle_add(self.parent.redraw)
            )
            ctx.translate(sx, sy)
            ctx.set_source_surface(sprite)
            ctx.get_source().set_filter(cairo.Filter.NEAREST)
            ctx.paint()
            ctx.translate(-sx, -sy)
        # Warp zone
        if action.tr_type == TileRuleType.WARP_ZONE or action.tr_type == TileRuleType.WARP_ZONE_2:
            self._draw_stairs(ctx, sx, sy)
    elif isinstance(action, DirectRule):
        if action.tile.room_type == RoomType.KECLEON_SHOP:
            sprite, x, y, w, h = self.parent.sprite_provider.get_for_trap(
                30,
                lambda: GLib.idle_add(self.parent.redraw)
            )
            ctx.translate(sx, sy)
            ctx.set_source_surface(sprite)
            ctx.get_source().set_filter(cairo.Filter.NEAREST)
            ctx.paint()
            ctx.translate(-sx, -sy)
        if action.tile.typ == TileType.PLAYER_SPAWN or action.tile.typ == TileType.ENEMY:
            self._draw_pokemon(ctx, action.itmtpmon_id, action.direction, sx, sy)
        if action.tile.typ == TileType.STAIRS:
            self._draw_stairs(ctx, sx, sy)
        if action.tile.typ == TileType.TRAP:
            self._draw_trap(ctx, action.itmtpmon_id, sx, sy)
        if action.tile.typ == TileType.BURIED_ITEM:
            self._draw_item(ctx, action.itmtpmon_id, sx, sy, buried=True)
        if action.tile.typ == TileType.ITEM:
            self._draw_item(ctx, action.itmtpmon_id, sx, sy)
        if action.tile.room_type == RoomType.MONSTER_HOUSE:
            ctx.set_source_rgba(230, 0, 0, 0.2)
            ctx.rectangle(sx, sy, DPCI_TILE_DIM * DPC_TILING_DIM, DPCI_TILE_DIM * DPC_TILING_DIM)
            ctx.fill()