diff --git a/common/src/main/java/generations/gg/generations/core/generationscore/common/api/GenerationsMolangFunctions.kt b/common/src/main/java/generations/gg/generations/core/generationscore/common/api/GenerationsMolangFunctions.kt index 5a08be511..06444fe9f 100644 --- a/common/src/main/java/generations/gg/generations/core/generationscore/common/api/GenerationsMolangFunctions.kt +++ b/common/src/main/java/generations/gg/generations/core/generationscore/common/api/GenerationsMolangFunctions.kt @@ -2,15 +2,25 @@ package generations.gg.generations.core.generationscore.common.api import com.bedrockk.molang.runtime.MoParams import com.bedrockk.molang.runtime.value.DoubleValue +import com.bedrockk.molang.runtime.value.StringValue import com.cobblemon.mod.common.api.molang.MoLangFunctions import com.cobblemon.mod.common.api.molang.MoLangFunctions.addFunctions import com.cobblemon.mod.common.api.molang.ObjectValue import com.cobblemon.mod.common.api.pokemon.PokemonProperties -import com.cobblemon.mod.common.util.asResource -import com.cobblemon.mod.common.util.getStringOrNull +import com.cobblemon.mod.common.api.pokemon.feature.ChoiceSpeciesFeatureProvider +import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeature +import com.cobblemon.mod.common.api.pokemon.feature.SpeciesFeatures +import com.cobblemon.mod.common.api.pokemon.feature.StringSpeciesFeature +import com.cobblemon.mod.common.api.properties.CustomPokemonPropertyType +import com.cobblemon.mod.common.api.storage.party.PartyStore +import com.cobblemon.mod.common.pokemon.Pokemon +import com.cobblemon.mod.common.util.* import generations.gg.generations.core.generationscore.common.GenerationsCore import generations.gg.generations.core.generationscore.common.client.model.ModelContextProviders import generations.gg.generations.core.generationscore.common.config.SpeciesKey +import generations.gg.generations.core.generationscore.common.util.getOrCreate +import generations.gg.generations.core.generationscore.common.util.getProviderOrNull +import generations.gg.generations.core.generationscore.common.util.isSpecies import generations.gg.generations.core.generationscore.common.world.entity.block.PokemonUtil import net.minecraft.core.BlockPos import net.minecraft.core.registries.Registries @@ -44,6 +54,62 @@ inline fun MoParams.getObjectOrNull(index: Int, java: Class ): T? object GenerationsMolangFunctions { @JvmStatic fun init() { + val pokemonFunctions = mutableListOf<(Pokemon) -> HashMap>>( + { pokemon -> + hashMapOf( + "species" to java.util.function.Function { _ -> StringValue(pokemon.species.name) }, + "form" to java.util.function.Function { _ -> StringValue(pokemon.form.name) }, + "feature" to Function { + val featureName = it.getStringOrNull(0) ?: return@Function DoubleValue.ZERO + val feature = pokemon.getOrCreateFeature(featureName) as? StringSpeciesFeature ?: return@Function DoubleValue.ZERO + + System.out.println("Test: " + featureName) + + val value = it.getStringOrNull(1) ?: return@Function StringValue(feature.value) + + System.out.println("Tester: " + value) + + feature.value = value + + pokemon.markFeatureDirty(feature) + pokemon.updateAspects() + pokemon.updateForm() + + return@Function DoubleValue.ONE + } + ) + }) + + fun Pokemon.asMoLangValue(): ObjectValue { + val value = ObjectValue( + obj = this, + stringify = { it.getDisplayName().toString() } + ) + value.addFunctions(pokemonFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap()) + return value + } + + val partyFunctions = mutableListOf<(PartyStore) -> HashMap>>( + { party -> + hashMapOf( +// "exists" to java.util.function.Function { it.getDoubleOrNull(0)?.toInt()?.let { party.get(it) }?.let { DoubleValue(1.0) } ?: DoubleValue(0.0) }, + "get" to java.util.function.Function { + it.getDoubleOrNull(0)?. + toInt()?.let { + party.get(it) + }?.asMoLangValue() ?: DoubleValue(0.0) } + ) + }) + + fun PartyStore.asMoLangValue(): ObjectValue { + val value = ObjectValue( + obj = this, + stringify = { "party" } + ) + value.addFunctions(partyFunctions.flatMap { it(this).entries.map { it.key to it.value } }.toMap()) + return value + } + MoLangFunctions.playerFunctions.add { player -> hashMapOf( "capped" to Function { @@ -55,6 +121,20 @@ object GenerationsMolangFunctions { }, "main_hand" to Function { player.mainHandItem.toMolang() + }, + "party" to Function { + player.party().asMoLangValue() + }, + + "has_in_party" to Function { + val properties = it.getStringOrNull(0)?.let { SpeciesKey.fromString(it) }?.createProperties() + + if(properties == null) return@Function DoubleValue(1.0) + + val index = it.getDoubleOrNull(1)?.toInt() + + if(index != null) return@Function DoubleValue(if (player.party().get(index)?.takeIf { properties.matches(it) } != null) 1.0 else 0.0) + else return@Function DoubleValue(if (player.party().any { properties.matches(it) }) 1.0 else 0.0) }) //TODO: Add money support } @@ -72,6 +152,18 @@ object GenerationsMolangFunctions { } +private fun Pokemon.getOrCreateFeature(featureName: String): SpeciesFeature? { + var provider = this.getProviderOrNull>(featureName) ?: return null + + when (provider) { + is ChoiceSpeciesFeatureProvider -> return provider.getOrCreate(this) + is FlagSpeciesFeatureProvider -> return provider.getOrCreate(this) + is IntSpeciesFeatureProvider -> return provider.getOrCreate(this) + } + + return null +} + private fun String.parseYaw(player: ServerPlayer): Float = if (startsWith("#")) TagKey.create(Registries.BLOCK, substring(1).asResource()).findNearestYaw(player) else ResourceKey.create(Registries.BLOCK, substring(1).asResource()).findNearestYaw(player) diff --git a/common/src/main/java/generations/gg/generations/core/generationscore/common/util/PokemonFunctions.kt b/common/src/main/java/generations/gg/generations/core/generationscore/common/util/PokemonFunctions.kt index 1cb3e8c6f..57f5640c8 100644 --- a/common/src/main/java/generations/gg/generations/core/generationscore/common/util/PokemonFunctions.kt +++ b/common/src/main/java/generations/gg/generations/core/generationscore/common/util/PokemonFunctions.kt @@ -1,5 +1,6 @@ package generations.gg.generations.core.generationscore.common.util +import com.cobblemon.mod.common.api.net.Encodable import com.cobblemon.mod.common.api.pokemon.PokemonProperties import com.cobblemon.mod.common.api.pokemon.PokemonSpecies import com.cobblemon.mod.common.api.pokemon.feature.* @@ -52,6 +53,8 @@ fun Pokemon.hasEmbeddedPokemon(): Boolean { } fun ChoiceSpeciesFeatureProvider.getOrCreate(pokemon: Pokemon, value: String = ""): StringSpeciesFeature = this.get(pokemon) ?: StringSpeciesFeature(keys.first(), value) +fun FlagSpeciesFeatureProvider.getOrCreate(pokemon: Pokemon, value: Boolean = false): FlagSpeciesFeature = this.get(pokemon) ?: FlagSpeciesFeature(keys.first(), value) +fun IntSpeciesFeatureProvider.getOrCreate(pokemon: Pokemon, value: Int = 0): IntSpeciesFeature = this.get(pokemon) ?: IntSpeciesFeature(keys.first(), value) fun ChoiceSpeciesFeatureProvider.cycle(value: String): String { val index = choices.indexOf(value) diff --git a/common/src/main/java/generations/gg/generations/core/generationscore/common/world/item/GenerationsItems.kt b/common/src/main/java/generations/gg/generations/core/generationscore/common/world/item/GenerationsItems.kt index 038d7da00..7e516e05c 100644 --- a/common/src/main/java/generations/gg/generations/core/generationscore/common/world/item/GenerationsItems.kt +++ b/common/src/main/java/generations/gg/generations/core/generationscore/common/world/item/GenerationsItems.kt @@ -799,7 +799,7 @@ object GenerationsItems { public static final RegistrySupplier BLUE_BIKE = register("blue_bike", Item::new, PLAYER_ITEMS); public static final RegistrySupplier PURPLE_BIKE = register("purple_bike", Item::new, PLAYER_ITEMS); */ - @JvmField val ROTOM_CATALOG = register("rotom_catalog", ::Item, PLAYER_ITEMS) + @JvmField val ROTOM_CATALOG = register("rotom_catalog", ::RotomCatalog, PLAYER_ITEMS) @JvmField val POKEDEX = register("pokedex", ::Item, PLAYER_ITEMS) @JvmField val LURE_MODULE = register("lure_module", ::Item, PLAYER_ITEMS) @JvmField val BOTTLE_CAP = register("bottle_cap", ::Item, PLAYER_ITEMS) diff --git a/common/src/main/java/generations/gg/generations/core/generationscore/common/world/item/RotomCatalog.kt b/common/src/main/java/generations/gg/generations/core/generationscore/common/world/item/RotomCatalog.kt new file mode 100644 index 000000000..0b754925f --- /dev/null +++ b/common/src/main/java/generations/gg/generations/core/generationscore/common/world/item/RotomCatalog.kt @@ -0,0 +1,29 @@ +package generations.gg.generations.core.generationscore.common.world.item + +import com.cobblemon.mod.common.api.dialogue.Dialogue +import com.cobblemon.mod.common.api.dialogue.Dialogues +import com.cobblemon.mod.common.util.openDialogue +import generations.gg.generations.core.generationscore.common.GenerationsCore +import net.minecraft.network.chat.Component +import net.minecraft.server.level.ServerPlayer +import net.minecraft.world.InteractionHand +import net.minecraft.world.InteractionResultHolder +import net.minecraft.world.entity.player.Player +import net.minecraft.world.item.Item +import net.minecraft.world.item.ItemStack +import net.minecraft.world.level.Level + +class RotomCatalog(properties: Properties) : Item(properties) { + override fun use(level: Level, player: Player, hand: InteractionHand): InteractionResultHolder { + if (player is ServerPlayer) { + if (hand == InteractionHand.MAIN_HAND) { + val dialogue: Dialogue = Dialogues.dialogues[GenerationsCore.id("rotom_catalog")] ?: return InteractionResultHolder.fail(player.mainHandItem) + + player.openDialogue(dialogue) + + return InteractionResultHolder.success(player.mainHandItem) + } + } + return super.use(level, player, hand) + } +} \ No newline at end of file diff --git a/common/src/main/resources/data/generations_core/dialogues/rotom_catalog.json b/common/src/main/resources/data/generations_core/dialogues/rotom_catalog.json new file mode 100644 index 000000000..d4f39a898 --- /dev/null +++ b/common/src/main/resources/data/generations_core/dialogues/rotom_catalog.json @@ -0,0 +1,149 @@ +{ + "speakers": { + "player": { + "face": "q.player.face();", + "name": { + "type": "expression", + "expression": "q.player.username" + } + } + }, + "pages": [ + { + "id": "intro", + "lines": [ + "Which rotom slot do you wish to change form?" + ], + "input": { + "type": "option", + "options": [ + { + "text": "Slot 1", + "value": "0", + "isVisible": "q.player.has_in_party('cobblemon:rotom', 0)", + "action": [ + "v.pokemon = q.player.party.get(0);", + "q.dialogue.set_page('forms');" + ] + }, + { + "text": "Slot 2", + "value": "1", + "isVisible": "q.player.has_in_party('cobblemon:rotom', 1)", + "action": [ + "v.pokemon = q.player.party.get(1);", + "q.dialogue.set_page('forms');" + ] + }, + { + "text": "Slot 3", + "value": "2", + "isVisible": "q.player.has_in_party('cobblemon:rotom', 2)", + "action": [ + "v.pokemon = q.player.party.get(2);", + "q.dialogue.set_page('forms');" + ] + }, + { + "text": "Slot 4", + "value": "3", + "isVisible": "q.player.has_in_party('cobblemon:rotom', 3)", + "action": [ + "v.pokemon = q.player.party.get(3);", + "q.dialogue.set_page('forms');" + ] + }, + { + "text": "Slot 5", + "value": "4", + "isVisible": "q.player.has_in_party('cobblemon:rotom', 4)", + "action": [ + "v.pokemon = q.player.party.get(4);", + "q.dialogue.set_page('forms');" + ] + }, + { + "text": "Slot 6", + "value": "5", + "isVisible": "q.player.has_in_party('cobblemon:rotom', 5)", + "action": [ + "v.pokemon = q.player.party.get(5);", + "q.dialogue.set_page('forms');" + ] + }, + { + "text": "None Available", + "value": "none", + "isVisible": "!q.player.has_in_party('cobblemon:rotom')", + "action": [ + "q.dialogue.close();" + ] + } + ] + } + }, + { + "id": "forms", + "lines": [ "Select form to change into:" ], + "input": { + "type": "option", + "options": [ + { + "text": "Normal", + "value": "normal", + "isVisible": "v.pokemon.feature('rotom_form') != 'false'", + "action": [ + "v.pokemon.feature('rotom_form', 'false');", + "q.dialogue.close();" + ] + }, + { + "text": "Heat", + "value": "heat", + "isVisible": "v.pokemon.feature('rotom_form') != 'heat'", + "action": [ + "v.pokemon.feature('rotom_form', 'heat');", + "q.dialogue.close();" + ] + }, + { + "text": "Wash", + "value": "wash", + "isVisible": "v.pokemon.feature('rotom_form') != 'wash'", + "action": [ + "v.pokemon.feature('rotom_form', 'wash');", + "q.dialogue.close();" + ] + }, + { + "text": "Frost", + "value": "frost", + "isVisible": "v.pokemon.feature('rotom_form') != 'frost'", + "action": [ + "v.pokemon.feature('rotom_form', 'frost');", + "q.dialogue.close();" + ] + }, + { + "text": "Fan", + "value": "fan", + "isVisible": "v.pokemon.feature('rotom_form') != 'fan'", + "action": [ + "v.pokemon.feature('rotom_form', 'fan');", + "q.dialogue.close();" + ] + }, + { + "text": "Mow", + "value": "mow", + "isVisible": "v.pokemon.feature('rotom_form') != 'mow'", + "action": [ + "v.pokemon.feature('rotom_form', 'mow');", + "q.dialogue.close();" + ] + } + ] + } + } + ] +} \ No newline at end of file