├── gradlew ├── src └── main │ ├── resources │ ├── moremobvariants.accesswidener │ ├── data │ │ ├── minecraft │ │ │ ├── variants │ │ │ │ └── cat │ │ │ │ │ ├── black.json │ │ │ │ │ ├── calico.json │ │ │ │ │ ├── jellie.json │ │ │ │ │ ├── red.json │ │ │ │ │ ├── tabby.json │ │ │ │ │ ├── white.json │ │ │ │ │ ├── persian.json │ │ │ │ │ ├── ragdoll.json │ │ │ │ │ ├── siamese.json │ │ │ │ │ ├── british_shorthair.json │ │ │ │ │ └── all_black.json │ │ │ └── tags │ │ │ │ └── block │ │ │ │ └── wolves_spawnable_on.json │ │ └── moremobvariants │ │ │ ├── blacklist │ │ │ ├── cat.json │ │ │ ├── cow.json │ │ │ ├── pig.json │ │ │ ├── wolf.json │ │ │ ├── chicken.json │ │ │ ├── sheep.json │ │ │ ├── spider.json │ │ │ └── zombie.json │ │ │ ├── variants │ │ │ ├── cat │ │ │ │ ├── doug.json │ │ │ │ ├── anita_hart.json │ │ │ │ ├── gray_tabby.json │ │ │ │ ├── handsome.json │ │ │ │ ├── tortoiseshell.json │ │ │ │ └── anita_hart_nametag.json │ │ │ ├── cow │ │ │ │ ├── ashen.json │ │ │ │ ├── dairy.json │ │ │ │ ├── pinto.json │ │ │ │ ├── umbra.json │ │ │ │ ├── wooly.json │ │ │ │ ├── cookie.json │ │ │ │ ├── default.json │ │ │ │ ├── sunset.json │ │ │ │ ├── cream.json │ │ │ │ └── albino.json │ │ │ ├── pig │ │ │ │ ├── sooty.json │ │ │ │ ├── default.json │ │ │ │ ├── mottled.json │ │ │ │ ├── piebald.json │ │ │ │ ├── spotted.json │ │ │ │ └── pink_footed.json │ │ │ ├── chicken │ │ │ │ ├── amber.json │ │ │ │ ├── stormy.json │ │ │ │ ├── bronzed.json │ │ │ │ ├── default.json │ │ │ │ ├── midnight.json │ │ │ │ ├── skewbald.json │ │ │ │ ├── gold_crested.json │ │ │ │ ├── bone.json │ │ │ │ └── duck.json │ │ │ ├── skeleton │ │ │ │ ├── sandy.json │ │ │ │ ├── default.json │ │ │ │ ├── dungeons.json │ │ │ │ ├── weathered.json │ │ │ │ ├── mossy.json │ │ │ │ └── sandy_increased_spawns_in_deserts.json │ │ │ ├── spider │ │ │ │ ├── default.json │ │ │ │ ├── black_widow.json │ │ │ │ ├── tarantula.json │ │ │ │ ├── brown.json │ │ │ │ └── bone.json │ │ │ ├── wolf │ │ │ │ ├── default.json │ │ │ │ ├── husky.json │ │ │ │ ├── jupiter.json │ │ │ │ ├── white_terrier.json │ │ │ │ ├── skeleton.json │ │ │ │ ├── ashen.json │ │ │ │ ├── black.json │ │ │ │ ├── rusty.json │ │ │ │ ├── snowy.json │ │ │ │ ├── woods.json │ │ │ │ ├── chestnut.json │ │ │ │ ├── spotted.json │ │ │ │ ├── striped.json │ │ │ │ ├── pale.json │ │ │ │ ├── husky_from_black_ashen.json │ │ │ │ ├── husky_from_snowy_ashen.json │ │ │ │ ├── basenji_from_rusty_ashen.json │ │ │ │ ├── jupiter_from_rusty_woods.json │ │ │ │ ├── jupiter_from_rusty_chestnut.json │ │ │ │ ├── jupiter_from_striped_woods.json │ │ │ │ ├── german_shepherd_from_jupiter_husky.json │ │ │ │ ├── german_shepherd_from_woods_chestnut.json │ │ │ │ ├── golden_retriever_from_rusty_pale.json │ │ │ │ ├── basenji_from_jupiter_golden_retriever.json │ │ │ │ ├── golden_retriever_from_jupiter_pale.json │ │ │ │ ├── french_bulldog_from_husky_golden_retriever.json │ │ │ │ └── french_bulldog_from_rusty_golden_retriever.json │ │ │ ├── zombie │ │ │ │ ├── alex.json │ │ │ │ ├── ari.json │ │ │ │ ├── default.json │ │ │ │ ├── efe.json │ │ │ │ ├── kai.json │ │ │ │ ├── makena.json │ │ │ │ ├── noor.json │ │ │ │ ├── sunny.json │ │ │ │ └── zuri.json │ │ │ └── sheep │ │ │ │ ├── default.json │ │ │ │ ├── rainbow.json │ │ │ │ ├── fuzzy.json │ │ │ │ ├── inky.json │ │ │ │ ├── patched.json │ │ │ │ ├── rocky.json │ │ │ │ └── long_nosed.json │ │ │ ├── tags │ │ │ ├── block │ │ │ │ └── pig_mud_blocks.json │ │ │ └── worldgen │ │ │ │ └── biome │ │ │ │ ├── additional_wolf_spawns.json │ │ │ │ ├── wolf_ashen_spawns.json │ │ │ │ ├── wolf_black_spawns.json │ │ │ │ ├── wolf_spotted_spawns.json │ │ │ │ ├── wolf_striped_spawns.json │ │ │ │ ├── wolf_snowy_spawns.json │ │ │ │ ├── wolf_pale_spawns.json │ │ │ │ ├── increased_sandy_skeletons.json │ │ │ │ ├── wolf_chestnut_spawns.json │ │ │ │ ├── wolf_rusty_spawns.json │ │ │ │ ├── wolf_woods_spawns.json │ │ │ │ ├── spawn_mossy_skeletons.json │ │ │ │ └── sheep_spawn_with_horns.json │ │ │ └── settings │ │ │ ├── settings.json │ │ │ └── sheep_horn_settings.json │ ├── assets │ │ ├── moremobvariants │ │ │ ├── icon.png │ │ │ └── textures │ │ │ │ └── entity │ │ │ │ ├── cat │ │ │ │ ├── doug.png │ │ │ │ ├── handsome.png │ │ │ │ ├── anita_hart.png │ │ │ │ ├── gray_tabby.png │ │ │ │ └── tortoiseshell.png │ │ │ │ ├── cow │ │ │ │ ├── albino.png │ │ │ │ ├── ashen.png │ │ │ │ ├── cookie.png │ │ │ │ ├── cream.png │ │ │ │ ├── dairy.png │ │ │ │ ├── pinto.png │ │ │ │ ├── sunset.png │ │ │ │ ├── umbra.png │ │ │ │ └── wooly.png │ │ │ │ ├── pig │ │ │ │ ├── sooty.png │ │ │ │ ├── mottled.png │ │ │ │ ├── piebald.png │ │ │ │ ├── spotted.png │ │ │ │ ├── pink_footed.png │ │ │ │ └── mud │ │ │ │ │ └── mud_overlay.png │ │ │ │ ├── sheep │ │ │ │ ├── inky.png │ │ │ │ ├── fuzzy.png │ │ │ │ ├── rocky.png │ │ │ │ ├── patched.png │ │ │ │ ├── rainbow.png │ │ │ │ ├── wool │ │ │ │ │ ├── inky.png │ │ │ │ │ ├── fuzzy.png │ │ │ │ │ ├── rocky.png │ │ │ │ │ ├── patched.png │ │ │ │ │ ├── rainbow.png │ │ │ │ │ └── long_nosed.png │ │ │ │ ├── long_nosed.png │ │ │ │ ├── horns │ │ │ │ │ ├── horns_gray.png │ │ │ │ │ ├── horns_beige.png │ │ │ │ │ ├── horns_black.png │ │ │ │ │ └── horns_brown.png │ │ │ │ └── sheared_color_overlay │ │ │ │ │ ├── inky.png │ │ │ │ │ ├── default.png │ │ │ │ │ ├── fuzzy.png │ │ │ │ │ ├── patched.png │ │ │ │ │ ├── rocky.png │ │ │ │ │ └── long_nosed.png │ │ │ │ ├── zombie │ │ │ │ ├── ari.png │ │ │ │ ├── efe.png │ │ │ │ ├── kai.png │ │ │ │ ├── alex.png │ │ │ │ ├── noor.png │ │ │ │ ├── sunny.png │ │ │ │ ├── zuri.png │ │ │ │ └── makena.png │ │ │ │ ├── chicken │ │ │ │ ├── bone.png │ │ │ │ ├── duck.png │ │ │ │ ├── amber.png │ │ │ │ ├── bronzed.png │ │ │ │ ├── stormy.png │ │ │ │ ├── midnight.png │ │ │ │ ├── skewbald.png │ │ │ │ └── gold_crested.png │ │ │ │ ├── spider │ │ │ │ ├── bone.png │ │ │ │ ├── brown.png │ │ │ │ ├── eyes │ │ │ │ │ ├── bone.png │ │ │ │ │ └── brown.png │ │ │ │ ├── tarantula.png │ │ │ │ └── black_widow.png │ │ │ │ ├── skeleton │ │ │ │ ├── mossy.png │ │ │ │ ├── sandy.png │ │ │ │ ├── dungeons.png │ │ │ │ └── weathered.png │ │ │ │ └── wolf │ │ │ │ ├── ashen_tame.png │ │ │ │ ├── ashen_wild.png │ │ │ │ ├── black_tame.png │ │ │ │ ├── black_wild.png │ │ │ │ ├── husky_tame.png │ │ │ │ ├── husky_wild.png │ │ │ │ ├── rusty_tame.png │ │ │ │ ├── rusty_wild.png │ │ │ │ ├── snowy_tame.png │ │ │ │ ├── snowy_wild.png │ │ │ │ ├── woods_tame.png │ │ │ │ ├── woods_wild.png │ │ │ │ ├── ashen_angry.png │ │ │ │ ├── basenji_tame.png │ │ │ │ ├── basenji_wild.png │ │ │ │ ├── black_angry.png │ │ │ │ ├── husky_angry.png │ │ │ │ ├── jupiter_tame.png │ │ │ │ ├── jupiter_wild.png │ │ │ │ ├── rusty_angry.png │ │ │ │ ├── snowy_angry.png │ │ │ │ ├── spotted_tame.png │ │ │ │ ├── spotted_wild.png │ │ │ │ ├── striped_tame.png │ │ │ │ ├── striped_wild.png │ │ │ │ ├── woods_angry.png │ │ │ │ ├── basenji_angry.png │ │ │ │ ├── chestnut_angry.png │ │ │ │ ├── chestnut_tame.png │ │ │ │ ├── chestnut_wild.png │ │ │ │ ├── jupiter_angry.png │ │ │ │ ├── skeleton_angry.png │ │ │ │ ├── skeleton_tame.png │ │ │ │ ├── skeleton_wild.png │ │ │ │ ├── spotted_angry.png │ │ │ │ ├── striped_angry.png │ │ │ │ ├── french_bulldog_angry.png │ │ │ │ ├── french_bulldog_tame.png │ │ │ │ ├── french_bulldog_wild.png │ │ │ │ ├── german_shepherd_tame.png │ │ │ │ ├── german_shepherd_wild.png │ │ │ │ ├── white_terrier_angry.png │ │ │ │ ├── white_terrier_tame.png │ │ │ │ ├── white_terrier_wild.png │ │ │ │ ├── german_shepherd_angry.png │ │ │ │ ├── golden_retriever_angry.png │ │ │ │ ├── golden_retriever_tame.png │ │ │ │ └── golden_retriever_wild.png │ │ └── minecraft │ │ │ └── textures │ │ │ └── entity │ │ │ └── wolf │ │ │ └── wolf_collar.png │ ├── moremobvariants.mixins.json │ └── fabric.mod.json │ └── java │ └── com │ └── github │ └── nyuppo │ ├── variant │ ├── VariantModifier.java │ ├── ShinyModifier.java │ ├── CustomEyesModifier.java │ ├── CustomWoolModifier.java │ ├── ShearedWoolColorModifier.java │ ├── NametagOverrideModifier.java │ ├── CustomVariantNameModifier.java │ ├── MoonPhaseModifier.java │ ├── DiscardableModifier.java │ ├── SpawnableBiomesModifier.java │ ├── BreedingResultModifier.java │ └── MobVariant.java │ ├── util │ ├── BiomeSpawnData.java │ ├── BreedingResultData.java │ └── VariantBag.java │ ├── mixin │ ├── QuadrupedEntityModelPartAccessor.java │ ├── ChickenEggMixin.java │ ├── PigFlowerMixin.java │ ├── MobEntityVariantsMixin.java │ ├── CatRendererMixin.java │ ├── CowRendererMixin.java │ ├── PigRendererMixin.java │ ├── SheepRendererMixin.java │ ├── SpiderRendererMixin.java │ ├── ChickenRendererMixin.java │ ├── ZombieRendererMixin.java │ ├── SkeletonRendererMixin.java │ ├── CustomEyesFeatureMixin.java │ ├── CatFluffMixin.java │ ├── SheepWoolFeatureMixin.java │ ├── WolfRendererMixin.java │ ├── SpiderVariantsMixin.java │ ├── ZombieVariantsMixin.java │ ├── SkeletonVariantsMixin.java │ ├── WolfVariantsMixin.java │ ├── CowVariantsMixin.java │ ├── ChickenVariantsMixin.java │ ├── CatVariantsMixin.java │ ├── SheepVariantsMixin.java │ └── PigVariantsMixin.java │ ├── networking │ ├── MMVNetworkingConstants.java │ ├── ClientRequestVariantPayload.java │ ├── ServerRespondBasicVariantPayload.java │ └── ServerRespondVariantPayload.java │ ├── config │ ├── VariantBlacklist.java │ ├── VariantSettings.java │ └── SheepHornSettings.java │ ├── client │ └── render │ │ └── entity │ │ └── feature │ │ ├── PigMudFeatureRenderer.java │ │ ├── ShearedWoolColorFeatureRenderer.java │ │ └── SheepHornsFeatureRenderer.java │ ├── MoreMobVariantsClient.java │ └── MoreMobVariants.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── .gitignore ├── gradle.properties ├── .github └── workflows │ └── build.yml ├── README.md ├── gradlew.bat └── LICENSE /gradlew: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/gradlew -------------------------------------------------------------------------------- /src/main/resources/moremobvariants.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v2 named -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/black.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/calico.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/jellie.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/red.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/tabby.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/white.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/persian.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/ragdoll.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/siamese.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/blacklist/cat.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [] 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/blacklist/cow.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [] 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/blacklist/pig.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [] 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/blacklist/wolf.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [] 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cat/doug.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/ashen.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/dairy.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/pinto.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/umbra.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/wooly.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/pig/sooty.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/blacklist/chicken.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [] 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/blacklist/sheep.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [] 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/blacklist/spider.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [] 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/blacklist/zombie.json: -------------------------------------------------------------------------------- 1 | { 2 | "blacklist": [] 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cat/anita_hart.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cat/gray_tabby.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cat/handsome.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/amber.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/stormy.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/cookie.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 3 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/sunset.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/pig/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/pig/mottled.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/pig/piebald.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/pig/spotted.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/skeleton/sandy.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/spider/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 5 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/husky.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/jupiter.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/alex.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/ari.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 3 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/efe.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/kai.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/makena.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/noor.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/sunny.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/zombie/zuri.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/british_shorthair.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cat/tortoiseshell.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/bronzed.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 3 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/midnight.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/skewbald.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/pig/pink_footed.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/skeleton/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/skeleton/dungeons.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 3 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/skeleton/weathered.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/spider/black_widow.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/spider/tarantula.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/gold_crested.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/white_terrier.json: -------------------------------------------------------------------------------- 1 | { 2 | "nametag_override": "Luna" 3 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/variants/cat/all_black.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "minimum_moon_size": 0.9 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/spider/brown.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 3, 3 | "custom_eyes": true 4 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/block/pig_mud_blocks.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:mud" 4 | ] 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/bone.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2, 3 | "biome_tag": "minecraft:is_nether" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/sheep/default.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "has_color_when_sheared": true 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/cream.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "shiny": true, 4 | "discard_chance": 0.8 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/sheep/rainbow.json: -------------------------------------------------------------------------------- 1 | { 2 | "custom_wool": true, 3 | "nametag_override": "rainbow" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/skeleton.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "minecraft:is_nether" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/chicken/duck.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "shiny": true, 4 | "discard_chance": 0.75 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/ashen.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "moremobvariants:wolf_ashen_spawns" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/black.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "moremobvariants:wolf_black_spawns" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/rusty.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "moremobvariants:wolf_rusty_spawns" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/snowy.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "moremobvariants:wolf_snowy_spawns" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/woods.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "moremobvariants:wolf_woods_spawns" 4 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/VariantModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | public interface VariantModifier { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cat/anita_hart_nametag.json: -------------------------------------------------------------------------------- 1 | { 2 | "nametag_override": "Anita Hart", 3 | "name": "anita_hart" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/skeleton/mossy.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2, 3 | "biome_tag": "moremobvariants:spawn_mossy_skeletons" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/chestnut.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "moremobvariants:wolf_chestnut_spawns" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/spotted.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "moremobvariants:wolf_spotted_spawns" 4 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/striped.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "biome_tag": "moremobvariants:wolf_striped_spawns" 4 | } -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/icon.png -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/sheep/fuzzy.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2, 3 | "custom_wool": true, 4 | "has_color_when_sheared": true 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/sheep/inky.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "custom_wool": true, 4 | "has_color_when_sheared": true 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/sheep/patched.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2, 3 | "custom_wool": true, 4 | "has_color_when_sheared": true 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/sheep/rocky.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2, 3 | "custom_wool": true, 4 | "has_color_when_sheared": true 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/sheep/long_nosed.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "custom_wool": true, 4 | "has_color_when_sheared": true 5 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/ShinyModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | public class ShinyModifier implements VariantModifier { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/spider/bone.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "shiny": true, 4 | "discard_chance": 0.8, 5 | "custom_eyes": true 6 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/pale.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "name": "default", 4 | "biome_tag": "moremobvariants:wolf_pale_spawns" 5 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/CustomEyesModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | public class CustomEyesModifier implements VariantModifier { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/CustomWoolModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | public class CustomWoolModifier implements VariantModifier { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/settings/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "enable_muddy_pigs": true, 3 | "muddy_pig_timeout": 0, 4 | "child_random_variant_chance": 0.25 5 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/cow/albino.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 2, 3 | "shiny": true, 4 | "biome_tag": "minecraft:is_taiga", 5 | "discard_chance": 0.9 6 | } -------------------------------------------------------------------------------- /src/main/resources/data/minecraft/tags/block/wolves_spawnable_on.json: -------------------------------------------------------------------------------- 1 | { 2 | "replace": false, 3 | "values": [ 4 | "minecraft:coarse_dirt", 5 | "minecraft:podzol" 6 | ] 7 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/ShearedWoolColorModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | public class ShearedWoolColorModifier implements VariantModifier { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/minecraft/textures/entity/wolf/wolf_collar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/minecraft/textures/entity/wolf/wolf_collar.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cat/doug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cat/doug.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/albino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/albino.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/ashen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/ashen.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/cookie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/cookie.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/cream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/cream.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/dairy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/dairy.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/pinto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/pinto.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/sunset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/sunset.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/umbra.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/umbra.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cow/wooly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cow/wooly.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/pig/sooty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/pig/sooty.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/inky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/inky.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/zombie/ari.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/zombie/ari.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/zombie/efe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/zombie/efe.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/zombie/kai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/zombie/kai.png -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/NametagOverrideModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | public record NametagOverrideModifier(String nametag) implements VariantModifier { 4 | } -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cat/handsome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cat/handsome.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/chicken/bone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/chicken/bone.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/chicken/duck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/chicken/duck.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/pig/mottled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/pig/mottled.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/pig/piebald.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/pig/piebald.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/pig/spotted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/pig/spotted.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/fuzzy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/fuzzy.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/rocky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/rocky.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/spider/bone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/spider/bone.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/spider/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/spider/brown.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/zombie/alex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/zombie/alex.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/zombie/noor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/zombie/noor.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/zombie/sunny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/zombie/sunny.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/zombie/zuri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/zombie/zuri.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cat/anita_hart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cat/anita_hart.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cat/gray_tabby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cat/gray_tabby.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/chicken/amber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/chicken/amber.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/chicken/bronzed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/chicken/bronzed.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/chicken/stormy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/chicken/stormy.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/pig/pink_footed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/pig/pink_footed.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/patched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/patched.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/rainbow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/rainbow.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/inky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/inky.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/skeleton/mossy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/skeleton/mossy.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/skeleton/sandy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/skeleton/sandy.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/ashen_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/ashen_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/ashen_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/ashen_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/black_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/black_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/black_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/black_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/husky_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/husky_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/husky_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/husky_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/rusty_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/rusty_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/rusty_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/rusty_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/snowy_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/snowy_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/snowy_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/snowy_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/woods_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/woods_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/woods_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/woods_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/zombie/makena.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/zombie/makena.png -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/skeleton/sandy_increased_spawns_in_deserts.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 4, 3 | "name": "sandy", 4 | "biome_tag": "moremobvariants:increased_sandy_skeletons" 5 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/CustomVariantNameModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | public record CustomVariantNameModifier(String variantName) implements VariantModifier { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/cat/tortoiseshell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/cat/tortoiseshell.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/chicken/midnight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/chicken/midnight.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/chicken/skewbald.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/chicken/skewbald.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/long_nosed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/long_nosed.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/fuzzy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/fuzzy.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/rocky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/rocky.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/skeleton/dungeons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/skeleton/dungeons.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/spider/eyes/bone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/spider/eyes/bone.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/spider/eyes/brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/spider/eyes/brown.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/spider/tarantula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/spider/tarantula.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/ashen_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/ashen_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/basenji_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/basenji_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/basenji_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/basenji_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/black_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/black_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/husky_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/husky_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/jupiter_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/jupiter_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/jupiter_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/jupiter_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/rusty_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/rusty_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/snowy_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/snowy_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/spotted_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/spotted_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/spotted_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/spotted_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/striped_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/striped_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/striped_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/striped_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/woods_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/woods_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/chicken/gold_crested.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/chicken/gold_crested.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/pig/mud/mud_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/pig/mud/mud_overlay.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/patched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/patched.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/rainbow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/rainbow.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/skeleton/weathered.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/skeleton/weathered.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/spider/black_widow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/spider/black_widow.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/basenji_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/basenji_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/chestnut_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/chestnut_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/chestnut_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/chestnut_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/chestnut_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/chestnut_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/jupiter_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/jupiter_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/skeleton_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/skeleton_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/skeleton_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/skeleton_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/skeleton_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/skeleton_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/spotted_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/spotted_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/striped_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/striped_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/horns/horns_gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/horns/horns_gray.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/long_nosed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/wool/long_nosed.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/horns/horns_beige.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/horns/horns_beige.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/horns/horns_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/horns/horns_black.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/horns/horns_brown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/horns/horns_brown.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/french_bulldog_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/french_bulldog_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/french_bulldog_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/french_bulldog_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/french_bulldog_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/french_bulldog_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/german_shepherd_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/german_shepherd_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/german_shepherd_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/german_shepherd_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/white_terrier_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/white_terrier_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/white_terrier_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/white_terrier_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/white_terrier_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/white_terrier_wild.png -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/additional_wolf_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:sparse_jungle", 4 | "minecraft:savanna_plateau", 5 | "minecraft:wooded_badlands" 6 | ] 7 | } -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/german_shepherd_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/german_shepherd_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/golden_retriever_angry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/golden_retriever_angry.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/golden_retriever_tame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/golden_retriever_tame.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/wolf/golden_retriever_wild.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/wolf/golden_retriever_wild.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/inky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/inky.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/default.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/fuzzy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/fuzzy.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/patched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/patched.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/rocky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/rocky.png -------------------------------------------------------------------------------- /src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/long_nosed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nyuppo/MobVariants/HEAD/src/main/resources/assets/moremobvariants/textures/entity/sheep/sheared_color_overlay/long_nosed.png -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/settings/sheep_horn_settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "chance": 0.125, 3 | "inherit_parents_chance": 0.8, 4 | "weights": { 5 | "brown": 8, 6 | "gray": 6, 7 | "black": 3, 8 | "beige": 1 9 | } 10 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { 4 | name = 'Fabric' 5 | url = 'https://maven.fabricmc.net/' 6 | } 7 | mavenCentral() 8 | gradlePluginPortal() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_ashen_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:snowy_taiga", 4 | 5 | { 6 | "id": "regions_unexplored:frozen_pine_taiga", 7 | "required": false 8 | } 9 | ] 10 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/husky_from_black_ashen.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "husky", 4 | "breeding": { 5 | "parent1": "moremobvariants:black", 6 | "parent2": "moremobvariants:ashen", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/husky_from_snowy_ashen.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "husky", 4 | "breeding": { 5 | "parent1": "moremobvariants:snowy", 6 | "parent2": "moremobvariants:ashen", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/basenji_from_rusty_ashen.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "basenji", 4 | "breeding": { 5 | "parent1": "moremobvariants:rusty", 6 | "parent2": "moremobvariants:ashen", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/jupiter_from_rusty_woods.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "jupiter", 4 | "breeding": { 5 | "parent1": "moremobvariants:rusty", 6 | "parent2": "moremobvariants:woods", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/jupiter_from_rusty_chestnut.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "jupiter", 4 | "breeding": { 5 | "parent1": "moremobvariants:rusty", 6 | "parent2": "moremobvariants:chestnut", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/jupiter_from_striped_woods.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "jupiter", 4 | "breeding": { 5 | "parent1": "moremobvariants:striped", 6 | "parent2": "moremobvariants:woods", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/german_shepherd_from_jupiter_husky.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "german_shepherd", 4 | "breeding": { 5 | "parent1": "moremobvariants:jupiter", 6 | "parent2": "moremobvariants:husky", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/german_shepherd_from_woods_chestnut.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "german_shepherd", 4 | "breeding": { 5 | "parent1": "moremobvariants:woods", 6 | "parent2": "moremobvariants:chestnut", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/golden_retriever_from_rusty_pale.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "golden_retriever", 4 | "breeding": { 5 | "parent1": "moremobvariants:rusty", 6 | "parent2": "moremobvariants:default", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/MoonPhaseModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | public record MoonPhaseModifier(float minimumMoonSize) implements VariantModifier { 4 | public boolean canSpawn(float moonSize) { 5 | return moonSize > minimumMoonSize; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/basenji_from_jupiter_golden_retriever.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "basenji", 4 | "breeding": { 5 | "parent1": "moremobvariants:jupiter", 6 | "parent2": "moremobvariants:golden_retriever", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/golden_retriever_from_jupiter_pale.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "golden_retriever", 4 | "breeding": { 5 | "parent1": "moremobvariants:jupiter", 6 | "parent2": "moremobvariants:default", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/french_bulldog_from_husky_golden_retriever.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "french_bulldog", 4 | "breeding": { 5 | "parent1": "moremobvariants:husky", 6 | "parent2": "moremobvariants:golden_retriever", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/variants/wolf/french_bulldog_from_rusty_golden_retriever.json: -------------------------------------------------------------------------------- 1 | { 2 | "weight": 1, 3 | "name": "french_bulldog", 4 | "breeding": { 5 | "parent1": "moremobvariants:rusty", 6 | "parent2": "moremobvariants:golden_retriever", 7 | "breeding_chance": 0.5 8 | } 9 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # gradle 2 | 3 | .gradle/ 4 | build/ 5 | out/ 6 | classes/ 7 | 8 | # eclipse 9 | 10 | *.launch 11 | 12 | # idea 13 | 14 | .idea/ 15 | *.iml 16 | *.ipr 17 | *.iws 18 | 19 | # vscode 20 | 21 | .settings/ 22 | .vscode/ 23 | bin/ 24 | .classpath 25 | .project 26 | 27 | # macos 28 | 29 | *.DS_Store 30 | 31 | # fabric 32 | 33 | run/ 34 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_black_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:old_growth_pine_taiga", 4 | 5 | 6 | { 7 | "id": "regions_unexplored:blackwood_taiga", 8 | "required": false 9 | }, 10 | { 11 | "id": "regions_unexplored:pine_taiga", 12 | "required": false 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/DiscardableModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | import net.minecraft.util.math.random.Random; 4 | 5 | public record DiscardableModifier(double discardChance) implements VariantModifier { 6 | public boolean shouldDiscard(Random random) { 7 | return random.nextDouble() < this.discardChance; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_spotted_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:savanna", 4 | "minecraft:savanna_plateau", 5 | "minecraft:windswept_savanna", 6 | 7 | { 8 | "id": "regions_unexplored:baobab_savanna", 9 | "required": false 10 | }, 11 | { 12 | "id": "regions_unexplored:steppe", 13 | "required": false 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_striped_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:badlands", 4 | "minecraft:eroded_badlands", 5 | "minecraft:wooded_badlands", 6 | 7 | { 8 | "id": "regions_unexplored:dry_bushland", 9 | "required": false 10 | }, 11 | { 12 | "id": "regions_unexplored:prairie", 13 | "required": false 14 | } 15 | ] 16 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_snowy_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:grove", 4 | 5 | { 6 | "id": "regions_unexplored:frozen_tundra", 7 | "required": false 8 | }, 9 | { 10 | "id": "regions_unexplored:spires", 11 | "required": false 12 | }, 13 | { 14 | "id": "regions_unexplored:icy_heights", 15 | "required": false 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_pale_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:taiga", 4 | 5 | { 6 | "id": "regions_unexplored:alpha_grove", 7 | "required": false 8 | }, 9 | { 10 | "id": "regions_unexplored:pine_slopes", 11 | "required": false 12 | }, 13 | { 14 | "id": "regions_unexplored:maple_forest", 15 | "required": false 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Done to increase the memory available to gradle. 2 | org.gradle.jvmargs=-Xmx1G 3 | 4 | # Fabric Properties 5 | # check these on https://fabricmc.net/develop 6 | minecraft_version=1.21 7 | yarn_mappings=1.21+build.9 8 | loader_version=0.15.11 9 | 10 | # Mod Properties 11 | mod_version = 1.3.1.1 12 | maven_group = com.github.nyuppo 13 | archives_base_name = moremobvariants 14 | 15 | # Dependencies 16 | fabric_version=0.100.7+1.21 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/util/BiomeSpawnData.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.util; 2 | 3 | import net.minecraft.registry.entry.RegistryEntry; 4 | import net.minecraft.registry.tag.TagKey; 5 | import net.minecraft.world.biome.Biome; 6 | 7 | public record BiomeSpawnData(TagKey validSpawnBiomes, RegistryEntry spawnBiome) { 8 | public boolean canSpawn() { 9 | return spawnBiome.isIn(validSpawnBiomes); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/increased_sandy_skeletons.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:desert", 4 | 5 | { 6 | "id": "regions_unexplored:joshua_desert", 7 | "required": false 8 | }, 9 | { 10 | "id": "regions_unexplored:grassy_beach", 11 | "required": false 12 | }, 13 | { 14 | "id": "regions_unexplored:saguaro_desert", 15 | "required": false 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_chestnut_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:old_growth_spruce_taiga", 4 | 5 | { 6 | "id": "regions_unexplored:boreal_taiga", 7 | "required": false 8 | }, 9 | { 10 | "id": "regions_unexplored:cold_boreal_taiga", 11 | "required": false 12 | }, 13 | { 14 | "id": "regions_unexplored:golden_boreal_taiga", 15 | "required": false 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/SpawnableBiomesModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | import net.minecraft.registry.entry.RegistryEntry; 4 | import net.minecraft.registry.tag.TagKey; 5 | import net.minecraft.world.biome.Biome; 6 | 7 | public record SpawnableBiomesModifier(TagKey spawnBiomes) implements VariantModifier { 8 | public boolean canSpawnInBiome(RegistryEntry biome) { 9 | return biome.isIn(this.spawnBiomes); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/QuadrupedEntityModelPartAccessor.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import net.minecraft.client.model.ModelPart; 4 | import net.minecraft.client.render.entity.model.QuadrupedEntityModel; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(QuadrupedEntityModel.class) 9 | public interface QuadrupedEntityModelPartAccessor { 10 | @Accessor("head") 11 | ModelPart getHead(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/util/BreedingResultData.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.util; 2 | 3 | import com.github.nyuppo.variant.MobVariant; 4 | import net.minecraft.util.math.random.Random; 5 | 6 | public record BreedingResultData(MobVariant parent1, MobVariant parent2) { 7 | public boolean validParents(MobVariant parent1, MobVariant parent2) { 8 | return parent1.getIdentifier().equals(this.parent1.getIdentifier()) && parent2.getIdentifier().equals(this.parent2.getIdentifier()); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_rusty_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:bamboo_jungle", 4 | "minecraft:jungle", 5 | "minecraft:sparse_jungle", 6 | 7 | { 8 | "id": "regions_unexplored:bamboo_forest", 9 | "required": false 10 | }, 11 | { 12 | "id": "regions_unexplored:sparse_redwoods", 13 | "required": false 14 | }, 15 | { 16 | "id": "regions_unexplored:redwoods", 17 | "required": false 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/networking/MMVNetworkingConstants.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.networking; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import net.minecraft.util.Identifier; 5 | 6 | public class MMVNetworkingConstants { 7 | public static final Identifier CLIENT_REQUEST_VARIANT_ID = MoreMobVariants.id("client_request"); 8 | public static final Identifier SERVER_RESPOND_VARIANT_ID = MoreMobVariants.id("server_respond"); 9 | public static final Identifier SERVER_RESPOND_BASIC_VARIANT_ID = MoreMobVariants.id("server_respond_basic"); 10 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/BreedingResultModifier.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | import net.minecraft.util.Identifier; 4 | import net.minecraft.util.math.random.Random; 5 | 6 | public record BreedingResultModifier(Identifier parent1, Identifier parent2, double breedingChance) implements VariantModifier { 7 | public boolean validParents(MobVariant parent1, MobVariant parent2) { 8 | return (parent1.getIdentifier().equals(this.parent1) && parent2.getIdentifier().equals(this.parent2)) 9 | || (parent1.getIdentifier().equals(this.parent2) && parent2.getIdentifier().equals(this.parent1)); 10 | } 11 | 12 | public boolean shouldBreed(Random random) { 13 | return random.nextDouble() < this.breedingChance; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/wolf_woods_spawns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:forest", 4 | "minecraft:flower_forest", 5 | "minecraft:birch_forest", 6 | "minecraft:old_growth_birch_forest", 7 | "minecraft:dark_forest", 8 | "minecraft:grove", 9 | 10 | { 11 | "id": "regions_unexplored:cold_deciduous_forest", 12 | "required": false 13 | }, 14 | { 15 | "id": "regions_unexplored:deciduous_forest", 16 | "required": false 17 | }, 18 | { 19 | "id": "regions_unexplored:maple_forest", 20 | "required": false 21 | }, 22 | { 23 | "id": "regions_unexplored:silver_birch_forest", 24 | "required": false 25 | }, 26 | { 27 | "id": "regions_unexplored:orchard", 28 | "required": false 29 | } 30 | ] 31 | } -------------------------------------------------------------------------------- /src/main/resources/moremobvariants.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "minVersion": "0.8", 4 | "package": "com.github.nyuppo.mixin", 5 | "compatibilityLevel": "JAVA_17", 6 | "mixins": [ 7 | "MobEntityVariantsMixin", 8 | "CatVariantsMixin", 9 | "ChickenVariantsMixin", 10 | "ChickenEggMixin", 11 | "PigVariantsMixin", 12 | "SheepVariantsMixin", 13 | "SkeletonVariantsMixin", 14 | "SpiderVariantsMixin", 15 | "CowVariantsMixin", 16 | "WolfVariantsMixin", 17 | "ZombieVariantsMixin" 18 | ], 19 | "client": [ 20 | "CatRendererMixin", 21 | "CatFluffMixin", 22 | "ChickenRendererMixin", 23 | "PigRendererMixin", 24 | "SheepRendererMixin", 25 | "SkeletonRendererMixin", 26 | "SpiderRendererMixin", 27 | "CowRendererMixin", 28 | "WolfRendererMixin", 29 | "ZombieRendererMixin", 30 | "PigFlowerMixin", 31 | "SheepWoolFeatureMixin", 32 | "CustomEyesFeatureMixin", 33 | "QuadrupedEntityModelPartAccessor" 34 | ], 35 | "injectors": { 36 | "defaultRequire": 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/networking/ClientRequestVariantPayload.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.networking; 2 | 3 | import net.minecraft.network.PacketByteBuf; 4 | import net.minecraft.network.codec.PacketCodec; 5 | import net.minecraft.network.packet.CustomPayload; 6 | 7 | import java.util.UUID; 8 | 9 | public record ClientRequestVariantPayload(UUID uuid) implements CustomPayload { 10 | public static final Id ID = new Id<>(MMVNetworkingConstants.CLIENT_REQUEST_VARIANT_ID); 11 | public static final PacketCodec PACKET_CODEC = PacketCodec.of(ClientRequestVariantPayload::write, ClientRequestVariantPayload::read); 12 | 13 | private static ClientRequestVariantPayload read(PacketByteBuf buf) { 14 | UUID uuid = buf.readUuid(); 15 | return new ClientRequestVariantPayload(uuid); 16 | } 17 | 18 | private void write(PacketByteBuf buf) { 19 | buf.writeUuid(uuid); 20 | } 21 | 22 | @Override 23 | public Id getId() { 24 | return ID; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "moremobvariants", 4 | "version": "${version}", 5 | 6 | "name": "More Mob Variants", 7 | "description": "Give boring mobs a fresh coat of paint!", 8 | "authors": [ 9 | "nyuppo" 10 | ], 11 | "contributors": [ 12 | "LlamaLad7", 13 | "KLONOA9X6", 14 | "Dev0Louis", 15 | "Steveplays28", 16 | "fzzyhmstrs", 17 | "amyavi", 18 | "hisakid" 19 | ], 20 | "contact": { 21 | "homepage": "https://nyuppo.github.io/moremobvariants/" 22 | }, 23 | 24 | "license": "CC0-1.0", 25 | "icon": "assets/moremobvariants/icon.png", 26 | 27 | "environment": "*", 28 | "entrypoints": { 29 | "main": [ 30 | "com.github.nyuppo.MoreMobVariants" 31 | ], 32 | "client": [ 33 | "com.github.nyuppo.MoreMobVariantsClient" 34 | ] 35 | }, 36 | "mixins": [ 37 | "moremobvariants.mixins.json" 38 | ], 39 | "depends": { 40 | "fabricloader": ">=0.15.11", 41 | "minecraft": "~1.21", 42 | "java": ">=21", 43 | "fabric-api": "*" 44 | }, 45 | "accessWidener": "moremobvariants.accesswidener" 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/networking/ServerRespondBasicVariantPayload.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.networking; 2 | 3 | import net.minecraft.network.PacketByteBuf; 4 | import net.minecraft.network.codec.PacketCodec; 5 | import net.minecraft.network.packet.CustomPayload; 6 | 7 | public record ServerRespondBasicVariantPayload(int entityId, String variantId) implements CustomPayload { 8 | public static final Id ID = new Id<>(MMVNetworkingConstants.SERVER_RESPOND_BASIC_VARIANT_ID); 9 | public static final PacketCodec PACKET_CODEC = PacketCodec.of(ServerRespondBasicVariantPayload::write, ServerRespondBasicVariantPayload::read); 10 | 11 | private static ServerRespondBasicVariantPayload read(PacketByteBuf buf) { 12 | return new ServerRespondBasicVariantPayload( 13 | buf.readInt(), 14 | buf.readString() 15 | ); 16 | } 17 | 18 | private void write(PacketByteBuf buf) { 19 | buf.writeInt(entityId); 20 | buf.writeString(variantId); 21 | } 22 | 23 | @Override 24 | public Id getId() { 25 | return ID; 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/spawn_mossy_skeletons.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:bamboo_jungle", 4 | "minecraft:jungle", 5 | "minecraft:sparse_jungle", 6 | "minecraft:swamp", 7 | "minecraft:mangrove_swamp", 8 | "minecraft:lush_caves", 9 | 10 | { 11 | "id": "regions_unexplored:bamboo_forest", 12 | "required": false 13 | }, 14 | { 15 | "id": "regions_unexplored:bayou", 16 | "required": false 17 | }, 18 | { 19 | "id": "regions_unexplored:fen", 20 | "required": false 21 | }, 22 | { 23 | "id": "regions_unexplored:fungal_fen", 24 | "required": false 25 | }, 26 | { 27 | "id": "regions_unexplored:marsh", 28 | "required": false 29 | }, 30 | { 31 | "id": "regions_unexplored:muddy_river", 32 | "required": false 33 | }, 34 | { 35 | "id": "regions_unexplored:old_growth_bayou", 36 | "required": false 37 | }, 38 | { 39 | "id": "regions_unexplored:rainforest", 40 | "required": false 41 | }, 42 | { 43 | "id": "regions_unexplored:sparse_rainforest", 44 | "required": false 45 | }, 46 | { 47 | "id": "regions_unexplored:tropics", 48 | "required": false 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # Automatically build the project and run any configured tests for every push 2 | # and submitted pull request. This can help catch issues that only occur on 3 | # certain platforms or Java versions, and provides a first line of defence 4 | # against bad commits. 5 | 6 | name: build 7 | on: [pull_request, push] 8 | 9 | jobs: 10 | build: 11 | strategy: 12 | matrix: 13 | # Use these Java versions 14 | java: [ 15 | 21, # Current Java LTS 16 | ] 17 | runs-on: ubuntu-22.04 18 | steps: 19 | - name: checkout repository 20 | uses: actions/checkout@v4 21 | - name: validate gradle wrapper 22 | uses: gradle/wrapper-validation-action@v2 23 | - name: setup jdk ${{ matrix.java }} 24 | uses: actions/setup-java@v4 25 | with: 26 | java-version: ${{ matrix.java }} 27 | distribution: 'microsoft' 28 | - name: make gradle wrapper executable 29 | run: chmod +x ./gradlew 30 | - name: build 31 | run: ./gradlew build 32 | - name: capture build artifacts 33 | if: ${{ matrix.java == '21' }} # Only upload artifacts built from latest java 34 | uses: actions/upload-artifact@v4 35 | with: 36 | name: Artifacts 37 | path: build/libs/ 38 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/ChickenEggMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.entity.EntityType; 7 | import net.minecraft.entity.passive.ChickenEntity; 8 | import net.minecraft.entity.projectile.thrown.EggEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.ModifyVariable; 13 | 14 | @Mixin(EggEntity.class) 15 | public class ChickenEggMixin { 16 | @ModifyVariable( 17 | method = "onCollision(Lnet/minecraft/util/hit/HitResult;)V", 18 | at = @At("STORE") 19 | ) 20 | private ChickenEntity mixin(ChickenEntity chickenEntity) { 21 | MobVariant variant = Variants.getRandomVariant(EntityType.CHICKEN, chickenEntity.getRandom().nextLong(), chickenEntity.getWorld().getBiome(chickenEntity.getBlockPos()), null, chickenEntity.getWorld().getMoonSize()); 22 | 23 | NbtCompound newNbt = new NbtCompound(); 24 | chickenEntity.writeNbt(newNbt); 25 | newNbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 26 | chickenEntity.readCustomDataFromNbt(newNbt); 27 | 28 | return chickenEntity; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/resources/data/moremobvariants/tags/worldgen/biome/sheep_spawn_with_horns.json: -------------------------------------------------------------------------------- 1 | { 2 | "values": [ 3 | "minecraft:jagged_peaks", 4 | "minecraft:frozen_peaks", 5 | "minecraft:stony_peaks", 6 | "minecraft:meadow", 7 | "minecraft:grove", 8 | "minecraft:snowy_slopes", 9 | "minecraft:windswept_hills", 10 | "minecraft:windswept_forest", 11 | "minecraft:windswept_gravelly_hills", 12 | "minecraft:snowy_taiga", 13 | "minecraft:frozen_river", 14 | "minecraft:snowy_beach", 15 | "minecraft:snowy_plains", 16 | "minecraft:ice_spikes", 17 | 18 | { 19 | "id": "regions_unexplored:cold_boreal_taiga", 20 | "required": false 21 | }, 22 | { 23 | "id": "regions_unexplored:cold_deciduous_forest", 24 | "required": false 25 | }, 26 | { 27 | "id": "regions_unexplored:frozen_pine_taiga", 28 | "required": false 29 | }, 30 | { 31 | "id": "regions_unexplored:frozen_tundra", 32 | "required": false 33 | }, 34 | { 35 | "id": "regions_unexplored:highland_fields", 36 | "required": false 37 | }, 38 | { 39 | "id": "regions_unexplored:icy_heights", 40 | "required": false 41 | }, 42 | { 43 | "id": "regions_unexplored:spires", 44 | "required": false 45 | }, 46 | { 47 | "id": "regions_unexplored:towering_cliffs", 48 | "required": false 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/config/VariantBlacklist.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.config; 2 | 3 | import net.minecraft.entity.EntityType; 4 | import net.minecraft.util.Identifier; 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | 9 | public class VariantBlacklist { 10 | private static HashMap, ArrayList> blacklistedIdentifiers = new HashMap<>(); 11 | 12 | public static void blacklist(EntityType mob, Identifier identifier) { 13 | if (!blacklistedIdentifiers.containsKey(mob)) { 14 | blacklistedIdentifiers.put(mob, new ArrayList<>()); 15 | } 16 | blacklistedIdentifiers.get(mob).add(identifier); 17 | } 18 | 19 | public static boolean isBlacklisted(EntityType mob, Identifier identifier) { 20 | if (!blacklistedIdentifiers.containsKey(mob)) { 21 | return false; 22 | } 23 | 24 | return blacklistedIdentifiers.get(mob).contains(identifier); 25 | } 26 | 27 | public static void clearBlacklist(EntityType mob) { 28 | blacklistedIdentifiers.remove(mob); 29 | blacklistedIdentifiers.put(mob, new ArrayList<>()); 30 | } 31 | 32 | public static void clearAllBlacklists() { 33 | Variants.getAllDefaultVariants().keySet().forEach(VariantBlacklist::clearBlacklist); 34 | clearBlacklist(EntityType.CAT); // Special case for cat since it isn't included in variants list 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/networking/ServerRespondVariantPayload.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.networking; 2 | 3 | import net.minecraft.network.PacketByteBuf; 4 | import net.minecraft.network.codec.PacketCodec; 5 | import net.minecraft.network.packet.CustomPayload; 6 | 7 | public record ServerRespondVariantPayload(int entityId, String variant, boolean sittingOrMuddy, int muddyTimeout, String sheepHornColour) implements CustomPayload { 8 | public static final Id ID = new Id<>(MMVNetworkingConstants.SERVER_RESPOND_VARIANT_ID); 9 | public static final PacketCodec PACKET_CODEC = PacketCodec.of(ServerRespondVariantPayload::write, ServerRespondVariantPayload::read); 10 | 11 | private static ServerRespondVariantPayload read(PacketByteBuf buf) { 12 | return new ServerRespondVariantPayload( 13 | buf.readInt(), 14 | buf.readString(), 15 | buf.readBoolean(), 16 | buf.readVarInt(), 17 | buf.readString() 18 | ); 19 | } 20 | 21 | private void write(PacketByteBuf buf) { 22 | buf.writeInt(entityId); 23 | buf.writeString(variant); 24 | buf.writeBoolean(sittingOrMuddy); 25 | buf.writeVarInt(muddyTimeout); 26 | buf.writeString(sheepHornColour); 27 | } 28 | 29 | @Override 30 | public Id getId() { 31 | return ID; 32 | } 33 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/PigFlowerMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import net.minecraft.client.model.*; 4 | import net.minecraft.client.render.entity.model.EntityModelPartNames; 5 | import net.minecraft.client.render.entity.model.PigEntityModel; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 10 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 11 | 12 | @Mixin(PigEntityModel.class) 13 | public class PigFlowerMixin { 14 | @Inject(method = "getTexturedModelData", at = @At("RETURN"), locals = LocalCapture.CAPTURE_FAILEXCEPTION) 15 | private static void onGetTexturedModelData(Dilation dilation, CallbackInfoReturnable ci, ModelData modelData, ModelPartData modelPartData) { 16 | modelPartData.addChild(EntityModelPartNames.HEAD, 17 | ModelPartBuilder.create() 18 | .uv(0, 0).cuboid(-4.0f, -4.0f, -8.0f, 8.0f, 8.0f, 8.0f, dilation) 19 | .uv(16, 16).cuboid(-2.0f, 0.0f, -9.0f, 4.0f, 3.0f, 1.0f, dilation) 20 | .uv(28, 3).cuboid(-1.0f, -5.0f, -7.0f, 4.0f, 1.0f, 4.0f, dilation) 21 | .uv(44, 2).cuboid(0.0f, -11.0f, -5.0f,4, 6, 0, dilation), 22 | ModelTransform.pivot(0.0f, 12.0f, -6.0f)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/config/VariantSettings.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.config; 2 | 3 | public class VariantSettings { 4 | private static boolean enableMuddyPigs; // Should pigs be able to get muddy/wash their mud off 5 | private static int muddyPigTimeout; // How long pigs should stay muddy for in seconds (0 to disable) 6 | private static double childRandomVariantChance; // The chance to get a random variant instead of inheriting from parents 7 | 8 | public static void setEnableMuddyPigs(boolean shouldEnableMuddyPigs) { 9 | enableMuddyPigs = shouldEnableMuddyPigs; 10 | } 11 | 12 | public static boolean getEnableMuddyPigs() { 13 | return enableMuddyPigs; 14 | } 15 | 16 | public static void setMuddyPigTimeout(int seconds) { 17 | muddyPigTimeout = seconds; 18 | } 19 | 20 | public static int getMuddyPigTimeout() { 21 | return muddyPigTimeout; 22 | } 23 | 24 | public static void setChildRandomVariantChance(double chance) { 25 | childRandomVariantChance = chance; 26 | } 27 | 28 | public static double getChildRandomVariantChance() { 29 | return childRandomVariantChance; 30 | } 31 | 32 | public static void resetSettings() { 33 | enableMuddyPigs = true; 34 | muddyPigTimeout = 0; 35 | childRandomVariantChance = 0.25d; 36 | } 37 | 38 | static { 39 | enableMuddyPigs = true; 40 | muddyPigTimeout = 0; 41 | childRandomVariantChance = 0.25d; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # More Mob Variants 2 | 3 | Minecraft Fabric mod for adding new variants to existing mobs. Developed for 1.19.4. 4 | 5 | For the Forge version, visit [this page](https://github.com/nyuppo/MobVariantsForge). 6 | 7 | ## Installation 8 | 9 | This mod features **persistent variant skins for all players**, as opposed to client-side reskins that can differ from person to person. 10 | 11 | As a result, however, this means that this mod must be installed both **server-side and client-side** to work. 12 | 13 | ## Features 14 | 15 | In addition to the default texture, the mod currently features the following new variants: 16 | 17 | - Cat 18 | - Gray Tabby 19 | - Doug 20 | - Handsome 21 | - Chicken 22 | - Amber 23 | - Bronzed 24 | - Gold Crested 25 | - Midnight 26 | - Skewbald 27 | - Stormy 28 | - Skeleton (*if spawned in the nether*) 29 | - Cow 30 | - Ashen 31 | - Cookie 32 | - Dairy 33 | - pinto 34 | - Sunset 35 | - Umbra 36 | - Wooly 37 | - Pig 38 | - Mottled 39 | - Piebald 40 | - Pink Footed 41 | - Sooty 42 | - Spotted 43 | - Sheep 44 | - Fuzzy 45 | - Patched 46 | - Rocky 47 | - Wolf 48 | - Husky 49 | - Brown 50 | - German Shepherd (*through breeding a husky and a brown wolf*) 51 | - Golden Retriever/Shiba Inu (*through breeding a brown and a white wolf*) 52 | - French Bulldog/Pug (*through breeding a husky and a golden retriever/shiba inu*) 53 | - Zombie 54 | - Alex 55 | - Ari 56 | - Efe 57 | - Kai 58 | - Makena 59 | - Noor 60 | - Sunny 61 | - Zuri 62 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/util/VariantBag.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.util; 2 | 3 | import com.github.nyuppo.config.Variants; 4 | import com.github.nyuppo.variant.MobVariant; 5 | import net.minecraft.entity.EntityType; 6 | import net.minecraft.util.math.random.Random; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class VariantBag { 12 | private class Entry { 13 | double accumulatedWeight; 14 | MobVariant variant; 15 | } 16 | 17 | private List entries = new ArrayList<>(); 18 | private double accumulatedWeight; 19 | private final EntityType mob; 20 | 21 | public VariantBag(EntityType mob, List variants) { 22 | this.mob = mob; 23 | for (MobVariant variant : variants) { 24 | addEntry(variant); 25 | } 26 | } 27 | 28 | public void addEntry(MobVariant variant) { 29 | accumulatedWeight += variant.getWeight(); 30 | Entry e = new Entry(); 31 | e.variant = variant; 32 | e.accumulatedWeight = accumulatedWeight; 33 | entries.add(e); 34 | } 35 | 36 | public MobVariant getRandomEntry(Random random) { 37 | double r = random.nextDouble() * accumulatedWeight; 38 | 39 | for (Entry entry : entries) { 40 | if (entry.accumulatedWeight >= r) { 41 | return entry.variant; 42 | } 43 | } 44 | 45 | // Should only occur when there are no entries 46 | return Variants.getDefaultVariant(mob); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/MobEntityVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import net.minecraft.entity.EntityData; 4 | import net.minecraft.entity.SpawnReason; 5 | import net.minecraft.entity.mob.MobEntity; 6 | import net.minecraft.nbt.NbtCompound; 7 | import net.minecraft.world.LocalDifficulty; 8 | import net.minecraft.world.ServerWorldAccess; 9 | import org.jetbrains.annotations.Nullable; 10 | import org.spongepowered.asm.mixin.Mixin; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 14 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 15 | 16 | @Mixin(MobEntity.class) 17 | public abstract class MobEntityVariantsMixin { 18 | @Inject( 19 | method = "writeCustomDataToNbt", 20 | at = @At("RETURN") 21 | ) 22 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 23 | 24 | } 25 | 26 | @Inject( 27 | method = "readCustomDataFromNbt", 28 | at = @At("RETURN") 29 | ) 30 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 31 | 32 | } 33 | 34 | @Inject( 35 | method = "initialize(Lnet/minecraft/world/ServerWorldAccess;Lnet/minecraft/world/LocalDifficulty;Lnet/minecraft/entity/SpawnReason;Lnet/minecraft/entity/EntityData;)Lnet/minecraft/entity/EntityData;", 36 | at = @At("RETURN") 37 | ) 38 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 39 | 40 | } 41 | 42 | @Inject( 43 | method = "tick", 44 | at = @At("RETURN") 45 | ) 46 | protected void onTick(CallbackInfo ci) { 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/CatRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.CatEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.passive.CatEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(CatEntityRenderer.class) 17 | public class CatRendererMixin { 18 | private static final Identifier DEFAULT = Identifier.ofVanilla("textures/entity/cat/tabby.png"); 19 | 20 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 21 | private void onGetTexture(CatEntity catEntity, CallbackInfoReturnable ci) { 22 | NbtCompound nbt = new NbtCompound(); 23 | catEntity.writeNbt(nbt); 24 | 25 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 26 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 27 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 28 | ci.setReturnValue(DEFAULT); 29 | } else { 30 | String[] split = Variants.splitVariant(variant); 31 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/cat/" + split[1] + ".png")); 32 | } 33 | } 34 | 35 | if (catEntity.hasCustomName()) { 36 | MobVariant variant = Variants.getVariantFromNametag(EntityType.CAT, catEntity.getName().getString()); 37 | if (variant != null) { 38 | Identifier identifier = variant.getIdentifier(); 39 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/cat/" + identifier.getPath() + ".png")); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/CowRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.CowEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.passive.CowEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(CowEntityRenderer.class) 17 | public class CowRendererMixin { 18 | private static final Identifier DEFAULT = Identifier.ofVanilla("textures/entity/cow/cow.png"); 19 | 20 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 21 | private void onGetTexture(CowEntity cowEntity, CallbackInfoReturnable ci) { 22 | NbtCompound nbt = new NbtCompound(); 23 | cowEntity.writeNbt(nbt); 24 | 25 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 26 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 27 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 28 | ci.setReturnValue(DEFAULT); 29 | } else { 30 | String[] split = Variants.splitVariant(variant); 31 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/cow/" + split[1] + ".png")); 32 | } 33 | } 34 | 35 | if (cowEntity.hasCustomName()) { 36 | MobVariant variant = Variants.getVariantFromNametag(EntityType.COW, cowEntity.getName().getString()); 37 | if (variant != null) { 38 | Identifier identifier = variant.getIdentifier(); 39 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/cow/" + identifier.getPath() + ".png")); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/PigRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.PigEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.passive.PigEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(PigEntityRenderer.class) 17 | public class PigRendererMixin { 18 | private static final Identifier DEFAULT = Identifier.ofVanilla("textures/entity/pig/pig.png"); 19 | 20 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 21 | private void onGetTexture(PigEntity pigEntity, CallbackInfoReturnable ci) { 22 | NbtCompound nbt = new NbtCompound(); 23 | pigEntity.writeNbt(nbt); 24 | 25 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 26 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 27 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 28 | ci.setReturnValue(DEFAULT); 29 | } else { 30 | String[] split = Variants.splitVariant(variant); 31 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/pig/" + split[1] + ".png")); 32 | } 33 | } 34 | 35 | if (pigEntity.hasCustomName()) { 36 | MobVariant variant = Variants.getVariantFromNametag(EntityType.PIG, pigEntity.getName().getString()); 37 | if (variant != null) { 38 | Identifier identifier = variant.getIdentifier(); 39 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/pig/" + identifier.getPath() + ".png")); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/SheepRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.SheepEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.passive.SheepEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(SheepEntityRenderer.class) 17 | public class SheepRendererMixin { 18 | private static final Identifier DEFAULT = Identifier.ofVanilla("textures/entity/sheep/sheep.png"); 19 | 20 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 21 | private void onGetTexture(SheepEntity sheepEntity, CallbackInfoReturnable ci) { 22 | NbtCompound nbt = new NbtCompound(); 23 | sheepEntity.writeNbt(nbt); 24 | 25 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 26 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 27 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 28 | ci.setReturnValue(DEFAULT); 29 | } else { 30 | String[] split = Variants.splitVariant(variant);; 31 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/sheep/" + split[1] + ".png")); 32 | } 33 | } 34 | 35 | if (sheepEntity.hasCustomName()) { 36 | MobVariant variant = Variants.getVariantFromNametag(EntityType.SHEEP, sheepEntity.getName().getString()); 37 | if (variant != null) { 38 | Identifier identifier = variant.getIdentifier(); 39 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/sheep/" + identifier.getPath() + ".png")); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/SpiderRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.SpiderEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.mob.SpiderEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(SpiderEntityRenderer.class) 17 | public class SpiderRendererMixin { 18 | private static final Identifier DEFAULT = Identifier.ofVanilla("textures/entity/spider/spider.png"); 19 | 20 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 21 | private void onGetTexture(SpiderEntity spiderEntity, CallbackInfoReturnable ci) { 22 | NbtCompound nbt = new NbtCompound(); 23 | spiderEntity.writeNbt(nbt); 24 | 25 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 26 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 27 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 28 | ci.setReturnValue(DEFAULT); 29 | } else { 30 | String[] split = Variants.splitVariant(variant); 31 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/spider/" + split[1] + ".png")); 32 | } 33 | } 34 | 35 | if (spiderEntity.hasCustomName()) { 36 | MobVariant variant = Variants.getVariantFromNametag(EntityType.SPIDER, spiderEntity.getName().getString()); 37 | if (variant != null) { 38 | Identifier identifier = variant.getIdentifier(); 39 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/spider/" + identifier.getPath() + ".png")); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/ChickenRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.ChickenEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.passive.ChickenEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(ChickenEntityRenderer.class) 17 | public class ChickenRendererMixin { 18 | private static final Identifier DEFAULT = Identifier.ofVanilla("textures/entity/chicken.png"); 19 | 20 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 21 | private void onGetTexture(ChickenEntity chickenEntity, CallbackInfoReturnable ci) { 22 | NbtCompound nbt = new NbtCompound(); 23 | chickenEntity.writeNbt(nbt); 24 | 25 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 26 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 27 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 28 | ci.setReturnValue(DEFAULT); 29 | } else { 30 | String[] split = Variants.splitVariant(variant); 31 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/chicken/" + split[1] + ".png")); 32 | } 33 | } 34 | 35 | if (chickenEntity.hasCustomName()) { 36 | MobVariant variant = Variants.getVariantFromNametag(EntityType.CHICKEN, chickenEntity.getName().getString()); 37 | if (variant != null) { 38 | Identifier identifier = variant.getIdentifier(); 39 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/chicken/" + identifier.getPath() + ".png")); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/ZombieRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.ZombieBaseEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.mob.ZombieEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(ZombieBaseEntityRenderer.class) 17 | public class ZombieRendererMixin { 18 | private static final Identifier DEFAULT = Identifier.ofVanilla("textures/entity/zombie/zombie.png"); 19 | 20 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 21 | private void onGetTexture(ZombieEntity zombieEntity, CallbackInfoReturnable ci) { 22 | NbtCompound nbt = new NbtCompound(); 23 | zombieEntity.writeNbt(nbt); 24 | 25 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 26 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 27 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 28 | ci.setReturnValue(DEFAULT); 29 | } else { 30 | String[] split = Variants.splitVariant(variant); 31 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/zombie/" + split[1] + ".png")); 32 | } 33 | } 34 | 35 | if (zombieEntity.hasCustomName()) { 36 | MobVariant variant = Variants.getVariantFromNametag(EntityType.ZOMBIE, zombieEntity.getName().getString()); 37 | if (variant != null) { 38 | Identifier identifier = variant.getIdentifier(); 39 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/zombie/" + identifier.getPath() + ".png")); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/SkeletonRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.SkeletonEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.mob.AbstractSkeletonEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(SkeletonEntityRenderer.class) 17 | public class SkeletonRendererMixin { 18 | private static final Identifier DEFAULT = Identifier.ofVanilla("textures/entity/skeleton/skeleton.png"); 19 | 20 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 21 | private void onGetTexture(AbstractSkeletonEntity skeletonEntity, CallbackInfoReturnable ci) { 22 | NbtCompound nbt = new NbtCompound(); 23 | skeletonEntity.writeNbt(nbt); 24 | 25 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 26 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 27 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 28 | ci.setReturnValue(DEFAULT); 29 | } else { 30 | String[] split = Variants.splitVariant(variant); 31 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/skeleton/" + split[1] + ".png")); 32 | } 33 | } 34 | 35 | if (skeletonEntity.hasCustomName()) { 36 | MobVariant variant = Variants.getVariantFromNametag(EntityType.SKELETON, skeletonEntity.getName().getString()); 37 | if (variant != null) { 38 | Identifier identifier = variant.getIdentifier(); 39 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/skeleton/" + identifier.getPath() + ".png")); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/client/render/entity/feature/PigMudFeatureRenderer.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.client.render.entity.feature; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import net.fabricmc.api.EnvType; 5 | import net.fabricmc.api.Environment; 6 | import net.minecraft.client.model.Model; 7 | import net.minecraft.client.render.OverlayTexture; 8 | import net.minecraft.client.render.RenderLayer; 9 | import net.minecraft.client.render.VertexConsumer; 10 | import net.minecraft.client.render.VertexConsumerProvider; 11 | import net.minecraft.client.render.entity.feature.FeatureRenderer; 12 | import net.minecraft.client.render.entity.feature.FeatureRendererContext; 13 | import net.minecraft.client.render.entity.model.PigEntityModel; 14 | import net.minecraft.client.util.math.MatrixStack; 15 | import net.minecraft.entity.passive.PigEntity; 16 | import net.minecraft.nbt.NbtCompound; 17 | import net.minecraft.util.Identifier; 18 | 19 | @Environment(EnvType.CLIENT) 20 | public class PigMudFeatureRenderer> extends FeatureRenderer { 21 | private static final RenderLayer MUD_SKIN = RenderLayer.getEntityTranslucent(Identifier.of(MoreMobVariants.MOD_ID, "textures/entity/pig/mud/mud_overlay.png")); 22 | 23 | public PigMudFeatureRenderer(FeatureRendererContext featureRendererContext) { 24 | super(featureRendererContext); 25 | } 26 | 27 | @Override 28 | public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, T entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { 29 | NbtCompound nbt = new NbtCompound(); 30 | entity.writeCustomDataToNbt(nbt); 31 | 32 | if (nbt.contains(MoreMobVariants.MUDDY_NBT_KEY)) { 33 | if (nbt.getBoolean(MoreMobVariants.MUDDY_NBT_KEY)) { 34 | VertexConsumer vertexConsumer = vertexConsumers.getBuffer(this.getMudTexture()); 35 | ((Model)this.getContextModel()).render(matrices, vertexConsumer, 0xF00000, OverlayTexture.DEFAULT_UV, 0xFFFFFFFF); 36 | } 37 | } 38 | } 39 | 40 | private RenderLayer getMudTexture() { 41 | return MUD_SKIN; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/CustomEyesFeatureMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import net.minecraft.client.render.RenderLayer; 6 | import net.minecraft.client.render.VertexConsumerProvider; 7 | import net.minecraft.client.render.entity.feature.EyesFeatureRenderer; 8 | import net.minecraft.client.util.math.MatrixStack; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.entity.EntityType; 11 | import net.minecraft.entity.mob.SpiderEntity; 12 | import net.minecraft.nbt.NbtCompound; 13 | import net.minecraft.util.Identifier; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.injection.At; 16 | import org.spongepowered.asm.mixin.injection.ModifyArgs; 17 | import org.spongepowered.asm.mixin.injection.invoke.arg.Args; 18 | 19 | @Mixin(EyesFeatureRenderer.class) 20 | public class CustomEyesFeatureMixin { 21 | @ModifyArgs( 22 | method = "render", 23 | at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/VertexConsumerProvider;getBuffer(Lnet/minecraft/client/render/RenderLayer;)Lnet/minecraft/client/render/VertexConsumer;") 24 | ) 25 | private void mixinEyesFeatureTexture(Args args, MatrixStack matrices, VertexConsumerProvider vertexConsumerProvider, int light, T entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { 26 | SpiderEntity spider = null; 27 | if (entity instanceof SpiderEntity) { 28 | spider = (SpiderEntity)entity; 29 | } 30 | 31 | if (spider != null) { 32 | NbtCompound nbt = new NbtCompound(); 33 | spider.writeCustomDataToNbt(nbt); 34 | 35 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 36 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 37 | if (variant.isEmpty()) { 38 | return; 39 | } 40 | 41 | String[] split = Variants.splitVariant(variant); 42 | 43 | if (Variants.getVariant(EntityType.SPIDER, Identifier.of(split[0], split[1])).hasCustomEyes()) { 44 | args.set(0, RenderLayer.getEyes(Identifier.of(split[0], "textures/entity/spider/eyes/" + split[1] + ".png"))); 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/CatFluffMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import net.minecraft.client.model.*; 4 | import net.minecraft.client.render.entity.model.EntityModelPartNames; 5 | import net.minecraft.client.render.entity.model.OcelotEntityModel; 6 | import org.spongepowered.asm.mixin.Mixin; 7 | import org.spongepowered.asm.mixin.injection.At; 8 | import org.spongepowered.asm.mixin.injection.Inject; 9 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 10 | import org.spongepowered.asm.mixin.injection.callback.LocalCapture; 11 | 12 | @Mixin(OcelotEntityModel.class) 13 | public class CatFluffMixin { 14 | @Inject(method = "getModelData", at = @At("RETURN"), locals = LocalCapture.CAPTURE_FAILEXCEPTION) 15 | private static void onGetModelData(Dilation dilation, CallbackInfoReturnable ci, ModelData modelData, ModelPartData modelPartData) { 16 | modelPartData.addChild(EntityModelPartNames.HEAD, 17 | ModelPartBuilder.create() 18 | .cuboid("main", -2.5f, -2.0f, -3.0f, 5.0f, 4.0f, 5.0f, dilation) 19 | .cuboid(EntityModelPartNames.NOSE, -1.5f, 0.0f, -4.0f, 3, 2, 2, dilation, 0, 24) 20 | .cuboid("ear1", -2.0f, -3.0f, 0.0f, 1, 1, 2, dilation, 0, 10) 21 | .cuboid("ear2", 1.0f, -3.0f, 0.0f, 1, 1, 2, dilation, 6, 10) 22 | .cuboid("scruff1", -4.5f, -2.0f, 1.0f, 9, 4, 0, dilation, 40, 28) 23 | .cuboid("scruff2", -4.5f, -2.0f, -1.0f, 9, 4, 0, dilation, 40, 28), 24 | ModelTransform.pivot(0.0f, 15.0f, -9.0f)); 25 | 26 | ModelPartBuilder modelpartBuilder3 = ModelPartBuilder.create().uv(20, 0).cuboid(-2.0f, 3.0f, -8.0f, 4.0f, 16.0f, 6.0f, dilation) 27 | .uv(32, 12).cuboid(-4.0f, 6.0f, -9.0f, 8.0f, 0.0f, 8.0f, dilation) 28 | .uv(32, 20).cuboid(-4.0f, 8.0f, -9.0f, 8.0f, 0.0f, 8.0f, dilation) 29 | .uv(32, 12).cuboid(-4.0f, 10.0f, -9.0f, 8.0f, 0.0f, 8.0f, dilation) 30 | .uv(32, 20).cuboid(-4.0f, 12.0f, -9.0f, 8.0f, 0.0f, 8.0f, dilation) 31 | .uv(32, 12).cuboid(-4.0f, 14.0f, -9.0f, 8.0f, 0.0f, 8.0f, dilation) 32 | .uv(32, 20).cuboid(-4.0f, 16.0f, -9.0f, 8.0f, 0.0f, 8.0f, dilation); 33 | modelPartData.addChild(EntityModelPartNames.BODY, modelpartBuilder3, ModelTransform.of(0.0f, 12.0f, -10.0f, 1.5707964f, 0.0f, 0.0f)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/SheepWoolFeatureMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.feature.SheepWoolFeatureRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.passive.SheepEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | import org.spongepowered.asm.mixin.Mixin; 12 | import org.spongepowered.asm.mixin.injection.At; 13 | import org.spongepowered.asm.mixin.injection.ModifyArgs; 14 | import org.spongepowered.asm.mixin.injection.invoke.arg.Args; 15 | 16 | @Mixin(SheepWoolFeatureRenderer.class) 17 | public class SheepWoolFeatureMixin { 18 | @ModifyArgs( 19 | method = "Lnet/minecraft/client/render/entity/feature/SheepWoolFeatureRenderer;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/entity/passive/SheepEntity;FFFFFF)V", 20 | at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/feature/SheepWoolFeatureRenderer;render(Lnet/minecraft/client/render/entity/model/EntityModel;Lnet/minecraft/client/render/entity/model/EntityModel;Lnet/minecraft/util/Identifier;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/entity/LivingEntity;FFFFFFI)V") 21 | ) 22 | private void mixinSheepFurTexture(Args args) { 23 | SheepEntity sheepEntity = args.get(6); 24 | NbtCompound nbt = new NbtCompound(); 25 | sheepEntity.writeCustomDataToNbt(nbt); 26 | 27 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 28 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 29 | if (variant.isEmpty()) { 30 | return; 31 | } 32 | 33 | String[] split = Variants.splitVariant(variant); 34 | 35 | if (Variants.getVariant(EntityType.SHEEP, Identifier.of(split[0], split[1])).hasCustomWool()) { 36 | args.set(2, Identifier.of(split[0], "textures/entity/sheep/wool/" + split[1] + ".png")); 37 | 38 | if (sheepEntity.hasCustomName()) { 39 | MobVariant nametagVariant = Variants.getVariantFromNametag(EntityType.SHEEP, sheepEntity.getName().getString()); 40 | if (nametagVariant != null) { 41 | Identifier identifier = nametagVariant.getIdentifier(); 42 | args.set(2, Identifier.of(identifier.getNamespace(), "textures/entity/sheep/wool/" + identifier.getPath() + ".png")); 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/WolfRendererMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.minecraft.client.render.entity.WolfEntityRenderer; 7 | import net.minecraft.entity.EntityType; 8 | import net.minecraft.entity.passive.WolfEntity; 9 | import net.minecraft.nbt.NbtCompound; 10 | import net.minecraft.util.Identifier; 11 | 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.CallbackInfoReturnable; 15 | 16 | @Mixin(WolfEntityRenderer.class) 17 | public class WolfRendererMixin { 18 | private static final Identifier DEFAULT_WILD = Identifier.ofVanilla("textures/entity/wolf/wolf.png"); 19 | private static final Identifier DEFAULT_TAMED = Identifier.ofVanilla("textures/entity/wolf/wolf_tame.png"); 20 | private static final Identifier DEFAULT_ANGRY = Identifier.ofVanilla("textures/entity/wolf/wolf_angry.png"); 21 | 22 | @Inject(method = "getTexture", at = @At("HEAD"), cancellable = true) 23 | private void onGetTexture(WolfEntity wolfEntity, CallbackInfoReturnable ci) { 24 | NbtCompound nbt = new NbtCompound(); 25 | wolfEntity.writeNbt(nbt); 26 | 27 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 28 | String variant = nbt.getString(MoreMobVariants.NBT_KEY); 29 | if (variant.equals(MoreMobVariants.id("default").toString()) || variant.isEmpty()) { 30 | if (wolfEntity.isTamed()) { 31 | ci.setReturnValue(DEFAULT_TAMED); 32 | } else { 33 | ci.setReturnValue(wolfEntity.hasAngerTime() ? DEFAULT_ANGRY : DEFAULT_WILD); 34 | } 35 | } else { 36 | String[] split = Variants.splitVariant(variant); 37 | if (wolfEntity.isTamed()) { 38 | ci.setReturnValue(Identifier.of(split[0], "textures/entity/wolf/" + split[1] + "_tame.png")); 39 | } else { 40 | ci.setReturnValue(wolfEntity.hasAngerTime() ? Identifier.of(split[0], "textures/entity/wolf/" + split[1] + "_angry.png") : Identifier.of(split[0], "textures/entity/wolf/" + split[1] + "_wild.png")); 41 | } 42 | } 43 | } 44 | 45 | if (wolfEntity.hasCustomName()) { 46 | MobVariant variant = Variants.getVariantFromNametag(EntityType.WOLF, wolfEntity.getName().getString()); 47 | if (variant != null) { 48 | Identifier identifier = variant.getIdentifier(); 49 | if (wolfEntity.isTamed()) { 50 | ci.setReturnValue(Identifier.of(identifier.getNamespace(), "textures/entity/wolf/" + identifier.getPath() + "_tame.png")); 51 | } else { 52 | ci.setReturnValue(wolfEntity.hasAngerTime() ? Identifier.of(identifier.getNamespace(), "textures/entity/wolf/" + identifier.getPath() + "_angry.png") : Identifier.of(identifier.getNamespace(), "textures/entity/wolf/" + identifier.getPath() + "_wild.png")); 53 | } 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/SpiderVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 6 | import com.github.nyuppo.variant.MobVariant; 7 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityData; 10 | import net.minecraft.entity.EntityType; 11 | import net.minecraft.entity.SpawnReason; 12 | import net.minecraft.entity.mob.SpiderEntity; 13 | import net.minecraft.nbt.NbtCompound; 14 | import net.minecraft.server.MinecraftServer; 15 | import net.minecraft.util.Identifier; 16 | import net.minecraft.world.LocalDifficulty; 17 | import net.minecraft.world.ServerWorldAccess; 18 | import org.jetbrains.annotations.Nullable; 19 | import org.spongepowered.asm.mixin.Mixin; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 22 | 23 | @Mixin(SpiderEntity.class) 24 | public class SpiderVariantsMixin extends MobEntityVariantsMixin { 25 | private MobVariant variant = Variants.getDefaultVariant(EntityType.SPIDER); 26 | 27 | @Override 28 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 29 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 30 | } 31 | 32 | @Override 33 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 34 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 35 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 36 | variant = Variants.getVariant(EntityType.SPIDER, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 37 | } else { 38 | variant = Variants.getVariant(EntityType.SPIDER, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 39 | } 40 | } else { 41 | variant = Variants.getRandomVariant(EntityType.SPIDER, ((SpiderEntity)(Object)this).getRandom().nextLong(), ((SpiderEntity)(Object)this).getWorld().getBiome(((SpiderEntity)(Object)this).getBlockPos()), null, ((SpiderEntity)(Object)this).getWorld().getMoonSize()); 42 | } 43 | 44 | // Update all players in the event that this is from modifying entity data with a command 45 | // This should be fine since the packet is so small anyways 46 | MinecraftServer server = ((Entity)(Object)this).getServer(); 47 | if (server != null) { 48 | server.getPlayerManager().getPlayerList().forEach((player) -> { 49 | ServerPlayNetworking.send(player, new ServerRespondBasicVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString())); 50 | }); 51 | } 52 | } 53 | 54 | @Override 55 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 56 | variant = Variants.getRandomVariant(EntityType.SPIDER, ((SpiderEntity)(Object)this).getRandom().nextLong(), world.getBiome(((SpiderEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/ZombieVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 6 | import com.github.nyuppo.variant.MobVariant; 7 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityData; 10 | import net.minecraft.entity.EntityType; 11 | import net.minecraft.entity.SpawnReason; 12 | import net.minecraft.entity.mob.ZombieEntity; 13 | import net.minecraft.nbt.NbtCompound; 14 | import net.minecraft.server.MinecraftServer; 15 | import net.minecraft.util.Identifier; 16 | import net.minecraft.world.LocalDifficulty; 17 | import net.minecraft.world.ServerWorldAccess; 18 | import org.jetbrains.annotations.Nullable; 19 | import org.spongepowered.asm.mixin.Mixin; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 22 | 23 | @Mixin(ZombieEntity.class) 24 | public class ZombieVariantsMixin extends MobEntityVariantsMixin { 25 | private MobVariant variant = Variants.getDefaultVariant(EntityType.ZOMBIE); 26 | 27 | @Override 28 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 29 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 30 | } 31 | 32 | @Override 33 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 34 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 35 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 36 | variant = Variants.getVariant(EntityType.ZOMBIE, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 37 | } else { 38 | variant = Variants.getVariant(EntityType.ZOMBIE, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 39 | } 40 | } else { 41 | variant = Variants.getRandomVariant(EntityType.ZOMBIE, ((ZombieEntity)(Object)this).getRandom().nextLong(), ((ZombieEntity)(Object)this).getWorld().getBiome(((ZombieEntity)(Object)this).getBlockPos()), null, ((ZombieEntity)(Object)this).getWorld().getMoonSize()); 42 | } 43 | 44 | // Update all players in the event that this is from modifying entity data with a command 45 | // This should be fine since the packet is so small anyways 46 | MinecraftServer server = ((Entity)(Object)this).getServer(); 47 | if (server != null) { 48 | server.getPlayerManager().getPlayerList().forEach((player) -> { 49 | ServerPlayNetworking.send(player, new ServerRespondBasicVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString())); 50 | }); 51 | } 52 | } 53 | 54 | @Override 55 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 56 | variant = Variants.getRandomVariant(EntityType.ZOMBIE, ((ZombieEntity)(Object)this).getRandom().nextLong(), world.getBiome(((ZombieEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/SkeletonVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 6 | import com.github.nyuppo.variant.MobVariant; 7 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityData; 10 | import net.minecraft.entity.EntityType; 11 | import net.minecraft.entity.SpawnReason; 12 | import net.minecraft.entity.mob.SkeletonEntity; 13 | import net.minecraft.nbt.NbtCompound; 14 | import net.minecraft.server.MinecraftServer; 15 | import net.minecraft.util.Identifier; 16 | import net.minecraft.world.LocalDifficulty; 17 | import net.minecraft.world.ServerWorldAccess; 18 | import org.jetbrains.annotations.Nullable; 19 | import org.spongepowered.asm.mixin.Mixin; 20 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 21 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 22 | 23 | @Mixin(SkeletonEntity.class) 24 | public class SkeletonVariantsMixin extends MobEntityVariantsMixin { 25 | private MobVariant variant = Variants.getDefaultVariant(EntityType.SKELETON); 26 | 27 | @Override 28 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 29 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 30 | } 31 | 32 | @Override 33 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 34 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 35 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 36 | variant = Variants.getVariant(EntityType.SKELETON, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 37 | } else { 38 | variant = Variants.getVariant(EntityType.SKELETON, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 39 | } 40 | } else { 41 | variant = Variants.getRandomVariant(EntityType.SKELETON, ((SkeletonEntity)(Object)this).getRandom().nextLong(), ((SkeletonEntity)(Object)this).getWorld().getBiome(((SkeletonEntity)(Object)this).getBlockPos()), null, ((SkeletonEntity)(Object)this).getWorld().getMoonSize()); 42 | } 43 | 44 | // Update all players in the event that this is from modifying entity data with a command 45 | // This should be fine since the packet is so small anyways 46 | MinecraftServer server = ((Entity)(Object)this).getServer(); 47 | if (server != null) { 48 | server.getPlayerManager().getPlayerList().forEach((player) -> { 49 | ServerPlayNetworking.send(player, new ServerRespondBasicVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString())); 50 | }); 51 | } 52 | } 53 | 54 | @Override 55 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 56 | variant = Variants.getRandomVariant(EntityType.SKELETON, ((SkeletonEntity)(Object)this).getRandom().nextLong(), world.getBiome(((SkeletonEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 57 | } 58 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/client/render/entity/feature/ShearedWoolColorFeatureRenderer.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.client.render.entity.feature; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.variant.MobVariant; 6 | import net.fabricmc.api.EnvType; 7 | import net.fabricmc.api.Environment; 8 | import net.minecraft.client.model.Model; 9 | import net.minecraft.client.render.OverlayTexture; 10 | import net.minecraft.client.render.RenderLayer; 11 | import net.minecraft.client.render.VertexConsumer; 12 | import net.minecraft.client.render.VertexConsumerProvider; 13 | import net.minecraft.client.render.entity.feature.FeatureRenderer; 14 | import net.minecraft.client.render.entity.feature.FeatureRendererContext; 15 | import net.minecraft.client.render.entity.model.SheepEntityModel; 16 | import net.minecraft.client.util.math.MatrixStack; 17 | import net.minecraft.entity.EntityType; 18 | import net.minecraft.entity.passive.SheepEntity; 19 | import net.minecraft.nbt.NbtCompound; 20 | import net.minecraft.util.Identifier; 21 | 22 | @Environment(EnvType.CLIENT) 23 | public class ShearedWoolColorFeatureRenderer> extends FeatureRenderer { 24 | public ShearedWoolColorFeatureRenderer(FeatureRendererContext context) { 25 | super(context); 26 | } 27 | 28 | @Override 29 | public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, T sheepEntity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { 30 | /* 31 | if (!sheepEntity.isSheared()) { 32 | return; 33 | } 34 | */ 35 | // It actually looks better without this check lol 36 | 37 | // Check for custom name override 38 | if (sheepEntity.hasCustomName()) { 39 | MobVariant variant = Variants.getVariantFromNametag(EntityType.SHEEP, sheepEntity.getName().getString()); 40 | if (variant != null) { 41 | if (variant.hasColorWhenSheared()) { 42 | int color = SheepEntity.getRgbColor(sheepEntity.getColor()); 43 | 44 | RenderLayer FUR_OVERLAY = RenderLayer.getEntityCutoutNoCull(MoreMobVariants.id("textures/entity/sheep/sheared_color_overlay/" + variant.getIdentifier().getPath() + ".png")); 45 | VertexConsumer vertexConsumer = vertexConsumers.getBuffer(FUR_OVERLAY); 46 | ((Model)this.getContextModel()).render(matrices, vertexConsumer, 0xF00000, OverlayTexture.DEFAULT_UV, color); 47 | } 48 | return; 49 | } 50 | } 51 | 52 | NbtCompound nbt = new NbtCompound(); 53 | sheepEntity.writeCustomDataToNbt(nbt); 54 | 55 | if (nbt.contains(MoreMobVariants.NBT_KEY)) { 56 | Identifier variant = Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY)); 57 | if (Variants.getVariant(EntityType.SHEEP, variant).hasColorWhenSheared()) { 58 | int color = SheepEntity.getRgbColor(sheepEntity.getColor()); 59 | 60 | RenderLayer FUR_OVERLAY = RenderLayer.getEntityCutoutNoCull(MoreMobVariants.id("textures/entity/sheep/sheared_color_overlay/" + variant.getPath() + ".png")); 61 | VertexConsumer vertexConsumer = vertexConsumers.getBuffer(FUR_OVERLAY); 62 | ((Model)this.getContextModel()).render(matrices, vertexConsumer, 0xF00000, OverlayTexture.DEFAULT_UV, color); 63 | } 64 | } 65 | 66 | 67 | }; 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/WolfVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 6 | import com.github.nyuppo.variant.MobVariant; 7 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityData; 10 | import net.minecraft.entity.EntityType; 11 | import net.minecraft.entity.SpawnReason; 12 | import net.minecraft.entity.passive.PassiveEntity; 13 | import net.minecraft.entity.passive.WolfEntity; 14 | import net.minecraft.nbt.NbtCompound; 15 | import net.minecraft.server.MinecraftServer; 16 | import net.minecraft.server.world.ServerWorld; 17 | import net.minecraft.util.Identifier; 18 | import net.minecraft.world.LocalDifficulty; 19 | import net.minecraft.world.ServerWorldAccess; 20 | import org.jetbrains.annotations.Nullable; 21 | import org.spongepowered.asm.mixin.Mixin; 22 | import org.spongepowered.asm.mixin.injection.At; 23 | import org.spongepowered.asm.mixin.injection.Inject; 24 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 25 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 26 | 27 | @Mixin(WolfEntity.class) 28 | public class WolfVariantsMixin extends MobEntityVariantsMixin { 29 | private MobVariant variant = Variants.getDefaultVariant(EntityType.WOLF); 30 | 31 | @Override 32 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 33 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 34 | } 35 | 36 | @Override 37 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 38 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 39 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 40 | variant = Variants.getVariant(EntityType.WOLF, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 41 | } else { 42 | variant = Variants.getVariant(EntityType.WOLF, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 43 | } 44 | } else { 45 | variant = Variants.getRandomVariant(EntityType.WOLF, ((WolfEntity)(Object)this).getRandom().nextLong(), ((WolfEntity)(Object)this).getWorld().getBiome(((WolfEntity)(Object)this).getBlockPos()), null, ((WolfEntity)(Object)this).getWorld().getMoonSize()); 46 | } 47 | 48 | // Update all players in the event that this is from modifying entity data with a command 49 | // This should be fine since the packet is so small anyways 50 | MinecraftServer server = ((Entity)(Object)this).getServer(); 51 | if (server != null) { 52 | server.getPlayerManager().getPlayerList().forEach((player) -> { 53 | ServerPlayNetworking.send(player, new ServerRespondBasicVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString())); 54 | }); 55 | } 56 | } 57 | 58 | @Override 59 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 60 | variant = Variants.getRandomVariant(EntityType.WOLF, ((WolfEntity)(Object)this).getRandom().nextLong(), world.getBiome(((WolfEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 61 | } 62 | 63 | @Inject( 64 | method = "createChild(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/entity/passive/PassiveEntity;)Lnet/minecraft/entity/passive/WolfEntity;", 65 | at = @At("RETURN") 66 | ) 67 | private void onCreateChild(ServerWorld world, PassiveEntity entity, CallbackInfoReturnable ci) { 68 | WolfEntity child = ci.getReturnValue(); 69 | 70 | MobVariant variant = Variants.getChildVariant(EntityType.WOLF, world, ((WolfEntity)(Object)this), entity); 71 | 72 | // Write variant to child's NBT 73 | NbtCompound childNbt = new NbtCompound(); 74 | child.writeNbt(childNbt); 75 | childNbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 76 | child.readCustomDataFromNbt(childNbt); 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/CowVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 6 | import com.github.nyuppo.variant.MobVariant; 7 | import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; 8 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.entity.EntityData; 11 | import net.minecraft.entity.EntityType; 12 | import net.minecraft.entity.SpawnReason; 13 | import net.minecraft.entity.passive.*; 14 | import net.minecraft.nbt.NbtCompound; 15 | import net.minecraft.network.PacketByteBuf; 16 | import net.minecraft.server.MinecraftServer; 17 | import net.minecraft.server.world.ServerWorld; 18 | import net.minecraft.util.Identifier; 19 | import net.minecraft.world.LocalDifficulty; 20 | import net.minecraft.world.ServerWorldAccess; 21 | import org.jetbrains.annotations.Nullable; 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.injection.At; 24 | import org.spongepowered.asm.mixin.injection.Inject; 25 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 26 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 27 | 28 | @Mixin(CowEntity.class) 29 | public abstract class CowVariantsMixin extends MobEntityVariantsMixin { 30 | private MobVariant variant = Variants.getDefaultVariant(EntityType.COW); 31 | 32 | @Override 33 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 34 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 35 | } 36 | 37 | @Override 38 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 39 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 40 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 41 | variant = Variants.getVariant(EntityType.COW, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 42 | } else { 43 | variant = Variants.getVariant(EntityType.COW, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 44 | } 45 | } else { 46 | variant = Variants.getRandomVariant(EntityType.COW, ((CowEntity)(Object)this).getRandom().nextLong(), ((CowEntity)(Object)this).getWorld().getBiome(((CowEntity)(Object)this).getBlockPos()), null, ((CowEntity)(Object)this).getWorld().getMoonSize()); 47 | } 48 | 49 | // Update all players in the event that this is from modifying entity data with a command 50 | // This should be fine since the packet is so small anyways 51 | MinecraftServer server = ((Entity)(Object)this).getServer(); 52 | if (server != null) { 53 | server.getPlayerManager().getPlayerList().forEach((player) -> { 54 | ServerPlayNetworking.send(player, new ServerRespondBasicVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString())); 55 | }); 56 | } 57 | } 58 | 59 | @Override 60 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 61 | variant = Variants.getRandomVariant(EntityType.COW, ((CowEntity)(Object)this).getRandom().nextLong(), world.getBiome(((CowEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 62 | } 63 | 64 | @Inject( 65 | method = "createChild(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/entity/passive/PassiveEntity;)Lnet/minecraft/entity/passive/CowEntity;", 66 | at = @At("RETURN") 67 | ) 68 | private void onCreateChild(ServerWorld world, PassiveEntity entity, CallbackInfoReturnable ci) { 69 | CowEntity child = ci.getReturnValue(); 70 | 71 | MobVariant variant = Variants.getChildVariant(EntityType.COW, world, ((CowEntity)(Object)this), entity); 72 | 73 | // Write variant to child's NBT 74 | NbtCompound childNbt = new NbtCompound(); 75 | child.writeNbt(childNbt); 76 | childNbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 77 | child.readCustomDataFromNbt(childNbt); 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/ChickenVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 6 | import com.github.nyuppo.variant.MobVariant; 7 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityData; 10 | import net.minecraft.entity.EntityType; 11 | import net.minecraft.entity.SpawnReason; 12 | import net.minecraft.entity.passive.ChickenEntity; 13 | import net.minecraft.entity.passive.PassiveEntity; 14 | import net.minecraft.nbt.NbtCompound; 15 | import net.minecraft.server.MinecraftServer; 16 | import net.minecraft.server.world.ServerWorld; 17 | import net.minecraft.util.Identifier; 18 | import net.minecraft.world.LocalDifficulty; 19 | import net.minecraft.world.ServerWorldAccess; 20 | import org.jetbrains.annotations.Nullable; 21 | import org.spongepowered.asm.mixin.Mixin; 22 | import org.spongepowered.asm.mixin.injection.At; 23 | import org.spongepowered.asm.mixin.injection.Inject; 24 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 25 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 26 | 27 | @Mixin(ChickenEntity.class) 28 | public abstract class ChickenVariantsMixin extends MobEntityVariantsMixin { 29 | private MobVariant variant = Variants.getDefaultVariant(EntityType.CHICKEN); 30 | 31 | @Override 32 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 33 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 34 | } 35 | 36 | @Override 37 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 38 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 39 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 40 | variant = Variants.getVariant(EntityType.CHICKEN, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 41 | } else { 42 | variant = Variants.getVariant(EntityType.CHICKEN, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 43 | } 44 | } else { 45 | variant = Variants.getRandomVariant(EntityType.CHICKEN, ((ChickenEntity)(Object)this).getRandom().nextLong(), ((ChickenEntity)(Object)this).getWorld().getBiome(((ChickenEntity)(Object)this).getBlockPos()), null, ((ChickenEntity)(Object)this).getWorld().getMoonSize()); 46 | } 47 | 48 | // Update all players in the event that this is from modifying entity data with a command 49 | // This should be fine since the packet is so small anyways 50 | MinecraftServer server = ((Entity)(Object)this).getServer(); 51 | if (server != null) { 52 | server.getPlayerManager().getPlayerList().forEach((player) -> { 53 | ServerPlayNetworking.send(player, new ServerRespondBasicVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString())); 54 | }); 55 | } 56 | } 57 | 58 | @Override 59 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 60 | variant = Variants.getRandomVariant(EntityType.CHICKEN, ((ChickenEntity)(Object)this).getRandom().nextLong(), world.getBiome(((ChickenEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 61 | } 62 | 63 | @Inject( 64 | method = "createChild(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/entity/passive/PassiveEntity;)Lnet/minecraft/entity/passive/ChickenEntity;", 65 | at = @At("RETURN") 66 | ) 67 | private void onCreateChild(ServerWorld world, PassiveEntity entity, CallbackInfoReturnable ci) { 68 | ChickenEntity child = ci.getReturnValue(); 69 | 70 | MobVariant variant = Variants.getChildVariant(EntityType.CHICKEN, world, ((ChickenEntity)(Object)this), entity); 71 | 72 | // Write variant to child's NBT 73 | NbtCompound childNbt = new NbtCompound(); 74 | child.writeNbt(childNbt); 75 | childNbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 76 | child.readCustomDataFromNbt(childNbt); 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/config/SheepHornSettings.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.config; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import net.minecraft.registry.entry.RegistryEntry; 5 | import net.minecraft.util.math.random.Random; 6 | import net.minecraft.world.biome.Biome; 7 | import org.jetbrains.annotations.Nullable; 8 | 9 | import java.util.ArrayList; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | 13 | public class SheepHornSettings { 14 | private static double hasHornsChance; 15 | private static double inheritParentsChance; 16 | private static HashMap weights; 17 | private static HashMap defaultWeights; 18 | 19 | public static double getHornsChance() { 20 | return hasHornsChance; 21 | } 22 | 23 | public static void setHornsChance(double chance) { 24 | hasHornsChance = chance; 25 | } 26 | 27 | public static double getInheritChance() { 28 | return inheritParentsChance; 29 | } 30 | 31 | public static void setInheritChance(double chance) { 32 | inheritParentsChance = chance; 33 | } 34 | 35 | public static void setWeight(SheepHornColour colour, int weight) { 36 | if (weight <= 0) { 37 | weights.remove(colour); 38 | return; 39 | } 40 | 41 | weights.put(colour, weight); 42 | } 43 | 44 | @Nullable 45 | public static SheepHornColour getRandomSheepHornColour(Random random, @Nullable RegistryEntry spawnBiome) { 46 | if (random.nextDouble() > hasHornsChance) { 47 | return null; 48 | } 49 | 50 | if (spawnBiome == null || !spawnBiome.isIn(MoreMobVariants.SHEEP_SPAWN_WITH_HORNS)) { 51 | return null; 52 | } 53 | 54 | WeightedRandomBag hornColours = new WeightedRandomBag<>(random); 55 | weights.forEach(hornColours::addEntry); 56 | 57 | return hornColours.getRandom(); 58 | } 59 | 60 | public static void resetSettings() { 61 | hasHornsChance = 0.125d; 62 | inheritParentsChance = 0.8d; 63 | 64 | weights.clear(); 65 | weights.put(SheepHornColour.BROWN, defaultWeights.get(SheepHornColour.BROWN)); 66 | weights.put(SheepHornColour.GRAY, defaultWeights.get(SheepHornColour.GRAY)); 67 | weights.put(SheepHornColour.BLACK, defaultWeights.get(SheepHornColour.BLACK)); 68 | weights.put(SheepHornColour.BEIGE, defaultWeights.get(SheepHornColour.BEIGE)); 69 | } 70 | 71 | public enum SheepHornColour { 72 | BROWN("brown"), 73 | GRAY("gray"), 74 | BLACK("black"), 75 | BEIGE("beige"); 76 | 77 | String id; 78 | 79 | SheepHornColour(String id) { 80 | this.id = id; 81 | } 82 | 83 | public String getId() { 84 | return this.id; 85 | } 86 | } 87 | 88 | static { 89 | hasHornsChance = 0.125d; 90 | inheritParentsChance = 0.8d; 91 | 92 | weights = new HashMap<>(); 93 | 94 | defaultWeights = new HashMap<>(); 95 | defaultWeights.put(SheepHornColour.BROWN, 8); 96 | defaultWeights.put(SheepHornColour.GRAY, 6); 97 | defaultWeights.put(SheepHornColour.BLACK, 3); 98 | defaultWeights.put(SheepHornColour.BEIGE, 1); 99 | } 100 | } 101 | 102 | class WeightedRandomBag { 103 | private class Entry { 104 | double accumulatedWeight; 105 | T object; 106 | } 107 | 108 | private List entries = new ArrayList<>(); 109 | private double accumulatedWeight; 110 | private final Random random; 111 | 112 | public WeightedRandomBag(Random random) { 113 | this.random = random; 114 | } 115 | 116 | public void addEntry(T object, double weight) { 117 | accumulatedWeight += weight; 118 | Entry e = new Entry(); 119 | e.object = object; 120 | e.accumulatedWeight = accumulatedWeight; 121 | entries.add(e); 122 | } 123 | 124 | public T getRandom() { 125 | double r = random.nextDouble() * accumulatedWeight; 126 | 127 | for (Entry entry: entries) { 128 | if (entry.accumulatedWeight >= r) { 129 | return entry.object; 130 | } 131 | } 132 | return null; //should only happen when there are no entries 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/CatVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.Variants; 5 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 6 | import com.github.nyuppo.variant.MobVariant; 7 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 8 | import net.minecraft.entity.Entity; 9 | import net.minecraft.entity.EntityData; 10 | import net.minecraft.entity.EntityType; 11 | import net.minecraft.entity.SpawnReason; 12 | import net.minecraft.entity.passive.CatEntity; 13 | import net.minecraft.entity.passive.PassiveEntity; 14 | import net.minecraft.nbt.NbtCompound; 15 | import net.minecraft.registry.tag.StructureTags; 16 | import net.minecraft.server.MinecraftServer; 17 | import net.minecraft.server.world.ServerWorld; 18 | import net.minecraft.util.Identifier; 19 | import net.minecraft.world.LocalDifficulty; 20 | import net.minecraft.world.ServerWorldAccess; 21 | import org.jetbrains.annotations.Nullable; 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.injection.At; 24 | import org.spongepowered.asm.mixin.injection.Inject; 25 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 26 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 27 | 28 | @Mixin(CatEntity.class) 29 | public class CatVariantsMixin extends MobEntityVariantsMixin { 30 | private MobVariant variant = Variants.getDefaultVariant(EntityType.CAT); 31 | 32 | @Override 33 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 34 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 35 | } 36 | 37 | @Override 38 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 39 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 40 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 41 | variant = Variants.getVariant(EntityType.CAT, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 42 | } else { 43 | variant = Variants.getVariant(EntityType.CAT, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 44 | } 45 | } else { 46 | variant = Variants.getRandomVariant(EntityType.CAT, ((CatEntity)(Object)this).getRandom().nextLong(), ((CatEntity)(Object)this).getWorld().getBiome(((CatEntity)(Object)this).getBlockPos()), null, ((CatEntity)(Object)this).getWorld().getMoonSize()); 47 | } 48 | 49 | // Update all players in the event that this is from modifying entity data with a command 50 | // This should be fine since the packet is so small anyways 51 | MinecraftServer server = ((Entity)(Object)this).getServer(); 52 | if (server != null) { 53 | server.getPlayerManager().getPlayerList().forEach((player) -> { 54 | ServerPlayNetworking.send(player, new ServerRespondBasicVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString())); 55 | }); 56 | } 57 | } 58 | 59 | @Override 60 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 61 | variant = Variants.getRandomVariant(EntityType.CAT, ((CatEntity)(Object)this).getRandom().nextLong(), world.getBiome(((CatEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 62 | 63 | // Check if we should spawn black cats (witch huts) 64 | if (world.toServerWorld().getStructureAccessor().getStructureContaining(((CatEntity) (Object) this).getBlockPos(), StructureTags.CATS_SPAWN_AS_BLACK).hasChildren()) { 65 | MobVariant allBlack = Variants.getVariantNullable(EntityType.CAT, Identifier.ofVanilla("all_black")); 66 | if (allBlack != null) { 67 | variant = allBlack; 68 | ((CatEntity) (Object) this).setPersistent(); 69 | } 70 | } 71 | } 72 | 73 | @Inject( 74 | method = "createChild(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/entity/passive/PassiveEntity;)Lnet/minecraft/entity/passive/CatEntity;", 75 | at = @At("RETURN") 76 | ) 77 | private void onCreateChild(ServerWorld world, PassiveEntity entity, CallbackInfoReturnable ci) { 78 | CatEntity child = ci.getReturnValue(); 79 | 80 | MobVariant variant = Variants.getChildVariant(EntityType.CAT, world, ((CatEntity)(Object)this), entity); 81 | 82 | // Write variant to child's NBT 83 | NbtCompound childNbt = new NbtCompound(); 84 | child.writeNbt(childNbt); 85 | childNbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 86 | child.readCustomDataFromNbt(childNbt); 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/client/render/entity/feature/SheepHornsFeatureRenderer.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.client.render.entity.feature; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.mixin.QuadrupedEntityModelPartAccessor; 5 | import net.fabricmc.api.EnvType; 6 | import net.fabricmc.api.Environment; 7 | import net.minecraft.client.model.*; 8 | import net.minecraft.client.render.OverlayTexture; 9 | import net.minecraft.client.render.RenderLayer; 10 | import net.minecraft.client.render.VertexConsumerProvider; 11 | import net.minecraft.client.render.entity.feature.FeatureRenderer; 12 | import net.minecraft.client.render.entity.feature.FeatureRendererContext; 13 | import net.minecraft.client.render.entity.model.EntityModelPartNames; 14 | import net.minecraft.client.render.entity.model.SheepEntityModel; 15 | import net.minecraft.client.util.math.MatrixStack; 16 | import net.minecraft.entity.passive.SheepEntity; 17 | import net.minecraft.nbt.NbtCompound; 18 | import net.minecraft.util.Identifier; 19 | 20 | @Environment(EnvType.CLIENT) 21 | public class SheepHornsFeatureRenderer> extends FeatureRenderer { 22 | private static final RenderLayer HORNS_BROWN = RenderLayer.getEntityCutoutNoCull(Identifier.of(MoreMobVariants.MOD_ID, "textures/entity/sheep/horns/horns_brown.png")); 23 | private static final RenderLayer HORNS_GRAY = RenderLayer.getEntityCutoutNoCull(Identifier.of(MoreMobVariants.MOD_ID, "textures/entity/sheep/horns/horns_gray.png")); 24 | private static final RenderLayer HORNS_BLACK = RenderLayer.getEntityCutoutNoCull(Identifier.of(MoreMobVariants.MOD_ID, "textures/entity/sheep/horns/horns_black.png")); 25 | private static final RenderLayer HORNS_BEIGE = RenderLayer.getEntityCutoutNoCull(Identifier.of(MoreMobVariants.MOD_ID, "textures/entity/sheep/horns/horns_beige.png")); 26 | private final ModelPart horns = getTexturedModelData().createModel(); 27 | 28 | public SheepHornsFeatureRenderer(FeatureRendererContext featureRendererContext) { 29 | super(featureRendererContext); 30 | } 31 | 32 | @Override 33 | public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, T entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { 34 | NbtCompound nbt = new NbtCompound(); 35 | entity.writeCustomDataToNbt(nbt); 36 | 37 | if (nbt.contains(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY)) { 38 | if (!nbt.getString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY).isEmpty()) { 39 | matrices.push(); 40 | 41 | ModelPart sheepHead = ((QuadrupedEntityModelPartAccessor)this.getContextModel()).getHead(); 42 | horns.copyTransform(sheepHead); 43 | 44 | String hornColour = nbt.getString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY); 45 | 46 | if (entity.isBaby()) { 47 | matrices.push(); 48 | matrices.translate(0.0f, 0.5f, 0.25f); 49 | 50 | if (hornColour.equalsIgnoreCase("brown")) { 51 | horns.render(matrices, vertexConsumers.getBuffer(HORNS_BROWN), light, OverlayTexture.DEFAULT_UV); 52 | } else if (hornColour.equalsIgnoreCase("gray")) { 53 | horns.render(matrices, vertexConsumers.getBuffer(HORNS_GRAY), light, OverlayTexture.DEFAULT_UV); 54 | } else if (hornColour.equalsIgnoreCase("black")) { 55 | horns.render(matrices, vertexConsumers.getBuffer(HORNS_BLACK), light, OverlayTexture.DEFAULT_UV); 56 | } else if (hornColour.equalsIgnoreCase("beige")) { 57 | horns.render(matrices, vertexConsumers.getBuffer(HORNS_BEIGE), light, OverlayTexture.DEFAULT_UV); 58 | } 59 | 60 | matrices.pop(); 61 | } else { 62 | if (hornColour.equalsIgnoreCase("brown")) { 63 | horns.render(matrices, vertexConsumers.getBuffer(HORNS_BROWN), light, OverlayTexture.DEFAULT_UV); 64 | } else if (hornColour.equalsIgnoreCase("gray")) { 65 | horns.render(matrices, vertexConsumers.getBuffer(HORNS_GRAY), light, OverlayTexture.DEFAULT_UV); 66 | } else if (hornColour.equalsIgnoreCase("black")) { 67 | horns.render(matrices, vertexConsumers.getBuffer(HORNS_BLACK), light, OverlayTexture.DEFAULT_UV); 68 | } else if (hornColour.equalsIgnoreCase("beige")) { 69 | horns.render(matrices, vertexConsumers.getBuffer(HORNS_BEIGE), light, OverlayTexture.DEFAULT_UV); 70 | } 71 | } 72 | 73 | matrices.pop(); 74 | } 75 | } 76 | } 77 | 78 | private static TexturedModelData getTexturedModelData() { 79 | ModelData modelData = new ModelData(); 80 | ModelPartData modelPartData = modelData.getRoot(); 81 | 82 | modelPartData.addChild(EntityModelPartNames.HEAD, 83 | ModelPartBuilder.create() 84 | .uv(0, 0).cuboid(3.0f, -3.5f, -3.0f, 4.0f, 7.0f, 6.0f) 85 | .uv(0, 13).cuboid(3.0f, 0.5f, -6.0f, 4.0f, 3.0f, 3.0f) 86 | .uv(0, 19).cuboid(-7.0f, -3.5f, -3.0f, 4.0f, 7.0f, 6.0f) 87 | .uv(14, 13).cuboid(-7.0f, 0.5f, -6.0f, 4.0f, 3.0f, 3.0f), 88 | ModelTransform.pivot(0.0f, -1.5f, -2.1f)); 89 | return TexturedModelData.of(modelData, 32, 32); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/SheepVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.SheepHornSettings; 5 | import com.github.nyuppo.config.Variants; 6 | import com.github.nyuppo.networking.ServerRespondVariantPayload; 7 | import com.github.nyuppo.variant.MobVariant; 8 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 9 | import net.minecraft.entity.Entity; 10 | import net.minecraft.entity.EntityData; 11 | import net.minecraft.entity.EntityType; 12 | import net.minecraft.entity.SpawnReason; 13 | import net.minecraft.entity.passive.PassiveEntity; 14 | import net.minecraft.entity.passive.SheepEntity; 15 | import net.minecraft.nbt.NbtCompound; 16 | import net.minecraft.server.MinecraftServer; 17 | import net.minecraft.server.world.ServerWorld; 18 | import net.minecraft.util.Identifier; 19 | import net.minecraft.world.LocalDifficulty; 20 | import net.minecraft.world.ServerWorldAccess; 21 | import org.jetbrains.annotations.Nullable; 22 | import org.spongepowered.asm.mixin.Mixin; 23 | import org.spongepowered.asm.mixin.injection.At; 24 | import org.spongepowered.asm.mixin.injection.Inject; 25 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 26 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 27 | 28 | @Mixin(SheepEntity.class) 29 | public abstract class SheepVariantsMixin extends MobEntityVariantsMixin { 30 | private MobVariant variant = Variants.getDefaultVariant(EntityType.SHEEP); 31 | private String hornColour = ""; 32 | 33 | @Override 34 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 35 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 36 | nbt.putString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY, hornColour); 37 | } 38 | 39 | @Override 40 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 41 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 42 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 43 | variant = Variants.getVariant(EntityType.SHEEP, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 44 | } else { 45 | variant = Variants.getVariant(EntityType.SHEEP, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 46 | } 47 | } else { 48 | variant = Variants.getRandomVariant(EntityType.SHEEP, ((SheepEntity)(Object)this).getRandom().nextLong(), ((SheepEntity)(Object)this).getWorld().getBiome(((SheepEntity)(Object)this).getBlockPos()), null, ((SheepEntity)(Object)this).getWorld().getMoonSize()); 49 | } 50 | hornColour = nbt.getString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY); 51 | 52 | // Update all players in the event that this is from modifying entity data with a command 53 | // This should be fine since the packet is so small anyways 54 | MinecraftServer server = ((Entity)(Object)this).getServer(); 55 | if (server != null) { 56 | server.getPlayerManager().getPlayerList().forEach((player) -> { 57 | ServerPlayNetworking.send(player, new ServerRespondVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString(), false, 0, hornColour)); 58 | }); 59 | } 60 | } 61 | 62 | @Override 63 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 64 | variant = Variants.getRandomVariant(EntityType.SHEEP, ((SheepEntity)(Object)this).getRandom().nextLong(), world.getBiome(((SheepEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 65 | 66 | SheepHornSettings.SheepHornColour colour = SheepHornSettings.getRandomSheepHornColour(((SheepEntity)(Object)this).getRandom(), world.getBiome(((SheepEntity)(Object)this).getBlockPos())); 67 | if (colour != null) { 68 | hornColour = colour.getId(); 69 | } 70 | } 71 | 72 | @Inject( 73 | method = "createChild(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/entity/passive/PassiveEntity;)Lnet/minecraft/entity/passive/SheepEntity;", 74 | at = @At("RETURN") 75 | ) 76 | private void onCreateChild(ServerWorld world, PassiveEntity entity, CallbackInfoReturnable ci) { 77 | SheepEntity child = ci.getReturnValue(); 78 | 79 | MobVariant variant = Variants.getChildVariant(EntityType.SHEEP, world, ((SheepEntity)(Object)this), entity); 80 | 81 | // Determine horn colour 82 | NbtCompound nbtParent1 = new NbtCompound(); 83 | ((SheepEntity)(Object)this).writeCustomDataToNbt(nbtParent1); 84 | NbtCompound nbtParent2 = new NbtCompound(); 85 | entity.writeCustomDataToNbt(nbtParent2); 86 | 87 | String colour = ""; 88 | if (nbtParent1.contains(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY) 89 | && !nbtParent1.getString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY).isEmpty() 90 | && nbtParent2.contains(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY) 91 | && !nbtParent2.getString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY).isEmpty() 92 | && entity.getRandom().nextDouble() <= SheepHornSettings.getInheritChance()) { 93 | colour = entity.getRandom().nextBoolean() ? nbtParent1.getString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY) : nbtParent2.getString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY); 94 | } else { 95 | SheepHornSettings.SheepHornColour col = SheepHornSettings.getRandomSheepHornColour(entity.getRandom(), world.getBiome(((SheepEntity)(Object)this).getBlockPos())); 96 | if (col != null) { 97 | colour = col.getId(); 98 | } 99 | } 100 | 101 | // Write variant to child's NBT 102 | NbtCompound childNbt = new NbtCompound(); 103 | child.writeNbt(childNbt); 104 | childNbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 105 | childNbt.putString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY, colour); 106 | child.readCustomDataFromNbt(childNbt); 107 | } 108 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/mixin/PigVariantsMixin.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.mixin; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import com.github.nyuppo.config.VariantSettings; 5 | import com.github.nyuppo.config.Variants; 6 | import com.github.nyuppo.networking.ServerRespondVariantPayload; 7 | import com.github.nyuppo.variant.MobVariant; 8 | import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; 9 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 10 | import net.minecraft.entity.Entity; 11 | import net.minecraft.entity.EntityData; 12 | import net.minecraft.entity.EntityType; 13 | import net.minecraft.entity.SpawnReason; 14 | import net.minecraft.entity.passive.*; 15 | import net.minecraft.nbt.NbtCompound; 16 | import net.minecraft.network.PacketByteBuf; 17 | import net.minecraft.registry.tag.BiomeTags; 18 | import net.minecraft.server.MinecraftServer; 19 | import net.minecraft.server.world.ServerWorld; 20 | import net.minecraft.util.Identifier; 21 | import net.minecraft.world.LocalDifficulty; 22 | import net.minecraft.world.ServerWorldAccess; 23 | import org.jetbrains.annotations.Nullable; 24 | import org.spongepowered.asm.mixin.Mixin; 25 | import org.spongepowered.asm.mixin.injection.At; 26 | import org.spongepowered.asm.mixin.injection.Inject; 27 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 28 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 29 | 30 | @Mixin(PigEntity.class) 31 | public abstract class PigVariantsMixin extends MobEntityVariantsMixin { 32 | private MobVariant variant = Variants.getDefaultVariant(EntityType.COW); 33 | private boolean isMuddy = false; 34 | private int muddyTimeLeft = -1; 35 | 36 | @Override 37 | protected void onWriteCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { 38 | nbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 39 | nbt.putBoolean(MoreMobVariants.MUDDY_NBT_KEY, isMuddy); 40 | nbt.putInt(MoreMobVariants.MUDDY_TIMEOUT_NBT_KEY, muddyTimeLeft); 41 | } 42 | 43 | @Override 44 | protected void onReadCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { 45 | if (!nbt.getString(MoreMobVariants.NBT_KEY).isEmpty()) { 46 | if (nbt.getString(MoreMobVariants.NBT_KEY).contains(":")) { 47 | variant = Variants.getVariant(EntityType.PIG, Identifier.of(nbt.getString(MoreMobVariants.NBT_KEY))); 48 | } else { 49 | variant = Variants.getVariant(EntityType.PIG, MoreMobVariants.id(nbt.getString(MoreMobVariants.NBT_KEY))); 50 | } 51 | } else { 52 | variant = Variants.getRandomVariant(EntityType.PIG, ((PigEntity)(Object)this).getRandom().nextLong(), ((PigEntity)(Object)this).getWorld().getBiome(((PigEntity)(Object)this).getBlockPos()), null, ((PigEntity)(Object)this).getWorld().getMoonSize()); 53 | } 54 | isMuddy = nbt.getBoolean(MoreMobVariants.MUDDY_NBT_KEY); 55 | muddyTimeLeft = nbt.getInt(MoreMobVariants.MUDDY_TIMEOUT_NBT_KEY); 56 | 57 | // Update all players in the event that this is from modifying entity data with a command 58 | // This should be fine since the packet is so small anyways 59 | MinecraftServer server = ((Entity)(Object)this).getServer(); 60 | if (server != null) { 61 | server.getPlayerManager().getPlayerList().forEach((player) -> { 62 | ServerPlayNetworking.send(player, new ServerRespondVariantPayload(((Entity)(Object)this).getId(), variant.getIdentifier().toString(), isMuddy, muddyTimeLeft, "")); 63 | }); 64 | } 65 | } 66 | 67 | @Override 68 | protected void onInitialize(ServerWorldAccess world, LocalDifficulty difficulty, SpawnReason spawnReason, @Nullable EntityData entityData, CallbackInfoReturnable ci) { 69 | variant = Variants.getRandomVariant(EntityType.PIG, ((PigEntity)(Object)this).getRandom().nextLong(), world.getBiome(((PigEntity)(Object)this).getBlockPos()), null, world.getMoonSize()); 70 | 71 | // 2% chance of pig starting muddy if in swamp 72 | if (world.getBiome(((PigEntity)(Object)this).getBlockPos()).isIn(BiomeTags.RUINED_PORTAL_SWAMP_HAS_STRUCTURE) && world.getRandom().nextDouble() < 0.02) { 73 | isMuddy = true; 74 | } 75 | } 76 | 77 | @Override 78 | protected void onTick(CallbackInfo ci) { 79 | // Handle muddy pigs 80 | if (VariantSettings.getEnableMuddyPigs()) { 81 | int muddyPigTimeout = VariantSettings.getMuddyPigTimeout(); 82 | 83 | if (muddyTimeLeft == -1) { 84 | if (((PigEntity)(Object)this).getWorld().getBlockState(((PigEntity)(Object)this).getBlockPos()).isIn(MoreMobVariants.PIG_MUD_BLOCKS) || ((PigEntity)(Object)this).getWorld().getBlockState(((PigEntity)(Object)this).getBlockPos().down()).isIn(MoreMobVariants.PIG_MUD_BLOCKS)) { 85 | isMuddy = true; 86 | if (muddyPigTimeout > 0 ) { 87 | muddyTimeLeft = 20 * muddyPigTimeout; 88 | } 89 | } else if (((PigEntity)(Object)this).isTouchingWaterOrRain()) { 90 | isMuddy = false; 91 | muddyTimeLeft = -1; 92 | } 93 | } 94 | 95 | if (muddyPigTimeout > 0 && muddyTimeLeft > 0) { 96 | muddyTimeLeft--; 97 | if (muddyTimeLeft == 0) { 98 | isMuddy = false; 99 | muddyTimeLeft = -1; 100 | } 101 | } 102 | } 103 | } 104 | 105 | @Inject( 106 | method = "createChild(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/entity/passive/PassiveEntity;)Lnet/minecraft/entity/passive/PigEntity;", 107 | at = @At("RETURN") 108 | ) 109 | private void onCreateChild(ServerWorld world, PassiveEntity entity, CallbackInfoReturnable ci) { 110 | PigEntity child = ci.getReturnValue(); 111 | 112 | MobVariant variant = Variants.getChildVariant(EntityType.PIG, world, ((PigEntity)(Object)this), entity); 113 | 114 | // Write variant to child's NBT 115 | NbtCompound childNbt = new NbtCompound(); 116 | child.writeNbt(childNbt); 117 | childNbt.putString(MoreMobVariants.NBT_KEY, variant.getIdentifier().toString()); 118 | child.readCustomDataFromNbt(childNbt); 119 | } 120 | } -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/variant/MobVariant.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo.variant; 2 | 3 | import com.github.nyuppo.MoreMobVariants; 4 | import net.minecraft.registry.entry.RegistryEntry; 5 | import net.minecraft.util.Identifier; 6 | import net.minecraft.util.math.random.Random; 7 | import net.minecraft.world.biome.Biome; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class MobVariant { 13 | private final Identifier identifier; 14 | private final int weight; 15 | private final List modifiers; 16 | 17 | public MobVariant(Identifier identifier, int weight) { 18 | this.identifier = identifier; 19 | this.weight = weight; 20 | this.modifiers = new ArrayList(); 21 | } 22 | 23 | public MobVariant(Identifier identifier, int weight, List modifiers) { 24 | this.identifier = identifier; 25 | this.weight = weight; 26 | this.modifiers = modifiers; 27 | } 28 | 29 | public MobVariant addModifier(VariantModifier modifier) { 30 | this.modifiers.add(modifier); 31 | return this; 32 | } 33 | 34 | public Identifier getIdentifier() { 35 | return this.hasCustomVariantName() ? this.getCustomVariantName() : this.identifier; 36 | } 37 | 38 | public Identifier getRawIdentifier() { 39 | return this.identifier; 40 | } 41 | 42 | public int getWeight() { 43 | return this.weight; 44 | } 45 | 46 | public boolean isShiny() { 47 | for (VariantModifier modifier : this.modifiers) { 48 | if (modifier instanceof ShinyModifier) { 49 | return true; 50 | } 51 | } 52 | return false; 53 | } 54 | 55 | public boolean hasCustomVariantName() { 56 | for (VariantModifier modifier : this.modifiers) { 57 | if (modifier instanceof CustomVariantNameModifier) { 58 | return true; 59 | } 60 | } 61 | return false; 62 | } 63 | 64 | public Identifier getCustomVariantName() { 65 | for (VariantModifier modifier : this.modifiers) { 66 | if (modifier instanceof CustomVariantNameModifier) { 67 | return Identifier.of(this.identifier.getNamespace(), ((CustomVariantNameModifier) modifier).variantName()); 68 | } 69 | } 70 | 71 | return MoreMobVariants.id("default"); 72 | } 73 | 74 | public boolean shouldDiscard(Random random) { 75 | for (VariantModifier modifier : this.modifiers) { 76 | if (modifier instanceof DiscardableModifier) { 77 | return ((DiscardableModifier) modifier).shouldDiscard(random); 78 | } 79 | } 80 | return false; 81 | } 82 | 83 | public boolean isInSpawnBiome(RegistryEntry biome) { 84 | for (VariantModifier modifier : this.modifiers) { 85 | if (modifier instanceof SpawnableBiomesModifier) { 86 | return ((SpawnableBiomesModifier) modifier).canSpawnInBiome(biome); 87 | } 88 | } 89 | return true; 90 | } 91 | 92 | public boolean canBreed(MobVariant parent1, MobVariant parent2) { 93 | for (VariantModifier modifier : this.modifiers) { 94 | if (modifier instanceof BreedingResultModifier) { 95 | return ((BreedingResultModifier) modifier).validParents(parent1, parent2); 96 | } 97 | } 98 | return false; 99 | } 100 | 101 | public boolean shouldBreed(Random random) { 102 | for (VariantModifier modifier : this.modifiers) { 103 | if (modifier instanceof BreedingResultModifier) { 104 | return ((BreedingResultModifier) modifier).shouldBreed(random); 105 | } 106 | } 107 | return false; 108 | } 109 | 110 | public boolean hasSpawnableBiomeModifier() { 111 | for (VariantModifier modifier : this.modifiers) { 112 | if (modifier instanceof SpawnableBiomesModifier) { 113 | return true; 114 | } 115 | } 116 | 117 | return false; 118 | } 119 | 120 | public boolean hasBreedingResultModifier() { 121 | for (VariantModifier modifier : this.modifiers) { 122 | if (modifier instanceof BreedingResultModifier) { 123 | return true; 124 | } 125 | } 126 | 127 | return false; 128 | } 129 | 130 | public boolean hasCustomEyes() { 131 | for (VariantModifier modifier : this.modifiers) { 132 | if (modifier instanceof CustomEyesModifier) { 133 | return true; 134 | } 135 | } 136 | return false; 137 | } 138 | 139 | public boolean hasCustomWool() { 140 | for (VariantModifier modifier : this.modifiers) { 141 | if (modifier instanceof CustomWoolModifier) { 142 | return true; 143 | } 144 | } 145 | return false; 146 | } 147 | 148 | public boolean hasColorWhenSheared() { 149 | for (VariantModifier modifier : this.modifiers) { 150 | if (modifier instanceof ShearedWoolColorModifier) { 151 | return true; 152 | } 153 | } 154 | return false; 155 | } 156 | 157 | public boolean isNametagOverride() { 158 | for (VariantModifier modifier : this.modifiers) { 159 | if (modifier instanceof NametagOverrideModifier) { 160 | return true; 161 | } 162 | } 163 | return false; 164 | } 165 | 166 | public String getNametagOverride() { 167 | for (VariantModifier modifier : this.modifiers) { 168 | if (modifier instanceof NametagOverrideModifier) { 169 | return ((NametagOverrideModifier)modifier).nametag(); 170 | } 171 | } 172 | return "error"; 173 | } 174 | 175 | public boolean hasMinimumMoonSize() { 176 | for (VariantModifier modifier : this.modifiers) { 177 | if (modifier instanceof MoonPhaseModifier) { 178 | return true; 179 | } 180 | } 181 | return false; 182 | } 183 | 184 | public boolean meetsMinimumMoonSize(float moonSize) { 185 | for (VariantModifier modifier : this.modifiers) { 186 | if (modifier instanceof MoonPhaseModifier) { 187 | return ((MoonPhaseModifier) modifier).canSpawn(moonSize); 188 | } 189 | } 190 | return false; 191 | } 192 | } 193 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/MoreMobVariantsClient.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo; 2 | 3 | import com.github.nyuppo.client.render.entity.feature.PigMudFeatureRenderer; 4 | import com.github.nyuppo.client.render.entity.feature.ShearedWoolColorFeatureRenderer; 5 | import com.github.nyuppo.client.render.entity.feature.SheepHornsFeatureRenderer; 6 | import com.github.nyuppo.networking.ClientRequestVariantPayload; 7 | import com.github.nyuppo.networking.MMVNetworkingConstants; 8 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 9 | import com.github.nyuppo.networking.ServerRespondVariantPayload; 10 | import net.fabricmc.api.ClientModInitializer; 11 | import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents; 12 | import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; 13 | import net.fabricmc.fabric.api.client.rendering.v1.LivingEntityFeatureRendererRegistrationCallback; 14 | import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; 15 | import net.minecraft.client.render.entity.PigEntityRenderer; 16 | import net.minecraft.client.render.entity.SheepEntityRenderer; 17 | import net.minecraft.client.render.entity.feature.FeatureRendererContext; 18 | import net.minecraft.client.render.entity.model.PigEntityModel; 19 | import net.minecraft.client.render.entity.model.SheepEntityModel; 20 | import net.minecraft.entity.Entity; 21 | import net.minecraft.entity.EntityType; 22 | import net.minecraft.entity.passive.CatEntity; 23 | import net.minecraft.entity.passive.PigEntity; 24 | import net.minecraft.entity.passive.SheepEntity; 25 | import net.minecraft.entity.passive.TameableEntity; 26 | import net.minecraft.nbt.NbtCompound; 27 | import net.minecraft.network.PacketByteBuf; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | import java.util.Set; 32 | 33 | public class MoreMobVariantsClient implements ClientModInitializer { 34 | Set validEntities = Set.of(EntityType.CAT, EntityType.CHICKEN, EntityType.COW, EntityType.PIG, EntityType.SHEEP, EntityType.SKELETON, EntityType.SPIDER, EntityType.WOLF, EntityType.ZOMBIE); 35 | 36 | @Override 37 | public void onInitializeClient() { 38 | // Add render layers 39 | LivingEntityFeatureRendererRegistrationCallback.EVENT.register((entityType, entityRenderer, registrationHelper, context) -> { 40 | if (entityRenderer instanceof PigEntityRenderer) { 41 | registrationHelper.register(new PigMudFeatureRenderer>((FeatureRendererContext)entityRenderer)); 42 | } else if (entityRenderer instanceof SheepEntityRenderer) { 43 | registrationHelper.register(new ShearedWoolColorFeatureRenderer>((FeatureRendererContext)entityRenderer)); 44 | registrationHelper.register(new SheepHornsFeatureRenderer>((FeatureRendererContext)entityRenderer)); 45 | } 46 | }); 47 | 48 | // Client event to request variant when a mob is loaded 49 | ClientEntityEvents.ENTITY_LOAD.register((entity, world) -> { 50 | // Check if entity can have variants so we don't make useless requests 51 | if (validEntities.contains(entity.getType())) { 52 | ClientPlayNetworking.send(new ClientRequestVariantPayload(entity.getUuid())); 53 | } 54 | }); 55 | 56 | // Client event to handle response from server about basic mob variants 57 | ClientPlayNetworking.registerGlobalReceiver(ServerRespondBasicVariantPayload.ID, ((payload, context) -> { 58 | var client = context.client(); 59 | int id = payload.entityId(); 60 | String variantId = payload.variantId(); 61 | client.execute(() -> { 62 | if (client.world != null) { 63 | Entity entity = client.world.getEntityById(id); 64 | if (entity != null) { 65 | NbtCompound nbt = new NbtCompound(); 66 | entity.writeNbt(nbt); 67 | nbt.putString(MoreMobVariants.NBT_KEY, variantId); 68 | entity.readNbt(nbt); 69 | } 70 | } 71 | }); 72 | })); 73 | 74 | 75 | // Client event to handle response from server about complex mob variants 76 | ClientPlayNetworking.registerGlobalReceiver(ServerRespondVariantPayload.ID, ((payload, context) -> { 77 | var client = context.client(); 78 | int id = payload.entityId(); 79 | String variantId = payload.variant(); 80 | 81 | //read all three buffer values regardless, in the Netty loop. use as needed in the client. 82 | boolean bl = payload.sittingOrMuddy(); 83 | int i = payload.muddyTimeout(); 84 | String str = payload.sheepHornColour(); 85 | 86 | client.execute(() -> { 87 | if (client.world != null) { 88 | Entity entity = client.world.getEntityById(id); 89 | if (entity != null) { 90 | NbtCompound nbt = new NbtCompound(); 91 | entity.writeNbt(nbt); 92 | 93 | nbt.putString(MoreMobVariants.NBT_KEY, variantId); 94 | 95 | // For some reason, "Sitting" syncing breaks, so get that too I guess 96 | if (entity instanceof TameableEntity) { 97 | nbt.putBoolean("Sitting",bl); 98 | } 99 | 100 | // Muddy pigs 101 | boolean isMuddy; 102 | int muddyTimeLeft; 103 | if (entity instanceof PigEntity) { 104 | isMuddy = bl; 105 | muddyTimeLeft = i; 106 | 107 | nbt.putBoolean(MoreMobVariants.MUDDY_NBT_KEY, isMuddy); 108 | nbt.putInt(MoreMobVariants.MUDDY_TIMEOUT_NBT_KEY, muddyTimeLeft); 109 | } 110 | 111 | // Sheep horns 112 | String hornColour; 113 | if (entity instanceof SheepEntity) { 114 | hornColour = str; 115 | 116 | nbt.putString(MoreMobVariants.SHEEP_HORN_COLOUR_NBT_KEY, hornColour); 117 | } 118 | 119 | entity.readNbt(nbt); 120 | } 121 | } 122 | }); 123 | })); 124 | } 125 | 126 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /src/main/java/com/github/nyuppo/MoreMobVariants.java: -------------------------------------------------------------------------------- 1 | package com.github.nyuppo; 2 | 3 | import com.github.nyuppo.config.ConfigDataLoader; 4 | import com.github.nyuppo.networking.ClientRequestVariantPayload; 5 | import com.github.nyuppo.networking.MMVNetworkingConstants; 6 | import com.github.nyuppo.networking.ServerRespondBasicVariantPayload; 7 | import com.github.nyuppo.networking.ServerRespondVariantPayload; 8 | import net.fabricmc.api.ModInitializer; 9 | import net.fabricmc.fabric.api.biome.v1.BiomeModifications; 10 | import net.fabricmc.fabric.api.biome.v1.BiomeSelectors; 11 | import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; 12 | import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; 13 | import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; 14 | import net.fabricmc.fabric.api.resource.ResourceManagerHelper; 15 | import net.minecraft.block.Block; 16 | import net.minecraft.entity.Entity; 17 | import net.minecraft.entity.EntityType; 18 | import net.minecraft.entity.SpawnGroup; 19 | import net.minecraft.entity.passive.PigEntity; 20 | import net.minecraft.entity.passive.SheepEntity; 21 | import net.minecraft.entity.passive.TameableEntity; 22 | import net.minecraft.nbt.NbtCompound; 23 | import net.minecraft.network.PacketByteBuf; 24 | import net.minecraft.registry.RegistryKeys; 25 | import net.minecraft.registry.tag.TagKey; 26 | import net.minecraft.resource.ResourceType; 27 | import net.minecraft.server.world.ServerWorld; 28 | import net.minecraft.util.Identifier; 29 | import net.minecraft.world.biome.Biome; 30 | import org.slf4j.Logger; 31 | import org.slf4j.LoggerFactory; 32 | 33 | import java.util.UUID; 34 | 35 | public class MoreMobVariants implements ModInitializer { 36 | public static final String MOD_ID = "moremobvariants"; 37 | public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); 38 | 39 | // NBT keys 40 | public static final String NBT_KEY = "VariantID"; 41 | public static final String MUDDY_NBT_KEY = "IsMuddy"; // Muddy pigs 42 | public static final String MUDDY_TIMEOUT_NBT_KEY = "MuddyTimeLeft"; // Muddy pigs 43 | public static final String SHEEP_HORN_COLOUR_NBT_KEY = "HornColour"; 44 | 45 | // Pig mud tag 46 | public static final TagKey PIG_MUD_BLOCKS = TagKey.of(RegistryKeys.BLOCK, Identifier.of(MOD_ID, "pig_mud_blocks")); 47 | 48 | // Biome tags 49 | public static final TagKey SPAWN_MOSSY_SKELETONS = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "spawn_mossy_skeletons")); 50 | public static final TagKey INCREASED_SANDY_SKELETONS = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "increased_sandy_skeletons")); 51 | public static final TagKey SHEEP_SPAWN_WITH_HORNS = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "sheep_spawn_with_horns")); 52 | public static final TagKey SPAWN_PALE_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_pale_spawns")); 53 | public static final TagKey SPAWN_RUSTY_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_rusty_spawns")); 54 | public static final TagKey SPAWN_SPOTTED_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_spotted_spawns")); 55 | public static final TagKey SPAWN_BLACK_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_black_spawns")); 56 | public static final TagKey SPAWN_STRIPED_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_striped_spawns")); 57 | public static final TagKey SPAWN_SNOWY_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_snowy_spawns")); 58 | public static final TagKey SPAWN_ASHEN_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_ashen_spawns")); 59 | public static final TagKey SPAWN_WOODS_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_woods_spawns")); 60 | public static final TagKey SPAWN_CHESTNUT_WOLF = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "wolf_chestnut_spawns")); 61 | public static final TagKey ADDITIONAL_WOLF_SPAWNS = TagKey.of(RegistryKeys.BIOME, Identifier.of(MOD_ID, "additional_wolf_spawns")); 62 | 63 | @Override 64 | public void onInitialize() { 65 | LOGGER.info("Giving mobs a fresh coat of paint..."); 66 | 67 | // Config 68 | ResourceManagerHelper.get(ResourceType.SERVER_DATA).registerReloadListener(new ConfigDataLoader()); 69 | 70 | // Make wolves spawn in more biomes 71 | BiomeModifications.addSpawn(BiomeSelectors.tag(ADDITIONAL_WOLF_SPAWNS), SpawnGroup.CREATURE, EntityType.WOLF, 5, 4, 4); 72 | 73 | // Register payloads 74 | PayloadTypeRegistry.playC2S().register(ClientRequestVariantPayload.ID, ClientRequestVariantPayload.PACKET_CODEC); 75 | PayloadTypeRegistry.playS2C().register(ServerRespondBasicVariantPayload.ID, ServerRespondBasicVariantPayload.PACKET_CODEC); 76 | PayloadTypeRegistry.playS2C().register(ServerRespondVariantPayload.ID, ServerRespondVariantPayload.PACKET_CODEC); 77 | 78 | // Server event to respond to client request for a variant 79 | ServerPlayNetworking.registerGlobalReceiver(ClientRequestVariantPayload.ID, ((payload, context) -> { 80 | var server = context.server(); 81 | var uuid = payload.uuid(); 82 | server.execute( () -> { 83 | Entity entity = server.getOverworld().getEntity(uuid); 84 | 85 | // If we couldn't find the mob in the overworld, start checking all other worlds 86 | if (entity == null) { 87 | for (ServerWorld serverWorld : server.getWorlds()) { 88 | Entity entity2 = serverWorld.getEntity(uuid); 89 | if (entity2 != null) { 90 | entity = entity2; 91 | } 92 | } 93 | } 94 | 95 | if (entity != null) { 96 | NbtCompound nbt = new NbtCompound(); 97 | entity.writeNbt(nbt); 98 | 99 | if (nbt.contains(NBT_KEY)) { 100 | //going to pass all three of these regardless, so buf structure is constant. More cases can be added and hook into these as needed. 101 | boolean bl = false; 102 | int i = 0; 103 | String str = ""; 104 | 105 | // For some reason, "Sitting" syncing breaks, so send that too I guess 106 | if (entity instanceof TameableEntity) { 107 | bl = nbt.getBoolean("Sitting"); 108 | } 109 | 110 | // Muddy pigs 111 | if (entity instanceof PigEntity) { 112 | bl = nbt.getBoolean(MUDDY_NBT_KEY); 113 | i = nbt.getInt(MUDDY_TIMEOUT_NBT_KEY); 114 | } 115 | 116 | // Sheep horns 117 | if (entity instanceof SheepEntity) { 118 | str = nbt.getString(SHEEP_HORN_COLOUR_NBT_KEY); 119 | } 120 | 121 | var responsePayload = new ServerRespondVariantPayload(entity.getId(), nbt.getString(NBT_KEY), bl, i, str); 122 | ServerPlayNetworking.send(context.player(), responsePayload); 123 | } 124 | } 125 | }); 126 | })); 127 | } 128 | 129 | public static Identifier id(String path) { 130 | return Identifier.of(MOD_ID, path); 131 | } 132 | } --------------------------------------------------------------------------------