CaughtFish
釣り上げた魚の情報を表すデータクラスです(party.morino.moripafishing.api.model.fish.CaughtFish)。実装依存を持たない純粋なデータ構造で、AnglerFishCaughtEventとAnglerFishCaughtResultEventでのデータ受け渡しと、釣果アイテムに使用されます。
@Serializableが付与されているため、kotlinx.serializationでそのままJSON化できます。釣果履歴やランキングのように、Addon側で永続化やAPI返却を行いたい場合はこのクラスをそのまま利用できます。Core自体は釣果を保存しません。
フィールド
| フィールド | 型 | 説明 |
|---|---|---|
uniqueId | UUID | 釣果の一意ID(ランダムな UUIDv4) |
fish | FishId | 魚種ID |
rarity | RarityId | レアリティID |
size | Double | 魚のサイズ。表示時は小数2桁に整形される |
lengthRate | Double | サイズの累積分布関数値(0〜1)。価値の計算式の length_rate と同じ値 |
worth | Double | 魚の価値 |
angler | AnglerId | つりびとID。プレイヤーの Minecraft UUID と同じで、JSONでは UUID 文字列になる |
world | FishingWorldId | 釣り場ワールドID |
timestamp | ZonedDateTime | 釣った日時。ISO8601形式の文字列としてシリアライズされる |
FishId・RarityId・FishingWorldIdはいずれもvalue: Stringを持つデータクラスで、専用のシリアライザによって文字列として直接シリアライズされます。生の識別子を取り出したい場合はcaughtFish.fish.valueのようにvalueを参照してください。
fish・rarity・worldの各IDは、それぞれmoripa_fishing.fish.<id>.name、moripa_fishing.rarity.<id>.name、moripa_fishing.world.<id>.nameという翻訳キーに対応しています。各IDのtoTranslateKey()でこのキーを取得できるため、閲覧者のロケールに応じた表示名を解決したい場合は、その戻り値をComponent.translatableに渡してください。
生成
CaughtFish.of(fish, angler, world)で、抽選済みのFish(FishDrawerの戻り値)とAnglerId・FishingWorldIdから生成できます。uniqueIdはランダムなUUID、timestampは生成時点のZonedDateTime.now()が自動的に設定されます。
val fish = api.getFishDrawer().draw(worldId) ?: return
val caughtFish = CaughtFish.of(fish, angler.getId(), worldId)釣果アイテム
Coreが生成する釣果アイテムのPersistentDataContainerには、キーmoripafishing:caught_fishにCaughtFishのJSONが文字列として保存されます。アイテムから釣果を復元できます。
val key = NamespacedKey("moripafishing", "caught_fish")
val json = item.persistentDataContainer.get(key, PersistentDataType.STRING) ?: return
val caughtFish = Json.decodeFromString(CaughtFish.serializer(), json)利用例
AnglerFishCaughtEvent(釣り上げ確定前・キャンセルや差し替えが可能)と、
AnglerFishCaughtResultEvent(釣り上げ完了後・読み取り専用)から釣果データを取得できます。
通知や記録などの副作用にはAnglerFishCaughtResultEventを使用してください。
@EventHandler
fun onFishCaught(event: AnglerFishCaughtResultEvent) {
val angler = event.getAngler()
val caught = event.getCaughtFish()
logger.info("つりびと: ${angler.getName()}, 魚: ${caught.fish.value}, サイズ: ${caught.size}, 価値: ${caught.worth}")
}一方、AnglerFishCaughtEventはCancellableを実装しています。setCancelled(true)でキャンセルすると、Core側のリスナーが元のPlayerFishEventもキャンセルするため、釣果アイテムは生成されず釣り自体が成立しません。特定条件で釣りを禁止したい場合に利用できます。
@EventHandler
fun onFishCaught(event: AnglerFishCaughtEvent) {
if (isFishingBanned(event.getAngler())) {
event.isCancelled = true
}
}またAnglerFishCaughtEventではsetCaughtFish(caughtFish)によって釣果そのものを差し替えられます。差し替えた内容はアイテム化と後続のAnglerFishCaughtResultEventの両方に反映されます。ただし未登録のFishIdへ差し替えるとアイテムを生成できず、その場合はバニラのドロップが維持され、AnglerFishCaughtResultEventは発火しません。