mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-30 13:58:53 -04:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a0f389c6b | ||
|
|
df8f078d13 |
No files matched your search
@@ -1,5 +1,11 @@
|
||||
# Changelog
|
||||
|
||||
## [1.5.2 (May 27th, 2024)](#1-5-2)
|
||||
### Fixes
|
||||
- Fixed Wooloo and Dubwool dyeing making your game start dying. Only if you do it on a server.
|
||||
- Fixed Gimmighoul causing PCs and parties to look glitched out, also only in a server.
|
||||
- Fixed players being able to dye other people's sheep Pokémon.
|
||||
|
||||
## [1.5.1 (May 27th, 2024)](#1-5-1)
|
||||
|
||||
### Additions
|
||||
|
||||
@@ -48,6 +48,7 @@ object CobblemonCommands {
|
||||
PokemonRestartCommand.register(dispatcher)
|
||||
BedrockParticleCommand.register(dispatcher)
|
||||
OpenDialogueCommand.register(dispatcher)
|
||||
ChallengeCommand.register(dispatcher)
|
||||
|
||||
// Possibly lock down registration if and only if under dev environment or running in an environment
|
||||
// with a certain system environment variable set
|
||||
|
||||
+3
-1
@@ -64,7 +64,9 @@ class ActivateInstruction(val instructionSet: InstructionSet, val message: Battl
|
||||
val actionEffect = status?.getActionEffect() ?: return@dispatch GO
|
||||
val providers = mutableListOf<Any>(battle)
|
||||
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
|
||||
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
if (!SwitchInstruction.isVirtual) {
|
||||
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
}
|
||||
val context = ActionEffectContext(
|
||||
actionEffect = actionEffect,
|
||||
runtime = runtime,
|
||||
|
||||
+3
-1
@@ -49,7 +49,9 @@ class BoostInstruction(val instructionSet: InstructionSet, val message: BattleMe
|
||||
val actionEffect = if (isBoost) BOOST_EFFECT else UNBOOST_EFFECT
|
||||
val providers = mutableListOf<Any>(battle)
|
||||
val pokemon = message.battlePokemon(0, battle) ?: return@dispatch GO
|
||||
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
if (!SwitchInstruction.isVirtual) {
|
||||
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
}
|
||||
val context = ActionEffectContext(
|
||||
actionEffect = actionEffect,
|
||||
runtime = runtime,
|
||||
|
||||
+3
-1
@@ -53,7 +53,9 @@ class CantInstruction(val message: BattleMessage): ActionEffectInstruction {
|
||||
val status = Statuses.getStatus(effectID)
|
||||
val actionEffect = status?.getActionEffect() ?: return@dispatch GO
|
||||
val providers = mutableListOf<Any>(battle)
|
||||
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
if (!SwitchInstruction.isVirtual) {
|
||||
pokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
}
|
||||
|
||||
val context = ActionEffectContext(
|
||||
actionEffect = actionEffect,
|
||||
|
||||
+5
-3
@@ -107,7 +107,9 @@ class DamageInstruction(
|
||||
}
|
||||
val actionEffect = status?.getActionEffect() ?: return@dispatch GO
|
||||
val providers = mutableListOf<Any>(battle)
|
||||
battlePokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
if (!SwitchInstruction.isVirtual) {
|
||||
battlePokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
}
|
||||
|
||||
val context = ActionEffectContext(
|
||||
actionEffect = actionEffect,
|
||||
@@ -132,7 +134,7 @@ class DamageInstruction(
|
||||
val pokemonName = battlePokemon.getName()
|
||||
val pokemonEntity = battlePokemon.entity
|
||||
//Play recoil animation if the pokemon recoiling isnt dead
|
||||
if (!causedFaint && pokemonEntity != null) {
|
||||
if (!causedFaint && pokemonEntity != null && !SwitchInstruction.isVirtual) {
|
||||
val pkt = PlayPoseableAnimationPacket(pokemonEntity.id, setOf("recoil"), emptySet())
|
||||
pkt.sendToPlayersAround(
|
||||
x = pokemonEntity.x,
|
||||
@@ -143,7 +145,7 @@ class DamageInstruction(
|
||||
)
|
||||
}
|
||||
//Play hit particle
|
||||
if (pokemonEntity != null) {
|
||||
if (pokemonEntity != null && !SwitchInstruction.isVirtual) {
|
||||
RunPosableMoLangPacket(pokemonEntity.id, setOf("q.particle('cobblemon:hit', 'target')")).sendToPlayersAround(
|
||||
x = pokemonEntity.x,
|
||||
y = pokemonEntity.y,
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ class DragInstruction(val instructionSet: InstructionSet, val battleActor: Battl
|
||||
val entity = if (battleActor is EntityBackedBattleActor<*>) battleActor.entity else null
|
||||
setOf(
|
||||
BattleDispatch {
|
||||
if (entity != null) {
|
||||
if (entity != null && !SwitchInstruction.isVirtual) {
|
||||
SwitchInstruction.createEntitySwitch(battle, battleActor, entity, pnx, activePokemon, pokemon, illusion, imposter)
|
||||
} else {
|
||||
SwitchInstruction.createNonEntitySwitch(battle, battleActor, pnx, activePokemon, pokemon, illusion)
|
||||
|
||||
+3
-1
@@ -38,7 +38,9 @@ class EndItemInstruction(val message: BattleMessage): InterpreterInstruction {
|
||||
battle.minorBattleActions[battlePokemon.uuid] = message
|
||||
battlePokemon.contextManager.remove(itemEffect.id, BattleContext.Type.ITEM)
|
||||
if (message.hasOptionalArgument("eat")) {
|
||||
battlePokemon.entity?.playSound(CobblemonSounds.BERRY_EAT, 1F, 1F)
|
||||
if (!SwitchInstruction.isVirtual) {
|
||||
battlePokemon.entity?.playSound(CobblemonSounds.BERRY_EAT, 1F, 1F)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -86,6 +86,7 @@ class MoveInstruction(
|
||||
battle.majorBattleActions[userPokemon.uuid] = message
|
||||
|
||||
val providers = mutableListOf<Any>(battle)
|
||||
if (SwitchInstruction.isVirtual) return@dispatch GO
|
||||
userPokemon.effectedPokemon.entity?.let { UsersProvider(it) }?.let(providers::add)
|
||||
targetPokemon?.effectedPokemon?.entity?.let { TargetsProvider(it) }?.let(providers::add)
|
||||
val runtime = MoLangRuntime().also {
|
||||
|
||||
+4
-2
@@ -32,8 +32,10 @@ class ReplaceInstruction(val message: BattleMessage): InterpreterInstruction {
|
||||
val pokemon = message.battlePokemon(0, battle) ?: return
|
||||
|
||||
battle.dispatchGo {
|
||||
val entity = pokemon.entity
|
||||
entity?.let { it.effects.mockEffect?.end(it) }
|
||||
if (!SwitchInstruction.isVirtual) {
|
||||
val entity = pokemon.entity
|
||||
entity?.let { it.effects.mockEffect?.end(it) }
|
||||
}
|
||||
|
||||
battle.sendSidedUpdate(
|
||||
source = actor,
|
||||
|
||||
+4
-2
@@ -48,7 +48,7 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
|
||||
activePokemon.battlePokemon = pokemon
|
||||
activePokemon.illusion = illusion
|
||||
val pokemonEntity = pokemon.entity
|
||||
if (pokemonEntity == null && entity != null) {
|
||||
if (pokemonEntity == null && entity != null && !isVirtual) {
|
||||
val targetPos = battleActor.getSide().getOppositeSide().actors.filterIsInstance<EntityBackedBattleActor<*>>().firstOrNull()?.entity?.pos?.let { pos ->
|
||||
val offset = pos.subtract(entity.pos)
|
||||
val idealPos = entity.pos.add(offset.multiply(0.33))
|
||||
@@ -87,7 +87,7 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
|
||||
|
||||
setOf(
|
||||
BattleDispatch {
|
||||
if (entity != null) {
|
||||
if (entity != null && !isVirtual) {
|
||||
createEntitySwitch(battle, actor, entity, pnx, activePokemon, pokemon, illusion, imposter)
|
||||
} else {
|
||||
createNonEntitySwitch(battle, actor, pnx, activePokemon, pokemon, illusion)
|
||||
@@ -99,6 +99,8 @@ class SwitchInstruction(val instructionSet: InstructionSet, val battleActor: Bat
|
||||
}
|
||||
|
||||
companion object{
|
||||
val isVirtual = true
|
||||
|
||||
fun createEntitySwitch(
|
||||
battle: PokemonBattle,
|
||||
actor: BattleActor,
|
||||
|
||||
+11
-7
@@ -40,22 +40,26 @@ class TransformInstruction(val battle: PokemonBattle, val message: BattleMessage
|
||||
ShowdownInterpreter.broadcastOptionalAbility(battle, effect, pokemon)
|
||||
|
||||
battle.dispatch {
|
||||
if (SwitchInstruction.isVirtual) return@dispatch GO
|
||||
val entity = pokemon.entity ?: return@dispatch GO
|
||||
val future = TransformEffect(targetPokemon.effectedPokemon, battle.started).start(entity)
|
||||
UntilDispatch { future?.isDone != false }
|
||||
}
|
||||
|
||||
battle.dispatchWaiting {
|
||||
val mock = pokemon.entity?.effects?.mockEffect?.mock
|
||||
val pokemonName = pokemon.getName()
|
||||
val targetPokemonName = targetPokemon.getName()
|
||||
|
||||
mock?.let {
|
||||
battle.sendSidedUpdate(
|
||||
source = actor,
|
||||
allyPacket = BattleTransformPokemonPacket(pnx, pokemon, it, true),
|
||||
opponentPacket = BattleTransformPokemonPacket(pnx, pokemon, it, false)
|
||||
)
|
||||
if (!SwitchInstruction.isVirtual) {
|
||||
val mock = pokemon.entity?.effects?.mockEffect?.mock
|
||||
|
||||
mock?.let {
|
||||
battle.sendSidedUpdate(
|
||||
source = actor,
|
||||
allyPacket = BattleTransformPokemonPacket(pnx, pokemon, it, true),
|
||||
opponentPacket = BattleTransformPokemonPacket(pnx, pokemon, it, false)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val lang = battleLang("transform", pokemonName, targetPokemonName)
|
||||
|
||||
@@ -10,6 +10,7 @@ package com.cobblemon.mod.common.battles.runner
|
||||
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.battles.runner.graal.GraalShowdownService
|
||||
import com.cobblemon.mod.common.battles.runner.socket.SocketShowdownService
|
||||
import com.google.gson.JsonArray
|
||||
import java.util.UUID
|
||||
|
||||
@@ -36,6 +37,6 @@ interface ShowdownService {
|
||||
|
||||
|
||||
companion object {
|
||||
val service: ShowdownService by lazy { GraalShowdownService() }
|
||||
val service: ShowdownService by lazy { SocketShowdownService() }
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-2
@@ -9,6 +9,7 @@
|
||||
package com.cobblemon.mod.common.battles.runner.socket
|
||||
|
||||
import com.cobblemon.mod.common.Cobblemon
|
||||
import com.cobblemon.mod.common.CobblemonImplementation
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||
import com.cobblemon.mod.common.battles.BagItems
|
||||
@@ -16,9 +17,11 @@ import com.cobblemon.mod.common.battles.ShowdownInterpreter
|
||||
import com.cobblemon.mod.common.battles.runner.ShowdownService
|
||||
import com.cobblemon.mod.common.pokemon.FormData
|
||||
import com.cobblemon.mod.common.pokemon.Species
|
||||
import com.cobblemon.mod.common.util.server
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonArray
|
||||
import java.io.BufferedReader
|
||||
import java.io.File
|
||||
import java.io.InputStreamReader
|
||||
import java.io.OutputStreamWriter
|
||||
import java.net.InetAddress
|
||||
@@ -83,7 +86,9 @@ class SocketShowdownService(val host: String = "localhost", val port: Int = 1846
|
||||
|
||||
private fun readMessage(): String {
|
||||
val payloadSize = read(reader, 8).toInt()
|
||||
println("Reading payload of size: $payloadSize")
|
||||
val payload = read(reader, payloadSize)
|
||||
println("Response: $payload")
|
||||
return payload
|
||||
}
|
||||
|
||||
@@ -113,7 +118,18 @@ class SocketShowdownService(val host: String = "localhost", val port: Int = 1846
|
||||
writer.write(">getCobbledMoves\n")
|
||||
writer.flush()
|
||||
val response = readMessage()
|
||||
return gson.fromJson(response, JsonArray::class.java)
|
||||
try {
|
||||
return gson.fromJson(response, JsonArray::class.java)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
println("Error, JSON logged to logs/showdown.log")
|
||||
File("./showdown.log").writer().use {
|
||||
server()?.getFile("./logs/showdown.log")?.writer().use { writer ->
|
||||
writer?.write(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
return JsonArray()
|
||||
}
|
||||
|
||||
override fun getItemIds(): JsonArray {
|
||||
@@ -166,4 +182,4 @@ class SocketShowdownService(val host: String = "localhost", val port: Int = 1846
|
||||
acknowledge()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.cobblemon.mod.common.command
|
||||
|
||||
import com.cobblemon.mod.common.battles.BattleBuilder
|
||||
import com.cobblemon.mod.common.util.party
|
||||
import com.mojang.brigadier.Command
|
||||
import com.mojang.brigadier.CommandDispatcher
|
||||
import com.mojang.brigadier.context.CommandContext
|
||||
import net.minecraft.command.argument.EntityArgumentType
|
||||
import net.minecraft.server.command.CommandManager
|
||||
import net.minecraft.server.command.ServerCommandSource
|
||||
|
||||
object ChallengeCommand {
|
||||
|
||||
fun register(dispatcher : CommandDispatcher<ServerCommandSource>) {
|
||||
val command = CommandManager.literal("battle")
|
||||
.then(
|
||||
CommandManager
|
||||
.argument("target", EntityArgumentType.player())
|
||||
.executes(::execute)
|
||||
)
|
||||
|
||||
dispatcher.register(command)
|
||||
}
|
||||
|
||||
private fun execute(context: CommandContext<ServerCommandSource>) : Int {
|
||||
val player = context.source.playerOrThrow
|
||||
val target = EntityArgumentType.getPlayer(context, "target")
|
||||
|
||||
val leadingPlayerPokemon = player.party().filterNotNull().firstOrNull() ?: return 0
|
||||
val leadingTargetPokemon = target.party().filterNotNull().firstOrNull() ?: return 0
|
||||
BattleBuilder.pvp1v1(player, target, leadingPlayerPokemon.uuid, leadingTargetPokemon.uuid)
|
||||
return Command.SINGLE_SUCCESS
|
||||
}
|
||||
|
||||
}
|
||||
@@ -619,147 +619,149 @@ open class PokemonEntity(
|
||||
val colorFeatureType = SpeciesFeatures.getFeaturesFor(pokemon.species).find { it is ChoiceSpeciesFeatureProvider && DataKeys.CAN_BE_COLORED in it.keys }
|
||||
val colorFeature = pokemon.getFeature<StringSpeciesFeature>(DataKeys.CAN_BE_COLORED)
|
||||
|
||||
if (itemStack.isOf(Items.SHEARS) && this.isShearable) {
|
||||
this.sheared(SoundCategory.PLAYERS)
|
||||
this.emitGameEvent(GameEvent.SHEAR, player)
|
||||
itemStack.damage(1, player) { it.sendToolBreakStatus(hand) }
|
||||
return ActionResult.SUCCESS
|
||||
}
|
||||
else if (itemStack.isOf(Items.BUCKET)) {
|
||||
if (pokemon.getFeature<FlagSpeciesFeature>(DataKeys.CAN_BE_MILKED) != null) {
|
||||
player.playSound(SoundEvents.ENTITY_GOAT_MILK, 1.0f, 1.0f)
|
||||
val milkBucket = ItemUsage.exchangeStack(itemStack, player, Items.MILK_BUCKET.defaultStack)
|
||||
player.setStackInHand(hand, milkBucket)
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
} else if (itemStack.isOf(Items.BOWL)) {
|
||||
if (pokemon.aspects.any() {it.contains("mooshtank")}) {
|
||||
player.playSound(SoundEvents.ENTITY_MOOSHROOM_MILK, 1.0f, 1.0f)
|
||||
// if the Mooshtank ate a Flower beforehand
|
||||
if (pokemon.lastFlowerFed != ItemStack.EMPTY && pokemon.aspects.any() {it.contains("mooshtank-brown")}) {
|
||||
var effect: StatusEffect? = null
|
||||
var duration = 0
|
||||
|
||||
if (pokemon.lastFlowerFed.isOf(Items.ALLIUM)) {
|
||||
effect = StatusEffect.byRawId(12) // Fire Resistance
|
||||
duration = 80 // 4 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.AZURE_BLUET)) {
|
||||
effect = StatusEffect.byRawId(15) // Blindness
|
||||
duration = 160 // 8 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.BLUE_ORCHID) || pokemon.lastFlowerFed.isOf(Items.DANDELION)) {
|
||||
effect = StatusEffect.byRawId(23) // Saturation
|
||||
duration = 7 // .35 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.CORNFLOWER)) {
|
||||
effect = StatusEffect.byRawId(8) // Jump Boost
|
||||
duration = 120 // 6 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.LILY_OF_THE_VALLEY)) {
|
||||
effect = StatusEffect.byRawId(19) // Poison
|
||||
duration = 240 // 12 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.OXEYE_DAISY)) {
|
||||
effect = StatusEffect.byRawId(10) // Regeneration
|
||||
duration = 160 // 8 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.POPPY) || pokemon.lastFlowerFed.isOf(Items.TORCHFLOWER)) {
|
||||
effect = StatusEffect.byRawId(16) // Night Vision
|
||||
duration = 100 // 5 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.PINK_TULIP) || pokemon.lastFlowerFed.isOf(Items.RED_TULIP) || pokemon.lastFlowerFed.isOf(Items.WHITE_TULIP) || pokemon.lastFlowerFed.isOf(Items.ORANGE_TULIP)) {
|
||||
effect = StatusEffect.byRawId(18) // Weakness
|
||||
duration = 180 // 9 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.WITHER_ROSE)) {
|
||||
effect = StatusEffect.byRawId(20) // Wither
|
||||
duration = 160 // 8 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(CobblemonItems.PEP_UP_FLOWER)) {
|
||||
effect = StatusEffect.byRawId(25) // Levitation
|
||||
duration = 160 // 8 seconds
|
||||
}
|
||||
|
||||
|
||||
// modify the suspicious stew with the effect
|
||||
val susStewStack = Items.SUSPICIOUS_STEW.defaultStack
|
||||
SuspiciousStewItem.addEffectToStew(susStewStack, effect, duration)
|
||||
val susStewEffect = ItemUsage.exchangeStack(itemStack, player, susStewStack)
|
||||
//give player modified Suspicious Stew
|
||||
player.setStackInHand(hand, susStewEffect)
|
||||
// reset the flower fed state
|
||||
pokemon.lastFlowerFed = ItemStack.EMPTY
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
else {
|
||||
val mushroomStew = ItemUsage.exchangeStack(itemStack, player, Items.MUSHROOM_STEW.defaultStack)
|
||||
player.setStackInHand(hand, mushroomStew)
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// Flowers used on brown MooshTanks
|
||||
else if (itemStack.isOf(Items.ALLIUM) ||
|
||||
itemStack.isOf(Items.AZURE_BLUET) ||
|
||||
itemStack.isOf(Items.BLUE_ORCHID) ||
|
||||
itemStack.isOf(Items.DANDELION) ||
|
||||
itemStack.isOf(Items.CORNFLOWER) ||
|
||||
itemStack.isOf(Items.LILY_OF_THE_VALLEY) ||
|
||||
itemStack.isOf(Items.OXEYE_DAISY) ||
|
||||
itemStack.isOf(Items.POPPY) ||
|
||||
itemStack.isOf(Items.TORCHFLOWER) ||
|
||||
itemStack.isOf(Items.PINK_TULIP) ||
|
||||
itemStack.isOf(Items.RED_TULIP) ||
|
||||
itemStack.isOf(Items.WHITE_TULIP) ||
|
||||
itemStack.isOf(Items.ORANGE_TULIP) ||
|
||||
itemStack.isOf(Items.WITHER_ROSE) ||
|
||||
itemStack.isOf(CobblemonItems.PEP_UP_FLOWER)) {
|
||||
if (pokemon.aspects.any() {it.contains("mooshtank")}) {
|
||||
player.playSound(SoundEvents.ENTITY_MOOSHROOM_EAT, 1.0f, 1.0f)
|
||||
pokemon.lastFlowerFed = itemStack
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
} else if(!player.isSneaking && (itemStack.isOf(CobblemonItems.RELIC_COIN)
|
||||
|| itemStack.isOf(CobblemonItems.RELIC_COIN_POUCH)
|
||||
|| itemStack.isOf(CobblemonItems.RELIC_COIN_SACK)
|
||||
|| itemStack.isOf(Items.NETHERITE_SCRAP)
|
||||
|| itemStack.isOf(Items.NETHERITE_INGOT)
|
||||
|| itemStack.isOf(Items.NETHERITE_BLOCK))) {
|
||||
|
||||
if(GimmighoulStashHandler.interactMob(player, hand, pokemon)) {
|
||||
if (ownerUuid == player.uuid || ownerUuid == null) {
|
||||
if (itemStack.isOf(Items.SHEARS) && this.isShearable) {
|
||||
this.sheared(SoundCategory.PLAYERS)
|
||||
this.emitGameEvent(GameEvent.SHEAR, player)
|
||||
itemStack.damage(1, player) { it.sendToolBreakStatus(hand) }
|
||||
return ActionResult.SUCCESS
|
||||
}
|
||||
}
|
||||
else if (itemStack.item is DyeItem && colorFeatureType != null) {
|
||||
val currentColor = colorFeature?.value ?: "white"
|
||||
val item = itemStack.item as DyeItem
|
||||
if (!item.color.name.equals(currentColor, ignoreCase = true)) {
|
||||
|
||||
val applied = if (item.color.name.lowercase() == "white" && colorFeature != null) {
|
||||
this.pokemon.features.remove(colorFeature)
|
||||
this.pokemon.anyChangeObservable.emit(pokemon)
|
||||
true
|
||||
} else if (colorFeature != null) {
|
||||
colorFeature.value = item.color.name.lowercase()
|
||||
this.pokemon.markFeatureDirty(colorFeature)
|
||||
true
|
||||
} else if (item.color.name.lowercase() != "white") {
|
||||
val newColorFeature = StringSpeciesFeature(DataKeys.CAN_BE_COLORED, item.color.name.lowercase())
|
||||
this.pokemon.features.add(newColorFeature)
|
||||
true
|
||||
} else {
|
||||
false
|
||||
} else if (itemStack.isOf(Items.BUCKET)) {
|
||||
if (pokemon.getFeature<FlagSpeciesFeature>(DataKeys.CAN_BE_MILKED) != null) {
|
||||
player.playSound(SoundEvents.ENTITY_GOAT_MILK, 1.0f, 1.0f)
|
||||
val milkBucket = ItemUsage.exchangeStack(itemStack, player, Items.MILK_BUCKET.defaultStack)
|
||||
player.setStackInHand(hand, milkBucket)
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
} else if (itemStack.isOf(Items.BOWL)) {
|
||||
if (pokemon.aspects.any { it.contains("mooshtank") }) {
|
||||
player.playSound(SoundEvents.ENTITY_MOOSHROOM_MILK, 1.0f, 1.0f)
|
||||
// if the Mooshtank ate a Flower beforehand
|
||||
if (pokemon.lastFlowerFed != ItemStack.EMPTY && pokemon.aspects.any() { it.contains("mooshtank-brown") }) {
|
||||
var effect: StatusEffect? = null
|
||||
var duration = 0
|
||||
|
||||
if (applied) {
|
||||
this.pokemon.updateAspects()
|
||||
if (!player.isCreative) {
|
||||
itemStack.decrement(1)
|
||||
if (pokemon.lastFlowerFed.isOf(Items.ALLIUM)) {
|
||||
effect = StatusEffect.byRawId(12) // Fire Resistance
|
||||
duration = 80 // 4 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.AZURE_BLUET)) {
|
||||
effect = StatusEffect.byRawId(15) // Blindness
|
||||
duration = 160 // 8 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.BLUE_ORCHID) || pokemon.lastFlowerFed.isOf(Items.DANDELION)) {
|
||||
effect = StatusEffect.byRawId(23) // Saturation
|
||||
duration = 7 // .35 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.CORNFLOWER)) {
|
||||
effect = StatusEffect.byRawId(8) // Jump Boost
|
||||
duration = 120 // 6 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.LILY_OF_THE_VALLEY)) {
|
||||
effect = StatusEffect.byRawId(19) // Poison
|
||||
duration = 240 // 12 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.OXEYE_DAISY)) {
|
||||
effect = StatusEffect.byRawId(10) // Regeneration
|
||||
duration = 160 // 8 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.POPPY) || pokemon.lastFlowerFed.isOf(Items.TORCHFLOWER)) {
|
||||
effect = StatusEffect.byRawId(16) // Night Vision
|
||||
duration = 100 // 5 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.PINK_TULIP) || pokemon.lastFlowerFed.isOf(Items.RED_TULIP) || pokemon.lastFlowerFed.isOf(
|
||||
Items.WHITE_TULIP
|
||||
) || pokemon.lastFlowerFed.isOf(Items.ORANGE_TULIP)
|
||||
) {
|
||||
effect = StatusEffect.byRawId(18) // Weakness
|
||||
duration = 180 // 9 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(Items.WITHER_ROSE)) {
|
||||
effect = StatusEffect.byRawId(20) // Wither
|
||||
duration = 160 // 8 seconds
|
||||
} else if (pokemon.lastFlowerFed.isOf(CobblemonItems.PEP_UP_FLOWER)) {
|
||||
effect = StatusEffect.byRawId(25) // Levitation
|
||||
duration = 160 // 8 seconds
|
||||
}
|
||||
|
||||
|
||||
// modify the suspicious stew with the effect
|
||||
val susStewStack = Items.SUSPICIOUS_STEW.defaultStack
|
||||
SuspiciousStewItem.addEffectToStew(susStewStack, effect, duration)
|
||||
val susStewEffect = ItemUsage.exchangeStack(itemStack, player, susStewStack)
|
||||
//give player modified Suspicious Stew
|
||||
player.setStackInHand(hand, susStewEffect)
|
||||
// reset the flower fed state
|
||||
pokemon.lastFlowerFed = ItemStack.EMPTY
|
||||
return ActionResult.success(world.isClient)
|
||||
} else {
|
||||
val mushroomStew = ItemUsage.exchangeStack(itemStack, player, Items.MUSHROOM_STEW.defaultStack)
|
||||
player.setStackInHand(hand, mushroomStew)
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
// Flowers used on brown MooshTanks
|
||||
else if (itemStack.isOf(Items.ALLIUM) ||
|
||||
itemStack.isOf(Items.AZURE_BLUET) ||
|
||||
itemStack.isOf(Items.BLUE_ORCHID) ||
|
||||
itemStack.isOf(Items.DANDELION) ||
|
||||
itemStack.isOf(Items.CORNFLOWER) ||
|
||||
itemStack.isOf(Items.LILY_OF_THE_VALLEY) ||
|
||||
itemStack.isOf(Items.OXEYE_DAISY) ||
|
||||
itemStack.isOf(Items.POPPY) ||
|
||||
itemStack.isOf(Items.TORCHFLOWER) ||
|
||||
itemStack.isOf(Items.PINK_TULIP) ||
|
||||
itemStack.isOf(Items.RED_TULIP) ||
|
||||
itemStack.isOf(Items.WHITE_TULIP) ||
|
||||
itemStack.isOf(Items.ORANGE_TULIP) ||
|
||||
itemStack.isOf(Items.WITHER_ROSE) ||
|
||||
itemStack.isOf(CobblemonItems.PEP_UP_FLOWER)
|
||||
) {
|
||||
if (pokemon.aspects.any { it.contains("mooshtank") }) {
|
||||
player.playSound(SoundEvents.ENTITY_MOOSHROOM_EAT, 1.0f, 1.0f)
|
||||
pokemon.lastFlowerFed = itemStack
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
} else if (!player.isSneaking && player.uuid == ownerUuid && (itemStack.isOf(CobblemonItems.RELIC_COIN)
|
||||
|| itemStack.isOf(CobblemonItems.RELIC_COIN_POUCH)
|
||||
|| itemStack.isOf(CobblemonItems.RELIC_COIN_SACK)
|
||||
|| itemStack.isOf(Items.NETHERITE_SCRAP)
|
||||
|| itemStack.isOf(Items.NETHERITE_INGOT)
|
||||
|| itemStack.isOf(Items.NETHERITE_BLOCK))
|
||||
) {
|
||||
if (GimmighoulStashHandler.interactMob(player, hand, pokemon)) {
|
||||
return ActionResult.SUCCESS
|
||||
}
|
||||
} else if (itemStack.item is DyeItem && colorFeatureType != null) {
|
||||
val currentColor = colorFeature?.value ?: ""
|
||||
val item = itemStack.item as DyeItem
|
||||
if (!item.color.name.equals(currentColor, ignoreCase = true)) {
|
||||
if (player is ServerPlayerEntity) {
|
||||
if (colorFeature != null) {
|
||||
colorFeature.value = item.color.name.lowercase()
|
||||
this.pokemon.markFeatureDirty(colorFeature)
|
||||
} else {
|
||||
val newColorFeature =
|
||||
StringSpeciesFeature(DataKeys.CAN_BE_COLORED, item.color.name.lowercase())
|
||||
this.pokemon.features.add(newColorFeature)
|
||||
this.pokemon.anyChangeObservable.emit(pokemon)
|
||||
}
|
||||
|
||||
this.pokemon.updateAspects()
|
||||
if (!player.isCreative) {
|
||||
itemStack.decrement(1)
|
||||
}
|
||||
}
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
} else if (itemStack.item.equals(Items.WATER_BUCKET) && colorFeatureType != null) {
|
||||
if (player is ServerPlayerEntity) {
|
||||
if (colorFeature != null) {
|
||||
if (!player.isCreative) {
|
||||
itemStack.decrement(1)
|
||||
player.giveOrDropItemStack(Items.BUCKET.defaultStack)
|
||||
}
|
||||
colorFeature.value = ""
|
||||
this.pokemon.markFeatureDirty(colorFeature)
|
||||
this.pokemon.updateAspects()
|
||||
}
|
||||
}
|
||||
return ActionResult.success(world.isClient)
|
||||
}
|
||||
}
|
||||
else if (itemStack.item.equals(Items.WATER_BUCKET) && colorFeature != null) {
|
||||
itemStack.decrement(1)
|
||||
player.giveOrDropItemStack(Items.BUCKET.defaultStack)
|
||||
colorFeature.value = ""
|
||||
this.pokemon.markFeatureDirty(colorFeature)
|
||||
this.pokemon.updateAspects()
|
||||
}
|
||||
|
||||
|
||||
if (hand == Hand.MAIN_HAND && player is ServerPlayerEntity && pokemon.getOwnerPlayer() == player) {
|
||||
if (player.isSneaking) {
|
||||
|
||||
@@ -269,7 +269,6 @@ class PokemonDTO : Encodable, Decodable {
|
||||
val featureProviders = SpeciesFeatures
|
||||
.getFeaturesFor(species)
|
||||
.filterIsInstance<SynchronizedSpeciesFeatureProvider<*>>()
|
||||
.filter { it.visible }
|
||||
val feature = featureProviders.firstNotNullOfOrNull { it(featuresBuffer, speciesFeatureName) }
|
||||
?: throw IllegalArgumentException("Couldn't find a feature provider to deserialize this feature. Something's wrong.")
|
||||
it.features.removeIf { it.name == feature.name }
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.cobblemon.mod.common.api.pokemon.experience.ExperienceSource
|
||||
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.SynchronizedSpeciesFeature
|
||||
import com.cobblemon.mod.common.api.pokemon.feature.SynchronizedSpeciesFeatureProvider
|
||||
import com.cobblemon.mod.common.api.pokemon.friendship.FriendshipMutationCalculator
|
||||
import com.cobblemon.mod.common.api.pokemon.labels.CobblemonPokemonLabels
|
||||
import com.cobblemon.mod.common.api.pokemon.moves.LearnsetQuery
|
||||
@@ -1618,7 +1619,8 @@ open class Pokemon : ShowdownIdentifiable {
|
||||
private val _originalTrainerName = registerObservable(SimpleObservable<String?>()) { OriginalTrainerUpdatePacket({ this }, it) }
|
||||
|
||||
private val _features = registerObservable(SimpleObservable<SpeciesFeature>()) {
|
||||
if (it is SynchronizedSpeciesFeature) {
|
||||
val featureProvider = SpeciesFeatures.getFeature(it.name)
|
||||
if (it is SynchronizedSpeciesFeature && featureProvider is SynchronizedSpeciesFeatureProvider && featureProvider.visible) {
|
||||
SpeciesFeatureUpdatePacket({ this }, species.resourceIdentifier, it)
|
||||
} else {
|
||||
null
|
||||
|
||||
+1
-1
@@ -190,7 +190,7 @@
|
||||
"layers": [
|
||||
{
|
||||
"name": "color",
|
||||
"texture": "cobblemon:textures/pokemon/0831_wooloo/wooloo_wool.png",
|
||||
"texture": "cobblemon:textures/pokemon/0831_wooloo/wooloo_wool_white.png",
|
||||
"emissive": false
|
||||
}
|
||||
]
|
||||
|
||||
@@ -21,5 +21,6 @@
|
||||
"black"
|
||||
],
|
||||
"isAspect": true,
|
||||
"visible": true,
|
||||
"aspectFormat": "color-{{choice}}"
|
||||
}
|
||||
+1
-1
@@ -12,7 +12,7 @@ mc_version = 1.20.1
|
||||
yarn_version = 1.20.1+build.9
|
||||
|
||||
mod_id=cobblemon
|
||||
mod_version=1.5.1
|
||||
mod_version=1.5.2
|
||||
snapshot=false
|
||||
|
||||
fabric.loom.multiProjectOptimisation=true
|
||||
Reference in new issue
Block a user