where can we find changelogs of patch releases? I'...
# intellij
b
where can we find changelogs of patch releases? I'm having quite some trouble with kotlin on k2 beta and want to see if anything has been fixed
t
Hi! What particular trouble solution are you interested in?
b
the one where imports are marked as unused (and are removed if you enable it in save actions)
thank you color 1
let me check if I can find the ticket
can't findt the ticket, but that's the behavior
image.png
see how DC is used in the last line, but marked as unused
both are annotated with @JsPlainObject btw
and it does not happen for every plain object import
so unsure how to reproduce it
seems to also happen for other things like https://kotlinlang.slack.com/archives/C0B8H786P/p1723270324880349 but not sure if it's the same thing
r
Hi @Bernhard! This indeed seems like a bug! Could you please send a screenshot of how exactly
Dc
and
PF2ERollOptions
classes are used in your file, so that we can reproduce the issue and file a ticket?
b
Copy code
package at.posselt.kingmaker.camping

import at.posselt.kingmaker.actor.resolveAttribute
import at.posselt.kingmaker.app.Select
import at.posselt.kingmaker.app.awaitablePrompt
import at.posselt.kingmaker.camping.dialogs.RegionSetting
import at.posselt.kingmaker.data.actor.*
import at.posselt.kingmaker.data.checks.DegreeOfSuccess
import at.posselt.kingmaker.data.checks.RollMode
import at.posselt.kingmaker.data.checks.getLevelBasedDC
import at.posselt.kingmaker.fromCamelCase
import at.posselt.kingmaker.fromOrdinal
import at.posselt.kingmaker.slugify
import at.posselt.kingmaker.utils.postChatTemplate
import at.posselt.kingmaker.utils.postDegreeOfSuccess
import com.foundryvtt.pf2e.Dc
import com.foundryvtt.pf2e.PF2ERollOptions
import com.foundryvtt.pf2e.actor.PF2ECreature
import js.array.push
import js.objects.Object
import js.objects.recordOf
import kotlinx.coroutines.await
import kotlinx.js.JsPlainObject

@JsPlainObject
private external interface AskDcData {
    val dc: Int
}

private suspend fun askDc(activity: String): Int {
    return awaitablePrompt<AskDcData, Int>(
        title = "$activity: Select DC",
        templatePath = "components/forms/form.hbs",
        templateContext = recordOf(
            "formRows" to Select.dc().toContext()
        ),
    ) {
        it.dc
    }
}

@JsPlainObject
private external interface AskSkillData {
    val skill: String
}

fun PF2ECreature.satisfiesSkillRequirement(
    selectedSkill: String,
    skillRequirements: Array<SkillRequirement>,
): Boolean {
    val requirements = skillRequirements.find { it.skill == selectedSkill }
    return if (requirements == null) {
        true
    } else {
        val attribute = Attribute.fromString(selectedSkill)
        val rank = resolveAttribute(attribute)?.rank ?: 0
        fromCamelCase<Proficiency>(requirements.proficiency)
            ?.let { rank >= it.ordinal }
            ?: false
    }
}

fun PF2ECreature.hasAnyActivitySkill(
    activity: CampingActivityData,
): Boolean =
    findCampingActivitySkills(activity, true)
        .map { Attribute.fromString(it) }
        .any { resolveAttribute(it) != null }

fun PF2ECreature.findCampingActivitySkills(
    activity: CampingActivityData,
    disableSkillRequirements: Boolean,
): List<String> {
    val activitySkills = activity.skills
    val availableSkills = if (activitySkills == "any") {
        Object.keys(skills)
    } else {
        @Suppress("UNCHECKED_CAST")
        activitySkills as Array<String>
    }
    return availableSkills.filter {
        if (disableSkillRequirements) {
            true
        } else {
            satisfiesSkillRequirement(it, activity.skillRequirements)
        }
    }
}

/**
 * @throws Error if a popup asking for a skill or dc is closed
 */
suspend fun PF2ECreature.campingActivityCheck(
    region: RegionSetting,
    activity: CampingActivityData,
    skill: Attribute,
): DegreeOfSuccess? {
    val activityName = activity.name
    val extraRollOptions = arrayOf("action:${activityName.slugify()}")
    val dc = when (val activityDc = activity.dc) {
        "zone" -> region.zoneDc
        "actorLevel" -> getLevelBasedDC(level)
        null -> askDc(activityName)
        is String -> activityDc.toInt()
        else -> activityDc as Int
    }
    val result = performCampingCheck(
        attribute = skill,
        isSecret = activity.isSecret,
        extraRollOptions = extraRollOptions,
        dc = dc,
    )
    if (result != null) {
        val config = when (result) {
            DegreeOfSuccess.CRITICAL_FAILURE -> activity.criticalFailure
            DegreeOfSuccess.FAILURE -> activity.failure
            DegreeOfSuccess.SUCCESS -> activity.success
            DegreeOfSuccess.CRITICAL_SUCCESS -> activity.criticalSuccess
        }
        postDegreeOfSuccess(degreeOfSuccess = result, message = config?.message)
        if (config?.checkRandomEncounter == true) {
            postChatTemplate(
                "chatmessages/random-camping-encounter.hbs",
                rollMode = RollMode.BLINDROLL
            );
        }
    }
    return result
}


private suspend fun PF2ECreature.performCampingCheck(
    attribute: Attribute,
    isSecret: Boolean = false,
    isWatch: Boolean = false,
    extraRollOptions: Array<String> = emptyArray(),
    dc: Int,
): DegreeOfSuccess? {
    val data = PF2ERollOptions(
        rollMode = if (isSecret) "blindroll" else undefined,
        dc = Dc(value = dc),
        extraRollOptions = arrayOf("camping") + extraRollOptions
    )
    if (isWatch) {
        data.extraRollOptions?.push("watch")
    }
    return resolveAttribute(attribute)
        ?.roll(data)
        ?.await()
        ?.let { fromOrdinal<DegreeOfSuccess>(it.degreeOfSuccess) }
}
I would have submitted a bug, I just don't understand how to reproduce it
image.png
there's also something weird going in here with the roll options attribute
r
I see that both of those classes are used here:
Copy code
val data = PF2ERollOptions(
    rollMode = if (isSecret) "blindroll" else undefined,
    dc = Dc(value = dc),
    extraRollOptions = arrayOf("camping") + extraRollOptions
  )
Is it correct that those are calls to their constructors? I mean the
PF2ERollOptions(…)
and
Dc(…)
?
b
those are plain objects
compiler plugin that generates an invoke block IIRC
Copy code
import kotlinx.js.JsPlainObject

@JsPlainObject
external interface Dc {
    val value: Int
}

@JsPlainObject
external interface PF2ERollOptions {
    val rollMode: String?
    val dc: Dc?
    val extraRollOptions: Array<String>?
}
r
Oh, got it! Thank you very much, I now understand the problem - I will take a look 👍
b
thank you color 1
src/jsMain/kotlin/at/posselt/kingmaker/camping/CampingCheck.kt
r
I believe that you have faced this issue with
JsPlainObject
not being properly handled in the K2 Mode: KTIJ-31036 It will be fixed soon, but it will probably not be backported to 242, so look forward to 243 EAPs 🙏
b
yeah, that's my issue xD
fantastic to hear btw
r
Oh, sorry! Haven’t noticed that it was you who reported it 😅
Thanks for the reports BTW Regarding the imports, I will see if this is still an issue, or if it was already fixed in the master
t
@Bernhard Also now, starting with this 2024.3 EAP 2 you can also monitor changes in the IntelliJ changelist.
🙌 1