Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: マナが無くなったら掘れなくするパッシブスキルを追加 #2370

Open
wants to merge 26 commits into
base: 1_18
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1fc70ab
feat: パッシブスキルメニューにマナが無くなったら掘れなくするスキルのトグルボタンを追加
kuroma6666 Sep 15, 2024
09a17d6
feat: マナを消費しきった際の分岐処理を追加
kuroma6666 Sep 15, 2024
924113e
chore: V1.19.0 ブロック破壊の抑制トリガー設定を保存するマイグレーションファイルを追加
kuroma6666 Sep 15, 2024
9f45f42
feat: breakskilltriggerconfigサブシステムの追加
kuroma6666 Sep 15, 2024
e7c7cd3
feat: ブロック破壊時、「マナ切れ」かどうか判定する処理を追加
kuroma6666 Sep 15, 2024
6725736
fix: `isBreakBlockManaFullyConsumed`を`breakskilltriggerconfig`サブシステムに実装
kuroma6666 Sep 16, 2024
c043e8d
fix: スキル発動分のマナ不足のとき、ブロック破壊処理を終了するようにする
kuroma6666 Sep 21, 2024
f1e0599
fix: 消費マナ不足処理の修正
kuroma6666 Sep 21, 2024
66d94e1
fix: `PlayerBlockBreakListener`へマナ切れブロック破壊停止設定取得処理を移動
kuroma6666 Sep 21, 2024
acb3cf8
fix: マナ消費できるかどうか判断する関数を修正
kuroma6666 Sep 21, 2024
9753a7a
fix: `isBreakBlockManaFullyConsumed`関数を`PlayerBlockBreakListener`へ定義
kuroma6666 Sep 22, 2024
05c80c1
chore: importするパッケージの修正
kuroma6666 Sep 22, 2024
d79bad1
fix: 消費マナ不足判定処理とブロック破壊時処理を明確にした
kuroma6666 Sep 22, 2024
ad5b883
chore: scalafmt
kuroma6666 Sep 22, 2024
02c9368
chore: `BreakSkillTriggerSettings`の削除
kuroma6666 Sep 22, 2024
ae8d4c2
chore: `canAcquire`のコメント修正
kuroma6666 Oct 12, 2024
914bf47
fix: 「マナがないときにスキルの発動を抑制するかどうか」のテーブル構造を修正
kuroma6666 Oct 12, 2024
eaec16e
fix `isBreakBlockManaFullyConsumed`の処理を修正
kuroma6666 Oct 12, 2024
df86061
fix: 指摘内容(*)を反映し、`onPlayerActiveSkillEvent`の処理を修正
kuroma6666 Oct 12, 2024
5d5bcd0
fix: BreakSkillTriggerConfigKey->BreakSuppressionPreferenceへcase clas…
kuroma6666 Dec 14, 2024
a4451d0
fix: `BreakSkillTriggerConfigKey`定義の削除
kuroma6666 Dec 14, 2024
38c29da
fix: `BreakSkillTrigger`->`BreakSuppressionPreference`への変更に伴うsubsyste…
kuroma6666 Dec 14, 2024
7b3c3c7
fix: `BreakSkillTrigger`->`BreakSuppressionPreference`への変更に伴うビルドエラー修正
kuroma6666 Dec 14, 2024
a10401e
fix: DBマイグレーションSQLの修正
kuroma6666 Dec 14, 2024
1680ffe
fix: `tryConsume`の削除
kuroma6666 Dec 14, 2024
95d772f
fix: `canAcuire`の修正
kuroma6666 Dec 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
USE seichiassist;

