<commit_before>package org.runestar.client.plugins.grounditems

import org.runestar.client.api.util.DisposablePlugin
import org.runestar.client.api.util.FontForm
import org.runestar.client.api.util.RgbaForm
import org.runestar.client.api.util.drawStringShadowed
import org.runestar.client.game.api.GroundItem
import org.runestar.client.game.api.SceneElement
import org.runestar.client.game.api.live.Game
import org.runestar.client.game.api.live.LiveCanvas
import org.runestar.client.game.api.live.LiveViewport
import org.runestar.client.game.api.live.SceneElements
import org.runestar.client.game.raw.Client
import org.runestar.client.game.raw.access.XItemDefinition
import org.runestar.client.plugins.spi.PluginSettings
import org.runestar.general.fonts.RUNESCAPE_SMALL_FONT

class GroundItems : DisposablePlugin<GroundItems.Settings>() {

    override val defaultSettings = Settings()

    override val name = "Ground Items"

    val piles = LinkedHashSet<SceneElement.ItemPile>()

    val blockedIds = HashSet<Int>()
    val unblockedIds = HashSet<Int>()
    val blockRegexes = ArrayList<Regex>()

    override fun start() {
        ctx.settings.blockedNames.mapTo(blockRegexes) { it.toRegex() }
        piles.addAll(SceneElements.ItemPile.all())
        SceneElements.ItemPile.additions.subscribe { piles.add(it) }
        SceneElements.ItemPile.removals.subscribe { piles.remove(it) }

        val defaultColor = ctx.settings.color.get()
        val font = ctx.settings.font.get()

        add(LiveCanvas.repaints.subscribe { g ->
            g.font = font
            g.clip(LiveViewport.shape)
            val height = g.fontMetrics.height

            val itr = piles.iterator()
            while (itr.hasNext()) {
                val pile = itr.next()
                if (pile.plane != Game.plane) continue
                val pt = pile.modelPosition.toScreen()
                if (pt == null || pt !in g.clip) continue
                val gis = pile.toList().asReversed()
                if (gis.isEmpty()) {
                    itr.remove()
                    continue
                }
                val items = LinkedHashMap<XItemDefinition, Int>()
                for (gi in gis) {
                    val def = Client.accessor.getItemDefinition(gi.id)
                    if (def != null) {
                        items.merge(def, gi.quantity) { old, new -> old + new }
                    }
                }
                val x = pt.x<commit_msg>Fix GroundItem plugins on scene clear<commit_after>package org.runestar.client.plugins.grounditems

import org.runestar.client.api.util.DisposablePlugin
import org.runestar.client.api.util.FontForm
import org.runestar.client.api.util.RgbaForm
import org.runestar.client.api.util.drawStringShadowed
import org.runestar.client.game.api.GroundItem
import org.runestar.client.game.api.SceneElement
import org.runestar.client.game.api.live.Game
import org.runestar.client.game.api.live.LiveCanvas
import org.runestar.client.game.api.live.LiveViewport
import org.runestar.client.game.api.live.SceneElements
import org.runestar.client.game.raw.Client
import org.runestar.client.game.raw.access.XItemDefinition
import org.runestar.client.plugins.spi.PluginSettings
import org.runestar.general.fonts.RUNESCAPE_SMALL_FONT

class GroundItems : DisposablePlugin<GroundItems.Settings>() {

    override val defaultSettings = Settings()

    override val name = "Ground Items"

    val piles = LinkedHashSet<SceneElement.ItemPile>()

    val blockedIds = HashSet<Int>()
    val unblockedIds = HashSet<Int>()
    val blockRegexes = ArrayList<Regex>()

    override fun start() {
        ctx.settings.blockedNames.mapTo(blockRegexes) { it.toRegex() }

        piles.addAll(SceneElements.ItemPile.all())
        SceneElements.ItemPile.additions.subscribe { piles.add(it) }
        SceneElements.ItemPile.removals.subscribe { piles.remove(it) }
        SceneElements.clears.subscribe { piles.clear() }

        val defaultColor = ctx.settings.color.get()
        val font = ctx.settings.font.get()

        add(LiveCanvas.repaints.subscribe { g ->
            g.font = font
            g.clip(LiveViewport.shape)
            val height = g.fontMetrics.height

            val itr = piles.iterator()
            while (itr.hasNext()) {
                val pile = itr.next()
                if (pile.plane != Game.plane) continue
                val pt = pile.modelPosition.toScreen()
                if (pt == null || pt !in g.clip) continue
                val gis = pile.toList().asReversed()
                if (gis.isEmpty()) {
                    itr.remove()
                    continue
                }
                val items = LinkedHashMap<XItemDefinition, Int>()
                for (gi in gis) {
                    val def = Client.accessor.getItemDefinition(gi.id)
                    if (def != null) {
                        items.merge(def, gi.quantity) { old, new -> old + new }
                    }
                }
                val x = pt.x
{'fraction_non_alphanumeric': 0.10617529880478088, 'fraction_numerical': 0.0, 'mean_word_length': 2.2816993464052286, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1893268', 'n_tokens_mistral': 1527, 'n_tokens_neox': 1453, 'n_words': 266}