Skip to content

Commit 855dc1a

Browse files
committed
Pokemon item rendering!
1 parent 59fb9fb commit 855dc1a

File tree

10 files changed

+321
-26
lines changed

10 files changed

+321
-26
lines changed

common/src/main/java/generations/gg/generations/core/generationscore/common/client/GenerationsCoreClient.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import com.cobblemon.mod.common.api.Priority
44
import com.cobblemon.mod.common.api.spawning.TimeRange
55
import com.cobblemon.mod.common.api.types.ElementalTypes
66
import com.cobblemon.mod.common.client.render.item.CobblemonBuiltinItemRendererRegistry
7+
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer
78
import com.cobblemon.mod.common.client.render.models.blockbench.pokeball.PokeBallModel
89
import com.cobblemon.mod.common.client.render.models.blockbench.pose.Bone
910
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokeBallModelRepository
@@ -120,14 +121,12 @@ object GenerationsCoreClient {
120121

121122
ITextureLoader.setInstance(GenerationsTextureLoader)
122123

123-
// TODO: Readd
124-
// var renderer = TimeCapsuleItemRenderer.INSTANCE;
125-
//
126-
// CobblemonBuiltinItemRendererRegistry.INSTANCE.register(GenerationsItems.TIME_CAPSULE.get(), renderer);
127-
// CobblemonBuiltinItemRendererRegistry.INSTANCE.register(GenerationsItems.SUICUNE_STATUE.get(), renderer);
128-
// CobblemonBuiltinItemRendererRegistry.INSTANCE.register(GenerationsItems.RAIKOU_STATUE.get(), renderer);
129-
// CobblemonBuiltinItemRendererRegistry.INSTANCE.register(GenerationsItems.ENTEI_STATUE.get(), renderer);
130-
// CobblemonBuiltinItemRendererRegistry.INSTANCE.register(CobblemonItems.POKEMON_MODEL, renderer);
124+
val renderer = PokemonItemRenderer()
125+
126+
CobblemonBuiltinItemRendererRegistry.register(GenerationsItems.TIME_CAPSULE.get(), renderer);
127+
CobblemonBuiltinItemRendererRegistry.register(GenerationsItems.SUICUNE_STATUE.get(), renderer);
128+
CobblemonBuiltinItemRendererRegistry.register(GenerationsItems.RAIKOU_STATUE.get(), renderer);
129+
CobblemonBuiltinItemRendererRegistry.register(GenerationsItems.ENTEI_STATUE.get(), renderer);
131130

132131

133132
GenerationsCore.implementation.registerResourceReloader(GenerationsCore.id("model_registry"), CompiledModelLoader(), PackType.CLIENT_RESOURCES, emptyList())
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package generations.gg.generations.core.generationscore.common.client
2+
3+
import com.cobblemon.mod.common.client.render.SpriteType
4+
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer
5+
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer.Companion.positions
6+
import com.cobblemon.mod.common.client.render.models.blockbench.FloatingState
7+
import com.cobblemon.mod.common.client.render.models.blockbench.repository.PokemonModelRepository
8+
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
9+
import com.cobblemon.mod.common.entity.PoseType
10+
import com.cobblemon.mod.common.item.PokemonItem
11+
import com.cobblemon.mod.common.util.math.fromEulerXYZDegrees
12+
import com.mojang.blaze3d.platform.Lighting
13+
import com.mojang.blaze3d.vertex.PoseStack
14+
import com.mojang.blaze3d.vertex.VertexConsumer
15+
import generations.gg.generations.core.generationscore.common.client.model.RareCandyBone
16+
import generations.gg.generations.core.generationscore.common.client.render.rarecandy.instanceOrNull
17+
import generations.gg.generations.core.generationscore.common.world.item.PokemonProvidingItem
18+
import net.minecraft.client.renderer.LightTexture
19+
import net.minecraft.client.renderer.MultiBufferSource
20+
import net.minecraft.client.renderer.RenderType
21+
import net.minecraft.client.renderer.texture.MissingTextureAtlasSprite
22+
import net.minecraft.client.renderer.texture.OverlayTexture
23+
import net.minecraft.world.item.ItemDisplayContext
24+
import net.minecraft.world.item.ItemStack
25+
import org.joml.Quaternionf
26+
import org.joml.Vector3f
27+
28+
object PokemonItemRendererProxy {
29+
val context = RenderContext().also {
30+
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.PROFILE)
31+
it.put(RenderContext.DO_QUIRKS, false)
32+
}
33+
34+
@JvmStatic
35+
fun render(
36+
stack: ItemStack,
37+
mode: ItemDisplayContext,
38+
matrices: PoseStack,
39+
vertexConsumers: MultiBufferSource,
40+
light: Int,
41+
overlay: Int,
42+
) {
43+
val pokemonItem = stack.item as? PokemonProvidingItem ?: return
44+
val (species, aspects) = pokemonItem.getSpeciesAndAspectsPair(stack) ?: return
45+
val state = FloatingState()
46+
state.currentAspects = aspects
47+
matrices.pushPose()
48+
val model = PokemonModelRepository.getPoser(species.resourceIdentifier, state)
49+
50+
val sprite = model.rootPart.instanceOrNull<RareCandyBone>()?.let { RenderType.entityCutoutNoCull(PokemonModelRepository.getSprite(species.resourceIdentifier, state, SpriteType.PROFILE) ?: MissingTextureAtlasSprite.getLocation()) }
51+
52+
if(sprite == null) {
53+
54+
model.context = context
55+
context.put(RenderContext.RENDER_STATE, RenderContext.RenderState.PROFILE)
56+
context.put(RenderContext.SPECIES, species.resourceIdentifier)
57+
context.put(RenderContext.ASPECTS, aspects)
58+
context.put(RenderContext.POSABLE_STATE, state)
59+
state.currentModel = model
60+
}
61+
62+
val renderLayer = if(sprite == null) RenderType.entityCutout(PokemonModelRepository.getTexture(species.resourceIdentifier, state)) else sprite
63+
64+
val transformations = if(sprite == null) positions[mode]!! else positionsSprite[mode]!!
65+
66+
if (mode == ItemDisplayContext.GUI) {
67+
if(sprite == null) Lighting.setupForFlatItems()
68+
else Lighting.setupForEntityInInventory()
69+
}
70+
71+
matrices.scale(transformations.scale.x, transformations.scale.y, transformations.scale.z)
72+
matrices.translate(transformations.translation.x, transformations.translation.y, transformations.translation.z)
73+
74+
if(sprite == null) {
75+
state.setPoseToFirstSuitable(PoseType.PORTRAIT)
76+
model.applyAnimations(null, state, 0F, 0F, 0F, 0F, 0F)
77+
78+
matrices.translate(model.profileTranslation.x, model.profileTranslation.y, -4.0)
79+
matrices.scale(model.profileScale, model.profileScale, 0.15F)
80+
}
81+
82+
val rotation = Quaternionf().fromEulerXYZDegrees(Vector3f(transformations.rotation.x, transformations.rotation.y, transformations.rotation.z))
83+
matrices.mulPose(rotation)
84+
rotation.conjugate()
85+
val buffer = vertexConsumers.getBuffer(renderLayer)
86+
matrices.pushPose()
87+
val packedLight = if (mode == ItemDisplayContext.GUI) {
88+
if(sprite == null) LightTexture.pack(13, 13)
89+
else LightTexture.FULL_BRIGHT
90+
} else {
91+
light
92+
}
93+
94+
// x = red, y = green, z = blue, w = alpha
95+
val tint = pokemonItem.stackTint(stack)
96+
val tintRed = (tint.x * 255).toInt()
97+
val tintGreen = (tint.y * 255).toInt()
98+
val tintBlue = (tint.z * 255).toInt()
99+
val tintAlpha = (tint.w * 255).toInt()
100+
val color = (tintAlpha shl 24) or (tintRed shl 16) or (tintGreen shl 8) or tintBlue
101+
102+
if(sprite == null) {
103+
model.withLayerContext(
104+
vertexConsumers,
105+
state,
106+
PokemonModelRepository.getLayers(species.resourceIdentifier, state)
107+
) {
108+
model.render(context, matrices, buffer, packedLight, OverlayTexture.NO_OVERLAY, color)
109+
}
110+
111+
model.setDefault()
112+
} else {
113+
val matrix = matrices.last()
114+
matrix.pose().translate(-0.5f, 0f, 0f)
115+
buffer.addVertex(matrix, 1f, 0f, 0f).setColor(color).setUv(1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
116+
.setLight(packedLight).setNormal(matrix, 0f, 1f, 0f)
117+
buffer.addVertex(matrix, 0f, 0f, 0f).setColor(color).setUv(0f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
118+
.setLight(packedLight).setNormal(matrix, 0f, 1f, 0f)
119+
buffer.addVertex(matrix, 0f, 1f, 0f).setColor(color).setUv(0f, 1f).setOverlay(OverlayTexture.NO_OVERLAY)
120+
.setLight(packedLight).setNormal(matrix, 0f, 1f, 0f)
121+
buffer.addVertex(matrix, 1f, 1f, 0f).setColor(color).setUv(1f, 1f).setOverlay(OverlayTexture.NO_OVERLAY)
122+
.setLight(packedLight).setNormal(matrix, 0f, 1f, 0f)
123+
}
124+
125+
matrices.popPose()
126+
matrices.popPose()
127+
128+
if (mode == ItemDisplayContext.GUI) {
129+
Lighting.setupFor3DItems()
130+
}
131+
}
132+
133+
val positionsSprite: MutableMap<ItemDisplayContext, PokemonItemRenderer.Transformations> = mutableMapOf()
134+
135+
init {
136+
positionsSprite[ItemDisplayContext.GUI] = PokemonItemRenderer().Transformations(
137+
PokemonItemRenderer().Transformation(0.5, -1.0, -0.5),
138+
PokemonItemRenderer().Transformation(1F, -1F, -1F),
139+
PokemonItemRenderer().Transformation(0F, 0F, 0F))
140+
141+
positionsSprite[ItemDisplayContext.FIXED] = PokemonItemRenderer().Transformations(
142+
PokemonItemRenderer().Transformation(0.5, -1.0, -0.5),
143+
PokemonItemRenderer().Transformation(1F, -1F, -1F),
144+
PokemonItemRenderer().Transformation(0F, 0F, 0F))
145+
146+
positionsSprite[ItemDisplayContext.FIRST_PERSON_RIGHT_HAND] = PokemonItemRenderer().Transformations(
147+
PokemonItemRenderer().Transformation(2.75, -1.2, 0.0),
148+
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
149+
PokemonItemRenderer().Transformation(0F, 35F, 0F))
150+
151+
positionsSprite[ItemDisplayContext.FIRST_PERSON_LEFT_HAND] = PokemonItemRenderer().Transformations(
152+
PokemonItemRenderer().Transformation(-0.75, -1.2, 0.0),
153+
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
154+
PokemonItemRenderer().Transformation(0F, -35F, 0F))
155+
156+
positionsSprite[ItemDisplayContext.THIRD_PERSON_RIGHT_HAND] = PokemonItemRenderer().Transformations(
157+
PokemonItemRenderer().Transformation(1.0, -2.6, 0.75),
158+
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
159+
PokemonItemRenderer().Transformation(0F, 35F, 0F))
160+
161+
positionsSprite[ItemDisplayContext.THIRD_PERSON_LEFT_HAND] = PokemonItemRenderer().Transformations(
162+
PokemonItemRenderer().Transformation(1.0, -2.6, -0.75),
163+
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
164+
PokemonItemRenderer().Transformation(0F, -35F, 0F))
165+
166+
positionsSprite[ItemDisplayContext.GROUND] = PokemonItemRenderer().Transformations(
167+
PokemonItemRenderer().Transformation(1.0, -1.6, -1.0),
168+
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
169+
PokemonItemRenderer().Transformation(0F, 0f, 0F))
170+
171+
positionsSprite[ItemDisplayContext.HEAD] = PokemonItemRenderer().Transformations(
172+
PokemonItemRenderer().Transformation(1.0, -3.5, 3.0),
173+
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
174+
PokemonItemRenderer().Transformation(0F, 215F, 0F))
175+
176+
positionsSprite[ItemDisplayContext.NONE] = PokemonItemRenderer().Transformations(
177+
PokemonItemRenderer().Transformation(0.0, 0.0, 0.0),
178+
PokemonItemRenderer().Transformation(0.5F, -0.5F, -0.5F),
179+
PokemonItemRenderer().Transformation(0F, 0F, 0F))
180+
}
181+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package generations.gg.generations.core.generationscore.common.mixin;
2+
3+
import earth.terrarium.common_storage_lib.item.impl.vanilla.VanillaDelegatingSlot;
4+
import earth.terrarium.common_storage_lib.item.impl.vanilla.WrappedVanillaContainer;
5+
import earth.terrarium.common_storage_lib.resources.ResourceStack;
6+
import earth.terrarium.common_storage_lib.resources.item.ItemResource;
7+
import earth.terrarium.common_storage_lib.storage.util.ModifiableItemSlot;
8+
import net.minecraft.world.Container;
9+
import net.minecraft.world.item.ItemStack;
10+
import org.spongepowered.asm.mixin.Final;
11+
import org.spongepowered.asm.mixin.Mixin;
12+
import org.spongepowered.asm.mixin.Shadow;
13+
14+
@Mixin(VanillaDelegatingSlot.class)
15+
public class MixinVanillaDelegatingSlot implements ModifiableItemSlot {
16+
@Shadow @Final private Container container;
17+
18+
@Shadow @Final private int slot;
19+
20+
@Override
21+
public void setAmount(long l) {
22+
container.getItem(slot).setCount((int) l);
23+
}
24+
25+
@Override
26+
public void setResource(ItemResource itemResource) {
27+
container.setItem(slot, itemResource.toStack());
28+
}
29+
30+
@Override
31+
public void set(ItemStack stack) {
32+
container.setItem(slot, stack);
33+
}
34+
35+
public void set(ResourceStack<ItemResource> data) {
36+
container.setItem(slot, ResourceStack.toItemStack(data));
37+
}
38+
39+
40+
@Override
41+
public ItemStack toItemStack() {
42+
return container.getItem(slot).copy();
43+
}
44+
45+
@Override
46+
public int getMaxAllowed(ItemResource resource) {
47+
return resource.getCachedStack().getMaxStackSize();
48+
}
49+
50+
@Override
51+
public boolean isEmpty() {
52+
return container.getItem(slot).isEmpty();
53+
}
54+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package generations.gg.generations.core.generationscore.common.mixin;
2+
3+
import com.cobblemon.mod.common.item.PokemonItem;
4+
import com.cobblemon.mod.common.pokemon.Species;
5+
import generations.gg.generations.core.generationscore.common.world.item.PokemonProvidingItem;
6+
import kotlin.Pair;
7+
import net.minecraft.world.item.ItemStack;
8+
import org.jetbrains.annotations.NotNull;
9+
import org.jetbrains.annotations.Nullable;
10+
import org.joml.Vector4f;
11+
import org.spongepowered.asm.mixin.Mixin;
12+
import org.spongepowered.asm.mixin.Shadow;
13+
14+
import java.util.Set;
15+
16+
@Mixin(PokemonItem.class)
17+
abstract public class PokemonItemMixin implements PokemonProvidingItem {
18+
@Shadow public abstract Vector4f tint(ItemStack stack);
19+
@Shadow @Nullable public abstract Pair<Species, Set<String>> getSpeciesAndAspects(@NotNull ItemStack stack);
20+
21+
@Override
22+
public @Nullable Pair<Species, Set<String>> getSpeciesAndAspectsPair(@NotNull ItemStack stack) {
23+
return getSpeciesAndAspects(stack);
24+
}
25+
26+
@Override
27+
public @NotNull Vector4f stackTint(@NotNull ItemStack stack) {
28+
return this.tint(stack);
29+
}
30+
}

common/src/main/java/generations/gg/generations/core/generationscore/common/mixin/client/PokemonItemRendererMixin.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,23 @@
44
import com.cobblemon.mod.common.client.render.item.PokemonItemRenderer;
55
import com.mojang.blaze3d.vertex.PoseStack;
66
//import generations.gg.generations.core.generationscore.common.client.render.TimeCapsuleItemRenderer;
7+
import generations.gg.generations.core.generationscore.common.client.PokemonItemRendererProxy;
78
import net.minecraft.client.renderer.MultiBufferSource;
89
import net.minecraft.world.item.ItemDisplayContext;
910
import net.minecraft.world.item.ItemStack;
1011
import org.spongepowered.asm.mixin.Mixin;
12+
import org.spongepowered.asm.mixin.injection.At;
13+
import org.spongepowered.asm.mixin.injection.Inject;
14+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
1115

1216
//TODO: Remove once on cobblemon version with whole context needed.
1317

14-
//@Mixin(PokemonItemRenderer.class)
15-
//public class PokemonItemRendererMixin implements CobblemonBuiltinItemRenderer {
16-
// public void render(ItemStack stack, ItemDisplayContext mode, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay) {
17-
// TimeCapsuleItemRenderer.INSTANCE.render(stack, mode, matrices, vertexConsumers, light, overlay);
18-
// }
19-
//}
18+
@Mixin(PokemonItemRenderer.class)
19+
public class PokemonItemRendererMixin {
20+
21+
@Inject(method = "render", at = @At("HEAD"), cancellable = true)
22+
public void renderProxy(ItemStack stack, ItemDisplayContext mode, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay, CallbackInfo ci) {
23+
PokemonItemRendererProxy.render(stack, mode, matrices, vertexConsumers, light, overlay);
24+
ci.cancel();
25+
}
26+
}

common/src/main/java/generations/gg/generations/core/generationscore/common/util/GenerationsUtils.kt

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -147,13 +147,21 @@ object GenerationsUtils {
147147
}
148148

149149
fun raycast(entity: Entity, maxDistance: Double, tickDelta: Float, predicate: Predicate<Entity?>): HitResult? {
150-
val vec3d = entity.getEyePosition(tickDelta)
151-
val vec3d2 = entity.getViewVector(tickDelta)
152-
val vec3d3 = vec3d.add(vec3d2.x * maxDistance, vec3d2.y * maxDistance, vec3d2.z * maxDistance)
153-
val box = entity.boundingBox.expandTowards(vec3d2.scale(maxDistance)).inflate(1.0, 1.0, 1.0)
154-
return ProjectileUtil.getEntityHitResult(entity, vec3d, vec3d3, box, predicate, maxDistance)
150+
val start = entity.getEyePosition(tickDelta)
151+
val direction = entity.getViewVector(tickDelta)
152+
val end = start.add(direction.x * maxDistance, direction.y * maxDistance, direction.z * maxDistance)
153+
val box = entity.boundingBox.expandTowards(direction.scale(maxDistance)).inflate(1.0)
154+
155+
return ProjectileUtil.getEntityHitResult(
156+
entity.level(),
157+
entity,
158+
start,
159+
end,
160+
box,
161+
predicate,
162+
0.3f
163+
)
155164
}
156-
157165
@JvmRecord
158166
data class Serializer<T>(val codec: Codec<T>) : JsonSerializer<T>,
159167
JsonDeserializer<T> {

common/src/main/java/generations/gg/generations/core/generationscore/common/world/item/MelodyFluteItem.kt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,9 @@ class MelodyFluteItem(properties: Properties) : ElementalPostBattleUpdateItem(pr
9494
@JvmStatic
9595
fun getImbuedItem(stack: ItemStack?): ItemStack {
9696
if (stack != null) {
97-
val lists = stack.get(
98-
IMBUED.componentType()
99-
)!!
100-
.stacks()
97+
val lists = stack.get(IMBUED.componentType())?.stacks()
10198

102-
if (lists != null && !lists.isEmpty()) {
99+
if (!lists.isNullOrEmpty()) {
103100
return lists[0].resource().cachedStack
104101
}
105102
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package generations.gg.generations.core.generationscore.common.world.item
2+
3+
import com.cobblemon.mod.common.pokemon.Species
4+
import net.minecraft.world.item.ItemStack
5+
import org.joml.Vector4f
6+
7+
interface PokemonProvidingItem {
8+
fun getSpeciesAndAspectsPair(stack: ItemStack): Pair<Species, Set<String>>?
9+
fun stackTint(stack: ItemStack): Vector4f = Vector4f(1f, 1f, 1f, 1f)
10+
}

0 commit comments

Comments
 (0)