Compare commits

...
4 Commits
Author SHA1 Message Date
Landon Wills c921496b50 some shader stuff 2025-08-31 11:37:55 -04:00
Landon Wills a9d1000384 testing 2025-08-28 01:11:03 -04:00
Landon Wills 225721aec4 Add tropius 2025-08-26 16:58:05 -04:00
Landon Wills ae9475959d Add sound scraping 2025-08-26 16:57:52 -04:00
23 changed files with 864 additions and 134 deletions
@@ -8,17 +8,26 @@
package com.cobblemon.mod.common.client.render.models.blockbench
import com.cobblemon.mod.common.client.render.models.blockbench.PosableModel.Companion.getOrMakeShard
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.shader.CobblemonShaders
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.util.cobblemonResource
import com.google.common.collect.ImmutableList
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.client.renderer.RenderType
import com.mojang.blaze3d.vertex.VertexConsumer
import net.minecraft.client.renderer.entity.LivingEntityRenderer
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.client.model.EntityModel
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.world.entity.Entity
import net.minecraft.world.entity.LivingEntity
import net.minecraft.resources.ResourceLocation
import org.apache.commons.lang3.tuple.Triple
/**
* A wrapping around a [PosableModel] that presents as an [EntityModel]. This is used to continue using
@@ -29,13 +38,46 @@ import net.minecraft.resources.ResourceLocation
* @since January 5th, 2024
*/
abstract class PosableEntityModel<T : Entity>(
renderTypeFunc: (ResourceLocation) -> RenderType = RenderType::entityCutout
renderTypeFunc: (ResourceLocation) -> RenderType = {
val textures = ImmutableList.of(
Triple.of(it, false, false),
Triple.of(cobblemonResource("textures/tera_layer.png"), false, false),
Triple.of(cobblemonResource("textures/tera_layer.png"), false, false),
Triple.of(cobblemonResource("textures/tera_layer.png"), false, false),
Triple.of(cobblemonResource("textures/tera_layer.png"), false, false),
)
makeLayer(RenderStateShard.MultiTextureStateShard(textures), false, false, false)
}
) : EntityModel<T>(renderTypeFunc) {
val context: RenderContext = RenderContext().also {
it.put(RenderContext.RENDER_STATE, RenderContext.RenderState.WORLD)
}
lateinit var posableModel: PosableModel
companion object {
fun makeLayer(texture: RenderStateShard.EmptyTextureStateShard, emissive: Boolean, translucent: Boolean, translucentCull: Boolean): RenderType {
val multiPhaseParameters: RenderType.CompositeState = RenderType.CompositeState.builder()
.setShaderState(getOrMakeShard() as RenderStateShard.ShaderStateShard)
.setTextureState(texture)
.setTransparencyState(if (translucent) RenderStateShard.TRANSLUCENT_TRANSPARENCY else RenderStateShard.NO_TRANSPARENCY)
.setLightmapState(if (!emissive) RenderStateShard.LIGHTMAP else RenderStateShard.LightmapStateShard(false))
.setCullState(RenderStateShard.CULL)
.setWriteMaskState(RenderStateShard.COLOR_DEPTH_WRITE)
.setOverlayState(RenderStateShard.OVERLAY)
.createCompositeState(false)
return RenderType.create(
"cobblemon_entity_layer",
DefaultVertexFormat.NEW_ENTITY,
VertexFormat.Mode.QUADS,
256,
true,
translucent,
multiPhaseParameters
)
}
}
override fun renderToBuffer(
stack: PoseStack,
buffer: VertexConsumer,
@@ -49,6 +91,7 @@ abstract class PosableEntityModel<T : Entity>(
// We're using the living entity renderer, ergo we need to apply a Y offset of 24 model units (1.5 blocks) for reasons only God can tell us.
stack.translate(0.0, 1.5, 0.0)
}
// RenderSystem.setShader { CobblemonShaders.OVERLAY }
posableModel.render(context, stack, buffer, packedLight, overlay, color)
}
@@ -17,6 +17,7 @@ import com.cobblemon.mod.common.api.molang.MoLangFunctions.addFunctions
import com.cobblemon.mod.common.api.molang.MoLangFunctions.setup
import com.cobblemon.mod.common.client.ClientMoLangFunctions.animationFunctions
import com.cobblemon.mod.common.client.ClientMoLangFunctions.setupClient
import com.cobblemon.mod.common.client.CobblemonClient
import com.cobblemon.mod.common.client.entity.PokemonClientDelegate
import com.cobblemon.mod.common.client.render.AnimatedModelTextureSupplier
import com.cobblemon.mod.common.client.render.ModelLayer
@@ -33,6 +34,7 @@ import com.cobblemon.mod.common.client.render.models.blockbench.quirk.ModelQuirk
import com.cobblemon.mod.common.client.render.models.blockbench.quirk.SimpleQuirk
import com.cobblemon.mod.common.client.render.models.blockbench.repository.RenderContext
import com.cobblemon.mod.common.client.render.models.blockbench.wavefunction.WaveFunction
import com.cobblemon.mod.common.client.render.shader.CobblemonShaders
import com.cobblemon.mod.common.entity.PosableEntity
import com.cobblemon.mod.common.entity.PoseType
import com.cobblemon.mod.common.entity.generic.GenericBedrockEntity
@@ -40,26 +42,33 @@ import com.cobblemon.mod.common.entity.npc.NPCEntity
import com.cobblemon.mod.common.entity.pokeball.EmptyPokeBallEntity
import com.cobblemon.mod.common.entity.pokemon.PokemonEntity
import com.cobblemon.mod.common.util.asExpressionLike
import com.cobblemon.mod.common.util.cobblemonResource
import com.cobblemon.mod.common.util.plus
import com.cobblemon.mod.common.util.toRGBA
import com.google.common.collect.ImmutableList
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Axis
import net.minecraft.client.Minecraft
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.ShaderInstance
import net.minecraft.client.renderer.texture.DynamicTexture
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.Mth
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.ItemDisplayContext
import net.minecraft.world.phys.Vec3
import org.apache.commons.lang3.tuple.Triple
import org.joml.Matrix4f
import org.joml.Vector3f
import java.lang.reflect.Constructor
/**
* A model that can be posed and animated using [PoseAnimation]s and [ActiveAnimation]s. This
@@ -414,6 +423,7 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
/** Needed a custom one, so I can make it take in a dynamic texture instead of resource location */
class DynamicStateShard(texture: DynamicTexture) : RenderStateShard.EmptyTextureStateShard(Runnable {
RenderSystem.setShaderTexture(0, texture.id)
RenderSystem.setShaderTexture(1, cobblemonResource("textures/tera_layer.png"))
}, Runnable {
texture.close() // Cleanup
})
@@ -453,13 +463,14 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
if (provider != null) {
for (layer in currentLayers) {
var renderLayer : RenderType
var texture: ResourceLocation? = null
if (layer.texture is AnimatedModelTextureSupplier && layer.texture.interpolation) {
//Handle Interpolation
val texture = layer.texture.interpolatedTexture(currentState ?: FloatingState()) ?: continue
renderLayer = makeLayer(DynamicStateShard(texture), layer.emissive, layer.translucent, layer.translucent_cull)
}
else {
val texture = layer.texture?.invoke(currentState ?: FloatingState()) ?: continue
texture = layer.texture?.invoke(currentState ?: FloatingState()) ?: continue
renderLayer = getLayer(texture, layer.emissive, layer.translucent, layer.translucent_cull)
}
val consumer = provider.getBuffer(renderLayer)
@@ -490,18 +501,21 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
return ItemDisplayContext.valueOf(displayContextString)
}
companion object {
var test: Any? = null
fun getOrMakeShard(): Any {
if (test == null) {
test = RenderStateShard.ShaderStateShard({ CobblemonShaders.OVERLAY })
}
return test!!
}
}
/** Generates a [RenderType] by the power of god and anime. Only possible thanks to 100 access wideners. */
fun makeLayer(texture: RenderStateShard.EmptyTextureStateShard, emissive: Boolean, translucent: Boolean, translucentCull: Boolean): RenderType {
val multiPhaseParameters: RenderType.CompositeState = RenderType.CompositeState.builder()
.setShaderState(
when {
emissive && translucent -> RenderStateShard.RENDERTYPE_ENTITY_TRANSLUCENT_EMISSIVE_SHADER
!emissive && translucent && translucentCull -> RenderStateShard.RENDERTYPE_ENTITY_TRANSLUCENT_CULL_SHADER
!emissive && translucent -> RenderStateShard.RENDERTYPE_ENTITY_TRANSLUCENT_SHADER
!emissive && !translucent -> RenderStateShard.RENDERTYPE_ENTITY_CUTOUT_SHADER
else -> RenderStateShard.RENDERTYPE_ENTITY_TRANSLUCENT_EMISSIVE_SHADER // This one should be changed to maybe a custom shader? Translucent stuffs with things
}
)
.setShaderState(getOrMakeShard() as RenderStateShard.ShaderStateShard)
.setTextureState(texture)
.setTransparencyState(if (translucent) RenderStateShard.TRANSLUCENT_TRANSPARENCY else RenderStateShard.NO_TRANSPARENCY)
.setLightmapState(if (!emissive) RenderStateShard.LIGHTMAP else RenderStateShard.LightmapStateShard(false))
@@ -528,7 +542,14 @@ open class PosableModel(@Transient override val rootPart: Bone) : ModelFrame {
} else if (!emissive && !translucentCull) {
RenderType.entityTranslucent(texture)
} else {
makeLayer(RenderStateShard.TextureStateShard(texture, false, false), emissive = emissive, translucent = translucent, translucentCull = translucentCull)
val texture = RenderStateShard.MultiTextureStateShard(ImmutableList.of(
Triple.of(texture, false, false),
Triple.of(cobblemonResource("textures/tera_layer.png"), false, false),
Triple.of(cobblemonResource("textures/tera_layer.png"), false, false),
Triple.of(cobblemonResource("textures/tera_layer.png"), false, false),
Triple.of(cobblemonResource("textures/tera_layer.png"), false, false),
))
makeLayer(texture, emissive = emissive, translucent = translucent, translucentCull = translucentCull)
}
}
@@ -20,6 +20,7 @@ object CobblemonShaders {
lateinit var PARTICLE_BLEND: ShaderInstance
// This is Material.ALPHA. Weird internal name for "alphatest" shader.
lateinit var PARTICLE_CUTOUT: ShaderInstance
lateinit var OVERLAY: ShaderInstance
private fun registerShader(shader: (ResourceProvider) -> ShaderRegistryData, callback: Consumer<ShaderInstance>){
SHADERS_TO_REGISTER.add(Pair(shader, callback))
@@ -31,5 +32,8 @@ object CobblemonShaders {
registerShader({rm: ResourceProvider -> ShaderRegistryData(rm, cobblemonResource("particle_cutout"), DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP) }) {
PARTICLE_CUTOUT = it
}
registerShader({rm: ResourceProvider -> ShaderRegistryData(rm, cobblemonResource("overlay"), DefaultVertexFormat.NEW_ENTITY) }) {
OVERLAY = it
}
}
}
@@ -0,0 +1,36 @@
#version 150
#moj_import <fog.glsl>
uniform sampler2D Sampler0;
uniform sampler2D Sampler3;
uniform vec4 ColorModulator;
uniform float FogStart;
uniform float FogEnd;
uniform vec4 FogColor;
uniform float u_evo_progress;
in float vertexDistance;
in vec4 vertexColor;
in vec4 lightMapColor;
in vec4 overlayColor;
in vec2 texCoord0;
in vec4 normal;
out vec4 fragColor;
void main() {
vec4 color = texture(Sampler0, texCoord0);
vec4 teraColor = texture(Sampler3, texCoord0);
if (color.a < 0.1) {
discard;
}
vec4 mixed = mix(color, teraColor, teraColor.a);
color = mixed * vertexColor * ColorModulator;
color.rgb = mix(overlayColor.rgb, color.rgb, overlayColor.a);
color *= lightMapColor;
color = mix(color, vec4(1.0, 1.0, 1.0, 1.0), u_evo_progress);
fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
}
@@ -0,0 +1,37 @@
#version 150
#moj_import <light.glsl>
#moj_import <fog.glsl>
in vec3 Position;
in vec4 Color;
in vec2 UV0;
in ivec2 UV1;
in ivec2 UV2;
in vec3 Normal;
uniform sampler2D Sampler1;
uniform sampler2D Sampler2;
uniform mat4 ModelViewMat;
uniform mat4 ProjMat;
uniform int FogShape;
uniform vec3 Light0_Direction;
uniform vec3 Light1_Direction;
out float vertexDistance;
out vec4 vertexColor;
out vec4 lightMapColor;
out vec4 overlayColor;
out vec2 texCoord0;
void main() {
gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);
vertexDistance = fog_distance(Position, FogShape);
vertexColor = minecraft_mix_light(Light0_Direction, Light1_Direction, Normal, Color);
lightMapColor = texelFetch(Sampler2, UV2 / 16, 0);
overlayColor = texelFetch(Sampler1, UV1, 0);
texCoord0 = UV0;
}
@@ -0,0 +1,36 @@
{
"blend": {
"func": "add",
"srcrgb": "srcalpha",
"dstrgb": "1-srcalpha"
},
"vertex": "cobblemon:foo",
"fragment": "cobblemon:bar",
"attributes": [
"Position",
"Color",
"UV0",
"UV1",
"UV2",
"Normal"
],
"samplers": [
{ "name": "Sampler0" },
{ "name": "Sampler1" },
{ "name": "Sampler2" },
{ "name": "Sampler3" }
],
"uniforms": [
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "IViewRotMat", "type": "matrix3x3", "count": 9, "values": [ 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
{ "name": "Light0_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] },
{ "name": "Light1_Direction", "type": "float", "count": 3, "values": [0.0, 0.0, 0.0] },
{ "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] },
{ "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] },
{ "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] },
{ "name": "u_evo_progress", "type": "float", "count": 1, "values": [ 0 ]}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 469 KiB

@@ -79,6 +79,9 @@ transitive-accessible field net/minecraft/client/renderer/RenderStateShard ADDIT
#transitive-accessible field net/minecraft/recipe/BrewingRecipeRegistry POTION_RECIPES Ljava/util/List;
#transitive-accessible field net/minecraft/recipe/BrewingRecipeRegistry POTION_TYPES Ljava/util/List;
transitive-accessible class net/minecraft/world/item/alchemy/PotionBrewing$Mix
transitive-accessible class net/minecraft/client/renderer/RenderStateShard$ShaderStateShard
transitive-accessible class net/minecraft/client/renderer/RenderStateShard$MultiTextureStateShard
transitive-accessible method net/minecraft/client/renderer/RenderStateShard$MultiTextureStateShard <init> (Lcom/google/common/collect/ImmutableList;)V
transitive-accessible class net/minecraft/util/datafix/fixes/ItemStackComponentizationFix$ItemStackData
@@ -52,32 +52,35 @@
"behaviours": {
"AIR": {
"key": "cobblemon:air/rocket",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "21-40",
"SKILL": "0-20",
"SPEED": "21-40",
"STAMINA": "41-60"
"ACCELERATION": "21-40",
"JUMP": "0-20",
"SKILL": "41-60",
"SPEED": "61-80",
"STAMINA": "21-40"
}
},
"LAND": {
"key": "cobblemon:land/horse",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "0-20",
"SKILL": "21-40",
"SPEED": "0-20",
"STAMINA": "61-80"
"ACCELERATION": "0-20",
"JUMP": "21-40",
"SKILL": "41-60",
"SPEED": "21-40",
"STAMINA": "0-20"
}
},
"LIQUID": {
"key": "cobblemon:liquid/boat",
"ridingSounds": [],
"stats": {
"ACCELERATION": "61-80",
"JUMP": "0-20",
"SKILL": "21-40",
"SPEED": "41-60",
"STAMINA": "61-80"
"ACCELERATION": "41-60",
"JUMP": "21-40",
"SKILL": "61-80",
"SPEED": "61-80",
"STAMINA": "0-20"
}
}
},
@@ -53,22 +53,35 @@
"behaviours": {
"AIR": {
"key": "cobblemon:air/bird",
"ridingSounds": [
{
"muffleEnabled": true,
"pitchExpr": "math.max(1.0 ,0.2 + math.pow(math.min(q.ride_velocity() / 1.5, 1.0),2))",
"playForNonPassengers": true,
"soundLocation": "cobblemon:ride.loop.leather",
"volumeExpr": "math.pow(math.min(q.ride_velocity() / 1.5, 1.0),2)"
},
{
"soundLocation": "cobblemon:ride.loop.wind"
}
],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "21-40",
"SKILL": "61-80",
"SPEED": "41-60",
"JUMP": "61-80",
"SKILL": "41-60",
"SPEED": "21-40",
"STAMINA": "21-40"
}
},
"LAND": {
"key": "cobblemon:land/horse",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "0-20",
"SKILL": "21-40",
"ACCELERATION": "21-40",
"JUMP": "21-40",
"SKILL": "41-60",
"SPEED": "21-40",
"STAMINA": "41-60"
"STAMINA": "0-20"
}
}
},
@@ -54,22 +54,24 @@
"behaviours": {
"AIR": {
"key": "cobblemon:air/bird",
"ridingSounds": [],
"stats": {
"ACCELERATION": "21-40",
"JUMP": "21-40",
"SKILL": "41-60",
"SPEED": "0-20",
"STAMINA": "41-60"
"ACCELERATION": "0-20",
"JUMP": "41-60",
"SKILL": "21-40",
"SPEED": "21-40",
"STAMINA": "21-40"
}
},
"LAND": {
"key": "cobblemon:land/horse",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "21-40",
"ACCELERATION": "0-20",
"JUMP": "41-60",
"SKILL": "41-60",
"SPEED": "0-20",
"STAMINA": "61-80"
"SPEED": "21-40",
"STAMINA": "21-40"
}
}
},
@@ -51,26 +51,15 @@
},
"riding": {
"behaviours": {
"LAND": {
"canJump": false,
"canSprint": false,
"key": "cobblemon:land/horse",
"stats": {
"ACCELERATION": "21-40",
"JUMP": "21-40",
"SKILL": "21-40",
"SPEED": "21-40",
"STAMINA": "21-40"
}
},
"LIQUID": {
"key": "cobblemon:liquid/boat",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "0-20",
"ACCELERATION": "21-40",
"JUMP": "41-60",
"SKILL": "41-60",
"SPEED": "21-40",
"STAMINA": "41-60"
"STAMINA": "0-20"
}
}
},
@@ -51,26 +51,15 @@
},
"riding": {
"behaviours": {
"LAND": {
"canJump": false,
"canSprint": false,
"key": "cobblemon:land/horse",
"stats": {
"ACCELERATION": "21-40",
"JUMP": "21-40",
"SKILL": "21-40",
"SPEED": "21-40",
"STAMINA": "21-40"
}
},
"LIQUID": {
"key": "cobblemon:liquid/submarine",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"ACCELERATION": "21-40",
"JUMP": "41-60",
"SKILL": "41-60",
"SPEED": "21-40",
"STAMINA": "61-80"
"STAMINA": "41-60"
}
}
},
@@ -54,32 +54,35 @@
"behaviours": {
"AIR": {
"key": "cobblemon:air/jet",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"ACCELERATION": "61-80",
"JUMP": "41-60",
"SKILL": "41-60",
"SPEED": "61-80",
"STAMINA": "21-40"
}
},
"LAND": {
"key": "cobblemon:land/horse",
"stats": {
"ACCELERATION": "21-40",
"JUMP": "61-80",
"SKILL": "41-60",
"SPEED": "41-60",
"STAMINA": "41-60"
}
},
"LAND": {
"key": "cobblemon:land/horse",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "41-60",
"SKILL": "21-40",
"SPEED": "21-40",
"STAMINA": "61-80"
}
},
"LIQUID": {
"key": "cobblemon:liquid/boat",
"ridingSounds": [],
"stats": {
"ACCELERATION": "21-40",
"JUMP": "0-20",
"SKILL": "41-60",
"SPEED": "0-20",
"STAMINA": "41-60"
"ACCELERATION": "0-20",
"JUMP": "41-60",
"SKILL": "21-40",
"SPEED": "41-60",
"STAMINA": "0-20"
}
}
},
@@ -54,22 +54,24 @@
"behaviours": {
"AIR": {
"key": "cobblemon:air/bird",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "61-80",
"ACCELERATION": "61-80",
"JUMP": "41-60",
"SKILL": "41-60",
"SPEED": "61-80",
"STAMINA": "41-60"
"SPEED": "21-40",
"STAMINA": "61-80"
}
},
"LAND": {
"key": "cobblemon:land/horse",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "61-80",
"SKILL": "21-40",
"ACCELERATION": "21-40",
"JUMP": "21-40",
"SKILL": "41-60",
"SPEED": "21-40",
"STAMINA": "21-40"
"STAMINA": "61-80"
}
}
},
@@ -52,12 +52,13 @@
"behaviours": {
"LAND": {
"key": "cobblemon:land/horse",
"ridingSounds": [],
"stats": {
"ACCELERATION": "21-40",
"JUMP": "41-60",
"ACCELERATION": "61-80",
"JUMP": "21-40",
"SKILL": "21-40",
"SPEED": "61-80",
"STAMINA": "81-100"
"SPEED": "21-40",
"STAMINA": "41-60"
}
}
},
@@ -53,22 +53,24 @@
"behaviours": {
"AIR": {
"key": "cobblemon:air/bird",
"ridingSounds": [],
"stats": {
"ACCELERATION": "0-20",
"ACCELERATION": "41-60",
"JUMP": "21-40",
"SKILL": "21-40",
"SPEED": "41-60",
"STAMINA": "61-80"
"SKILL": "0-20",
"SPEED": "21-40",
"STAMINA": "21-40"
}
},
"LAND": {
"key": "cobblemon:land/horse",
"ridingSounds": [],
"stats": {
"ACCELERATION": "21-40",
"JUMP": "21-40",
"SKILL": "21-40",
"SKILL": "0-20",
"SPEED": "21-40",
"STAMINA": "21-40"
"STAMINA": "41-60"
}
}
},
@@ -53,11 +53,12 @@
"behaviours": {
"LAND": {
"key": "cobblemon:land/horse",
"ridingSounds": [],
"stats": {
"ACCELERATION": "41-60",
"JUMP": "61-80",
"JUMP": "41-60",
"SKILL": "41-60",
"SPEED": "41-60",
"SPEED": "21-40",
"STAMINA": "61-80"
}
}
@@ -51,7 +51,7 @@
"riding": {
"behaviours": {
"LAND": {
"key": "cobblemon:land/vehicle",
"key": "cobblemon:land/horse",
"stats": {
"ACCELERATION": "61-80",
"JUMP": "41-60",
@@ -45,6 +45,320 @@
"eggCycles": 20,
"baseFriendship": 50,
"baseScale": 0.9,
"riding": {
"behaviours": {
"LAND": {
"key": "cobblemon:land/horse",
"stats": {
"ACCELERATION": "21-40",
"JUMP": "21-40",
"SKILL": "21-40",
"SPEED": "21-40",
"STAMINA": "21-40"
}
}
},
"seats": [
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseOffsets": [
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"WALK"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"OPEN"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"PROFILE"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"SHOULDER_LEFT"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"SWIM"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"PORTRAIT"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"FLY"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"NONE"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"GLIDE"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"SHOULDER_RIGHT"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"HOVER"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"STAND"
]
},
{
"offset": {
"x": 6.458311E-4,
"y": -0.7845242,
"z": 0.17028669
},
"poseTypes": [
"FLOAT"
]
},
{
"offset": {
"x": -0.020952305,
"y": -0.7691353,
"z": 0.26083404
},
"poseTypes": [
"SLEEP"
]
}
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseOffsets": [
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"WALK"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"OPEN"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"PROFILE"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"SHOULDER_LEFT"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"SWIM"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"PORTRAIT"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"FLY"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"NONE"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"GLIDE"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"SHOULDER_RIGHT"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"HOVER"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"STAND"
]
},
{
"offset": {
"x": -0.0015631126,
"y": -0.7421754,
"z": 1.1267918
},
"poseTypes": [
"FLOAT"
]
},
{
"offset": {
"x": -0.79389423,
"y": -0.7722497,
"z": 0.9370501
},
"poseTypes": [
"SLEEP"
]
}
]
}
]
},
"behaviour": {
"moving": {
"walk": {
@@ -41,7 +41,9 @@ public class GameRendererMixin {
} catch (IOException e) {
throw new RuntimeException(e);
}
FabricShaderProgram finalProgram = program;
list2.removeIf(x -> x.getFirst().getName().equals(finalProgram.getName()));
list2.add(Pair.of(program, pair.getSecond()));
});
}
}
}
+182
View File
@@ -0,0 +1,182 @@
(ns asset-status
(:require
[clojure.java.io :refer [file]]
[clojure.data.json :refer [read-str write-str]]
[clojure.set :as set]
[clj-http.client :as client]
[clojure.data.csv :as csv]
[clojure.string :as s])
(:import
(com.cobblemon.mod.common.api.pokemon PokemonSpecies)
(com.cobblemon.mod.common.client.render.models.blockbench FloatingState)
(com.cobblemon.mod.common.client.render.models.blockbench.bedrock.animation BedrockAnimationRepository)
(com.cobblemon.mod.common.client.render.models.blockbench.repository VaryingModelRepository)
(java.util Collection HashSet)
(net.minecraft.resources ResourceLocation)))
(def headers
[:generation :dex-no :species :land-behaviour :liquid-behaviour :air-behaviour :land-speed :land-acceleration
:land-skill :land-jump :land-stamina :liquid-speed :liquid-acceleration :liquid-skill :liquid-jump :liquid-stamina
:air-speed :air-acceleration :air-skill :air-jump :air-stamina])
(defn csv->map
"Takes a series of CSV rows and returns a map of the columns with the header as the key"
[csv-data]
(let [data (drop 3 csv-data)]
(map zipmap (repeat headers) data)))
(defn fetch-csv
"Fetch and parse the riding data CSV"
[]
(let [url "https://docs.google.com/spreadsheets/u/1/d/1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0/export?format=csv&id=1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0&gid=50216943"]
(->> (client/get url)
(:body)
(csv/read-csv)
(csv->map))))
(defn contains-animation? [animation coll]
(boolean (some #(s/ends-with? % animation) coll)))
(defn get-required-animations [riding-style riding-behaviour]
(condp = riding-style
:air #(and (contains-animation? "air_fly" %) (contains-animation? "air_idle" %))
:land (if (= riding-behaviour "Basic")
#(and (contains-animation? "ground_idle" %) (contains-animation? "ground_walk" %))
#(and (contains-animation? "ground_idle" %) (contains-animation? "ground_walk" %) (contains-animation? "ground_run" %)))
:liquid #(or (and (contains-animation? "water_idle" %) (contains-animation? "water_swim" %))
(and (contains-animation? "surfacewater_idle" %) (contains-animation? "surfacewater_swim" %)))))
(defn get-species-form-name [species form]
(if (or (nil? form) (= "Normal" (.getName form)))
(.getName species)
(str (.getName species) " [" (.getName form) "]")))
(def excluded-behaviours #{"Roll" "Climbing" "Burst" "Waterwalking" "Strider" "Airship" "Glider" "N/A" "Submarine"})
(defn has-riding-behaviour? [species form csv behaviour]
(let [csv-data (first (filter #(= (:species %) (get-species-form-name species form)) csv))
not-nil-or-na #(and (not (nil? %)) (not (set/subset? #{%} excluded-behaviours)))]
(if (not csv-data)
false
(not-nil-or-na (get csv-data behaviour)))))
(defn has-riding-behaviours? [species form csv]
(or
(has-riding-behaviour? species form csv :air-behaviour)
(has-riding-behaviour? species form csv :land-behaviour)
(has-riding-behaviour? species form csv :liquid-behaviour)))
(defn needs-riding-animation? [species form riding-style csv]
(let [csv-data (first (filter #(= (:species %) (get-species-form-name species form)) csv))
behaviour (get csv-data (keyword (str (name riding-style) "-behaviour")))
required-animation-fn (get-required-animations riding-style behaviour)]
(if (or (nil? csv-data) (set/subset? #{behaviour} excluded-behaviours))
false
(let [state (FloatingState.)
species-resource-id (.getResourceIdentifier species)]
(when form (.setCurrentAspects state (set (.getAspects form))))
(let [variation (get (.getVariations VaryingModelRepository/INSTANCE) species-resource-id)
resolved-poser (when variation (.getResolvedPoser variation state))
name (when resolved-poser (.getPath resolved-poser))]
(if name
(not (required-animation-fn (.getAnimations BedrockAnimationRepository/INSTANCE name)))
false))))))
(defn has-seat? [species form]
(let [state (FloatingState.)
species-resource-id (.getResourceIdentifier species)]
(when form
(.setCurrentAspects state (set (.getAspects form))))
(let [poser (.getPoser VaryingModelRepository/INSTANCE species-resource-id state)]
(.setCurrentModel state poser)
(.updateLocators poser nil state)
(boolean (some #(s/starts-with? % "seat_") (keys (.getLocatorStates state)))))))
(defn has-variation? [species form]
(let [aspects (.getAspects form)
resolver (-> (.getVariations VaryingModelRepository/INSTANCE) (.get (.getResourceIdentifier species)))
variations (.getVariations resolver)
matching-variation (filter #(= (set aspects) (set (.getAspects %))) variations)]
(not (empty? matching-variation))))
(defn implemented? [species form]
(if (or (nil? form) (= (.getName form) "Default"))
(.getImplemented species)
(and (.getImplemented species) (has-variation? species form))))
(defn create-implemented-map [species form csv]
(let [result-species (.getName species)
result-form (if (nil? form) "Normal" (.getName form))
implemented? (implemented? species form)
has-seat? (has-seat? species form)]
{:species result-species
:form result-form
:implemented? implemented?
:has-riding-behaviours? (has-riding-behaviours? species form csv)
:has-air-behaviour? (has-riding-behaviour? species form csv :air-behaviour)
:has-land-behaviour? (has-riding-behaviour? species form csv :land-behaviour)
:has-liquid-behaviour? (has-riding-behaviour? species form csv :liquid-behaviour)
:has-seat? has-seat?
:needs-air-riding-animations? (needs-riding-animation? species form :air csv)
:needs-land-riding-animations? (needs-riding-animation? species form :land csv)
:needs-liquid-riding-animations? (needs-riding-animation? species form :liquid csv)}))
(defn implemented-status [species csv]
(if (empty? (.getForms species))
[(create-implemented-map species nil csv)]
(map #(create-implemented-map species % csv) (.getForms species))))
(defn get-engineering-data []
(let [csv (fetch-csv)]
(->> (map #(implemented-status % csv) (.getSpecies PokemonSpecies/INSTANCE))
(reduce into []))))
(def results (get-engineering-data))
;
(defn general-stats []
(let [results (get-engineering-data)
total (count results)]
{:total total
:implemented? (count (filter :implemented? results))
:has-seat? (count (filter :has-seat? results))
:has-a-riding-behaviour? (count (filter :has-riding-behaviours? results))
:needs-animations? (count (filter #(or (:needs-air-riding-animations? %)
(:needs-land-riding-animations? %)
(:needs-liquid-riding-animations? %)) results))}))
(def ordered-keys [:species :form :implemented? :has-seat? :has-riding-behaviours? :has-air-behaviour? :needs-air-riding-animations? :has-land-behaviour? :needs-land-riding-animations? :has-liquid-behaviour? :needs-liquid-riding-animations?])
(defn sort-compare [a b]
(let [key->index (zipmap ordered-keys (range))]
(compare (get key->index a) (get key->index b))))
(defn get-engineering-data-csv []
(let [headers ["Species" "Form" "Implemented?" "Has Seat?" "Has Riding Behaviours?" "Has Air Behaviour?" "Needs Air Animations?" "Has Land Behaviour?" "Needs Land Animations?" "Has Liquid Behaviour?" "Needs Liquid Animations?"]]
(->> (get-engineering-data)
(map #(into (sorted-map-by sort-compare) %))
(sort-by (juxt :species :form))
(map #(s/join "," (vals %)))
(s/join "\n")
(str (s/join "," headers) "\n")
(spit "output.csv"))))
(defn get-engineering-data-csv []
(let [headers ["Species" "Form" "Implemented?" "Has Seat?" "Has Riding Behaviours?" "Has Air Behaviour?" "Needs Air Animations?" "Has Land Behaviour?" "Needs Land Animations?" "Has Liquid Behaviour?" "Needs Liquid Animations?"]]
(->> (get-engineering-data)
(map #(into (sorted-map-by sort-compare) %))
(sort-by (juxt :species :form)))))
(defn ready-to-scrape? [data]
(and (:implemented? data)
(not (:has-seat? data))
(:has-riding-behaviours? data)
(or (not (:has-air-behaviour? data)) (not (:needs-air-riding-animations? data)))
(or (not (:has-land-behaviour? data)) (not (:needs-land-riding-animations? data)))
(or (not (:has-liquid-behaviour? data)) (not (:needs-liquid-riding-animations? data)))))
(let [headers ["Species" "Form" "Implemented?" "Has Seat?" "Has Riding Behaviours?" "Has Air Behaviour?" "Needs Air Animations?" "Has Land Behaviour?" "Needs Land Animations?" "Has Liquid Behaviour?" "Needs Liquid Animations?"]
data (->> (get-engineering-data)
(map #(into (sorted-map-by sort-compare) %))
(sort-by (juxt :species :form))
(filter ready-to-scrape?))]
(map #(select-keys % [:species :form]) data))
+71 -24
View File
@@ -58,9 +58,10 @@
(into {} (map (fn [x] [x (get-seat-locator state x)]) seat-locators))))))
(def headers
[:generation :dex-no :species :land-behaviour :liquid-behaviour :air-behaviour :land-speed :land-acceleration
:land-skill :land-jump :land-stamina :liquid-speed :liquid-acceleration :liquid-skill :liquid-jump :liquid-stamina
:air-speed :air-acceleration :air-skill :air-jump :air-stamina])
[:generation :dex-no :species :land-behaviour :liquid-behaviour :air-behaviour :land-ready-to-scrape?
:liquid-ready-to-scrape? :air-ready-to-scrape? :land-speed :land-acceleration :land-skill :land-jump
:land-stamina :liquid-speed :liquid-acceleration :liquid-skill :liquid-jump :liquid-stamina :air-speed
:air-acceleration :air-skill :air-jump :air-stamina])
(def behaviour-keys
{"Jet" "cobblemon:air/jet"
@@ -86,8 +87,8 @@
(defn csv->map
"Takes a series of CSV rows and returns a map of the columns with the header as the key"
[csv-data]
(let [data (drop 3 csv-data)]
[csv-data headers start]
(let [data (drop start csv-data)]
(map zipmap (repeat headers) data)))
(defn concat-keyword
@@ -105,7 +106,7 @@
=> {:air {:behaviour \"Boat\" :skills {:speed \"B\"}}
"
[data type]
(if (= "N/A" (get data (concat-keyword type "behaviour")))
(if (or (not (= "Yes" (get data (concat-keyword type "ready-to-scrape?")))) (= "N/A" (get data (concat-keyword type "behaviour"))))
data
(assoc data (keyword type)
{:behaviour (get data (concat-keyword type "behaviour"))
@@ -197,11 +198,50 @@
(defn fetch-csv
"Fetch and parse the riding data CSV"
[]
(let [url "https://docs.google.com/spreadsheets/u/1/d/1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0/export?format=csv&id=1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0&gid=50216943"]
(->> (client/get url)
(let [riding-stat-url "https://docs.google.com/spreadsheets/u/1/d/1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0/export?format=csv&id=1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0&gid=50216943"]
(->> (client/get riding-stat-url)
(:body)
(csv/read-csv))))
(defn get-sound-mappings []
(let [data (->> (client/get "https://docs.google.com/spreadsheets/u/1/d/1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0/export?format=csv&id=1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0&gid=513653624")
(:body)
(csv/read-csv)
(rest)
(into {}))]
(update-vals data #(read-str % :key-fn keyword))))
(def sound-headers
[:generation :dex-no :species
:land-riding-sound-1 :land-riding-sound-2 :land-riding-sound-3 :land-riding-sound-4 :land-riding-sound-5
:liquid-riding-sound-1 :liquid-riding-sound-2 :liquid-riding-sound-3 :liquid-riding-sound-4 :liquid-riding-sound-5
:air-riding-sound-1 :air-riding-sound-2 :air-riding-sound-3 :air-riding-sound-4 :air-riding-sound-5])
(defn get-sounds []
(->> (client/get "https://docs.google.com/spreadsheets/u/1/d/1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0/export?format=csv&id=1YhQlnH6m-tlkVbopIg5KLV8BFaaDCgZNkx3dIAy5PZ0&gid=1378925558")
(:body)
(csv/read-csv)
(#(csv->map % sound-headers 3))
(map #(merge % (name->species-form (:species %))))
(map #(assoc % :form (or (:form %) "Normal")))))
(defn condense-sound-type [sound-data sound-mappings riding-type]
(let [keys (map #(concat-keyword riding-type (str "riding-sound-" %)) [1 2 3 4 5])
values (vec (filter not-empty (map #(get sound-data %) keys)))
json (map #(get sound-mappings %) values)]
(vec json)))
(defn sound-data->json [sound-mappings sound-data riding-type]
(->> (map #(assoc % :sound-json (condense-sound-type % sound-mappings riding-type)) sound-data)
(map (fn [x] {[(:species x) (:form x)] x}))
(apply merge)
(#(update-vals % :sound-json))))
(defn get-sounds-map [sound-mappings sounds]
(->> ["air" "liquid" "land"]
(map (fn [x] [x (sound-data->json sound-mappings sounds x)]))
(into {})))
(defn stats->json
"Builds a JSON-ready map of riding stat grades from the provided stats-data."
[stats-data]
@@ -242,13 +282,13 @@
- Expects `behaviour-data` like {:behaviour \"...\" :stats {:speed \"A\" ...}}.
- Resolves a stable key via `behaviour-keys`; returns nil if behaviour is unknown.
- Translates letter grades to numeric ranges via `grade-ranges`."
[behaviour-data]
[behaviour-data behaviour-sounds]
(let [behaviour (:behaviour behaviour-data)
behaviour-json (behaviour-type->json behaviour)
stats (:stats behaviour-data)
stats-json (stats->json stats)]
(when (and behaviour-json stats-json)
(merge behaviour-json stats-json))))
(merge behaviour-json stats-json behaviour-sounds))))
(defn assoc-behaviour
"Conditionally assoc a behaviour block into the accumulator `map`.
@@ -256,9 +296,10 @@
- `behaviour` is the keyword to read (e.g., :air).
- When present and valid, associates under an upper-cased key (e.g., :AIR).
Returns the updated map or the original map if nothing was added."
[map species-data behaviour]
(let [behaviour-data (get species-data behaviour)
behaviour-json (behaviour->json behaviour-data)]
[map species-data behaviour sounds]
(let [behaviour-sounds (get-in sounds [(name behaviour) [(:species species-data) (or (:form species-data) "Normal")]])
behaviour-data (get species-data behaviour)
behaviour-json (behaviour->json behaviour-data {:ridingSounds behaviour-sounds})]
(if (and behaviour-data behaviour-json)
(assoc map (keyword (upper-case (name behaviour))) behaviour-json)
map)))
@@ -306,12 +347,12 @@
"Assemble the behaviours section for a species in the expected JSON schema.
Builds a map of available behaviours (:AIR, :LAND, :LIQUID) using `assoc-behaviour`.
Wraps the result as {:riding {:behaviours {...}}}. Returns nil when no behaviours exist."
[species-data]
[species-data sounds]
(let [behaviours
(-> {}
(assoc-behaviour species-data :air)
(assoc-behaviour species-data :land)
(assoc-behaviour species-data :liquid))]
(assoc-behaviour species-data :air sounds)
(assoc-behaviour species-data :land sounds)
(assoc-behaviour species-data :liquid sounds))]
(when (not-empty behaviours)
{:riding {:behaviours behaviours
:seats (seats->json (:seat-data species-data))}})))
@@ -319,7 +360,10 @@
(defn sanitize-species-name
"Normalizes `species` by lower-casing and removing spaces, underscores, colons, dots, and hyphens."
[species]
(s/replace (lower-case species) #"([ _:\.\-]+)" ""))
(-> species
(lower-case)
(s/replace #"([ _:\.\-']+)" "")
(s/replace "é" "e")))
(defn get-file-for-species
"Return the first JSON file from `files` whose name matches `species`.
@@ -475,14 +519,14 @@
- Collapse the data into just the file and new updates, and group results by :file.
- Merge all updates into a single text blob
Returns a map: java.io.File -> string"
[csv files]
[csv files sounds]
(let [file-updates (->> csv
(csv->map)
(#(csv->map % headers 3))
(map sanitize-riding-data)
(filter #(or (:air %) (:land %) (:liquid %)))
(map #(assoc % :seat-data (generate-seat-data %)))
(filter #(:seat-data %))
(map #(assoc % :json (behaviours->json %)))
(map #(assoc % :json (behaviours->json % sounds)))
(filter #(:json %))
(map #(riding-data->cobblemon-json % files))
(group-by :file))]
@@ -491,8 +535,9 @@
(defn run-script []
(let [path "../../common/src/main/resources/data/cobblemon/species"
files (file-seq (file path))
csv (fetch-csv)
updates (get-file-updates csv files)]
riding-data-csv (fetch-csv)
sounds (get-sounds-map (get-sound-mappings) (get-sounds))
updates (get-file-updates riding-data-csv files sounds)]
(doseq [[file contents] updates]
(spit file contents))))
@@ -503,4 +548,6 @@
(run-script)
(.setRunnable PokemonRenderer/Companion nil)))))
(-main)
(-main)
(.setRunnable PokemonRenderer/Companion nil)