Compare commits

...
Author SHA1 Message Date
Polymeta 1ffd748615 heart particles <3
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-02-03 15:27:37 +00:00
Polymeta c6d1dce1b9 event for headpats
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-02-03 15:27:37 +00:00
Polymeta 268f8cf997 adjust cooldown to be 15 mins
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-02-03 15:27:37 +00:00
Polymeta c49c882a5b small fix with headpats
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-02-03 15:27:36 +00:00
Polymeta 55420ca53c port to 1.21, save last friendship gain via codec
Signed-off-by: Polymeta <40173118+Polymeta@users.noreply.github.com>
2025-02-03 15:27:36 +00:00
CerzixandPolymeta adcafc0234 CHANGED: Variable moved to companion object with static val 2025-02-03 15:27:36 +00:00
CerzixandPolymeta 8eb139bd3b CHANGED: Review changes implemented 2025-02-03 15:27:35 +00:00
CerzixandPolymeta 1ce91def2b CHANGED: Switched to a tick based solutions
CHANGED: now using minecraft constants for day length
CHANGED: now storing counter for headpats on Pokemon.kt not PokemonEntity.kt for consistency while being in the pokeball
2025-02-03 15:27:35 +00:00
CerzixandPolymeta b34f6fbfb0 CHANGED: Dropped Cobblemon suffix
CHANGED: Shortened variables
CHANGED: Added hand movement
CHANGED: Added Happiness increase by the following rules: Once every 20 minutes (1 full minecraft day) you should be able to pet your Pokemon to gain 2 points of friendship on that mon.
2025-02-03 15:27:34 +00:00
CerzixandPolymeta ad93e16028 ADDED: Headpat detection for owned pokemon, spawning heart particles and playing their cry
ADDED: Headpat detection for wild pokemon, not spawning heart particles, just playing cry.
ADDED: Parameter for detection of time between headpats to prevent spam.
2025-02-03 15:27:30 +00:00
8 changed files with 160 additions and 5 deletions
+46
View File
@@ -265,6 +265,52 @@
- Added effects for the burn status effect.
- Added effects for the moves: Seismic Toss, Withdraw, Bite, Crunch, Super Fang, Hyper Fang, Pursuit, Mist, Haze, Lick, Kinesis, Psychic, Water Sport, and Mud Sport.
- Added extra visuals to early berry growth stages.
- Adjusted Pokémon sendout positions for single battles.
- Wild Pokémon interaction range increased to 12 blocks (from 10 blocks)
- Player trade range increased to 12 blocks (from 10 blocks)
- PvP battle range increased to 32 blocks (from 10 blocks)
- Spectate range increased to 64 blocks (from 10 blocks)
- CriticalCaptures and Pokedex progress capture multiplier now work with dex
- Added the ability to pat your own Pokémon as an additional method to increase their happiness once a day.
### Developer
- SpawnCause is now an implementation of SpawningInfluence.
- Added "forcedAspects" to Pokemon to make it easier to easily add basic aspects to a Pokémon in a way that persists. We already know that everyone is going to overuse this.
- Made the Pokemon.aspects setter private. This could technically break sidemods but if you are affected by this then you were using it wrong! Use Pokemon.forcedAspects to fix it.
- Many types related to ``Pokemon`` including itself now have dedicated ``Codec``, please migrate to them from the NBT/JSON/PacketBuffer write/read methods.
- ``TeraTypes`` now implements ``Iterable``.
## [1.5.3](#1-5-3)
### Fixes
- Scaled down Amaura's fetus model to avoid clipping through the tank while animating
- Fixed Cubone's cry not having a sound.
- Fixed the Seafloor spawning context not being a usable context.
- Fixed Pokemon spawning in non-full blocks like slabs.
- Fixed Gilded Chests not dropping the chest itself when broken, only the contents.
- Fixed Pokémon losing their Hidden Ability through evolution if the middle stage did not have a Hidden Ability.
- Hidden Power no longer plays the water type action effect. (It now plays the normal type action effect.)
- Fixed Chimchar and Monferno T posing whenever they sleep.
- Fixed the Magby line not having any placeholder walk animations.
- Fixed Duskull and Dusclops using skylight levels for their nether spawn data. There is no sun in the Nether!
- Fixed Hisuian Zoroark using base Zoroark stats.
- Fixed Bellossom clipping into the player head when shoulder mounted.
- Fixed Shroomish's look range to prevent it from looking higher than it should.
- Fixed Crumbling Arch not blending in with the world.
- Fixed Energy Root applying being usable on a fainted Pokemon.
- Fixed Pokémon entity not spawning when starting a battle while recalling said Pokémon
- Fixed species comparison not using namespace for both sides in PokemonProperties.isSubsetOf.
- Fixed PokemonProperties#asString prefixing nicknames with a '$'
- Fixed PC not saving when Pokemon was changed outside.
- Fixed shearble Pokemon not dropping correct wool colors.
- Fixed pasture spawning Pokemon inside solid blocks when closest spawning position is blocked off.
- Fixed Tumbling Down advancement not being granted by tumblestone variants.
- Improve error handling when loading spawn-sets to ensure invalid configurations don't crash the server
- Fixed empty JsonPlayerData files resulting in players being unable to join server/world
### Additions
- Added extra visuals to early berry growth stages
- Hidden Power now displays its effective typing.
- Moves impacted by the abilities Pixelate, Refrigerate, Aerilate, Galvanize, and Normalize now display as their altered typing.
- Added Polished Tumblestone and Tumblestone Brick block sets from Tumblestone, Black Tumblestone, and Sky Tumblestone.
- Moves impacted by the abilities Pixelate, Refrigerate, Aerilate, Galvanize, and Normalize now display as their altered typing.
- Added Fire, Water, Thunder, Leaf, Ice, Sun, Moon, Shiny, Dawn, and Dusk Stone storage blocks.
@@ -77,6 +77,8 @@ object CobblemonEvents {
val EVOLUTION_COMPLETE = EventObservable<EvolutionCompleteEvent>()
@JvmField
val POKEMON_NICKNAMED = CancelableObservable<PokemonNicknamedEvent>()
@JvmField
val POKEMON_HEADPAT = CancelableObservable<PokemonHeadpatEvent>()
@JvmField
val THROWN_POKEBALL_HIT = CancelableObservable<ThrownPokeballHitEvent>()
@@ -0,0 +1,19 @@
/*
* 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.api.events.pokemon
import com.cobblemon.mod.common.api.events.Cancelable
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import net.minecraft.server.level.ServerPlayer
/**
* Fired whenever a pokemon is about to receive a headpat that would increment it's friendship.
* Cancelling will prevent this interaction from taking place
*/
data class PokemonHeadpatEvent(val pokemon: PokemonEntity, val player: ServerPlayer) : Cancelable()
@@ -20,6 +20,7 @@ import com.cobblemon.mod.common.api.events.CobblemonEvents
import com.cobblemon.mod.common.api.events.entity.PokemonEntityLoadEvent
import com.cobblemon.mod.common.api.events.entity.PokemonEntitySaveEvent
import com.cobblemon.mod.common.api.events.entity.PokemonEntitySaveToWorldEvent
import com.cobblemon.mod.common.api.events.pokemon.PokemonHeadpatEvent
import com.cobblemon.mod.common.api.events.pokemon.ShoulderMountEvent
import com.cobblemon.mod.common.api.interaction.PokemonEntityInteraction
import com.cobblemon.mod.common.api.molang.MoLangFunctions.addEntityFunctions
@@ -62,6 +63,7 @@ import com.cobblemon.mod.common.entity.pokemon.ai.goals.*
import com.cobblemon.mod.common.entity.pokemon.effects.EffectTracker
import com.cobblemon.mod.common.entity.pokemon.effects.IllusionEffect
import com.cobblemon.mod.common.net.messages.client.animation.PlayPosableAnimationPacket
import com.cobblemon.mod.common.net.messages.client.effect.SpawnSnowstormEntityParticlePacket
import com.cobblemon.mod.common.net.messages.client.sound.UnvalidatedPlaySoundS2CPacket
import com.cobblemon.mod.common.net.messages.client.spawn.SpawnPokemonPacket
import com.cobblemon.mod.common.net.messages.client.ui.InteractPokemonUIPacket
@@ -103,6 +105,10 @@ import net.minecraft.network.protocol.game.DebugPackets
import net.minecraft.network.syncher.EntityDataAccessor
import net.minecraft.network.syncher.EntityDataSerializers
import net.minecraft.network.syncher.SynchedEntityData
import net.minecraft.SharedConstants
import net.minecraft.core.particles.ParticleTypes
import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket
import java.util.*
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerEntity
import net.minecraft.server.level.ServerLevel
@@ -230,7 +236,7 @@ open class PokemonEntity(
get() = entityData.get(FRIENDSHIP)
var drops: DropTable? = null
var lastHeadpat: Long = 0L
var tethering: PokemonPastureBlockEntity.Tethering? = null
var queuedToDespawn = false
@@ -932,8 +938,9 @@ open class PokemonEntity(
player
)
} else {
// TODO #105
if (this.attemptItemInteraction(player, player.getItemInHand(hand))) return InteractionResult.SUCCESS
onHeadpat(pokemon, player)
}
}
@@ -1565,6 +1572,25 @@ open class PokemonEntity(
}
}
fun onHeadpat(pokemon: Pokemon, player: ServerPlayer) {
val currentTime = level().dayTime
if(currentTime - 30 < lastHeadpat){
return
}
lastHeadpat = currentTime
cry()
player.swing(InteractionHand.MAIN_HAND, true)
if(pokemon.headpatTime == 0L || lastHeadpat > (pokemon.headpatTime + (SharedConstants.TICKS_PER_MINUTE * 15))){
CobblemonEvents.POKEMON_HEADPAT.postThen(PokemonHeadpatEvent(this, player)) {
pokemon.headpatTime = currentTime
pokemon.incrementFriendship(2)
SpawnSnowstormEntityParticlePacket(cobblemonResource("happyheart"), id)
.sendToPlayersAround(this.x, this.y, this.z, 16.0, this.level().dimension())
}
}
}
/** Retrieves the battle theme associated with this Pokemon's Species/Form, or the default PVW theme if not found. */
fun getBattleTheme() = BuiltInRegistries.SOUND_EVENT.get(this.form.battleTheme) ?: CobblemonSounds.PVW_BATTLE
@@ -342,6 +342,10 @@ open class Pokemon : ShowdownIdentifiable {
val types: Iterable<ElementalType>
get() = form.types
var headpatTime: Long = 0L
set(value) {
field = value
}
var teraType: TeraType = TeraTypes.forElementalType(this.primaryType)
set(value) {
@@ -29,6 +29,7 @@ internal data class PokemonP3(
val originalTrainer: Optional<String>,
val forcedAspects: Set<String>,
val features: List<CompoundTag>,
val headpatTime: Long
) : Partial<Pokemon> {
override fun into(other: Pokemon): Pokemon {
@@ -53,6 +54,7 @@ internal data class PokemonP3(
other.features.removeIf { it.name == feature.name }
other.features.add(feature)
}
other.headpatTime = this.headpatTime
return other
}
@@ -62,8 +64,9 @@ internal data class PokemonP3(
OriginalTrainerType.CODEC.optionalFieldOfWithDefault(DataKeys.POKEMON_ORIGINAL_TRAINER_TYPE, OriginalTrainerType.NONE).forGetter(PokemonP3::originalTrainerType),
Codec.STRING.optionalFieldOf(DataKeys.POKEMON_ORIGINAL_TRAINER).forGetter(PokemonP3::originalTrainer),
Codec.list(Codec.STRING).optionalFieldOf(DataKeys.POKEMON_FORCED_ASPECTS, emptyList()).forGetter { it.forcedAspects.toMutableList() },
Codec.list(CompoundTag.CODEC).optionalFieldOf(FEATURES, emptyList()).forGetter(PokemonP3::features)
).apply(instance) { originalTrainerType, originalTrainer, forcedAspects, features -> PokemonP3(originalTrainerType, originalTrainer, forcedAspects.toSet(), features) }
Codec.list(CompoundTag.CODEC).optionalFieldOf(FEATURES, emptyList()).forGetter(PokemonP3::features),
Codec.LONG.optionalFieldOf("headpatTime", 0L).forGetter(PokemonP3::headpatTime)
).apply(instance) { originalTrainerType, originalTrainer, forcedAspects, features, headpatTime -> PokemonP3(originalTrainerType, originalTrainer, forcedAspects.toSet(), features, headpatTime) }
}
internal fun from(pokemon: Pokemon): PokemonP3 = PokemonP3(
@@ -74,7 +77,8 @@ internal data class PokemonP3(
val nbt = CompoundTag()
nbt.putString(FEATURE_ID, feature.name)
feature.saveToNBT(nbt)
}
},
pokemon.headpatTime
)
}
@@ -0,0 +1,54 @@
{
"format_version": "1.10.0",
"particle_effect": {
"description": {
"identifier": "cobblemon:happyheart",
"basic_render_parameters": {
"material": "particles_blend",
"texture": "textures/particles/happyheart"
}
},
"curves": {
"variable.smoothshrink": {
"type": "linear",
"input": "v.particle_age",
"horizontal_range": "v.particle_lifetime",
"nodes": [0, 0.5, 1, 1, 1, 1, 1, 1, 1, 0.8, 0]
}
},
"components": {
"minecraft:emitter_rate_steady": {
"spawn_rate": "math.clamp(25*(q.entity_radius*1.5),20,100)",
"max_particles": 120
},
"minecraft:emitter_lifetime_once": {
"active_time": 0.2
},
"minecraft:emitter_shape_disc": {
"offset": [0, "(q.entity_height*0.55)+(math.sin(v.emitter_age*1450)*(q.entity_height*0.33))", 0],
"radius": "(q.entity_radius*(1.2-v.emitter_age))/math.clamp(q.entity_scale*1.1-0.07,1,2)",
"surface_only": true,
"direction": [0, "math.random(1,2)", 0]
},
"minecraft:particle_lifetime_expression": {
"max_lifetime": 0.9
},
"minecraft:particle_initial_speed": "1.5+(q.entity_height*0.1)",
"minecraft:particle_motion_dynamic": {
"linear_acceleration": [0, -0.1, 0],
"linear_drag_coefficient": 2.5
},
"minecraft:particle_appearance_billboard": {
"size": ["((0.16-(v.particle_random_2*0.05))*math.clamp(q.entity_height*0.85,1,3))*v.smoothshrink", "((0.14-(v.particle_random_2*0.05))*math.clamp(q.entity_height*0.85,1,3))*v.smoothshrink"],
"facing_camera_mode": "rotate_xyz",
"uv": {
"texture_width": 8,
"texture_height": 7,
"uv": [0, 0],
"uv_size": [8, 7]
}
},
"minecraft:particle_appearance_lighting": {}
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB