forked from mirrors/cobblemon
Added a bunch of alpha pokemon functionality, bunch temp
This commit is contained in:
@@ -0,0 +1,9 @@
|
|||||||
|
- Some kind of particle effect for them? they're meant to have glowing eyes, so maybe some red particles on the eye locator
|
||||||
|
--- global posers? stacked posers?
|
||||||
|
--- red texture seems to be what some people wanted.
|
||||||
|
|
||||||
|
/- shoulder mounts part of it
|
||||||
|
- omni boost
|
||||||
|
- roar when player comes within reach, adjust levels
|
||||||
|
|
||||||
|
- Riding settings to control what the min scale is for a pokemon to be ridable.
|
||||||
@@ -86,6 +86,7 @@ import com.cobblemon.mod.common.net.messages.client.settings.ServerSettingsPacke
|
|||||||
import com.cobblemon.mod.common.permission.LaxPermissionValidator
|
import com.cobblemon.mod.common.permission.LaxPermissionValidator
|
||||||
import com.cobblemon.mod.common.platform.events.PlatformEvents
|
import com.cobblemon.mod.common.platform.events.PlatformEvents
|
||||||
import com.cobblemon.mod.common.pokemon.Pokemon
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.pokemon.aspects.ALPHA_ASPECT
|
||||||
import com.cobblemon.mod.common.pokemon.aspects.CHARACTERISTIC_RAINBOW_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.CHARACTERISTIC_RAINBOW_ASPECT
|
||||||
import com.cobblemon.mod.common.pokemon.aspects.COSMETIC_SLOT_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.COSMETIC_SLOT_ASPECT
|
||||||
import com.cobblemon.mod.common.pokemon.aspects.GENDER_ASPECT
|
import com.cobblemon.mod.common.pokemon.aspects.GENDER_ASPECT
|
||||||
@@ -302,6 +303,7 @@ object Cobblemon {
|
|||||||
GENDER_ASPECT.register()
|
GENDER_ASPECT.register()
|
||||||
COSMETIC_SLOT_ASPECT.register()
|
COSMETIC_SLOT_ASPECT.register()
|
||||||
CHARACTERISTIC_RAINBOW_ASPECT.register()
|
CHARACTERISTIC_RAINBOW_ASPECT.register()
|
||||||
|
ALPHA_ASPECT.register()
|
||||||
|
|
||||||
SpeciesFeatures.types["choice"] = ChoiceSpeciesFeatureProvider::class.java
|
SpeciesFeatures.types["choice"] = ChoiceSpeciesFeatureProvider::class.java
|
||||||
SpeciesFeatures.types["flag"] = FlagSpeciesFeatureProvider::class.java
|
SpeciesFeatures.types["flag"] = FlagSpeciesFeatureProvider::class.java
|
||||||
|
|||||||
@@ -325,6 +325,8 @@ object CobblemonNetwork {
|
|||||||
list.add(PacketRegisterInfo(MarkingsUpdatePacket.ID, MarkingsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
list.add(PacketRegisterInfo(MarkingsUpdatePacket.ID, MarkingsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||||
list.add(PacketRegisterInfo(RideBoostsUpdatePacket.ID, RideBoostsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
list.add(PacketRegisterInfo(RideBoostsUpdatePacket.ID, RideBoostsUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||||
list.add(PacketRegisterInfo(RideStaminaUpdatePacket.ID, RideStaminaUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
list.add(PacketRegisterInfo(RideStaminaUpdatePacket.ID, RideStaminaUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||||
|
list.add(PacketRegisterInfo(AlphaUpdatePacket.ID, AlphaUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||||
|
list.add(PacketRegisterInfo(ScaleModifierUpdatePacket.ID, ScaleModifierUpdatePacket::decode, PokemonUpdatePacketHandler()))
|
||||||
|
|
||||||
// Evolution start
|
// Evolution start
|
||||||
list.add(PacketRegisterInfo(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler()))
|
list.add(PacketRegisterInfo(AddEvolutionPacket.ID, AddEvolutionPacket::decode, PokemonUpdatePacketHandler()))
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ open class PokemonProperties {
|
|||||||
props.gender = Gender.entries.toList().parsePropertyOfCollection(keyPairs, listOf("gender"), labelsOptional = true) { it.name.lowercase() }
|
props.gender = Gender.entries.toList().parsePropertyOfCollection(keyPairs, listOf("gender"), labelsOptional = true) { it.name.lowercase() }
|
||||||
props.level = parseIntProperty(keyPairs, listOf("level", "lvl", "l"))?.coerceIn(1, Cobblemon.config.maxPokemonLevel)
|
props.level = parseIntProperty(keyPairs, listOf("level", "lvl", "l"))?.coerceIn(1, Cobblemon.config.maxPokemonLevel)
|
||||||
props.shiny = parseBooleanProperty(keyPairs, listOf("shiny", "s"))
|
props.shiny = parseBooleanProperty(keyPairs, listOf("shiny", "s"))
|
||||||
|
props.isAlpha = parseBooleanProperty(keyPairs, listOf("alpha", "is_alpha"))
|
||||||
props.species = parseSpeciesIdentifier(keyPairs)
|
props.species = parseSpeciesIdentifier(keyPairs)
|
||||||
props.form = parseForm(keyPairs)
|
props.form = parseForm(keyPairs)
|
||||||
props.friendship = parseIntProperty(keyPairs, listOf("friendship"))?.coerceIn(0, Cobblemon.config.maxPokemonFriendship)
|
props.friendship = parseIntProperty(keyPairs, listOf("friendship"))?.coerceIn(0, Cobblemon.config.maxPokemonFriendship)
|
||||||
@@ -359,6 +360,7 @@ open class PokemonProperties {
|
|||||||
var heldItem: String? = null
|
var heldItem: String? = null
|
||||||
var cosmeticItem: String? = null
|
var cosmeticItem: String? = null
|
||||||
var scaleModifier: Float? = null
|
var scaleModifier: Float? = null
|
||||||
|
var isAlpha: Boolean? = null
|
||||||
|
|
||||||
var minPerfectIVs: Int? = null
|
var minPerfectIVs: Int? = null
|
||||||
var ivs: IVs? = null
|
var ivs: IVs? = null
|
||||||
@@ -409,6 +411,7 @@ open class PokemonProperties {
|
|||||||
shiny?.let { pokemon.shiny = it }
|
shiny?.let { pokemon.shiny = it }
|
||||||
gender?.let { pokemon.gender = it }
|
gender?.let { pokemon.gender = it }
|
||||||
level?.let { pokemon.level = it }
|
level?.let { pokemon.level = it }
|
||||||
|
isAlpha?.let { pokemon.isAlpha = it }
|
||||||
friendship?.also { pokemon.setFriendship(it) }
|
friendship?.also { pokemon.setFriendship(it) }
|
||||||
fullness?.let { pokemon.currentFullness = it }
|
fullness?.let { pokemon.currentFullness = it }
|
||||||
pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace())?.let { pokeball -> pokemon.caughtBall = pokeball } }
|
pokeball?.let { PokeBalls.getPokeBall(it.asIdentifierDefaultingNamespace())?.let { pokeball -> pokemon.caughtBall = pokeball } }
|
||||||
@@ -528,6 +531,7 @@ open class PokemonProperties {
|
|||||||
pokeball?.takeIf { it != pokemon.caughtBall.name.toString() }?.let { return false }
|
pokeball?.takeIf { it != pokemon.caughtBall.name.toString() }?.let { return false }
|
||||||
nature?.takeIf { it != pokemon.nature.name.toString() }?.let { return false }
|
nature?.takeIf { it != pokemon.nature.name.toString() }?.let { return false }
|
||||||
ability?.takeIf { it != pokemon.ability.name }?.let { return false }
|
ability?.takeIf { it != pokemon.ability.name }?.let { return false }
|
||||||
|
isAlpha?.takeIf { it != pokemon.isAlpha }?.let { return false }
|
||||||
status?.takeIf { it != pokemon.status?.status?.showdownName }?.let { return false }
|
status?.takeIf { it != pokemon.status?.status?.showdownName }?.let { return false }
|
||||||
minPerfectIVs?.takeIf { pokemon.ivs.count { stat -> stat.value == IVs.MAX_VALUE } < it }?.let { return false }
|
minPerfectIVs?.takeIf { pokemon.ivs.count { stat -> stat.value == IVs.MAX_VALUE } < it }?.let { return false }
|
||||||
ivs?.forEach{ stat ->
|
ivs?.forEach{ stat ->
|
||||||
@@ -587,6 +591,7 @@ open class PokemonProperties {
|
|||||||
friendship?.takeIf { it != properties.friendship }?.let { return false }
|
friendship?.takeIf { it != properties.friendship }?.let { return false }
|
||||||
pokeball?.takeIf { it != properties.pokeball }?.let { return false }
|
pokeball?.takeIf { it != properties.pokeball }?.let { return false }
|
||||||
nature?.takeIf { it != properties.nature }?.let { return false }
|
nature?.takeIf { it != properties.nature }?.let { return false }
|
||||||
|
isAlpha?.takeIf { it != properties.isAlpha }?.let { return false }
|
||||||
ability?.takeIf { it != properties.ability }?.let { return false }
|
ability?.takeIf { it != properties.ability }?.let { return false }
|
||||||
status?.takeIf { it != properties.status }?.let { return false }
|
status?.takeIf { it != properties.status }?.let { return false }
|
||||||
minPerfectIVs?.takeIf { it != properties.minPerfectIVs }?.let { return false }
|
minPerfectIVs?.takeIf { it != properties.minPerfectIVs }?.let { return false }
|
||||||
@@ -630,13 +635,13 @@ open class PokemonProperties {
|
|||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun roll(pokemon: Pokemon, player: ServerPlayer? = null) {
|
fun roll(pokemon: Pokemon, player: ServerPlayer? = null) {
|
||||||
val baseTypes = pokemon.form.types.toList()
|
val baseTypes = pokemon.form.types.toList()
|
||||||
var shinyRate = Cobblemon.config.shinyRate
|
var shinyRate = config.shinyRate
|
||||||
CobblemonEvents.SHINY_CHANCE_CALCULATION.post(ShinyChanceCalculationEvent(shinyRate, pokemon)) { event ->
|
CobblemonEvents.SHINY_CHANCE_CALCULATION.post(ShinyChanceCalculationEvent(shinyRate, pokemon)) { event ->
|
||||||
shinyRate = event.calculate(player)
|
shinyRate = event.calculate(player)
|
||||||
}
|
}
|
||||||
if (this.shiny == null) pokemon.shiny = shinyRate.checkRate()
|
if (this.shiny == null) pokemon.shiny = shinyRate.checkRate()
|
||||||
if (this.teraType == null) pokemon.teraType =
|
if (this.teraType == null) pokemon.teraType =
|
||||||
if (Cobblemon.config.teraTypeRate.checkRate()) {
|
if (config.teraTypeRate.checkRate()) {
|
||||||
var picked = TeraTypes.random(true)
|
var picked = TeraTypes.random(true)
|
||||||
while (picked is ElementalTypeTeraType && picked.type in pokemon.types) {
|
while (picked is ElementalTypeTeraType && picked.type in pokemon.types) {
|
||||||
picked = TeraTypes.random(true)
|
picked = TeraTypes.random(true)
|
||||||
@@ -644,6 +649,10 @@ open class PokemonProperties {
|
|||||||
picked
|
picked
|
||||||
}
|
}
|
||||||
else TeraTypes.forElementalType(baseTypes.random())
|
else TeraTypes.forElementalType(baseTypes.random())
|
||||||
|
isAlpha?.let { pokemon.isAlpha = it }
|
||||||
|
if (this.scaleModifier == null) {
|
||||||
|
pokemon.initializeScale()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
@@ -666,6 +675,7 @@ open class PokemonProperties {
|
|||||||
pokeball?.let { nbt.putString(DataKeys.POKEMON_CAUGHT_BALL, it) }
|
pokeball?.let { nbt.putString(DataKeys.POKEMON_CAUGHT_BALL, it) }
|
||||||
nature?.let { nbt.putString(DataKeys.POKEMON_NATURE, it) }
|
nature?.let { nbt.putString(DataKeys.POKEMON_NATURE, it) }
|
||||||
ability?.let { nbt.putString(DataKeys.POKEMON_ABILITY, it) }
|
ability?.let { nbt.putString(DataKeys.POKEMON_ABILITY, it) }
|
||||||
|
isAlpha?.let { nbt.putBoolean(DataKeys.POKEMON_ALPHA, it) }
|
||||||
status?.let { nbt.putString(DataKeys.POKEMON_STATUS_NAME, it) }
|
status?.let { nbt.putString(DataKeys.POKEMON_STATUS_NAME, it) }
|
||||||
minPerfectIVs?.let { nbt.putInt(DataKeys.POKEMON_MIN_PERFECT_IVS, it) }
|
minPerfectIVs?.let { nbt.putInt(DataKeys.POKEMON_MIN_PERFECT_IVS, it) }
|
||||||
ivs?.let { nbt.put(DataKeys.POKEMON_IVS, IVs.CODEC.encodeStart(NbtOps.INSTANCE, it).result().get()) }
|
ivs?.let { nbt.put(DataKeys.POKEMON_IVS, IVs.CODEC.encodeStart(NbtOps.INSTANCE, it).result().get()) }
|
||||||
@@ -700,6 +710,7 @@ open class PokemonProperties {
|
|||||||
pokeball = if (tag.contains(DataKeys.POKEMON_CAUGHT_BALL)) tag.getString(DataKeys.POKEMON_CAUGHT_BALL) else null
|
pokeball = if (tag.contains(DataKeys.POKEMON_CAUGHT_BALL)) tag.getString(DataKeys.POKEMON_CAUGHT_BALL) else null
|
||||||
nature = if (tag.contains(DataKeys.POKEMON_NATURE)) tag.getString(DataKeys.POKEMON_NATURE) else null
|
nature = if (tag.contains(DataKeys.POKEMON_NATURE)) tag.getString(DataKeys.POKEMON_NATURE) else null
|
||||||
ability = if (tag.contains(DataKeys.POKEMON_ABILITY)) tag.getString(DataKeys.POKEMON_ABILITY) else null
|
ability = if (tag.contains(DataKeys.POKEMON_ABILITY)) tag.getString(DataKeys.POKEMON_ABILITY) else null
|
||||||
|
isAlpha = if (tag.contains(DataKeys.POKEMON_ALPHA)) tag.getBoolean(DataKeys.POKEMON_ALPHA) else null
|
||||||
status = if (tag.contains(DataKeys.POKEMON_STATUS_NAME)) tag.getString(DataKeys.POKEMON_STATUS_NAME) else null
|
status = if (tag.contains(DataKeys.POKEMON_STATUS_NAME)) tag.getString(DataKeys.POKEMON_STATUS_NAME) else null
|
||||||
minPerfectIVs = if (tag.contains(DataKeys.POKEMON_MIN_PERFECT_IVS)) tag.getInt(DataKeys.POKEMON_MIN_PERFECT_IVS) else null
|
minPerfectIVs = if (tag.contains(DataKeys.POKEMON_MIN_PERFECT_IVS)) tag.getInt(DataKeys.POKEMON_MIN_PERFECT_IVS) else null
|
||||||
ivs = if (tag.contains(DataKeys.POKEMON_IVS)) IVs.CODEC.decode(NbtOps.INSTANCE, tag.getCompound(DataKeys.POKEMON_IVS)).result().getOrNull()?.first else null
|
ivs = if (tag.contains(DataKeys.POKEMON_IVS)) IVs.CODEC.decode(NbtOps.INSTANCE, tag.getCompound(DataKeys.POKEMON_IVS)).result().getOrNull()?.first else null
|
||||||
@@ -735,6 +746,7 @@ open class PokemonProperties {
|
|||||||
pokeball?.let { json.addProperty(DataKeys.POKEMON_CAUGHT_BALL, it) }
|
pokeball?.let { json.addProperty(DataKeys.POKEMON_CAUGHT_BALL, it) }
|
||||||
nature?.let { json.addProperty(DataKeys.POKEMON_NATURE, it) }
|
nature?.let { json.addProperty(DataKeys.POKEMON_NATURE, it) }
|
||||||
ability?.let { json.addProperty(DataKeys.POKEMON_ABILITY, it) }
|
ability?.let { json.addProperty(DataKeys.POKEMON_ABILITY, it) }
|
||||||
|
isAlpha?.let { json.addProperty(DataKeys.POKEMON_ALPHA, it) }
|
||||||
status?.let { json.addProperty(DataKeys.POKEMON_STATUS_NAME, it) }
|
status?.let { json.addProperty(DataKeys.POKEMON_STATUS_NAME, it) }
|
||||||
minPerfectIVs?.let { json.addProperty(DataKeys.POKEMON_MIN_PERFECT_IVS, it) }
|
minPerfectIVs?.let { json.addProperty(DataKeys.POKEMON_MIN_PERFECT_IVS, it) }
|
||||||
ivs?.let { json.add(DataKeys.POKEMON_IVS, IVs.CODEC.encodeStart(JsonOps.INSTANCE, it).result().get()) }
|
ivs?.let { json.add(DataKeys.POKEMON_IVS, IVs.CODEC.encodeStart(JsonOps.INSTANCE, it).result().get()) }
|
||||||
@@ -769,6 +781,7 @@ open class PokemonProperties {
|
|||||||
pokeball = json.get(DataKeys.POKEMON_CAUGHT_BALL)?.asString
|
pokeball = json.get(DataKeys.POKEMON_CAUGHT_BALL)?.asString
|
||||||
nature = json.get(DataKeys.POKEMON_NATURE)?.asString
|
nature = json.get(DataKeys.POKEMON_NATURE)?.asString
|
||||||
ability = json.get(DataKeys.POKEMON_ABILITY)?.asString
|
ability = json.get(DataKeys.POKEMON_ABILITY)?.asString
|
||||||
|
isAlpha = json.get(DataKeys.POKEMON_ALPHA)?.asBoolean
|
||||||
status = json.get(DataKeys.POKEMON_STATUS_NAME)?.asString
|
status = json.get(DataKeys.POKEMON_STATUS_NAME)?.asString
|
||||||
minPerfectIVs = json.get(DataKeys.POKEMON_MIN_PERFECT_IVS)?.asInt
|
minPerfectIVs = json.get(DataKeys.POKEMON_MIN_PERFECT_IVS)?.asInt
|
||||||
ivs = json.getAsJsonObject(DataKeys.POKEMON_IVS)?.let { IVs.CODEC.decode(JsonOps.INSTANCE, it).result().getOrNull()?.first }
|
ivs = json.getAsJsonObject(DataKeys.POKEMON_IVS)?.let { IVs.CODEC.decode(JsonOps.INSTANCE, it).result().getOrNull()?.first }
|
||||||
@@ -803,6 +816,7 @@ open class PokemonProperties {
|
|||||||
pokeball?.let { pieces.add("pokeball=$it") }
|
pokeball?.let { pieces.add("pokeball=$it") }
|
||||||
nature?.let { pieces.add("nature=$it") }
|
nature?.let { pieces.add("nature=$it") }
|
||||||
ability?.let { pieces.add("ability=$it") }
|
ability?.let { pieces.add("ability=$it") }
|
||||||
|
isAlpha?.let { pieces.add("alpha=$it") }
|
||||||
status?.let { pieces.add("status=$it") }
|
status?.let { pieces.add("status=$it") }
|
||||||
minPerfectIVs?.let { pieces.add("min_perfect_ivs=$it") }
|
minPerfectIVs?.let { pieces.add("min_perfect_ivs=$it") }
|
||||||
ivs?.forEach{ stat ->
|
ivs?.forEach{ stat ->
|
||||||
|
|||||||
+2
-2
@@ -20,8 +20,6 @@ import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
|||||||
import com.cobblemon.mod.common.api.pokemon.aspect.aspectParticleMap
|
import com.cobblemon.mod.common.api.pokemon.aspect.aspectParticleMap
|
||||||
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
import com.cobblemon.mod.common.api.pokemon.PokemonSpecies
|
||||||
import com.cobblemon.mod.common.api.pokemon.aspect.ParticleData
|
import com.cobblemon.mod.common.api.pokemon.aspect.ParticleData
|
||||||
import com.cobblemon.mod.common.api.riding.behaviour.RidingBehaviourState
|
|
||||||
import com.cobblemon.mod.common.api.riding.stats.RidingStat
|
|
||||||
import com.cobblemon.mod.common.api.scheduling.ScheduledTask
|
import com.cobblemon.mod.common.api.scheduling.ScheduledTask
|
||||||
import com.cobblemon.mod.common.api.scheduling.SchedulingTracker
|
import com.cobblemon.mod.common.api.scheduling.SchedulingTracker
|
||||||
import com.cobblemon.mod.common.api.scheduling.afterOnClient
|
import com.cobblemon.mod.common.api.scheduling.afterOnClient
|
||||||
@@ -112,6 +110,8 @@ class PokemonClientDelegate : PosableState(), PokemonSideDelegate {
|
|||||||
// force a model update - handles edge case where the PosableState's tracked PosableModel isn't updated until the LivingEntityRenderer render is run
|
// force a model update - handles edge case where the PosableState's tracked PosableModel isn't updated until the LivingEntityRenderer render is run
|
||||||
currentModel = VaryingModelRepository.getPoser(identifier, this)
|
currentModel = VaryingModelRepository.getPoser(identifier, this)
|
||||||
currentEntity.refreshRiding()
|
currentEntity.refreshRiding()
|
||||||
|
} else if (data == PokemonEntity.IS_ALPHA) {
|
||||||
|
currentEntity.pokemon.isAlpha = currentEntity.entityData.get(PokemonEntity.IS_ALPHA)
|
||||||
} else if (data == PokemonEntity.ASPECTS) {
|
} else if (data == PokemonEntity.ASPECTS) {
|
||||||
currentAspects = currentEntity.entityData.get(PokemonEntity.ASPECTS)
|
currentAspects = currentEntity.entityData.get(PokemonEntity.ASPECTS)
|
||||||
currentEntity.pokemon.shiny = currentAspects.contains("shiny")
|
currentEntity.pokemon.shiny = currentAspects.contains("shiny")
|
||||||
|
|||||||
@@ -601,6 +601,20 @@ class Summary private constructor(party: Collection<Pokemon?>, private val edita
|
|||||||
shadow = true
|
shadow = true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val sizeCategory = selectedPokemon.getSizeCategory()
|
||||||
|
val isAlpha = selectedPokemon.isAlpha
|
||||||
|
|
||||||
|
drawScaledText(
|
||||||
|
x = x + 62,
|
||||||
|
y = y + 32,
|
||||||
|
font = CobblemonResources.DEFAULT_LARGE,
|
||||||
|
context = context,
|
||||||
|
text = (if (isAlpha) "A".text() else sizeCategory.name.text()).bold(),
|
||||||
|
scale = 1F,
|
||||||
|
shadow = true,
|
||||||
|
centered = true
|
||||||
|
)
|
||||||
|
|
||||||
// Shiny Icon
|
// Shiny Icon
|
||||||
if (selectedPokemon.shiny) {
|
if (selectedPokemon.shiny) {
|
||||||
blitk(
|
blitk(
|
||||||
|
|||||||
+1
-1
@@ -113,7 +113,7 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
|
|||||||
open var properties = mutableMapOf<String, String>()
|
open var properties = mutableMapOf<String, String>()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hello future Hiro, this is past Hiro. You've gotten forgetful in your old age.
|
* Hello future Hiro, this is past Hiro. You've become forgetful in your old age.
|
||||||
*
|
*
|
||||||
* The profile translation is not actually necessary. The reason why you thought it was necessary
|
* The profile translation is not actually necessary. The reason why you thought it was necessary
|
||||||
* is that there is a 1.5 block offset applied by living-entity-renderer-intended models due to
|
* is that there is a 1.5 block offset applied by living-entity-renderer-intended models due to
|
||||||
|
|||||||
+1
-1
@@ -292,7 +292,7 @@ class PokemonRenderer(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun scale(pEntity: PokemonEntity, pPoseStack: PoseStack, pPartialTickTime: Float) {
|
override fun scale(pEntity: PokemonEntity, pPoseStack: PoseStack, pPartialTickTime: Float) {
|
||||||
val scale = pEntity.pokemon.form.baseScale * pEntity.pokemon.scaleModifier * (pEntity.delegate as PokemonClientDelegate).entityScaleModifier
|
val scale = pEntity.pokemon.form.baseScale * pEntity.pokemon.effectiveScale * (pEntity.delegate as PokemonClientDelegate).entityScaleModifier
|
||||||
pPoseStack.scale(scale, scale, scale)
|
pPoseStack.scale(scale, scale, scale)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -219,6 +219,18 @@ class CobblemonConfig {
|
|||||||
@CobblemonConfigField(Category.Pokemon, lang = "player_damage_pokemon", SERVER)
|
@CobblemonConfigField(Category.Pokemon, lang = "player_damage_pokemon", SERVER)
|
||||||
var playerDamagePokemon = true
|
var playerDamagePokemon = true
|
||||||
|
|
||||||
|
@CobblemonConfigField(Category.Pokemon, lang = "pokemon_size_variation", SERVER)
|
||||||
|
var pokemonSizeVariation = 0.05F
|
||||||
|
|
||||||
|
@CobblemonConfigField(Category.Pokemon, lang = "alpha_pokemon_size_multiplier", SERVER)
|
||||||
|
var alphaPokemonSizeMultiplier = 1.2F
|
||||||
|
|
||||||
|
@CobblemonConfigField(Category.Pokemon, lang = "baby_pokemon_level_duration", SERVER)
|
||||||
|
var babyPokemonLevelDuration = 9
|
||||||
|
|
||||||
|
@CobblemonConfigField(Category.Pokemon, lang = "baby_pokemon_size_multiplier", SERVER)
|
||||||
|
var babyPokemonSizeMultiplier = 0.8F
|
||||||
|
|
||||||
@CobblemonConfigField(Category.World, lang = "apple_leftovers_chance", SERVER)
|
@CobblemonConfigField(Category.World, lang = "apple_leftovers_chance", SERVER)
|
||||||
var appleLeftoversChance = 0.025
|
var appleLeftoversChance = 0.025
|
||||||
|
|
||||||
|
|||||||
@@ -213,6 +213,7 @@ open class PokemonEntity(
|
|||||||
@JvmStatic var RIDE_BOOSTS = SynchedEntityData.defineId(PokemonEntity::class.java, RideBoostsDataSerializer)
|
@JvmStatic var RIDE_BOOSTS = SynchedEntityData.defineId(PokemonEntity::class.java, RideBoostsDataSerializer)
|
||||||
@JvmStatic var RIDE_STAMINA = SynchedEntityData.defineId(PokemonEntity::class.java, EntityDataSerializers.FLOAT)
|
@JvmStatic var RIDE_STAMINA = SynchedEntityData.defineId(PokemonEntity::class.java, EntityDataSerializers.FLOAT)
|
||||||
@JvmStatic var SCALE_MODIFIER = SynchedEntityData.defineId(PokemonEntity::class.java, EntityDataSerializers.FLOAT)
|
@JvmStatic var SCALE_MODIFIER = SynchedEntityData.defineId(PokemonEntity::class.java, EntityDataSerializers.FLOAT)
|
||||||
|
@JvmStatic var IS_ALPHA = SynchedEntityData.defineId(PokemonEntity::class.java, EntityDataSerializers.BOOLEAN)
|
||||||
|
|
||||||
const val BATTLE_LOCK = "battle"
|
const val BATTLE_LOCK = "battle"
|
||||||
const val EVOLUTION_LOCK = "evolving"
|
const val EVOLUTION_LOCK = "evolving"
|
||||||
@@ -460,6 +461,7 @@ open class PokemonEntity(
|
|||||||
builder.define(RIDE_BOOSTS, emptyMap())
|
builder.define(RIDE_BOOSTS, emptyMap())
|
||||||
builder.define(RIDE_STAMINA, 1F)
|
builder.define(RIDE_STAMINA, 1F)
|
||||||
builder.define(SCALE_MODIFIER, 1F)
|
builder.define(SCALE_MODIFIER, 1F)
|
||||||
|
builder.define(IS_ALPHA, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSyncedDataUpdated(data: EntityDataAccessor<*>) {
|
override fun onSyncedDataUpdated(data: EntityDataAccessor<*>) {
|
||||||
@@ -1095,7 +1097,7 @@ open class PokemonEntity(
|
|||||||
override fun getBreedOffspring(serverLevel: ServerLevel, ageableMob: AgeableMob) = null
|
override fun getBreedOffspring(serverLevel: ServerLevel, ageableMob: AgeableMob) = null
|
||||||
|
|
||||||
override fun canSitOnShoulder(): Boolean {
|
override fun canSitOnShoulder(): Boolean {
|
||||||
return pokemon.form.shoulderMountable
|
return pokemon.form.shoulderMountable && !pokemon.isAlpha
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun wantsToPickUp(stack: ItemStack): Boolean {
|
override fun wantsToPickUp(stack: ItemStack): Boolean {
|
||||||
@@ -1253,7 +1255,7 @@ open class PokemonEntity(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getDimensions(pose: Pose): EntityDimensions {
|
override fun getDimensions(pose: Pose): EntityDimensions {
|
||||||
val scale = effects.mockEffect?.scale ?: (form.baseScale * pokemon.scaleModifier)
|
val scale = effects.mockEffect?.scale ?: (form.baseScale * pokemon.effectiveScale)
|
||||||
var result = this.exposedForm.hitbox.scale(scale)
|
var result = this.exposedForm.hitbox.scale(scale)
|
||||||
result = result.withEyeHeight(this.exposedForm.eyeHeight(this) * result.height)
|
result = result.withEyeHeight(this.exposedForm.eyeHeight(this) * result.height)
|
||||||
result = result.scale(this.scale)
|
result = result.scale(this.scale)
|
||||||
@@ -2610,11 +2612,15 @@ open class PokemonEntity(
|
|||||||
* represents a kind of 'responsibility' that the leader feels towards their followers - they believe in this
|
* represents a kind of 'responsibility' that the leader feels towards their followers - they believe in this
|
||||||
* leader with some amount of fervor, and this gets used to ensure that the leader doesn't choose to follow a
|
* leader with some amount of fervor, and this gets used to ensure that the leader doesn't choose to follow a
|
||||||
* different Pokémon that is of an equal or lower tier than this Pokémon is to its followers.
|
* different Pokémon that is of an equal or lower tier than this Pokémon is to its followers.
|
||||||
|
* - Alpha Pokémon automatically have the maximum possible tier.
|
||||||
*/
|
*/
|
||||||
fun getHerdTier(): Int {
|
fun getHerdTier(): Int {
|
||||||
val world = level() as? ServerLevel ?: return 0
|
val world = level() as? ServerLevel ?: return 0
|
||||||
val herdLeader = this.brain.getMemorySafely(CobblemonMemories.HERD_LEADER).orElse(null)?.let(UUID::fromString)?.let(world::getEntity) as? PokemonEntity
|
val herdLeader = this.brain.getMemorySafely(CobblemonMemories.HERD_LEADER).orElse(null)?.let(UUID::fromString)?.let(world::getEntity) as? PokemonEntity
|
||||||
return if (herdLeader == null) {
|
return if (herdLeader == null) {
|
||||||
|
if (pokemon.isAlpha) {
|
||||||
|
return Int.MAX_VALUE
|
||||||
|
}
|
||||||
if (!brain.hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES)) {
|
if (!brain.hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES)) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -2626,6 +2632,9 @@ open class PokemonEntity(
|
|||||||
it.behaviour.herd.bestMatchLeader(follower = it, possibleLeader = this)?.tier ?: 0
|
it.behaviour.herd.bestMatchLeader(follower = it, possibleLeader = this)?.tier ?: 0
|
||||||
} ?: 0
|
} ?: 0
|
||||||
} else {
|
} else {
|
||||||
|
if (herdLeader.pokemon.isAlpha) {
|
||||||
|
return Int.MAX_VALUE
|
||||||
|
}
|
||||||
herdLeader.behaviour.herd.bestMatchLeader(follower = this, possibleLeader = herdLeader)?.tier ?: 0
|
herdLeader.behaviour.herd.bestMatchLeader(follower = this, possibleLeader = herdLeader)?.tier ?: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -243,6 +243,9 @@ class PokemonServerDelegate : PokemonSideDelegate {
|
|||||||
if (entity.entityData.get(PokemonEntity.MARK) !=trackedMark) {
|
if (entity.entityData.get(PokemonEntity.MARK) !=trackedMark) {
|
||||||
entity.entityData.set(PokemonEntity.MARK, trackedMark)
|
entity.entityData.set(PokemonEntity.MARK, trackedMark)
|
||||||
}
|
}
|
||||||
|
if (entity.entityData.get(PokemonEntity.IS_ALPHA) != entity.pokemon.isAlpha) {
|
||||||
|
entity.entityData.set(PokemonEntity.IS_ALPHA, entity.pokemon.isAlpha)
|
||||||
|
}
|
||||||
entity.entityData.set(PokemonEntity.ASPECTS, trackedAspects)
|
entity.entityData.set(PokemonEntity.ASPECTS, trackedAspects)
|
||||||
entity.entityData.set(PokemonEntity.LABEL_LEVEL, entity.pokemon.level)
|
entity.entityData.set(PokemonEntity.LABEL_LEVEL, entity.pokemon.level)
|
||||||
|
|
||||||
|
|||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.net.messages.client.pokemon.update
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.api.pokeball.PokeBalls
|
||||||
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
|
import com.cobblemon.mod.common.util.readIdentifier
|
||||||
|
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update packet for the alpha (as in the big scary pack leader) status of a Pokémon.
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since December 1st, 2025
|
||||||
|
*/
|
||||||
|
class AlphaUpdatePacket(pokemon: () -> Pokemon?, value: Boolean): SingleUpdatePacket<Boolean, AlphaUpdatePacket>(pokemon, value) {
|
||||||
|
override val id = ID
|
||||||
|
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
|
||||||
|
buffer.writeBoolean(this.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(pokemon: Pokemon, value: Boolean) {
|
||||||
|
pokemon.isAlpha = value
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ID = cobblemonResource("alpha_update")
|
||||||
|
fun decode(buffer: RegistryFriendlyByteBuf): CaughtBallUpdatePacket {
|
||||||
|
val pokemon = decodePokemon(buffer)
|
||||||
|
val pokeBall = PokeBalls.getPokeBall(buffer.readIdentifier()) ?: PokeBalls.POKE_BALL
|
||||||
|
return CaughtBallUpdatePacket(pokemon, pokeBall)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.net.messages.client.pokemon.update
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.pokemon.Pokemon
|
||||||
|
import com.cobblemon.mod.common.util.cobblemonResource
|
||||||
|
import net.minecraft.network.RegistryFriendlyByteBuf
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update packet for a Pokémon's scale modifier.
|
||||||
|
*
|
||||||
|
* @author Hiroku
|
||||||
|
* @since December 1st, 2025
|
||||||
|
*/
|
||||||
|
class ScaleModifierUpdatePacket(pokemon: () -> Pokemon?, value: Float): SingleUpdatePacket<Float, ScaleModifierUpdatePacket>(pokemon, value) {
|
||||||
|
override val id = ID
|
||||||
|
override fun encodeValue(buffer: RegistryFriendlyByteBuf) {
|
||||||
|
buffer.writeFloat(this.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(pokemon: Pokemon, value: Float) {
|
||||||
|
pokemon.scaleModifier = value
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val ID = cobblemonResource("scale_modifier_update")
|
||||||
|
fun decode(buffer: RegistryFriendlyByteBuf): ScaleModifierUpdatePacket {
|
||||||
|
val pokemon = decodePokemon(buffer)
|
||||||
|
val scaleModifier = buffer.readFloat()
|
||||||
|
return ScaleModifierUpdatePacket(pokemon, scaleModifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -61,6 +61,7 @@ class SpawnPokemonPacket(
|
|||||||
var tickSpawned: Int,
|
var tickSpawned: Int,
|
||||||
var rideBoosts: Map<RidingStat, Float>,
|
var rideBoosts: Map<RidingStat, Float>,
|
||||||
var rideStamina: Float,
|
var rideStamina: Float,
|
||||||
|
var isAlpha: Boolean,
|
||||||
vanillaSpawnPacket: ClientboundAddEntityPacket,
|
vanillaSpawnPacket: ClientboundAddEntityPacket,
|
||||||
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
|
) : SpawnExtraDataEntityPacket<SpawnPokemonPacket, PokemonEntity>(vanillaSpawnPacket) {
|
||||||
|
|
||||||
@@ -93,6 +94,7 @@ class SpawnPokemonPacket(
|
|||||||
entity.tickCount,
|
entity.tickCount,
|
||||||
entity.entityData.get(PokemonEntity.RIDE_BOOSTS),
|
entity.entityData.get(PokemonEntity.RIDE_BOOSTS),
|
||||||
entity.entityData.get(PokemonEntity.RIDE_STAMINA),
|
entity.entityData.get(PokemonEntity.RIDE_STAMINA),
|
||||||
|
entity.entityData.get(PokemonEntity.IS_ALPHA),
|
||||||
vanillaSpawnPacket
|
vanillaSpawnPacket
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -127,6 +129,7 @@ class SpawnPokemonPacket(
|
|||||||
{ _, value -> buffer.writeFloat(value) }
|
{ _, value -> buffer.writeFloat(value) }
|
||||||
)
|
)
|
||||||
buffer.writeFloat(rideStamina)
|
buffer.writeFloat(rideStamina)
|
||||||
|
buffer.writeBoolean(isAlpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun applyData(entity: PokemonEntity, level: ClientLevel) {
|
override fun applyData(entity: PokemonEntity, level: ClientLevel) {
|
||||||
@@ -162,6 +165,7 @@ class SpawnPokemonPacket(
|
|||||||
entity.entityData.set(PokemonEntity.RIDE_BOOSTS, rideBoosts)
|
entity.entityData.set(PokemonEntity.RIDE_BOOSTS, rideBoosts)
|
||||||
entity.entityData.set(PokemonEntity.RIDE_STAMINA, rideStamina)
|
entity.entityData.set(PokemonEntity.RIDE_STAMINA, rideStamina)
|
||||||
entity.entityData.set(PokemonEntity.SCALE_MODIFIER, scaleModifier)
|
entity.entityData.set(PokemonEntity.SCALE_MODIFIER, scaleModifier)
|
||||||
|
entity.entityData.set(PokemonEntity.IS_ALPHA, isAlpha)
|
||||||
|
|
||||||
entity.ejectPassengers()
|
entity.ejectPassengers()
|
||||||
passengers.forEach {
|
passengers.forEach {
|
||||||
@@ -206,6 +210,7 @@ class SpawnPokemonPacket(
|
|||||||
{ buffer.readFloat() }
|
{ buffer.readFloat() }
|
||||||
)
|
)
|
||||||
val rideStamina = buffer.readFloat()
|
val rideStamina = buffer.readFloat()
|
||||||
|
val isAlpha = buffer.readBoolean()
|
||||||
val vanillaPacket = decodeVanillaPacket(buffer)
|
val vanillaPacket = decodeVanillaPacket(buffer)
|
||||||
|
|
||||||
return SpawnPokemonPacket(
|
return SpawnPokemonPacket(
|
||||||
@@ -235,6 +240,7 @@ class SpawnPokemonPacket(
|
|||||||
tickSpawned,
|
tickSpawned,
|
||||||
rideBoosts,
|
rideBoosts,
|
||||||
rideStamina,
|
rideStamina,
|
||||||
|
isAlpha,
|
||||||
vanillaPacket
|
vanillaPacket
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ import com.cobblemon.mod.common.util.codec.internal.ClientPokemonP3
|
|||||||
import com.cobblemon.mod.common.util.codec.internal.PokemonP1
|
import com.cobblemon.mod.common.util.codec.internal.PokemonP1
|
||||||
import com.cobblemon.mod.common.util.codec.internal.PokemonP2
|
import com.cobblemon.mod.common.util.codec.internal.PokemonP2
|
||||||
import com.cobblemon.mod.common.util.codec.internal.PokemonP3
|
import com.cobblemon.mod.common.util.codec.internal.PokemonP3
|
||||||
|
import com.cobblemon.mod.common.util.nextBetween
|
||||||
import com.cobblemon.mod.common.util.playSoundServer
|
import com.cobblemon.mod.common.util.playSoundServer
|
||||||
import com.cobblemon.mod.common.util.server
|
import com.cobblemon.mod.common.util.server
|
||||||
import com.cobblemon.mod.common.util.setPositionSafely
|
import com.cobblemon.mod.common.util.setPositionSafely
|
||||||
@@ -238,6 +239,15 @@ open class Pokemon : ShowdownIdentifiable {
|
|||||||
var characteristic: Characteristic = Characteristic.calculate(ivs, uuid)
|
var characteristic: Characteristic = Characteristic.calculate(ivs, uuid)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var isAlpha: Boolean = false
|
||||||
|
set(value) {
|
||||||
|
if (field != value) {
|
||||||
|
field = value
|
||||||
|
updateAspects()
|
||||||
|
onChange(AlphaUpdatePacket({ this }, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun setIV(stat : Stat, value : Int) {
|
fun setIV(stat : Stat, value : Int) {
|
||||||
val quotient = clamp(currentHealth / maxHealth.toFloat(), 0F, 1F)
|
val quotient = clamp(currentHealth / maxHealth.toFloat(), 0F, 1F)
|
||||||
ivs[stat] = value
|
ivs[stat] = value
|
||||||
@@ -246,6 +256,11 @@ open class Pokemon : ShowdownIdentifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun initializeScale() {
|
||||||
|
val variation = Cobblemon.config.pokemonSizeVariation
|
||||||
|
scaleModifier = Random.nextBetween(1 - variation, 1 + variation)
|
||||||
|
}
|
||||||
|
|
||||||
fun hyperTrainIV(stat: Stat, value: Int) {
|
fun hyperTrainIV(stat: Stat, value: Int) {
|
||||||
val quotient = clamp(currentHealth / maxHealth.toFloat(), 0F, 1F)
|
val quotient = clamp(currentHealth / maxHealth.toFloat(), 0F, 1F)
|
||||||
CobblemonEvents.HYPER_TRAINED_IV_PRE.postThen(
|
CobblemonEvents.HYPER_TRAINED_IV_PRE.postThen(
|
||||||
@@ -550,7 +565,23 @@ open class Pokemon : ShowdownIdentifiable {
|
|||||||
val speed: Int
|
val speed: Int
|
||||||
get() = getStat(Stats.SPEED)
|
get() = getStat(Stats.SPEED)
|
||||||
|
|
||||||
var scaleModifier = 1F
|
var scaleModifier: Float = 1F
|
||||||
|
set(value) {
|
||||||
|
if (field != value) {
|
||||||
|
field = value
|
||||||
|
onChange(ScaleModifierUpdatePacket({ this }, value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val effectiveScale: Float
|
||||||
|
get() {
|
||||||
|
val babyPokemonMultiplier = if (level - Cobblemon.config.babyPokemonLevelDuration < 1) {
|
||||||
|
Cobblemon.config.babyPokemonSizeMultiplier
|
||||||
|
} else {
|
||||||
|
1F
|
||||||
|
}
|
||||||
|
return babyPokemonMultiplier * if (this.isAlpha) Cobblemon.config.alphaPokemonSizeMultiplier else scaleModifier
|
||||||
|
}
|
||||||
|
|
||||||
var caughtBall: PokeBall = PokeBalls.POKE_BALL
|
var caughtBall: PokeBall = PokeBalls.POKE_BALL
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -2001,6 +2032,10 @@ open class Pokemon : ShowdownIdentifiable {
|
|||||||
return createPokemonProperties(*extractors.toTypedArray())
|
return createPokemonProperties(*extractors.toTypedArray())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getSizeCategory(): PokemonSizeCategory {
|
||||||
|
return PokemonSizeCategory.fromScale(scaleModifier)
|
||||||
|
}
|
||||||
|
|
||||||
fun addExperience(source: ExperienceSource, xp: Int): AddExperienceResult {
|
fun addExperience(source: ExperienceSource, xp: Int): AddExperienceResult {
|
||||||
if (xp < 0 || !this.canLevelUpFurther()) {
|
if (xp < 0 || !this.canLevelUpFurther()) {
|
||||||
return AddExperienceResult(level, level, emptySet(), 0) // no negatives!
|
return AddExperienceResult(level, level, emptySet(), 0) // no negatives!
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Cobblemon Contributors
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.cobblemon.mod.common.pokemon
|
||||||
|
|
||||||
|
import com.cobblemon.mod.common.Cobblemon
|
||||||
|
|
||||||
|
enum class PokemonSizeCategory {
|
||||||
|
XS,
|
||||||
|
S,
|
||||||
|
M,
|
||||||
|
L,
|
||||||
|
XL;
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// Find which size category corresponds to the given scale modifier.
|
||||||
|
// The scale modifier should be between 1 - Cobblemon.config.pokemonSizeVariation and 1 + Cobblemon.config.pokemonSizeVariation
|
||||||
|
// First 20% -> XS, etc.
|
||||||
|
fun fromScale(scaleModifier: Float): PokemonSizeCategory {
|
||||||
|
val range = Cobblemon.config.pokemonSizeVariation * 2
|
||||||
|
val segmentSize = range / PokemonSizeCategory.entries.size
|
||||||
|
val adjustedScale = scaleModifier - (1 - Cobblemon.config.pokemonSizeVariation)
|
||||||
|
val index = (adjustedScale / segmentSize).toInt().coerceIn(0, PokemonSizeCategory.entries.size - 1)
|
||||||
|
return PokemonSizeCategory.entries[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,6 +53,26 @@ val COSMETIC_SLOT_ASPECT = object : AspectProvider {
|
|||||||
override fun provide(properties: PokemonProperties) = emptySet<String>()
|
override fun provide(properties: PokemonProperties) = emptySet<String>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ALPHA_ASPECT = object : AspectProvider {
|
||||||
|
val ASPECT = "alpha"
|
||||||
|
|
||||||
|
override fun provide(pokemon: Pokemon): Set<String> {
|
||||||
|
return if (pokemon.isAlpha) {
|
||||||
|
setOf(ASPECT)
|
||||||
|
} else {
|
||||||
|
emptySet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun provide(properties: PokemonProperties): Set<String> {
|
||||||
|
return if (properties.isAlpha == true) {
|
||||||
|
setOf(ASPECT)
|
||||||
|
} else {
|
||||||
|
emptySet()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val CHARACTERISTIC_RAINBOW_ASPECT = object : AspectProvider {
|
val CHARACTERISTIC_RAINBOW_ASPECT = object : AspectProvider {
|
||||||
fun calculateColourAspect(nature: Nature, characteristic: Characteristic): String? {
|
fun calculateColourAspect(nature: Nature, characteristic: Characteristic): String? {
|
||||||
return when (nature.increasedStat to characteristic.relevantStat) {
|
return when (nature.increasedStat to characteristic.relevantStat) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ object DataKeys {
|
|||||||
const val POKEMON_FRIENDSHIP = "Friendship"
|
const val POKEMON_FRIENDSHIP = "Friendship"
|
||||||
const val POKEMON_FULLNESS = "Fullness"
|
const val POKEMON_FULLNESS = "Fullness"
|
||||||
const val POKEMON_INTERACTION_COOLDOWN = "InteractionCooldown"
|
const val POKEMON_INTERACTION_COOLDOWN = "InteractionCooldown"
|
||||||
|
const val POKEMON_ALPHA = "Alpha"
|
||||||
|
|
||||||
const val POKEMON_IVS = "IVs"
|
const val POKEMON_IVS = "IVs"
|
||||||
const val POKEMON_IVS_BASE = "Base"
|
const val POKEMON_IVS_BASE = "Base"
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ internal data class ClientPokemonP3(
|
|||||||
val rideBoosts: Map<String, Float>,
|
val rideBoosts: Map<String, Float>,
|
||||||
val currentFullness: Int,
|
val currentFullness: Int,
|
||||||
val interactionCooldowns: Map<ResourceLocation, Int>,
|
val interactionCooldowns: Map<ResourceLocation, Int>,
|
||||||
|
val isAlpha: Boolean,
|
||||||
) : Partial<Pokemon> {
|
) : Partial<Pokemon> {
|
||||||
|
|
||||||
override fun into(other: Pokemon): Pokemon {
|
override fun into(other: Pokemon): Pokemon {
|
||||||
@@ -53,6 +54,7 @@ internal data class ClientPokemonP3(
|
|||||||
this.rideBoosts.let { other.setRideBoosts(it.mapKeys { RidingStat.valueOf(it.key) }) }
|
this.rideBoosts.let { other.setRideBoosts(it.mapKeys { RidingStat.valueOf(it.key) }) }
|
||||||
other.currentFullness = this.currentFullness
|
other.currentFullness = this.currentFullness
|
||||||
other.interactionCooldowns = this.interactionCooldowns.toMutableMap()
|
other.interactionCooldowns = this.interactionCooldowns.toMutableMap()
|
||||||
|
other.isAlpha = isAlpha
|
||||||
return other
|
return other
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +77,7 @@ internal data class ClientPokemonP3(
|
|||||||
Codec.unboundedMap(Codec.STRING, Codec.FLOAT).fieldOf(DataKeys.POKEMON_RIDE_BOOSTS).forGetter(ClientPokemonP3::rideBoosts),
|
Codec.unboundedMap(Codec.STRING, Codec.FLOAT).fieldOf(DataKeys.POKEMON_RIDE_BOOSTS).forGetter(ClientPokemonP3::rideBoosts),
|
||||||
Codec.intRange(0, 100).fieldOf(DataKeys.POKEMON_FULLNESS).forGetter(ClientPokemonP3::currentFullness),
|
Codec.intRange(0, 100).fieldOf(DataKeys.POKEMON_FULLNESS).forGetter(ClientPokemonP3::currentFullness),
|
||||||
Codec.unboundedMap(ResourceLocation.CODEC, Codec.INT).fieldOf(DataKeys.POKEMON_INTERACTION_COOLDOWN).forGetter(ClientPokemonP3::interactionCooldowns),
|
Codec.unboundedMap(ResourceLocation.CODEC, Codec.INT).fieldOf(DataKeys.POKEMON_INTERACTION_COOLDOWN).forGetter(ClientPokemonP3::interactionCooldowns),
|
||||||
|
Codec.BOOL.optionalFieldOf(DataKeys.POKEMON_ALPHA, false).forGetter(ClientPokemonP3::isAlpha)
|
||||||
).apply(instance, ::ClientPokemonP3)
|
).apply(instance, ::ClientPokemonP3)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +95,7 @@ internal data class ClientPokemonP3(
|
|||||||
pokemon.getRideBoosts().mapKeys { it.key.name },
|
pokemon.getRideBoosts().mapKeys { it.key.name },
|
||||||
pokemon.currentFullness,
|
pokemon.currentFullness,
|
||||||
pokemon.interactionCooldowns,
|
pokemon.interactionCooldowns,
|
||||||
|
pokemon.isAlpha,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ internal data class PokemonP3(
|
|||||||
val rideStamina: Float,
|
val rideStamina: Float,
|
||||||
val currentFullness: Int,
|
val currentFullness: Int,
|
||||||
val interactionCooldowns: Map<ResourceLocation, Int>,
|
val interactionCooldowns: Map<ResourceLocation, Int>,
|
||||||
|
val isAlpha: Boolean
|
||||||
) : Partial<Pokemon> {
|
) : Partial<Pokemon> {
|
||||||
|
|
||||||
override fun into(other: Pokemon): Pokemon {
|
override fun into(other: Pokemon): Pokemon {
|
||||||
@@ -79,6 +80,7 @@ internal data class PokemonP3(
|
|||||||
other.rideStamina = this.rideStamina
|
other.rideStamina = this.rideStamina
|
||||||
other.currentFullness = this.currentFullness
|
other.currentFullness = this.currentFullness
|
||||||
other.interactionCooldowns = this.interactionCooldowns.toMutableMap()
|
other.interactionCooldowns = this.interactionCooldowns.toMutableMap()
|
||||||
|
other.isAlpha = isAlpha
|
||||||
other.recalculateCharacteristic()
|
other.recalculateCharacteristic()
|
||||||
other.updateAspects()
|
other.updateAspects()
|
||||||
return other
|
return other
|
||||||
@@ -102,6 +104,7 @@ internal data class PokemonP3(
|
|||||||
Codec.FLOAT.optionalFieldOf(DataKeys.POKEMON_RIDE_STAMINA, 1F).forGetter(PokemonP3::rideStamina),
|
Codec.FLOAT.optionalFieldOf(DataKeys.POKEMON_RIDE_STAMINA, 1F).forGetter(PokemonP3::rideStamina),
|
||||||
Codec.intRange(0, 100).optionalFieldOf(DataKeys.POKEMON_FULLNESS, 0).forGetter(PokemonP3::currentFullness),
|
Codec.intRange(0, 100).optionalFieldOf(DataKeys.POKEMON_FULLNESS, 0).forGetter(PokemonP3::currentFullness),
|
||||||
Codec.unboundedMap(ResourceLocation.CODEC, Codec.INT).optionalFieldOf(DataKeys.POKEMON_INTERACTION_COOLDOWN, emptyMap<ResourceLocation, Int>()).forGetter(PokemonP3::interactionCooldowns),
|
Codec.unboundedMap(ResourceLocation.CODEC, Codec.INT).optionalFieldOf(DataKeys.POKEMON_INTERACTION_COOLDOWN, emptyMap<ResourceLocation, Int>()).forGetter(PokemonP3::interactionCooldowns),
|
||||||
|
Codec.BOOL.optionalFieldOf(DataKeys.POKEMON_ALPHA, false).forGetter(PokemonP3::isAlpha)
|
||||||
).apply(instance) {
|
).apply(instance) {
|
||||||
originalTrainerType,
|
originalTrainerType,
|
||||||
originalTrainer,
|
originalTrainer,
|
||||||
@@ -117,7 +120,8 @@ internal data class PokemonP3(
|
|||||||
rideBoosts,
|
rideBoosts,
|
||||||
rideStamina,
|
rideStamina,
|
||||||
currentFullness,
|
currentFullness,
|
||||||
interactionCooldown -> PokemonP3(
|
interactionCooldown,
|
||||||
|
isAlpha -> PokemonP3(
|
||||||
originalTrainerType,
|
originalTrainerType,
|
||||||
originalTrainer,
|
originalTrainer,
|
||||||
forcedAspects.toSet(),
|
forcedAspects.toSet(),
|
||||||
@@ -133,6 +137,7 @@ internal data class PokemonP3(
|
|||||||
rideStamina,
|
rideStamina,
|
||||||
currentFullness,
|
currentFullness,
|
||||||
interactionCooldown,
|
interactionCooldown,
|
||||||
|
isAlpha
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -157,6 +162,7 @@ internal data class PokemonP3(
|
|||||||
pokemon.rideStamina,
|
pokemon.rideStamina,
|
||||||
pokemon.currentFullness,
|
pokemon.currentFullness,
|
||||||
pokemon.interactionCooldowns,
|
pokemon.interactionCooldowns,
|
||||||
|
pokemon.isAlpha
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2522,6 +2522,14 @@
|
|||||||
"cobblemon.config.ui.capture_calculator.tooltip": "The ID of the capture calculator. Can be added by another mod. If the ID doesn't exist it uses the default capture calculator.",
|
"cobblemon.config.ui.capture_calculator.tooltip": "The ID of the capture calculator. Can be added by another mod. If the ID doesn't exist it uses the default capture calculator.",
|
||||||
"cobblemon.config.ui.player_damage_pokemon": "Player Damage Pokémon",
|
"cobblemon.config.ui.player_damage_pokemon": "Player Damage Pokémon",
|
||||||
"cobblemon.config.ui.player_damage_pokemon.tooltip": "Whether Players can attack Pokémon like normal Minecraft entities.",
|
"cobblemon.config.ui.player_damage_pokemon.tooltip": "Whether Players can attack Pokémon like normal Minecraft entities.",
|
||||||
|
"cobblemon.config.ui.pokemon_size_variation": "Pokémon Size Variation",
|
||||||
|
"cobblemon.config.ui.pokemon_size_variation.tooltip": "How much variation in size is possible for spawned Pokémon.",
|
||||||
|
"cobblemon.config.ui.alpha_pokemon_size_multiplier": "Alpha Pokémon Size Multiplier",
|
||||||
|
"cobblemon.config.ui.alpha_pokemon_size_multiplier.tooltip": "The size multiplier applied to alpha Pokémon.",
|
||||||
|
"cobblemon.config.ui.baby_pokemon_level_duration": "Baby Pokémon Level Duration",
|
||||||
|
"cobblemon.config.ui.baby_pokemon_level_duration.tooltip": "The number of levels that a Pokémon is considered a baby for the purposes of appearing smaller than usual.",
|
||||||
|
"cobblemon.config.ui.baby_pokemon_size_multiplier": "Baby Pokémon Minimum Size",
|
||||||
|
"cobblemon.config.ui.baby_pokemon_size_multiplier.tooltip": "The size multiplier applied to a level 1 Pokémon.",
|
||||||
"cobblemon.config.ui.apple_leftovers_chance": "Apple Leftovers Chance",
|
"cobblemon.config.ui.apple_leftovers_chance": "Apple Leftovers Chance",
|
||||||
"cobblemon.config.ui.apple_leftovers_chance.tooltip": "The chance to drop Leftovers when a Player eats an item that has #cobblemon:held/leaves_leftovers.",
|
"cobblemon.config.ui.apple_leftovers_chance.tooltip": "The chance to drop Leftovers when a Player eats an item that has #cobblemon:held/leaves_leftovers.",
|
||||||
"cobblemon.config.ui.max_roots_in_area": "Max Roots in Area",
|
"cobblemon.config.ui.max_roots_in_area": "Max Roots in Area",
|
||||||
|
|||||||
Reference in New Issue
Block a user