Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d8c3df1ab | ||
|
|
ca8ae8f999 | ||
|
|
d902e4dbab | ||
|
|
001efd86f3 | ||
|
|
1f2b6173d4 | ||
|
|
e4844c18fb | ||
|
|
2305a1792d | ||
|
|
cf0a6d17e0 |
No files matched your search
@@ -10,11 +10,13 @@ package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.client.render.player.MountedPlayerRenderer;
|
||||
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker;
|
||||
import com.cobblemon.mod.common.duck.RidePassenger;
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity;
|
||||
import net.minecraft.client.model.HumanoidModel;
|
||||
import net.minecraft.client.model.geom.ModelPart;
|
||||
import net.minecraft.client.player.AbstractClientPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
@@ -96,4 +98,26 @@ public class HumanoidModelMixin {
|
||||
MountedPlayerRenderer.INSTANCE.animate((HumanoidModel<AbstractClientPlayer>)(Object)this, pokemonEntity, player, netHeadYaw, headPitch, ageInTicks, limbSwing, limbSwingAmount);
|
||||
}
|
||||
}
|
||||
|
||||
// Pose the right arm forward while recalling so the held Poké Ball sits out in front.
|
||||
@Inject(method = "setupAnim*", at = @At("TAIL"))
|
||||
public void cobblemon$poseRecallArm(
|
||||
LivingEntity entity,
|
||||
float limbSwing,
|
||||
float limbSwingAmount,
|
||||
float ageInTicks,
|
||||
float netHeadYaw,
|
||||
float headPitch,
|
||||
CallbackInfo ci
|
||||
) {
|
||||
if (!(entity instanceof AbstractClientPlayer player)) return;
|
||||
// Skip while riding so we don't override the mounted-riding arm animation.
|
||||
if (entity.getVehicle() instanceof PokemonEntity) return;
|
||||
float raise = RecallArmAnimationTracker.INSTANCE.raiseFactor(player.getUUID());
|
||||
if (raise <= 0f) return;
|
||||
float armForwardXRot = (float) (-Math.PI / 2.0);
|
||||
this.rightArm.xRot = Mth.lerp(raise, this.rightArm.xRot, armForwardXRot);
|
||||
this.rightArm.yRot = Mth.lerp(raise, this.rightArm.yRot, 0f);
|
||||
this.rightArm.zRot = Mth.lerp(raise, this.rightArm.zRot, 0f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.entity.layers.ItemInHandLayer;
|
||||
import net.minecraft.world.entity.HumanoidArm;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
/**
|
||||
* Hides the player's right-hand item while recalling so it doesn't overlap the recall Poké Ball
|
||||
* drawn by PlayerRecallBallRenderer.
|
||||
*/
|
||||
@Mixin(ItemInHandLayer.class)
|
||||
public class ItemInHandLayerMixin {
|
||||
@Inject(method = "renderArmWithItem", at = @At("HEAD"), cancellable = true)
|
||||
private void cobblemon$hideRecallHandItem(
|
||||
LivingEntity entity,
|
||||
ItemStack itemStack,
|
||||
ItemDisplayContext itemDisplayContext,
|
||||
HumanoidArm humanoidArm,
|
||||
PoseStack poseStack,
|
||||
MultiBufferSource multiBufferSource,
|
||||
int light,
|
||||
CallbackInfo ci
|
||||
) {
|
||||
if (humanoidArm == HumanoidArm.RIGHT && RecallArmAnimationTracker.INSTANCE.isRecalling(entity.getUUID())) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
@@ -9,6 +9,8 @@
|
||||
package com.cobblemon.mod.common.mixin.client;
|
||||
|
||||
import com.cobblemon.mod.common.OrientationControllable;
|
||||
import com.cobblemon.mod.common.client.render.player.FirstPersonRecallBallRenderer;
|
||||
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker;
|
||||
import com.cobblemon.mod.common.item.PokedexItem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -31,6 +33,12 @@ public class ItemInHandRendererMixin {
|
||||
if (abstractClientPlayer.isUsingItem() && abstractClientPlayer.getUseItem().getItem() instanceof PokedexItem) {
|
||||
ci.cancel();
|
||||
}
|
||||
// While recalling, swap the main-hand item for the rising Poké Ball.
|
||||
else if (interactionHand == InteractionHand.MAIN_HAND
|
||||
&& RecallArmAnimationTracker.INSTANCE.isRecalling(abstractClientPlayer.getUUID())
|
||||
&& FirstPersonRecallBallRenderer.INSTANCE.render(poseStack, multiBufferSource, j, f)) {
|
||||
ci.cancel();
|
||||
}
|
||||
else if (abstractClientPlayer instanceof OrientationControllable controllable && controllable.getOrientationController().isActive()) {
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ import com.cobblemon.mod.common.client.render.entity.PokeBobberEntityRenderer
|
||||
import com.cobblemon.mod.common.client.render.generic.GenericBedrockRenderer
|
||||
import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererRegistry
|
||||
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer
|
||||
import com.cobblemon.mod.common.client.render.layer.PlayerRecallBallRenderer
|
||||
import com.cobblemon.mod.common.client.render.layer.PokemonOnShoulderRenderer
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation.BedrockAnimationRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.BerryModelRepository
|
||||
@@ -405,8 +406,10 @@ object CobblemonClient {
|
||||
var renderer: LivingEntityRenderer<Player, PlayerModel<Player>>? =
|
||||
skinMap?.get(PlayerSkin.Model.WIDE) as LivingEntityRenderer<Player, PlayerModel<Player>>
|
||||
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
|
||||
renderer?.addLayer(PlayerRecallBallRenderer(renderer))
|
||||
renderer = skinMap[PlayerSkin.Model.SLIM] as LivingEntityRenderer<Player, PlayerModel<Player>>?
|
||||
renderer?.addLayer(PokemonOnShoulderRenderer(renderer))
|
||||
renderer?.addLayer(PlayerRecallBallRenderer(renderer))
|
||||
}
|
||||
|
||||
private fun registerMenuScreens() {
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.PosableState
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.ActiveAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.animation.PrimaryAnimation
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
|
||||
import com.cobblemon.mod.common.client.render.pokemon.PokemonRenderer.Companion.ease
|
||||
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
|
||||
import com.cobblemon.mod.common.net.messages.server.pokemon.update.ServerboundUpdateRidingStatePacket
|
||||
@@ -320,6 +321,13 @@ class PokemonClientDelegate : PosableState(), PokemonSideDelegate {
|
||||
ballOffset = 0f
|
||||
ballRotOffset = 0f
|
||||
sendOutPosition = null
|
||||
// If a player is recalling, have them hold the matching Poké Ball out in their
|
||||
// right hand for the duration of the beam (see ourRecallArmAnimationTracker class).
|
||||
currentEntity.ownerUUID?.let { ownerId ->
|
||||
if (currentEntity.level().getPlayerByUUID(ownerId) != null) {
|
||||
RecallArmAnimationTracker.start(ownerId, currentEntity.exposedBall, emptySet())
|
||||
}
|
||||
}
|
||||
afterOnClient(seconds = BEAM_EXTEND_TIME) {
|
||||
activeSendoutScale = 1F
|
||||
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* 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.client.render.layer
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.model.PlayerModel
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer
|
||||
import net.minecraft.client.renderer.entity.RenderLayerParent
|
||||
import net.minecraft.client.renderer.entity.layers.RenderLayer
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
import net.minecraft.world.entity.HumanoidArm
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.joml.Vector3f
|
||||
|
||||
/**
|
||||
* Draws the matching Poké Ball in a recalling player's right hand and records where the recall beam
|
||||
* should start. Driven by [RecallArmAnimationTracker]; the right arm is posed forward in
|
||||
* HumanoidModelMixin so [PlayerModel.translateToHand] lands on the extended hand.
|
||||
*
|
||||
* The local player in first person is handled by FirstPersonRecallBallRenderer instead, so it's
|
||||
* skipped here.
|
||||
*/
|
||||
class PlayerRecallBallRenderer<T : Player>(
|
||||
renderLayerParent: RenderLayerParent<T, PlayerModel<T>>
|
||||
) : RenderLayer<T, PlayerModel<T>>(renderLayerParent) {
|
||||
|
||||
companion object {
|
||||
private const val BALL_SCALE = 0.5F
|
||||
|
||||
private const val HAND_X = 0.0625
|
||||
private const val HAND_Y = 0.125
|
||||
private const val HAND_Z = -0.625
|
||||
|
||||
private const val BALL_YAW_SPIN = 180F
|
||||
private const val BALL_INFLATE = 1.08F
|
||||
|
||||
private const val BEAM_X_OFFSET = 0F
|
||||
private const val BEAM_Y_OFFSET = 0.18F
|
||||
private const val BEAM_Z_OFFSET = -0.30F
|
||||
}
|
||||
|
||||
private val ballContext = RenderContext().also {
|
||||
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD)
|
||||
}
|
||||
|
||||
override fun render(
|
||||
matrixStack: PoseStack,
|
||||
buffer: MultiBufferSource,
|
||||
packedLight: Int,
|
||||
player: T,
|
||||
limbSwing: Float,
|
||||
limbSwingAmount: Float,
|
||||
partialTicks: Float,
|
||||
ageInTicks: Float,
|
||||
netHeadYaw: Float,
|
||||
headPitch: Float
|
||||
) {
|
||||
val anim = RecallArmAnimationTracker.get(player.uuid) ?: return
|
||||
val mc = Minecraft.getInstance()
|
||||
if (player === mc.player && mc.options.cameraType.isFirstPerson) return
|
||||
|
||||
matrixStack.pushPose()
|
||||
getParentModel().translateToHand(HumanoidArm.RIGHT, matrixStack)
|
||||
matrixStack.mulPose(Axis.XP.rotationDegrees(-90F))
|
||||
matrixStack.mulPose(Axis.YP.rotationDegrees(180F))
|
||||
matrixStack.translate(HAND_X, HAND_Y, HAND_Z)
|
||||
|
||||
renderBall(anim, matrixStack, buffer, packedLight, partialTicks)
|
||||
|
||||
matrixStack.popPose()
|
||||
}
|
||||
|
||||
private fun renderBall(
|
||||
anim: RecallArmAnimationTracker.RecallAnim,
|
||||
matrixStack: PoseStack,
|
||||
buffer: MultiBufferSource,
|
||||
packedLight: Int,
|
||||
partialTicks: Float
|
||||
) {
|
||||
val state = anim.ballState
|
||||
val ball = anim.ball
|
||||
matrixStack.pushPose()
|
||||
matrixStack.scale(BALL_INFLATE, BALL_INFLATE, BALL_INFLATE)
|
||||
matrixStack.translate(0.0, (-8.0 / 16.0) * BALL_SCALE, 0.0)
|
||||
matrixStack.scale(BALL_SCALE, -BALL_SCALE, -BALL_SCALE)
|
||||
matrixStack.mulPose(Axis.YP.rotationDegrees(BALL_YAW_SPIN))
|
||||
|
||||
val model = VaryingModelRepository.getPoser(ball.name, state)
|
||||
val texture = VaryingModelRepository.getTexture(ball.name, state)
|
||||
state.updatePartialTicks(partialTicks)
|
||||
model.context = ballContext
|
||||
ballContext.put(RenderContext.ASPECTS, state.aspects)
|
||||
ballContext.put(RenderContext.POSABLE_STATE, state)
|
||||
|
||||
model.applyAnimations(null, state, 0F, 0F, 0F, 0F, 0F)
|
||||
|
||||
state.locatorStates["beam"]?.let { beamLocator ->
|
||||
matrixStack.pushPose()
|
||||
matrixStack.mulPose(beamLocator.matrix)
|
||||
val camRelative = matrixStack.last().pose().transformPosition(Vector3f(BEAM_X_OFFSET, BEAM_Y_OFFSET, BEAM_Z_OFFSET))
|
||||
matrixStack.popPose()
|
||||
val camera = Minecraft.getInstance().gameRenderer.mainCamera.position
|
||||
anim.beamOrigin = Vec3(camera.x + camRelative.x, camera.y + camRelative.y, camera.z + camRelative.z)
|
||||
}
|
||||
val consumer = ItemRenderer.getFoilBufferDirect(buffer, RenderType.entityCutout(texture), false, false)
|
||||
model.render(ballContext, matrixStack, consumer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
|
||||
model.red = 1F
|
||||
model.green = 1F
|
||||
model.blue = 1F
|
||||
model.resetLayerContext()
|
||||
matrixStack.popPose()
|
||||
}
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.client.render.player
|
||||
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.mojang.blaze3d.vertex.PoseStack
|
||||
import com.mojang.math.Axis
|
||||
import net.minecraft.client.Minecraft
|
||||
import net.minecraft.client.renderer.MultiBufferSource
|
||||
import net.minecraft.client.renderer.RenderType
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer
|
||||
import net.minecraft.client.renderer.texture.OverlayTexture
|
||||
|
||||
/**
|
||||
* Draws the recalling player's Poké Ball in first person, rising into view from the bottom of the
|
||||
* screen in place of their held item. The world-space beam still starts near the hand (the eye/look
|
||||
* fallback in PokemonRenderer), so this is cosmetic only.
|
||||
*
|
||||
* Called from ItemInHandRendererMixin, which cancels the vanilla main-hand item while recalling.
|
||||
*/
|
||||
object FirstPersonRecallBallRenderer {
|
||||
|
||||
/** Resting position of the ball in view space (right, up, forward). */
|
||||
private const val REST_X = 0.45
|
||||
private const val REST_Y = -0.55
|
||||
private const val REST_Z = -.6
|
||||
/** How far below REST_Y the ball starts before rising into view. */
|
||||
private const val RISE_DISTANCE = 0.6
|
||||
private const val BALL_SCALE = 0.45F
|
||||
|
||||
private val ballContext = RenderContext().also {
|
||||
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD)
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if a recall ball was rendered (so the caller should cancel the vanilla item).
|
||||
*/
|
||||
fun render(poseStack: PoseStack, buffer: MultiBufferSource, packedLight: Int, partialTicks: Float): Boolean {
|
||||
val player = Minecraft.getInstance().player ?: return false
|
||||
val anim = RecallArmAnimationTracker.get(player.uuid) ?: return false
|
||||
val rise = RecallArmAnimationTracker.raiseFactor(player.uuid)
|
||||
|
||||
poseStack.pushPose()
|
||||
poseStack.translate(REST_X, REST_Y - RISE_DISTANCE * (1.0 - rise), REST_Z)
|
||||
poseStack.scale(BALL_SCALE, -BALL_SCALE, -BALL_SCALE)
|
||||
|
||||
poseStack.mulPose(Axis.YP.rotationDegrees(180F))
|
||||
poseStack.mulPose(Axis.XP.rotationDegrees(15F))
|
||||
|
||||
val state = anim.ballState
|
||||
val ball = anim.ball
|
||||
val model = VaryingModelRepository.getPoser(ball.name, state)
|
||||
val texture = VaryingModelRepository.getTexture(ball.name, state)
|
||||
state.updatePartialTicks(partialTicks)
|
||||
model.context = ballContext
|
||||
ballContext.put(RenderContext.ASPECTS, state.aspects)
|
||||
ballContext.put(RenderContext.POSABLE_STATE, state)
|
||||
model.applyAnimations(null, state, 0F, 0F, 0F, 0F, 0F)
|
||||
val consumer = ItemRenderer.getFoilBufferDirect(buffer, RenderType.entityCutout(texture), false, false)
|
||||
model.render(ballContext, poseStack, consumer, packedLight, OverlayTexture.NO_OVERLAY, -0x1)
|
||||
model.red = 1F
|
||||
model.green = 1F
|
||||
model.blue = 1F
|
||||
model.resetLayerContext()
|
||||
|
||||
poseStack.popPose()
|
||||
return true
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.client.render.player
|
||||
|
||||
import com.cobblemon.mod.common.client.battle.ClientBallDisplay
|
||||
import com.cobblemon.mod.common.pokeball.PokeBall
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.phys.Vec3
|
||||
|
||||
/**
|
||||
* Tracks which players are recalling a Pokémon so we can pose their arm, draw the Poké Ball in their
|
||||
* hand, and start the recall beam from it.
|
||||
*
|
||||
* Keyed by player UUID. Entries time out on their own once the beam is done, and a new recall resets
|
||||
* the timer, so nothing has to clear them.
|
||||
*
|
||||
* Written by PokemonClientDelegate on recall (beamMode 3); read by HumanoidModelMixin, the ball
|
||||
* renderers, and PokemonRenderer.
|
||||
*/
|
||||
object RecallArmAnimationTracker {
|
||||
|
||||
// How long the arm stays raised, in seconds.
|
||||
const val ARM_HOLD_SECONDS = 0.8
|
||||
|
||||
// Fraction of the hold spent easing the arm up at the start and down at the end.
|
||||
private const val EASE_SECONDS = 0.15
|
||||
|
||||
class RecallAnim(
|
||||
val ball: PokeBall,
|
||||
val aspects: Set<String>,
|
||||
val startTimeMs: Long
|
||||
) {
|
||||
val ballState = ClientBallDisplay(ball, aspects)
|
||||
var beamOrigin: Vec3? = null
|
||||
}
|
||||
|
||||
private val activeRecalls = ConcurrentHashMap<UUID, RecallAnim>()
|
||||
|
||||
fun start(playerUuid: UUID, ball: PokeBall, aspects: Set<String>) {
|
||||
activeRecalls[playerUuid] = RecallAnim(ball, aspects, System.currentTimeMillis())
|
||||
}
|
||||
|
||||
/** Returns the active recall for the player, or null if there is none or if it has expired. */
|
||||
fun get(playerUuid: UUID): RecallAnim? {
|
||||
val anim = activeRecalls[playerUuid] ?: return null
|
||||
if (secondsSince(anim) > ARM_HOLD_SECONDS) {
|
||||
activeRecalls.remove(playerUuid)
|
||||
return null
|
||||
}
|
||||
return anim
|
||||
}
|
||||
|
||||
fun isRecalling(playerUuid: UUID): Boolean = get(playerUuid) != null
|
||||
|
||||
private fun secondsSince(anim: RecallAnim) = (System.currentTimeMillis() - anim.startTimeMs) / 1000.0
|
||||
|
||||
/** 0..1 ramp: eases in at the start, holds at 1, eases out at the end. 0 when not recalling. */
|
||||
fun raiseFactor(playerUuid: UUID): Float {
|
||||
val anim = get(playerUuid) ?: return 0F
|
||||
val elapsed = secondsSince(anim)
|
||||
val riseIn = Mth.clamp((elapsed / EASE_SECONDS).toFloat(), 0F, 1F)
|
||||
val fallOut = Mth.clamp(((ARM_HOLD_SECONDS - elapsed) / EASE_SECONDS).toFloat(), 0F, 1F)
|
||||
return minOf(riseIn, fallOut)
|
||||
}
|
||||
}
|
||||
+14
-4
@@ -26,6 +26,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.pokemon.PosableP
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.MiscModelRepository
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
|
||||
import com.cobblemon.mod.common.client.render.models.blockbench.repository.VaryingModelRepository
|
||||
import com.cobblemon.mod.common.client.render.player.RecallArmAnimationTracker
|
||||
import com.cobblemon.mod.common.client.render.pokeball.PokeBallPosableState
|
||||
import com.cobblemon.mod.common.client.render.renderBeaconBeam
|
||||
import com.cobblemon.mod.common.client.settings.ServerSettings
|
||||
@@ -60,6 +61,7 @@ import net.minecraft.network.chat.Style
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.util.Mth
|
||||
import net.minecraft.world.entity.Entity
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.phys.Vec3
|
||||
import org.joml.*
|
||||
import kotlin.math.*
|
||||
@@ -69,6 +71,9 @@ class PokemonRenderer(
|
||||
) : MobRenderer<PokemonEntity, PosablePokemonEntityModel>(context, PosablePokemonEntityModel(), 0.5f) {
|
||||
companion object {
|
||||
val recallBeamColour = Vector4f(1F, 0.1F, 0.1F, 1F)
|
||||
private const val CAPTURE_BEAM_X_OFFSET = 0.0
|
||||
private const val CAPTURE_BEAM_Y_OFFSET = 0.2
|
||||
private const val CAPTURE_BEAM_Z_OFFSET = 0.45
|
||||
fun ease(x: Double): Double {
|
||||
return 1 - (1 - x).pow(3)
|
||||
}
|
||||
@@ -142,8 +147,6 @@ class PokemonRenderer(
|
||||
}
|
||||
|
||||
modelNow.setLayerContext(buffer, clientDelegate, VaryingModelRepository.getLayers(entity.pokemon.species.resourceIdentifier, clientDelegate))
|
||||
|
||||
|
||||
if (entity.passengers.isNotEmpty()) {
|
||||
renderRiding(entity, entityYaw, partialTicks, poseMatrix, buffer, packedLight)
|
||||
} else {
|
||||
@@ -316,8 +319,15 @@ class PokemonRenderer(
|
||||
fun renderBeam(matrixStack: PoseStack, partialTicks: Float, entity: PokemonEntity, beamTarget: Entity, buffer: MultiBufferSource, offset: Vec3) {
|
||||
val clientDelegate = entity.delegate as PokemonClientDelegate
|
||||
val pokemonPosition = entity.position().add(0.0, entity.bbHeight / 2.0 * clientDelegate.activeSendoutScale.toDouble(), 0.0)
|
||||
var beamSourcePosition = if (beamTarget is EmptyPokeBallEntity) {
|
||||
(beamTarget.delegate as PokeBallPosableState).locatorStates["beam"]?.getOrigin() ?: beamTarget.position()
|
||||
|
||||
// If a player is recalling, start the beam from the Poké Ball held in their hand
|
||||
val recallBallOrigin = (beamTarget as? Player)?.let { RecallArmAnimationTracker.get(it.uuid)?.beamOrigin }
|
||||
var beamSourcePosition = if (recallBallOrigin != null) {
|
||||
recallBallOrigin
|
||||
} else if (beamTarget is EmptyPokeBallEntity) {
|
||||
(beamTarget.delegate as PokeBallPosableState).locatorStates["beam"]
|
||||
?.transformPosition(Vec3(CAPTURE_BEAM_X_OFFSET, CAPTURE_BEAM_Y_OFFSET, CAPTURE_BEAM_Z_OFFSET))
|
||||
?: beamTarget.position()
|
||||
} else {
|
||||
if (beamTarget.uuid == Minecraft.getInstance().player?.uuid) {
|
||||
val lookVec = beamTarget.lookAngle.yRot((PI / 2).toFloat()).multiply(1.0, 0.0, 1.0).normalize()
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
"client.EntryListWidgetMixin",
|
||||
"client.GameRendererMixin",
|
||||
"client.HumanoidModelMixin",
|
||||
"client.ItemInHandLayerMixin",
|
||||
"client.ItemInHandRendererMixin",
|
||||
"client.ItemRendererMixin",
|
||||
"client.LivingEntityRendererMixin",
|
||||
|
||||
Reference in new issue
Block a user