diff --git a/build.gradle b/build.gradle index b08fe57..4bea491 100644 --- a/build.gradle +++ b/build.gradle @@ -1,8 +1,21 @@ plugins { id 'architectury-plugin' version "${architect_plugin_version}" - id 'dev.architectury.loom' version "${architectury_loom_version}" apply false + id 'dev.architectury.loom' version "${architectury_loom_version}" } +architectury { + minecraft = project.minecraft_version + common(project.enabled_platforms.split(',')) +} + +loom { + runConfigs.configureEach { + ideConfigGenerated = true + } +} + +sourceSets.main.resources.srcDir 'src/main/generated' + allprojects { apply plugin: 'architectury-plugin' apply plugin: 'dev.architectury.loom' @@ -20,6 +33,12 @@ allprojects { } repositories { + repositories { + maven { + name = 'Mod Menu' + url = 'https://maven.terraformersmc.com/releases' + } + } } dependencies { @@ -38,6 +57,7 @@ allprojects { developmentForge.extendsFrom common developmentFabric.extendsFrom common developmentNeoForge.extendsFrom common + developmentQuilt.extendsFrom common } def targetJavaVersion = 17 @@ -68,6 +88,7 @@ allprojects { var replaceTokens = [ minecraft_version: minecraft_version, mod_version: mod_version, + forge_loader_version: forge_loader_version, forge_version: forge_version, fabric_loader_version: fabric_loader_version, fabric_api_version: fabric_api_version, @@ -104,9 +125,3 @@ allprojects { } } } - -architectury { - common(project.enabled_platforms.split(',')) -} - -sourceSets.main.resources.srcDir 'src/main/generated' diff --git a/catsplus-fabric/build.gradle b/catsplus-fabric/build.gradle index 1313aac..6e8ff35 100644 --- a/catsplus-fabric/build.gradle +++ b/catsplus-fabric/build.gradle @@ -31,6 +31,8 @@ dependencies { modApi "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" modApi "dev.architectury:architectury-fabric:${project.architectury_version}" + modRuntimeOnly "com.terraformersmc:modmenu:${project.mod_menu_version}" + common(project(path: ':', configuration: 'namedElements')) { transitive = false } shadowCommon(project(path: ':', configuration: 'transformProductionFabric')) { transitive = false } } diff --git a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/CatsPlusFabric.java b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/CatsPlusFabric.java index f9f6730..3401276 100644 --- a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/CatsPlusFabric.java +++ b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/CatsPlusFabric.java @@ -1,9 +1,13 @@ package cuteneko.catsplus.fabric; import cuteneko.catsplus.CatsPlus; +import cuteneko.catsplus.item.ModItems; +import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; +import net.minecraft.item.DyeableItem; -public class CatsPlusFabric implements ModInitializer { +public class CatsPlusFabric implements ModInitializer, ClientModInitializer { private final CatsPlus mod; public CatsPlusFabric() { @@ -14,4 +18,14 @@ public CatsPlusFabric() { public void onInitialize() { mod.init(); } + + @Override + public void onInitializeClient() { + mod.initClient(); + + ColorProviderRegistry.ITEM.register( + ((stack, tintIndex) -> tintIndex > 0 ? -1 : ((DyeableItem) stack.getItem()).getColor(stack)), + ModItems.CAT_BAG.get() + ); + } } diff --git a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/client/CatsPlusFabricClient.java b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/client/CatsPlusFabricClient.java deleted file mode 100644 index 564319b..0000000 --- a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/client/CatsPlusFabricClient.java +++ /dev/null @@ -1,45 +0,0 @@ -package cuteneko.catsplus.fabric.client; - -import cuteneko.catsplus.item.ModItems; -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; -import net.minecraft.client.item.ModelPredicateProviderRegistry; -import net.minecraft.item.DyeableItem; -import net.minecraft.util.Identifier; - -import java.util.Objects; - -public class CatsPlusFabricClient implements ClientModInitializer { - @Override - public void onInitializeClient() { - ModelPredicateProviderRegistry.register( - ModItems.CAT_BAG.get(), - new Identifier("catsplus", "cat"), - (itemStack, clientWorld, livingEntity, index) -> { - if(!itemStack.hasNbt() || !Objects.requireNonNull(itemStack.getNbt()).contains("Cat")) { - return 0F; - } - - var nbt = itemStack.getNbt().getCompound("Cat"); - return switch (nbt.getString("variant")) { - case "minecraft:tabby" -> 0.05F; - case "minecraft:black" -> 0.1F; - case "minecraft:red" -> 0.15F; - case "minecraft:siamese" -> 0.2F; - case "minecraft:british_shorthair" -> 0.25F; - case "minecraft:calico" -> 0.3F; - case "minecraft:persian" -> 0.35F; - case "minecraft:ragdoll" -> 0.4F; - case "minecraft:white" -> 0.45F; - case "minecraft:jellie" -> 0.5F; - case "minecraft:all_black" -> 0.55F; - default -> 1F; - }; - }); - - ColorProviderRegistry.ITEM.register( - ((stack, tintIndex) -> tintIndex > 0 ? -1 : ((DyeableItem) stack.getItem()).getColor(stack)), - ModItems.CAT_BAG.get() - ); - } -} diff --git a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/data/GeniusCatFabric.java b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/data/GeniusCatFabric.java index e2f8b56..f8727d0 100644 --- a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/data/GeniusCatFabric.java +++ b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/data/GeniusCatFabric.java @@ -26,11 +26,6 @@ public void setTotem(boolean totem) { ((ICatEntityMixin) cat).catsplus$setTotem(totem); } - @Override - public boolean canRespawn() { - return hasTotem() || getLives() > 0; - } - @Override public int getFavorability(PlayerEntity player) { return ((ICatEntityMixin) cat).catsplus$getFavorability(player); @@ -40,25 +35,18 @@ public int getFavorability(PlayerEntity player) { public void setFavorability(int favorability, PlayerEntity player) { ((ICatEntityMixin) cat).catsplus$setFavorability(favorability, player); - if (cat.isOwner(player) && getFavorability(player) <= 0) { + if (getFavorability(player) <= 0) { cat.tryAttack(player); - cat.setOwnerUuid(null); - cat.setTamed(false); - cat.setSitting(false); - setLives(0); - cat.onTamedChanged(); cat.getWorld().sendEntityStatus(cat, EntityStatuses.ADD_VILLAGER_ANGRY_PARTICLES); - } - } - @Override - public void addFavorability(int value, PlayerEntity player) { - setFavorability(getFavorability(player) + value, player); - } - - @Override - public void subFavorability(int value, PlayerEntity player) { - setFavorability(getFavorability(player) - value, player); + if (cat.isOwner(player)) { + cat.setOwnerUuid(null); + cat.setTamed(false); + cat.setSitting(false); + setLives(0); + cat.onTamedChanged(); + } + } } @Override diff --git a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/mixins/mixin/CatEntityMixin.java b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/mixins/mixin/CatEntityMixin.java index d1e57a2..2eea410 100644 --- a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/mixins/mixin/CatEntityMixin.java +++ b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/mixins/mixin/CatEntityMixin.java @@ -46,7 +46,7 @@ public abstract class CatEntityMixin implements ICatEntityMixin { @Override public int catsplus$getFavorability(PlayerEntity player) { - if (catsplus$favorability.containsKey(player.getUuid())) { + if (!catsplus$favorability.containsKey(player.getUuid())) { catsplus$favorability.put(player.getUuid(), 0); } @@ -109,12 +109,12 @@ private void write(NbtCompound nbt, CallbackInfo ci) { } tag.put(Constants.TAG_GENIUS_CAT_FAVORABILITY, favorability); - nbt.put(Constants.TAG_GENIUS_CAT_DATA, tag); + nbt.put(Constants.CAP_GENIUS_CAT.toString(), tag); } @Inject(method = "readCustomDataFromNbt", at = @At("HEAD")) private void read(NbtCompound nbt, CallbackInfo ci) { - var tag = nbt.getCompound(Constants.TAG_GENIUS_CAT_DATA); + var tag = nbt.getCompound(Constants.CAP_GENIUS_CAT.toString()); catsplus$lives = tag.getInt(Constants.TAG_GENIUS_CAT_LIVES); catsplus$hasTotem = tag.getBoolean(Constants.TAG_GENIUS_CAT_TOTEM); diff --git a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/mixins/mixin/PlayerEntityMixin.java b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/mixins/mixin/PlayerEntityMixin.java index 7f3a557..0246fd7 100644 --- a/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/mixins/mixin/PlayerEntityMixin.java +++ b/catsplus-fabric/src/main/java/cuteneko/catsplus/fabric/mixins/mixin/PlayerEntityMixin.java @@ -88,12 +88,12 @@ private void write(NbtCompound nbt, CallbackInfo ci) { tag.putBoolean(Constants.TAG_CAT_PLAYER_IS_CAT, catsplus$isCat); - nbt.put(Constants.TAG_CAT_PLAYER_DATA, tag); + nbt.put(Constants.CAP_CAT_PLAYER.toString(), tag); } @Inject(method = "readCustomDataFromNbt", at = @At("HEAD")) private void read(NbtCompound nbt, CallbackInfo ci) { - var tag = nbt.getCompound(Constants.TAG_CAT_PLAYER_DATA); + var tag = nbt.getCompound(Constants.CAP_CAT_PLAYER.toString()); var catTag = tag.getCompound(Constants.TAG_CAT_PLAYER_INNER_CAT); catsplus$getCatEntity().readNbt(catTag); diff --git a/catsplus-fabric/src/main/resources/fabric.mod.json b/catsplus-fabric/src/main/resources/fabric.mod.json index ddf9697..ac5e3a8 100644 --- a/catsplus-fabric/src/main/resources/fabric.mod.json +++ b/catsplus-fabric/src/main/resources/fabric.mod.json @@ -19,7 +19,7 @@ "environment": "*", "entrypoints": { "client": [ - "cuteneko.catsplus.fabric.client.CatsPlusFabricClient" + "cuteneko.catsplus.fabric.CatsPlusFabric" ], "main": [ "cuteneko.catsplus.fabric.CatsPlusFabric" diff --git a/catsplus-forge/build.gradle b/catsplus-forge/build.gradle new file mode 100644 index 0000000..8e0e790 --- /dev/null +++ b/catsplus-forge/build.gradle @@ -0,0 +1,62 @@ +plugins { + id 'com.github.johnrengelman.shadow' version "${shadow_plugin_version}" + id 'me.shedaniel.unified-publishing' version "${unified_publishing_version}" +} + +architectury { + platformSetupLoomIde() + forge() +} + +loom { + accessWidenerPath = project(':').loom.accessWidenerPath + + forge { + convertAccessWideners = true + extraAccessWideners.add loom.accessWidenerPath.get().asFile.name + } +} + +dependencies { + forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}" + modApi "dev.architectury:architectury-forge:${project.architectury_version}" + + common(project(path: ':', configuration: 'namedElements')) { transitive = false } + shadowCommon(project(path: ':', configuration: 'transformProductionFabric')) { transitive = false } +} + +shadowJar { + exclude 'fabric.mod.json' + exclude 'architectury.common.json' + + configurations = [project.configurations.shadowCommon] + archiveClassifier = 'dev-shadow' +} + +remapJar { + injectAccessWidener = true + input.set shadowJar.archiveFile + dependsOn shadowJar +} + +sourcesJar { + def commonSources = project(':').sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenFabric(MavenPublication) { + artifactId = project.name + version = "true".equalsIgnoreCase(System.getenv("MOD_RELEASE")) ? version : "${version}-SNAPSHOT" + from components.java + } + } +} diff --git a/catsplus-forge/gradle.properties b/catsplus-forge/gradle.properties new file mode 100644 index 0000000..8242585 --- /dev/null +++ b/catsplus-forge/gradle.properties @@ -0,0 +1 @@ +loom.platform=forge diff --git a/catsplus-forge/src/main/java/cuteneko/catsplus/forge/CatsPlusDataImpl.java b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/CatsPlusDataImpl.java new file mode 100644 index 0000000..e19dcb5 --- /dev/null +++ b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/CatsPlusDataImpl.java @@ -0,0 +1,17 @@ +package cuteneko.catsplus.forge; + +import cuteneko.catsplus.data.ICatPlayer; +import cuteneko.catsplus.data.IGeniusCat; +import cuteneko.catsplus.forge.capability.ModCapabilities; +import net.minecraft.entity.passive.CatEntity; +import net.minecraft.entity.player.PlayerEntity; + +public class CatsPlusDataImpl { + public static ICatPlayer getCatPlayer(PlayerEntity player) { + return player.getCapability(ModCapabilities.CAT_PLAYER).orElseThrow(RuntimeException::new); + } + + public static IGeniusCat getGeniusCat(CatEntity cat) { + return cat.getCapability(ModCapabilities.GENIUS_CAT).orElseThrow(RuntimeException::new); + } +} diff --git a/catsplus-forge/src/main/java/cuteneko/catsplus/forge/CatsPlusForge.java b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/CatsPlusForge.java new file mode 100644 index 0000000..cc7970d --- /dev/null +++ b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/CatsPlusForge.java @@ -0,0 +1,33 @@ +package cuteneko.catsplus.forge; + +import cuteneko.catsplus.CatsPlus; +import dev.architectury.platform.forge.EventBuses; +import net.minecraftforge.common.capabilities.CapabilityManager; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +@Mod(CatsPlus.MODID) +public class CatsPlusForge { + private final CatsPlus mod; + + public CatsPlusForge() { + mod = new CatsPlus(); + + var bus = FMLJavaModLoadingContext.get().getModEventBus(); + + bus.addListener(this::onSetup); + bus.addListener(this::onClientSetup); + + EventBuses.registerModEventBus(CatsPlus.MODID, bus); + } + + public void onSetup(FMLCommonSetupEvent event) { + mod.init(); + } + + public void onClientSetup(FMLClientSetupEvent event) { + event.enqueueWork(mod::initClient); + } +} diff --git a/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/CatPlayerCapability.java b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/CatPlayerCapability.java new file mode 100644 index 0000000..34a923e --- /dev/null +++ b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/CatPlayerCapability.java @@ -0,0 +1,88 @@ +package cuteneko.catsplus.forge.capability; + +import cuteneko.catsplus.data.ICatPlayer; +import cuteneko.catsplus.utility.Constants; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.passive.CatEntity; +import net.minecraft.entity.passive.CatVariant; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.registry.Registries; +import net.minecraftforge.common.util.INBTSerializable; + +public class CatPlayerCapability implements ICatPlayer, INBTSerializable { + private CatEntity catEntity = null; + private boolean isCat = false; + + public CatPlayerCapability(PlayerEntity player) { + init(player); + } + + private void init(PlayerEntity player) { + int variant = (int) (player.getUuid().getLeastSignificantBits() % 11); + + if (variant < 0) { + variant += 11; + } + + var key = switch (variant) { + case 0 -> CatVariant.TABBY; + case 1 -> CatVariant.BLACK; + case 2 -> CatVariant.RED; + case 3 -> CatVariant.SIAMESE; + case 4 -> CatVariant.BRITISH_SHORTHAIR; + case 5 -> CatVariant.CALICO; + case 6 -> CatVariant.PERSIAN; + case 7 -> CatVariant.RAGDOLL; + case 8 -> CatVariant.WHITE; + case 9 -> CatVariant.JELLIE; + case 10 -> CatVariant.ALL_BLACK; + default -> throw new IllegalArgumentException("Invalid variant: " + variant); + }; + + catEntity = EntityType.CAT.create(player.getWorld()); + + if (catEntity != null) { + catEntity.setVariant(Registries.CAT_VARIANT.get(key)); + } + } + + @Override + public CatEntity getCatEntity() { + return catEntity; + } + + @Override + public void setCatEntity(CatEntity cat) { + this.catEntity = cat; + } + + @Override + public boolean isCat() { + return isCat; + } + + @Override + public void setCat(boolean cat) { + isCat = cat; + } + + @Override + public NbtCompound serializeNBT() { + var tag = new NbtCompound(); + + var catTag = new NbtCompound(); + getCatEntity().saveNbt(catTag); + tag.put(Constants.TAG_CAT_PLAYER_INNER_CAT, catTag); + + tag.putBoolean(Constants.TAG_CAT_PLAYER_IS_CAT, isCat); + return tag; + } + + @Override + public void deserializeNBT(NbtCompound tag) { + var catTag = tag.getCompound(Constants.TAG_CAT_PLAYER_INNER_CAT); + getCatEntity().readNbt(catTag); + isCat = tag.getBoolean(Constants.TAG_CAT_PLAYER_IS_CAT); + } +} diff --git a/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/GeniusCatCapability.java b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/GeniusCatCapability.java new file mode 100644 index 0000000..f45ea93 --- /dev/null +++ b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/GeniusCatCapability.java @@ -0,0 +1,128 @@ +package cuteneko.catsplus.forge.capability; + +import cuteneko.catsplus.data.IGeniusCat; +import cuteneko.catsplus.utility.Constants; +import cuteneko.catsplus.utility.NBTHelper; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtList; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.common.util.INBTSerializable; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class GeniusCatCapability implements IGeniusCat, INBTSerializable { + + private int lives = 0; + private boolean totem = false; + + private boolean songPlaying = false; + private BlockPos songSource = null; + + private final Map favorability = new HashMap<>(); + + @Override + public boolean hasTotem() { + return totem; + } + + @Override + public void setTotem(boolean totem) { + this.totem = totem; + } + + @Override + public int getFavorability(PlayerEntity player) { + if (!favorability.containsKey(player.getUuid())) { + favorability.put(player.getUuid(), 0); + } + + return favorability.get(player.getUuid()); + } + + @Override + public void setFavorability(int favorability, PlayerEntity player) { + this.favorability.put(player.getUuid(), favorability); + } + + @Override + public int getLives() { + return lives; + } + + @Override + public void setLives(int lives) { + this.lives = lives; + } + + @Override + public boolean isSongPlaying() { + return songPlaying; + } + + @Override + public BlockPos getSongSource() { + return songSource; + } + + @Override + public void songStartPlay(BlockPos source) { + songPlaying = true; + this.songSource = source; + } + + @Override + public void songStopPlay() { + songPlaying = false; + songSource = null; + } + + @Override + public NbtCompound serializeNBT() { + var tag = new NbtCompound(); + + tag.putInt(Constants.TAG_GENIUS_CAT_LIVES, lives); + tag.putBoolean(Constants.TAG_GENIUS_CAT_TOTEM, totem); + + var dancing = new NbtCompound(); + dancing.putBoolean(Constants.TAG_GENIUS_CAT_DANCING_SOUND_PLAYING, songPlaying); + dancing.put(Constants.TAG_GENIUS_CAT_DANCING_SOURCE, NBTHelper.putBlockPos(new NbtCompound(), songSource)); + tag.put(Constants.TAG_GENIUS_CAT_DANCING, dancing); + + var favorability = new NbtList(); + for (var entry : this.favorability.entrySet()) { + var f = new NbtCompound(); + f.putUuid(Constants.TAG_UUID, entry.getKey()); + f.putInt(Constants.TAG_VALUE, entry.getValue()); + favorability.add(f); + } + tag.put(Constants.TAG_GENIUS_CAT_FAVORABILITY, favorability); + + return tag; + } + + @Override + public void deserializeNBT(NbtCompound tag) { + lives = tag.getInt(Constants.TAG_GENIUS_CAT_LIVES); + totem = tag.getBoolean(Constants.TAG_GENIUS_CAT_TOTEM); + + var dancing = tag.getCompound(Constants.TAG_GENIUS_CAT_DANCING); + songPlaying = dancing.getBoolean(Constants.TAG_GENIUS_CAT_DANCING_SOUND_PLAYING); + songSource = NBTHelper.getBlockPos(dancing.getCompound(Constants.TAG_GENIUS_CAT_DANCING_SOURCE)); + + var favorability = tag.getList(Constants.TAG_GENIUS_CAT_FAVORABILITY, NbtElement.LIST_TYPE); + for (var entry : favorability) { + if (entry instanceof NbtCompound e + && e.contains(Constants.TAG_UUID) + && e.contains(Constants.TAG_VALUE)) { + var uuid = e.getUuid(Constants.TAG_UUID); + var value = e.getInt(Constants.TAG_VALUE); + + this.favorability.put(uuid, value); + } + } + } +} diff --git a/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/ModCapabilities.java b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/ModCapabilities.java new file mode 100644 index 0000000..43db918 --- /dev/null +++ b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/ModCapabilities.java @@ -0,0 +1,45 @@ +package cuteneko.catsplus.forge.capability; + +import cuteneko.catsplus.CatsPlus; +import cuteneko.catsplus.data.ICatPlayer; +import cuteneko.catsplus.data.IGeniusCat; +import cuteneko.catsplus.forge.capability.provider.CatPlayerProvider; +import cuteneko.catsplus.forge.capability.provider.GeniusCatProvider; +import cuteneko.catsplus.utility.Constants; +import net.minecraft.entity.Entity; +import net.minecraft.entity.passive.CatEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.CapabilityManager; +import net.minecraftforge.common.capabilities.CapabilityToken; +import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; +import net.minecraftforge.event.AttachCapabilitiesEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(modid = CatsPlus.MODID, bus = Mod.EventBusSubscriber.Bus.FORGE) +public class ModCapabilities { + public static Capability GENIUS_CAT = CapabilityManager.get(new CapabilityToken<>() {}); + public static Capability CAT_PLAYER = CapabilityManager.get(new CapabilityToken<>() {}); + + @SubscribeEvent + public void registerCaps(RegisterCapabilitiesEvent event) { + event.register(IGeniusCat.class); + event.register(ICatPlayer.class); + } + + @SubscribeEvent + public void onAttachEntityCaps(AttachCapabilitiesEvent event) { + if (event.getObject() instanceof CatEntity) { + var provider = new GeniusCatProvider(); + event.addCapability(Constants.CAP_GENIUS_CAT, provider); + event.addListener(provider::invalidate); + } + + if (event.getObject() instanceof PlayerEntity player) { + var provider = new CatPlayerProvider(player); + event.addCapability(Constants.CAP_CAT_PLAYER, provider); + event.addListener(provider::invalidate); + } + } +} diff --git a/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/provider/CatPlayerProvider.java b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/provider/CatPlayerProvider.java new file mode 100644 index 0000000..576780d --- /dev/null +++ b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/provider/CatPlayerProvider.java @@ -0,0 +1,47 @@ +package cuteneko.catsplus.forge.capability.provider; + +import cuteneko.catsplus.forge.capability.CatPlayerCapability; +import cuteneko.catsplus.forge.capability.GeniusCatCapability; +import cuteneko.catsplus.forge.capability.ModCapabilities; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.math.Direction; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilitySerializable; +import net.minecraftforge.common.util.LazyOptional; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class CatPlayerProvider implements ICapabilitySerializable { + private final PlayerEntity player; + + private final LazyOptional optional; + + public CatPlayerProvider(PlayerEntity player) { + this.player = player; + this.optional = LazyOptional.of(() -> new CatPlayerCapability(player)); + } + + public void invalidate() { + optional.invalidate(); + } + + @Override + public @NotNull LazyOptional getCapability(@NotNull Capability capability, @Nullable Direction arg) { + if (capability == ModCapabilities.CAT_PLAYER) { + return optional.cast(); + } + + return LazyOptional.empty(); + } + + @Override + public NbtCompound serializeNBT() { + return optional.orElse(new CatPlayerCapability(player)).serializeNBT(); + } + + @Override + public void deserializeNBT(NbtCompound nbt) { + optional.orElse(new CatPlayerCapability(player)).deserializeNBT(nbt); + } +} diff --git a/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/provider/GeniusCatProvider.java b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/provider/GeniusCatProvider.java new file mode 100644 index 0000000..47a62b3 --- /dev/null +++ b/catsplus-forge/src/main/java/cuteneko/catsplus/forge/capability/provider/GeniusCatProvider.java @@ -0,0 +1,38 @@ +package cuteneko.catsplus.forge.capability.provider; + +import cuteneko.catsplus.forge.capability.GeniusCatCapability; +import cuteneko.catsplus.forge.capability.ModCapabilities; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.math.Direction; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ICapabilitySerializable; +import net.minecraftforge.common.util.LazyOptional; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class GeniusCatProvider implements ICapabilitySerializable { + private final LazyOptional optional = LazyOptional.of(GeniusCatCapability::new); + + public void invalidate() { + optional.invalidate(); + } + + @Override + public @NotNull LazyOptional getCapability(@NotNull Capability capability, @Nullable Direction arg) { + if (capability == ModCapabilities.GENIUS_CAT) { + return optional.cast(); + } + + return LazyOptional.empty(); + } + + @Override + public NbtCompound serializeNBT() { + return optional.orElse(new GeniusCatCapability()).serializeNBT(); + } + + @Override + public void deserializeNBT(NbtCompound nbt) { + optional.orElse(new GeniusCatCapability()).deserializeNBT(nbt); + } +} diff --git a/catsplus-forge/src/main/resources/META-INF/mods.toml b/catsplus-forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..ab3df94 --- /dev/null +++ b/catsplus-forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,38 @@ +modLoader="javafml" +loaderVersion="[${forge_loader_version},)" +license="MIT" +issueTrackerURL="https://github.com/CuteNekoOwO/CatsPlus/issues" + +[[mods]] +modId="catsplus" +version="${mod_version}" +displayName="Cats+" +displayURL="https://github.com/CuteNekoOwO/CatsPlus" +#logoFile="" +credits="CuteNekoOwO" +authors="MeowBot233, YukieMiona and qyl27" +displayTest="MATCH_VERSION" +description=''' +Make cats in Minecraft more fun! +''' + +[[dependencies.catsplus]] + modId="forge" + mandatory=true + versionRange="[${forge_version},)" + ordering="NONE" + side="BOTH" + +[[dependencies.catsplus]] + modId="minecraft" + mandatory=true + versionRange="[${minecraft_version},)" + ordering="NONE" + side="BOTH" + +[[dependencies.catsplus]] + modId="architectury" + mandatory=true + versionRange="[${architectury_version},)" + ordering="NONE" + side="BOTH" diff --git a/catsplus-forge/src/main/resources/pack.mcmeta b/catsplus-forge/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..ad66130 --- /dev/null +++ b/catsplus-forge/src/main/resources/pack.mcmeta @@ -0,0 +1,8 @@ +{ + "pack": { + "description": { + "text": "Cats+ resources" + }, + "pack_format": 15 + } +} diff --git a/gradle.properties b/gradle.properties index 8c2a94d..bb36beb 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ # Done to increase the memory available to gradle. -org.gradle.jvmargs=-Xmx3G +org.gradle.jvmargs=-Xmx8G org.gradle.daemon=false architect_plugin_version=3.4-SNAPSHOT @@ -18,6 +18,7 @@ minecraft_version=1.20.4 yarn_mappings=1.20.4+build.3 # Forge +forge_loader_version=49 forge_version=49.0.30 # Fabric @@ -29,3 +30,4 @@ neoforge_version=20.4.164 # Dependencies architectury_version=11.0.12 +mod_menu_version=9.0.0 diff --git a/settings.gradle b/settings.gradle index ef39b27..4198b13 100644 --- a/settings.gradle +++ b/settings.gradle @@ -27,3 +27,4 @@ pluginManagement { rootProject.name = 'catsplus' include 'catsplus-fabric' +include 'catsplus-forge' diff --git a/src/main/java/cuteneko/catsplus/CatsPlus.java b/src/main/java/cuteneko/catsplus/CatsPlus.java index ad855ab..ee8451f 100644 --- a/src/main/java/cuteneko/catsplus/CatsPlus.java +++ b/src/main/java/cuteneko/catsplus/CatsPlus.java @@ -5,6 +5,11 @@ import cuteneko.catsplus.effect.potion.ModPotions; import cuteneko.catsplus.item.ModItems; import cuteneko.catsplus.item.group.ModItemGroups; +import cuteneko.catsplus.utility.Constants; +import dev.architectury.registry.item.ItemPropertiesRegistry; +import net.minecraft.util.Identifier; + +import java.util.Objects; public class CatsPlus { public static final String MODID = "catsplus"; @@ -26,4 +31,31 @@ public void init() { ModEffects.register(); ModPotions.register(); } + + public void initClient() { + ItemPropertiesRegistry.register(ModItems.CAT_BAG.get(), new Identifier(CatsPlus.MODID, "cat"), + (stack, clientLevel, livingEntity, i) -> { + if(!stack.hasNbt() + || stack.getNbt() == null + || !Objects.requireNonNull(stack.getNbt()).contains(Constants.TAG_CAT_CONTAINER)) { + return 0F; + } + + var nbt = stack.getNbt().getCompound(Constants.TAG_CAT_CONTAINER); + return switch (nbt.getString("variant")) { + case "minecraft:tabby" -> 0.05F; + case "minecraft:black" -> 0.1F; + case "minecraft:red" -> 0.15F; + case "minecraft:siamese" -> 0.2F; + case "minecraft:british_shorthair" -> 0.25F; + case "minecraft:calico" -> 0.3F; + case "minecraft:persian" -> 0.35F; + case "minecraft:ragdoll" -> 0.4F; + case "minecraft:white" -> 0.45F; + case "minecraft:jellie" -> 0.5F; + case "minecraft:all_black" -> 0.55F; + default -> 1F; + }; + }); + } } diff --git a/src/main/java/cuteneko/catsplus/data/ICatBag.java b/src/main/java/cuteneko/catsplus/data/ICatBag.java index fc27c12..7d46c08 100644 --- a/src/main/java/cuteneko/catsplus/data/ICatBag.java +++ b/src/main/java/cuteneko/catsplus/data/ICatBag.java @@ -1,4 +1,6 @@ package cuteneko.catsplus.data; +import cuteneko.catsplus.data.abstracted.ICatContainerItem; + public interface ICatBag extends ICatContainerItem { } diff --git a/src/main/java/cuteneko/catsplus/data/ICatSpirit.java b/src/main/java/cuteneko/catsplus/data/ICatSpirit.java index 6ecbd61..bbbcf65 100644 --- a/src/main/java/cuteneko/catsplus/data/ICatSpirit.java +++ b/src/main/java/cuteneko/catsplus/data/ICatSpirit.java @@ -1,5 +1,6 @@ package cuteneko.catsplus.data; +import cuteneko.catsplus.data.abstracted.ICatContainerItem; import net.minecraft.text.Text; import java.time.OffsetDateTime; diff --git a/src/main/java/cuteneko/catsplus/data/IGeniusCat.java b/src/main/java/cuteneko/catsplus/data/IGeniusCat.java index 260b659..bc45cf9 100644 --- a/src/main/java/cuteneko/catsplus/data/IGeniusCat.java +++ b/src/main/java/cuteneko/catsplus/data/IGeniusCat.java @@ -7,12 +7,19 @@ public interface IGeniusCat { boolean hasTotem(); void setTotem(boolean totem); - boolean canRespawn(); + default boolean canRespawn() { + return hasTotem() || getLives() > 0; + } int getFavorability(PlayerEntity player); void setFavorability(int favorability, PlayerEntity player); - void addFavorability(int value, PlayerEntity player); - void subFavorability(int value, PlayerEntity player); + + default void addFavorability(int value, PlayerEntity player) { + setFavorability(getFavorability(player) + value, player); + } + default void subFavorability(int value, PlayerEntity player) { + setFavorability(getFavorability(player) - value, player); + } int getLives(); // Todo: qyl27: Give it a purpose? void setLives(int lives); diff --git a/src/main/java/cuteneko/catsplus/data/ICatContainerItem.java b/src/main/java/cuteneko/catsplus/data/abstracted/ICatContainerItem.java similarity index 88% rename from src/main/java/cuteneko/catsplus/data/ICatContainerItem.java rename to src/main/java/cuteneko/catsplus/data/abstracted/ICatContainerItem.java index b6b3e0a..6c23a94 100644 --- a/src/main/java/cuteneko/catsplus/data/ICatContainerItem.java +++ b/src/main/java/cuteneko/catsplus/data/abstracted/ICatContainerItem.java @@ -1,4 +1,4 @@ -package cuteneko.catsplus.data; +package cuteneko.catsplus.data.abstracted; import net.minecraft.entity.passive.CatEntity; import net.minecraft.text.Text; diff --git a/src/main/java/cuteneko/catsplus/data/impl/CatContainer.java b/src/main/java/cuteneko/catsplus/data/impl/CatContainer.java index b2b81a5..a027367 100644 --- a/src/main/java/cuteneko/catsplus/data/impl/CatContainer.java +++ b/src/main/java/cuteneko/catsplus/data/impl/CatContainer.java @@ -1,6 +1,6 @@ package cuteneko.catsplus.data.impl; -import cuteneko.catsplus.data.ICatContainerItem; +import cuteneko.catsplus.data.abstracted.ICatContainerItem; import cuteneko.catsplus.utility.Constants; import net.minecraft.entity.EntityType; import net.minecraft.entity.passive.CatEntity; diff --git a/src/main/java/cuteneko/catsplus/item/CatBagItem.java b/src/main/java/cuteneko/catsplus/item/CatBagItem.java index e3d36c5..1d5c162 100644 --- a/src/main/java/cuteneko/catsplus/item/CatBagItem.java +++ b/src/main/java/cuteneko/catsplus/item/CatBagItem.java @@ -101,6 +101,7 @@ public ActionResult useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity cat.setSitting(false); bag.setCat(cat); cat.discard(); + user.setStackInHand(hand, stack); return ActionResult.SUCCESS; } else { return ActionResult.FAIL; diff --git a/src/main/java/cuteneko/catsplus/utility/Constants.java b/src/main/java/cuteneko/catsplus/utility/Constants.java index 62a152e..c33d469 100644 --- a/src/main/java/cuteneko/catsplus/utility/Constants.java +++ b/src/main/java/cuteneko/catsplus/utility/Constants.java @@ -1,5 +1,8 @@ package cuteneko.catsplus.utility; +import cuteneko.catsplus.CatsPlus; +import net.minecraft.util.Identifier; + public class Constants { public static final String TAG_CAT_CONTAINER = "Cat"; @@ -14,11 +17,11 @@ public class Constants { public static final String TAG_DEATH_TIME = "deathAt"; public static final String TAG_DEATH_MESSAGE = "deathMessage"; - public static final String TAG_CAT_PLAYER_DATA = "catsplus:cat_player_data"; + public static final Identifier CAP_CAT_PLAYER = new Identifier(CatsPlus.MODID, "cat_player_data"); public static final String TAG_CAT_PLAYER_INNER_CAT = "innerCat"; public static final String TAG_CAT_PLAYER_IS_CAT = "isCat"; - public static final String TAG_GENIUS_CAT_DATA = "catsplus:genius_cat_data"; + public static final Identifier CAP_GENIUS_CAT = new Identifier(CatsPlus.MODID, "genius_cat_data"); public static final String TAG_GENIUS_CAT_LIVES = "lives"; public static final String TAG_GENIUS_CAT_TOTEM = "totem"; public static final String TAG_GENIUS_CAT_CAN_RESPAWN = "respawn";