mirror of
https://gitlab.com/cable-mc/cobblemon.git
synced 2026-10-21 06:36:25 -04:00
Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
874d1d9329 | ||
|
|
d29e688064 | ||
|
|
b6802069d8 | ||
|
|
a4b8aafa27 | ||
|
|
c46a4d5936 | ||
|
|
c3c57f3f33 | ||
|
|
0dba1e9f82 | ||
|
|
41457d8da8 | ||
|
|
a8db098652 | ||
|
|
1f241fc8dc | ||
|
|
3921295fee | ||
|
|
790e5e6c8b | ||
|
|
2957cabf86 | ||
|
|
6909c5ad6f | ||
|
|
c65d6bd83e | ||
|
|
dd6a526a49 | ||
|
|
b30b03fffd | ||
|
|
1953538db5 |
@@ -457,6 +457,7 @@
|
||||
- MoLang `run_action_effect` now works on Pokémon.
|
||||
- Changed MoLang entity function `is_standing_on` to allow for block tags in the list.
|
||||
- Added entity (as `q.entity`) that executed the command to the `executemolangscript` command.
|
||||
- A wild Pokémon using Teleport now ends the battle and causes the Pokémon to teleport a short distance away. Teleport still behaves the same in PvP battles.
|
||||
- Refactored the following events to `.Pre` and `.Post` for consistency:
|
||||
- `PokemonSentEvent`
|
||||
- `ExperienceGainedEvent`
|
||||
|
||||
@@ -219,6 +219,7 @@ open class PokemonBattle(
|
||||
}
|
||||
|
||||
fun broadcastChatMessage(component: Component) {
|
||||
if (ended) {return}
|
||||
chatLog.add(component)
|
||||
sendSpectatorUpdate(BattleMessagePacket(component))
|
||||
return actors.forEach { it.sendMessage(component) }
|
||||
|
||||
@@ -181,7 +181,7 @@ object ShowdownInterpreter {
|
||||
while (iterator.hasNext()) {
|
||||
val message = iterator.next()
|
||||
val id = message.id.replace("|", "")
|
||||
val instruction = updateInstructionParser[id]?.invoke(battle, instructionSet, message, iterator) ?: UnknownInstruction(message)
|
||||
val instruction: InterpreterInstruction = updateInstructionParser[id]?.invoke(battle, instructionSet, message, iterator) ?: UnknownInstruction(message)
|
||||
instructionSet.instructions.add(instruction)
|
||||
}
|
||||
}
|
||||
|
||||
+92
-11
@@ -15,6 +15,9 @@ import com.cobblemon.mod.common.CobblemonMemories
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.BattleMessage
|
||||
import com.cobblemon.mod.common.api.battles.interpreter.Effect
|
||||
import com.cobblemon.mod.common.api.battles.model.PokemonBattle
|
||||
import com.cobblemon.mod.common.api.battles.model.actor.EntityBackedBattleActor
|
||||
import com.cobblemon.mod.common.api.events.CobblemonEvents
|
||||
import com.cobblemon.mod.common.api.events.battles.BattleFledEvent
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addBattleMessageFunctions
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addStandardFunctions
|
||||
import com.cobblemon.mod.common.api.molang.MoLangFunctions.asMostSpecificMoLangValue
|
||||
@@ -22,19 +25,24 @@ import com.cobblemon.mod.common.api.moves.Moves
|
||||
import com.cobblemon.mod.common.api.moves.animations.ActionEffectContext
|
||||
import com.cobblemon.mod.common.api.moves.animations.TargetsProvider
|
||||
import com.cobblemon.mod.common.api.moves.animations.UsersProvider
|
||||
import com.cobblemon.mod.common.api.text.yellow
|
||||
import com.cobblemon.mod.common.battles.ShowdownInterpreter
|
||||
import com.cobblemon.mod.common.battles.actor.PlayerBattleActor
|
||||
import com.cobblemon.mod.common.battles.dispatch.CauserInstruction
|
||||
import com.cobblemon.mod.common.battles.dispatch.GO
|
||||
import com.cobblemon.mod.common.battles.dispatch.InstructionSet
|
||||
import com.cobblemon.mod.common.battles.dispatch.InterpreterInstruction
|
||||
import com.cobblemon.mod.common.battles.dispatch.UntilDispatch
|
||||
import com.cobblemon.mod.common.battles.pokemon.BattlePokemon
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.pokemon.evolution.progress.UseMoveEvolutionProgress
|
||||
import com.cobblemon.mod.common.util.asArrayValue
|
||||
import com.cobblemon.mod.common.util.battleLang
|
||||
import com.cobblemon.mod.common.util.cobblemonResource
|
||||
import com.cobblemon.mod.common.util.*
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.sounds.SoundEvents
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import java.lang.Math.*
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* Format: |move|POKEMON|MOVE|TARGET
|
||||
@@ -72,17 +80,27 @@ class MoveInstruction(
|
||||
val pokemonName = userPokemon.getName()
|
||||
ShowdownInterpreter.lastCauser[battle.battleId] = message
|
||||
// For Spread targets the message data only gives the pnx strings. So we can't know what pokemon are actually targeted until the previous messages have been interpreted
|
||||
val spreadTargetPokemon = spreadTargets.map { battle.activePokemon.firstOrNull() { poke -> poke.getPNX() == it }?.battlePokemon }
|
||||
val spreadTargetPokemon =
|
||||
spreadTargets.map { battle.activePokemon.firstOrNull() { poke -> poke.getPNX() == it }?.battlePokemon }
|
||||
|
||||
val targetPokemonEntity = targetPokemon?.entity
|
||||
if (targetPokemonEntity != null) {
|
||||
userPokemon.entity?.brain?.setMemory(CobblemonMemories.TARGETED_BATTLE_POKEMON, targetPokemonEntity.uuid)
|
||||
userPokemon.entity?.brain?.setMemory(
|
||||
CobblemonMemories.TARGETED_BATTLE_POKEMON,
|
||||
targetPokemonEntity.uuid
|
||||
)
|
||||
}
|
||||
|
||||
userPokemon.effectedPokemon.let { pokemon ->
|
||||
if (UseMoveEvolutionProgress.supports(pokemon, move)) {
|
||||
val progress = pokemon.evolutionProxy.current().progressFirstOrCreate({ it is UseMoveEvolutionProgress && it.currentProgress().move == move }) { UseMoveEvolutionProgress() }
|
||||
progress.updateProgress(UseMoveEvolutionProgress.Progress(move, progress.currentProgress().amount + 1))
|
||||
val progress = pokemon.evolutionProxy.current()
|
||||
.progressFirstOrCreate({ it is UseMoveEvolutionProgress && it.currentProgress().move == move }) { UseMoveEvolutionProgress() }
|
||||
progress.updateProgress(
|
||||
UseMoveEvolutionProgress.Progress(
|
||||
move,
|
||||
progress.currentProgress().amount + 1
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,7 +122,7 @@ class MoveInstruction(
|
||||
|
||||
val providers = mutableListOf<Any>(battle)
|
||||
userPokemon.effectedPokemon.entity?.let { entity ->
|
||||
runtime.environment.query.addFunction("user") { entity.asMostSpecificMoLangValue()}
|
||||
runtime.environment.query.addFunction("user") { entity.asMostSpecificMoLangValue() }
|
||||
UsersProvider(entity)
|
||||
}?.let(providers::add)
|
||||
|
||||
@@ -128,6 +146,24 @@ class MoveInstruction(
|
||||
level = battle.players.firstOrNull()?.level()
|
||||
)
|
||||
|
||||
if (isWildTeleport(battle)) {
|
||||
var teleportSuccess = false
|
||||
val teleportingEntity = userPokemon.originalPokemon.entity
|
||||
if (teleportingEntity != null) {
|
||||
teleportSuccess = tryTeleport(battle.players.firstOrNull()?.level() as ServerLevel, teleportingEntity, 10, 30, 32)
|
||||
}
|
||||
|
||||
if (teleportSuccess){
|
||||
battle.ended = true
|
||||
battle.dispatchWaiting(1.0F) {
|
||||
battle.actors.filterIsInstance<EntityBackedBattleActor<*>>().mapNotNull { it.entity }
|
||||
.forEach { it.sendSystemMessage(battleLang("wild_flee", pokemonName).yellow()) }
|
||||
battle.end()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val subsequentInstructions = instructionSet.findInstructionsCausedBy(this)
|
||||
val missedTargets = subsequentInstructions.filterIsInstance<MissInstruction>().mapNotNull { it.target }
|
||||
val hitCountInstruction = subsequentInstructions.filterIsInstance<HitCountInstruction>().firstOrNull()
|
||||
@@ -141,7 +177,8 @@ class MoveInstruction(
|
||||
}
|
||||
}
|
||||
|
||||
val hurtTargets = subsequentInstructions.filterIsInstance<DamageInstruction>().mapNotNull { it.expectedTarget }
|
||||
val hurtTargets =
|
||||
subsequentInstructions.filterIsInstance<DamageInstruction>().mapNotNull { it.expectedTarget }
|
||||
runtime.environment.query.addFunction("hurt") { params ->
|
||||
if (params.params.size == 0) {
|
||||
return@addFunction DoubleValue(hurtTargets.isNotEmpty())
|
||||
@@ -164,8 +201,52 @@ class MoveInstruction(
|
||||
return@dispatch UntilDispatch { "effects" !in holds }.andThen {
|
||||
val userPokemonId = userPokemon.entity?.uuid ?: return@andThen
|
||||
val targets = hurtTargets.mapNotNull { it.entity }
|
||||
userPokemonId.let { id -> targets.forEach { it.brain.setMemory(CobblemonMemories.TARGETED_BATTLE_POKEMON, id) } }
|
||||
userPokemonId.let { id ->
|
||||
targets.forEach {
|
||||
it.brain.setMemory(
|
||||
CobblemonMemories.TARGETED_BATTLE_POKEMON,
|
||||
id
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun tryTeleport(
|
||||
level: ServerLevel,
|
||||
pokemon: PokemonEntity,
|
||||
minRadius: Int,
|
||||
maxRadius: Int,
|
||||
attempts: Int
|
||||
): Boolean {
|
||||
val origin = pokemon.blockPosition()
|
||||
val rng = level.random
|
||||
var success = false
|
||||
|
||||
for (i in 0 until attempts) {
|
||||
val dist = rng.nextInt(minRadius, maxRadius + 1)
|
||||
val angle = rng.nextDouble() * (PI * 2.0)
|
||||
val dx = (cos(angle) * dist)
|
||||
val dz = (sin(angle) * dist)
|
||||
val x = (origin.x + dx)
|
||||
val yOffsetMax = rng.nextInt(5, 15)
|
||||
val z = (origin.z + dz)
|
||||
val yOffsets = (0..yOffsetMax).flatMap { listOf(it, -it) }.distinct()
|
||||
|
||||
//iterate over possible y distance, tries least vertical movement first
|
||||
for (yOffset in yOffsets){
|
||||
success = pokemon.randomTeleport(x, pokemon.position().y + yOffset, z, false)
|
||||
if (success) {
|
||||
level.playSoundServer(origin.toVec3d(), SoundEvents.PLAYER_TELEPORT)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun isWildTeleport(battle: PokemonBattle) : Boolean {
|
||||
return move.name == "teleport" && message.battlePokemon(0, battle)?.originalPokemon?.isWild() ?: false
|
||||
}
|
||||
}
|
||||
@@ -900,6 +900,7 @@
|
||||
"cobblemon.battle.lose": "%1$s be out of usable monsters!",
|
||||
"cobblemon.battle.forfeit": "%1$s forfeited th' battle!",
|
||||
"cobblemon.battle.flee": "Th' battle was fled.",
|
||||
"cobblemon.battle.wild_flee": "Th' scallywag, %1$s abandoned ship.",
|
||||
"cobblemon.battle.switch_option": "Switch monsters: ",
|
||||
"cobblemon.battle.your_team": "Ye crew:",
|
||||
"cobblemon.battle.must_switch": "Choose a monster to switch in",
|
||||
|
||||
@@ -2700,6 +2700,7 @@
|
||||
"cobblemon.battle.lose": "%1$s is out of usable Pokémon!",
|
||||
"cobblemon.battle.forfeit": "%1$s forfeited the battle!",
|
||||
"cobblemon.battle.flee": "The battle was fled.",
|
||||
"cobblemon.battle.wild_flee": "The wild %1$s fled.",
|
||||
"cobblemon.battle.switch_option": "Switch Pokémon: ",
|
||||
"cobblemon.battle.your_team": "Your Team:",
|
||||
"cobblemon.battle.must_switch": "Choose a Pokémon to switch in",
|
||||
|
||||
Reference in New Issue
Block a user