CREATE TABLE player_break_suppression_preference(
uuid CHAR(36) NOT NULL,
do_break_suppression_due_to_mana BOOL NOT NULL DEFAULT FALSE,
FOREIGN KEY fk_player_break_suppression_preference_uuid REFERENCES playerdata(uuid)
);
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import com.github.unchama.seichiassist.subsystems.autosave.application.SystemCon
import com.github.unchama.seichiassist.subsystems.breakcount.{BreakCountAPI, BreakCountReadAPI}
import com.github.unchama.seichiassist.subsystems.breakcountbar.BreakCountBarAPI
import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.BreakSkillTargetConfigAPI
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.BreakSkillTriggerConfigAPI
import com.github.unchama.seichiassist.subsystems.buildcount.BuildCountAPI
import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
import com.github.unchama.seichiassist.subsystems.donate.DonatePremiumPointAPI
Expand Down Expand Up @@ -495,6 +496,10 @@ class SeichiAssist extends JavaPlugin() {
lazy val breakSkillTargetConfigSystem: subsystems.breakskilltargetconfig.System[IO, Player] =
subsystems.breakskilltargetconfig.System.wired[IO, SyncIO].unsafeRunSync()

lazy val breakSkillTriggerConfigSystem
: subsystems.breakskilltriggerconfig.System[IO, Player] =
subsystems.breakskilltriggerconfig.System.wired[IO, SyncIO].unsafeRunSync()

/* TODO: mineStackSystemは本来privateであるべきだが、mineStackにアイテムを格納するAPIが現状の
BreakUtilの実装から呼び出されている都合上やむを得ずpublicになっている。*/
lazy val mineStackSystem: subsystems.minestack.System[IO, Player, ItemStack] =
Expand Down Expand Up @@ -562,6 +567,7 @@ class SeichiAssist extends JavaPlugin() {
openirontrapdoor.System.wired,
gridRegionSystem,
breakSkillTargetConfigSystem,
breakSkillTriggerConfigSystem,
joinAndQuitMessenger,
elevatorSystem,
blockLiquidStreamSystem,
Expand Down Expand Up @@ -746,6 +752,8 @@ class SeichiAssist extends JavaPlugin() {
implicit val gridRegionAPI: GridRegionAPI[IO, Player, Location] = gridRegionSystem.api
implicit val breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player] =
breakSkillTargetConfigSystem.api
implicit val breakSkillTriggerConfigAPI: BreakSkillTriggerConfigAPI[IO, Player] =
breakSkillTriggerConfigSystem.api
implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player] = playerHeadSkinSystem.api

val menuRouter = TopLevelRouter.apply
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,19 @@ import com.github.unchama.minecraft.actions.OnMinecraftServerThread
import com.github.unchama.seichiassist.ManagedWorld._
import com.github.unchama.seichiassist.MaterialSets.{BlockBreakableBySkill, BreakTool}
import com.github.unchama.seichiassist.concurrent.PluginExecutionContexts
import com.github.unchama.seichiassist.data.{AxisAlignedCuboid}
import com.github.unchama.seichiassist.seichiskill.ActiveSkillRange.MultiArea
import com.github.unchama.seichiassist.seichiskill.SeichiSkillUsageMode.Disabled
import com.github.unchama.seichiassist.seichiskill.{BlockSearching, BreakArea}
import com.github.unchama.seichiassist.subsystems.breakcount.domain.level.SeichiExpAmount
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.domain.BreakSkillTriggerConfigKey
import com.github.unchama.seichiassist.subsystems.mana.ManaApi
import com.github.unchama.seichiassist.subsystems.mana.domain.ManaAmount
import com.github.unchama.seichiassist.subsystems.minestack.MineStackAPI
import com.github.unchama.seichiassist.util.BreakUtil
import com.github.unchama.seichiassist.{MaterialSets, SeichiAssist}
import com.github.unchama.targetedeffect.player.FocusedSoundEffect
import com.github.unchama.targetedeffect.player.ActionBarMessageEffect
import com.github.unchama.util.bukkit.ItemStackUtil
import com.github.unchama.util.effect.BukkitResources
import com.github.unchama.util.external.WorldGuardWrapper
Expand Down Expand Up @@ -101,20 +104,66 @@ class PlayerBlockBreakListener(
return
}

// 追加マナ獲得
manaApi
.manaAmount(player)
.restoreAbsolute(ManaAmount(BreakUtil.calcManaDrop(player)))
.unsafeRunSync()

// 選択したスキル
val selectedSkill = skillState
.activeSkill
.getOrElse(
return
)

if (!selectedSkill.range.isInstanceOf[MultiArea] || skillState.usageMode == Disabled) return

// 消費するマナが不足しているか判定
{
// プレイヤーのY座標
val playerLocY = player.getLocation.getBlockY - 1
// スキル破壊範囲
val skillArea = BreakArea(selectedSkill, skillState.usageMode)
// 破壊エリアリスト
val breakAreaList = skillArea.makeBreakArea(player).unsafeRunSync()
// 複数種類ブロック同時破壊設定
val isMultiTypeBreakingSkillEnabled =
BreakUtil.performsMultipleIDBlockBreakWhenUsingSkills(player).unsafeRunSync()
// 破壊範囲のブロック計算
val totalBreakRangeVolume = {
val breakLength = skillArea.breakLength
breakLength.x * breakLength.y * breakLength.z * skillArea.breakNum
}
breakAreaList.foreach { breakArea =>
import com.github.unchama.seichiassist.data.syntax._
val BlockSearching.Result(breakBlocks, waterBlocks, lavaBlocks) =
BlockSearching
.searchForBlocksBreakableWithSkill(player, breakArea.gridPoints(), block)
.unsafeRunSync()
.filterSolids(targetBlock =>
isMultiTypeBreakingSkillEnabled || BlockSearching
.multiTypeBreakingFilterPredicate(block)(targetBlock)
)
.filterAll(targetBlock =>
player.isSneaking || targetBlock
.getLocation
.getBlockY > playerLocY || targetBlock == block
)

// 破壊範囲で消費されるマナ計算
val manaToConsumeOnBreakArea = ManaAmount {
(gravity + 1) * selectedSkill.manaCost * (breakBlocks.size + 1).toDouble / totalBreakRangeVolume
}
// 消費マナが不足している場合は処理を終了
manaApi.manaAmount(player).canAcquire(manaToConsumeOnBreakArea).unsafeRunSync() match {
case false if isBreakBlockManaFullyConsumed(player).unsafeRunSync() =>
event.setCancelled(true)
return
case _ =>
}
}
}

// 追加マナ獲得
manaApi
.manaAmount(player)
.restoreAbsolute(ManaAmount(BreakUtil.calcManaDrop(player)))
.unsafeRunSync()

// 破壊不可能ブロックの時処理を終了
if (!BreakUtil.canBreakWithSkill(player, block)) {
event.setCancelled(true)
Expand All @@ -123,21 +172,22 @@ class PlayerBlockBreakListener(

event.setCancelled(true)

// ブロック破壊時に行う処理
{
// プレイヤーの足のy座標を取得
// プレイヤーのY座標
val playerLocY = player.getLocation.getBlockY - 1

// スキル破壊範囲
val skillArea = BreakArea(selectedSkill, skillState.usageMode)
// 破壊エリアリスト
val breakAreaList = skillArea.makeBreakArea(player).unsafeRunSync()

// 複数種類ブロック同時破壊設定
val isMultiTypeBreakingSkillEnabled =
BreakUtil.performsMultipleIDBlockBreakWhenUsingSkills(player).unsafeRunSync()

// 破壊範囲のブロック計算
val totalBreakRangeVolume = {
val breakLength = skillArea.breakLength
breakLength.x * breakLength.y * breakLength.z * skillArea.breakNum
}

// エフェクト用に壊されるブロック全てのリストデータ
val multiBreakList = new ArrayBuffer[Set[BlockBreakableBySkill]]
// 壊される溶岩の全てのリストデータ
Expand Down Expand Up @@ -169,7 +219,6 @@ class PlayerBlockBreakListener(
.getLocation
.getBlockY > playerLocY || targetBlock == block
)

// このチャンクで消費されるマナ
val manaToConsumeOnThisChunk = ManaAmount {
(gravity + 1) * selectedSkill.manaCost * (breakBlocks.size + 1).toDouble / totalBreakRangeVolume
Expand Down Expand Up @@ -373,4 +422,22 @@ class PlayerBlockBreakListener(
event.setCancelled(true)
player.sendMessage(s"${RED}Y-59以下に敷かれたハーフブロックは破壊不可能です。")
}

/**
* ブロック破壊時、「マナ切れブロック破壊停止設定」を取得する。
* マナ切れブロック破壊設定が `true` になっている場合、プレイヤーに破壊抑制メッセージを送信する。
* @param player マナ切れブロック破壊停止設定を取得するプレイヤー
*/
def isBreakBlockManaFullyConsumed(player: Player): IO[Boolean] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

見た限り PlayerBlockBreakListener 内の定義でしか使われていないようなので private にして良いと思います!(私の見落としだったらそのままで大丈夫です!)

Suggested change
def isBreakBlockManaFullyConsumed(player: Player): IO[Boolean] = {
private def isBreakBlockManaFullyConsumed(player: Player): IO[Boolean] = {

for {
isBreakBlockManaFullyConsumed <- SeichiAssist
.instance
.breakSkillTriggerConfigSystem
.api
.breakSkillTriggerConfig(player, BreakSkillTriggerConfigKey.ManaFullyConsumed)
_ <- ActionBarMessageEffect(s"${RED}マナ切れでブロック破壊を止めるスキルは有効化されています")
.run(player)
.whenA(isBreakBlockManaFullyConsumed)
} yield isBreakBlockManaFullyConsumed
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountAPI
import com.github.unchama.seichiassist.subsystems.breakcount.domain.SeichiAmountData
import com.github.unchama.seichiassist.subsystems.breakcountbar.BreakCountBarAPI
import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.BreakSkillTargetConfigAPI
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.BreakSkillTriggerConfigAPI
import com.github.unchama.seichiassist.subsystems.buildcount.domain.playerdata.BuildAmountData
import com.github.unchama.seichiassist.subsystems.discordnotification.DiscordNotificationAPI
import com.github.unchama.seichiassist.subsystems.donate.DonatePremiumPointAPI
Expand Down Expand Up @@ -104,6 +105,7 @@ object TopLevelRouter {
fairySpeechAPI: FairySpeechAPI[IO, Player],
gridRegionAPI: GridRegionAPI[IO, Player, Location],
breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player],
breakSkillTriggerConfigAPI: BreakSkillTriggerConfigAPI[IO, Player],
playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
): TopLevelRouter[IO] = new TopLevelRouter[IO] {
import assortedRankingApi._
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import com.github.unchama.seichiassist.menus.stickmenu.FirstPage
import com.github.unchama.seichiassist.subsystems.breakcount.BreakCountAPI
import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.BreakSkillTargetConfigAPI
import com.github.unchama.seichiassist.subsystems.breakskilltargetconfig.domain.BreakSkillTargetConfigKey
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.BreakSkillTriggerConfigAPI
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.domain.BreakSkillTriggerConfigKey
import com.github.unchama.seichiassist.subsystems.playerheadskin.PlayerHeadSkinAPI
import com.github.unchama.targetedeffect._
import com.github.unchama.targetedeffect.commandsender.MessageEffect
Expand All @@ -34,6 +36,7 @@ object PassiveSkillMenu extends Menu {
class Environment(
implicit val breakCountApi: BreakCountAPI[IO, SyncIO, Player],
implicit val breakSkillTargetConfigAPI: BreakSkillTargetConfigAPI[IO, Player],
implicit val breakSkillTriggerConfigAPI: BreakSkillTriggerConfigAPI[IO, Player],
val ioCanOpenFirstPage: IO CanOpen FirstPage.type,
implicit val playerHeadSkinAPI: PlayerHeadSkinAPI[IO, Player]
)
Expand Down Expand Up @@ -62,6 +65,7 @@ object PassiveSkillMenu extends Menu {
val dynamicPartComputation = List(
ChestSlotRef(0, 0) -> computeToggleMultipleBlockTypeDestructionButton,
ChestSlotRef(0, 1) -> computeToggleChestBreakButton,
ChestSlotRef(0, 2) -> computeToggleManaFullyConsumedBreakStopButton,
ChestSlotRef(1, 0) -> computeGiganticBerserkButton,
ChestSlotRef(1, 1) -> computeToggleNetherQuartzBlockButton
).traverse(_.sequence)
Expand Down Expand Up @@ -231,6 +235,49 @@ object PassiveSkillMenu extends Menu {
)
})

val computeToggleManaFullyConsumedBreakStopButton: IO[Button] = RecomputedButton(for {
originalBreakStopConfig <- breakSkillTriggerConfigAPI
.breakSkillTriggerConfig(player, BreakSkillTriggerConfigKey.ManaFullyConsumed)
} yield {
val baseLore = List(s"${YELLOW}マナ切れでブロック破壊を止めるスキル")
val statusLore = if (originalBreakStopConfig) {
List(s"${GREEN}ON (マナが切れるとブロック破壊を止めます。)", s"${DARK_RED}クリックでOFF")
} else {
List(s"${RED}OFF (マナが切れてもブロック破壊を続けます。)", s"${DARK_GREEN}クリックでON")
}

Button(
new IconItemStackBuilder(Material.LAPIS_LAZULI)
.tap { builder =>
if (originalBreakStopConfig)
builder.enchanted()
}
.title(s"$WHITE$UNDERLINE${BOLD}マナ切れでブロック破壊を止めるスキル切り替え")
.lore(baseLore ++ statusLore)
.build(),
LeftClickButtonEffect {
SequentialEffect(
breakSkillTriggerConfigAPI.toggleBreakSkillTriggerConfig(
BreakSkillTriggerConfigKey.ManaFullyConsumed
),
DeferredEffect(IO {
if (!originalBreakStopConfig) {
SequentialEffect(
MessageEffect(s"${GREEN}マナが切れたらブロック破壊を止めるスキルを有効化しました。"),
FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f)
)
} else {
SequentialEffect(
MessageEffect(s"${RED}マナが切れたらブロック破壊を止めるスキルを無効化しました。"),
FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 0.5f)
)
}
Comment on lines +262 to +272
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

以下のように書いたほうが、より読みやすくなると思います

Suggested change
if (!originalBreakStopConfig) {
SequentialEffect(
MessageEffect(s"${GREEN}マナが切れたらブロック破壊を止めるスキルを有効化しました"),
FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f)
)
} else {
SequentialEffect(
MessageEffect(s"${RED}マナが切れたらブロック破壊を止めるスキルを無効化しました"),
FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 0.5f)
)
}
if (originalBreakStopConfig) {
SequentialEffect(
MessageEffect(s"${RED}マナが切れたらブロック破壊を止めるスキルを無効化しました"),
FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 0.5f)
)
} else {
SequentialEffect(
MessageEffect(s"${GREEN}マナが切れたらブロック破壊を止めるスキルを有効化しました"),
FocusedSoundEffect(Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1f, 1f)
)
}

})
)
}
)
})

val computeGiganticBerserkButton: IO[Button] = RecomputedButton {
environment
.breakCountApi
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig

import cats.data.Kleisli
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.domain.BreakSkillTriggerConfigKey

trait BreakSkillTriggerConfigAPI[F[_], Player] {

/**
* @return 破壊トリガをトグルする作用
*/
def toggleBreakSkillTriggerConfig(
configKey: BreakSkillTriggerConfigKey
): Kleisli[F, Player, Unit]

/**
* @return 現在の破壊トリガを取得する作用
*/
def breakSkillTriggerConfig(player: Player, configKey: BreakSkillTriggerConfigKey): F[Boolean]

}

object BreakSkillTriggerConfigAPI {

def apply[F[_], Player](
implicit ev: BreakSkillTriggerConfigAPI[F, Player]
): BreakSkillTriggerConfigAPI[F, Player] = ev

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig

import cats.data.Kleisli
import cats.effect.SyncEffect
import com.github.unchama.datarepository.bukkit.player.BukkitRepositoryControls
import com.github.unchama.generic.ContextCoercion
import com.github.unchama.seichiassist.meta.subsystem.Subsystem
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.application.repository.BreakSkillTriggerConfigRepositoryDefinition
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.domain.{
BreakSkillTriggerConfigKey,
BreakSkillTriggerConfigPersistence
}
import com.github.unchama.seichiassist.subsystems.breakskilltriggerconfig.persistence.JdbcBreakSkillTriggerConfigPersistence
import org.bukkit.entity.Player

trait System[F[_], Player] extends Subsystem[F] {
val api: BreakSkillTriggerConfigAPI[F, Player]
}

object System {

import cats.implicits._

def wired[F[_], G[_]: SyncEffect: ContextCoercion[*[_], F]]: G[System[F, Player]] = {
implicit val breakSkillTriggerConfigPersistence: BreakSkillTriggerConfigPersistence[G] =
new JdbcBreakSkillTriggerConfigPersistence[G]

for {
breakSkillTriggerConfigRepositoryControls <- BukkitRepositoryControls.createHandles(
BreakSkillTriggerConfigRepositoryDefinition.withContext[G, Player]
)
} yield {
val breakSkillTriggerConfigRepository =
breakSkillTriggerConfigRepositoryControls.repository

new System[F, Player] {
override val api: BreakSkillTriggerConfigAPI[F, Player] =
new BreakSkillTriggerConfigAPI[F, Player] {
override def toggleBreakSkillTriggerConfig(
configKey: BreakSkillTriggerConfigKey
): Kleisli[F, Player, Unit] =
Kleisli { player =>
ContextCoercion(
breakSkillTriggerConfigRepository(player)
.update(_.toggleBreakSkillTriggerConfig(configKey))
)
}

override def breakSkillTriggerConfig(
player: Player,
configKey: BreakSkillTriggerConfigKey
): F[Boolean] =
ContextCoercion(
breakSkillTriggerConfigRepository(player)
.get
.map(_.breakSkillTriggerConfig(configKey))
)
}

override val managedRepositoryControls: Seq[BukkitRepositoryControls[F, _]] = Seq(
breakSkillTriggerConfigRepositoryControls.coerceFinalizationContextTo[F]
)
}
}
}

}
Loading