diff --git a/build.gradle b/build.gradle index 590e72b..29c45fd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,14 @@ +buildscript { + repositories { + // These repositories are only for Gradle plugins, put any other repositories in the repository block further below + maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } + mavenCentral() + } + dependencies { + classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT' + } +} + plugins { id 'eclipse' id 'idea' @@ -5,6 +16,8 @@ plugins { id 'net.minecraftforge.gradle' version '[6.0,6.2)' } +apply plugin: 'org.spongepowered.mixin' + version = mod_version group = mod_group_id @@ -93,11 +106,23 @@ repositories { maven { // CurseForge url "https://www.cursemaven.com" } + maven { url = 'https://repo.spongepowered.org/repository/maven-public/' } } dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" + + implementation fg.deobf("curse.maven:serene-seasons-291874:${serene_seasons_file_id}") + + implementation fg.deobf("curse.maven:cold-sweat-506194:${cold_sweat_file_id}-sources-5011470") + //implementation "curse.maven:cold-sweat-506194:${cold_sweat_file_id}-sources-5011470" + + implementation fg.deobf("curse.maven:thirst-was-taken-679270:${thirst_was_taken_file_id}") + compileOnly("curse.maven:overflowing-bars-852662:4578581") + implementation fg.deobf("curse.maven:player-animator-658587:${player_animator_file_id}") + implementation fg.deobf("curse.maven:elenai-dodge-442962:${elenai_dodge_file_id}") + annotationProcessor 'org.spongepowered:mixin:0.8.5:processor' } diff --git a/gradle.properties b/gradle.properties index 1cbcdc0..4ea3717 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,59 +1,23 @@ -# Sets default memory used for gradle commands. Can be overridden by user or command line properties. -# This is required to provide enough memory for the Minecraft decompilation process. org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false - - -## Environment Properties - -# The Minecraft version must agree with the Forge version to get a valid artifact -minecraft_version=1.20 -# The Minecraft version range can use any release version of Minecraft as bounds. -# Snapshots, pre-releases, and release candidates are not guaranteed to sort properly -# as they do not follow standard versioning conventions. +minecraft_version=1.20.1 minecraft_version_range=[1.20,1.21) -# The Forge version must agree with the Minecraft version to get a valid artifact -forge_version=46.0.14 -# The Forge version range can use any version of Forge as bounds or match the loader version range -forge_version_range=[46,) -# The loader version range can only use the major version of Forge/FML as bounds -loader_version_range=[46,) -# The mapping channel to use for mappings. -# The default set of supported mapping channels are ["official", "snapshot", "snapshot_nodoc", "stable", "stable_nodoc"]. -# Additional mapping channels can be registered through the "channelProviders" extension in a Gradle plugin. -# -# | Channel | Version | | -# |-----------|----------------------|--------------------------------------------------------------------------------| -# | official | MCVersion | Official field/method names from Mojang mapping files | -# | parchment | YYYY.MM.DD-MCVersion | Open community-sourced parameter names and javadocs layered on top of official | -# -# You must be aware of the Mojang license when using the 'official' or 'parchment' mappings. -# See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md -# -# Parchment is an unofficial project maintained by ParchmentMC, separate from Minecraft Forge. -# Additional setup is needed to use their mappings, see https://parchmentmc.org/docs/getting-started +forge_version=47.2.0 +forge_version_range=[47,) +loader_version_range=[47,) mapping_channel=official -# The mapping version to query from the mapping channel. -# This must match the format required by the mapping channel. -mapping_version=1.20 +mapping_version=1.20.1 - -## Mod Properties - -# The unique mod identifier for the mod. Must be lowercase in English locale. Must fit the regex [a-z][a-z0-9_]{1,63} -# Must match the String constant located in the main mod class annotated with @Mod. mod_id=feathers -# The human-readable display name for the mod. mod_name=Feathers -# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=GPU -# The mod version. See https://semver.org/ -mod_version=1.1 -# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. -# This should match the base package used for the mod sources. -# See https://maven.apache.org/guides/mini/guide-naming-conventions.html +mod_version=1.2 mod_group_id=com.elenai.feathers -# The authors of the mod. This is a simple text string that is used for display purposes in the mod list. -mod_authors=Elenai -# The description of the mod. This is a simple multiline text string that is used for display purposes in the mod list. -mod_description=Feathers is a stamina system for Minecraft, it adds a set of blue feathers to the hotbar to be spent by other mods, as well as an armor weight system to the game. \ No newline at end of file +mod_authors=Elenai, Darkona +mod_description=Feathers is a stamina system for Minecraft, it adds a set of blue feathers to the hotbar to be spent by other mods, as well as an armor weight system to the game. +player_animator_file_id=4587214 +elenai_dodge_file_id=4814313 + +serene_seasons_file_id=4761603 +cold_sweat_file_id=5349837 +thirst_was_taken_file_id=5287289 \ No newline at end of file diff --git a/src/main/java/com/elenai/feathers/Feathers.java b/src/main/java/com/elenai/feathers/Feathers.java index 7476849..c46c98d 100644 --- a/src/main/java/com/elenai/feathers/Feathers.java +++ b/src/main/java/com/elenai/feathers/Feathers.java @@ -26,6 +26,8 @@ public class Feathers { public static final String MODID = "feathers"; public static final Logger logger = LogManager.getLogger(MODID); public static final boolean OB_LOADED = ModList.get().isLoaded("overflowingbars"); + public static final boolean THIRST_LOADED = ModList.get().isLoaded("thirst"); + public static final boolean COLD_SWEAT_LOADED = ModList.get().isLoaded("cold_sweat"); public Feathers() { IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); @@ -49,6 +51,8 @@ private void commonSetup(FMLCommonSetupEvent event) { private void registerBrewingRecipes() { // Cold PotionBrewing.addMix(Potions.AWKWARD, Items.SNOWBALL, FeathersPotions.COLD_POTION.get()); + //Hot + PotionBrewing.addMix(Potions.AWKWARD, Items.MAGMA_BLOCK, FeathersPotions.HOT_POTION.get()); // Endurance PotionBrewing.addMix(Potions.AWKWARD, Items.FEATHER, FeathersPotions.ENDURANCE_POTION.get()); diff --git a/src/main/java/com/elenai/feathers/api/FeathersHelper.java b/src/main/java/com/elenai/feathers/api/FeathersHelper.java index 3ef9eed..5c9dbb7 100644 --- a/src/main/java/com/elenai/feathers/api/FeathersHelper.java +++ b/src/main/java/com/elenai/feathers/api/FeathersHelper.java @@ -11,6 +11,7 @@ import com.elenai.feathers.networking.packet.ColdSyncSTCPacket; import com.elenai.feathers.networking.packet.FeatherSyncCTSPacket; import com.elenai.feathers.networking.packet.FeatherSyncSTCPacket; +import com.elenai.feathers.networking.packet.HotSyncSTCPacket; import com.elenai.feathers.util.ArmorHandler; import net.minecraft.client.Minecraft; @@ -33,7 +34,7 @@ public static void setFeathers(ServerPlayer player, int feathers) { player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { f.setFeathers(feathers); f.setCooldown(0); - FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers()), player); + FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers(), getMaxFeathers()), player); }); } @@ -49,7 +50,7 @@ public static void setMaxFeathers(ServerPlayer player, int feathers) { if (player.getAttributeValue(FeathersAttributes.MAX_FEATHERS.get()) != feathers) player.getAttribute(FeathersAttributes.MAX_FEATHERS.get()).setBaseValue(feathers); f.setMaxFeathers(feathers); - FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers()), player); + FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); }); } @@ -63,7 +64,7 @@ public static void setMaxFeathers(ServerPlayer player, int feathers) { public static void setFeatherRegen(ServerPlayer player, int ticks) { player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { f.setRegen(ticks); - FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers()), player); + FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); }); } @@ -141,7 +142,7 @@ public static void addFeathers(ServerPlayer player, int feathers) { player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { f.addFeathers(feathers); f.setCooldown(0); - FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers()), player); + FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); }); } @@ -160,7 +161,7 @@ public static void subFeathers(ServerPlayer player, int feathers) { player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { f.subFeathers(feathers); f.setCooldown(0); - FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers()), player); + FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); }); } @@ -193,7 +194,7 @@ public static boolean spendFeathers(ServerPlayer player, int feathers) { } f.setCooldown(0); - FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers()), player); + FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); }); return true; } @@ -299,9 +300,7 @@ public static int getPlayerWeight(ServerPlayer player) { * @return if the player is cold */ public static boolean getCold(ServerPlayer player) { - return player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).map(f -> { - return f.isCold(); - }).orElse(false); + return player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).map(PlayerFeathers::isCold).orElse(false); } /** @@ -319,7 +318,7 @@ public static void setCold(ServerPlayer player, boolean cold) { }); } - /** + /**e * Checks whether the player has any feathers remaining * * @side client @@ -328,5 +327,22 @@ public static void setCold(ServerPlayer player, boolean cold) { public static boolean checkFeathersRemaining() { return getFeathers() + getEndurance() > ClientFeathersData.getWeight(); } - + + public static void setHot(ServerPlayer player, boolean b) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + f.setHot(b); + FeathersMessages.sendToPlayer(new HotSyncSTCPacket(f.isHot()), player); + }); + } + + /** + * Returns the given player's hotness + * + * @side server + * @param player + * @return if the player is hot ;) + */ + public static boolean getHot(ServerPlayer player) { + return player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).map(PlayerFeathers::isHot).orElse(false); + } } diff --git a/src/main/java/com/elenai/feathers/attributes/FeathersAttributes.java b/src/main/java/com/elenai/feathers/attributes/FeathersAttributes.java index 9edcfec..af97a16 100644 --- a/src/main/java/com/elenai/feathers/attributes/FeathersAttributes.java +++ b/src/main/java/com/elenai/feathers/attributes/FeathersAttributes.java @@ -23,8 +23,10 @@ public class FeathersAttributes { public static final HashMap, UUID> UUIDS = new HashMap<>(); public static final DeferredRegister ATTRIBUTES = DeferredRegister.create(ForgeRegistries.ATTRIBUTES, Feathers.MODID); - public static final RegistryObject MAX_FEATHERS = registerAttribute("feathers.max_feathers", (id) -> new RangedAttribute(id, 20.0D, 0.0D, 1024.0D).setSyncable(true), "1ce4960d-c50e-44bf-ad23-7bcd77f4c1dc"); - public static final RegistryObject FEATHER_REGEN = registerAttribute("feathers.feather_regen", (id) -> new RangedAttribute(id, 1.0D, 0.0D, 1024.0D).setSyncable(true), "d74ded8f-c5b6-4222-80e2-dbea7ccf8d02"); + public static final RegistryObject MAX_FEATHERS = registerAttribute("feathers.max_feathers", + (id) -> new RangedAttribute(id, 20.0D, 0.0D, 1024.0D).setSyncable(true), "1ce4960d-c50e-44bf-ad23-7bcd77f4c1dc"); + public static final RegistryObject FEATHER_REGEN = registerAttribute("feathers.feather_regen", + (id) -> new RangedAttribute(id, 1.0D, 0.0D, 1024.0D).setSyncable(true), "d74ded8f-c5b6-4222-80e2-dbea7ccf8d02"); public static RegistryObject registerAttribute(String name, Function attribute, String uuid) { return registerAttribute(name, attribute, UUID.fromString(uuid)); diff --git a/src/main/java/com/elenai/feathers/capability/PlayerFeathers.java b/src/main/java/com/elenai/feathers/capability/PlayerFeathers.java index 130b083..85b1545 100644 --- a/src/main/java/com/elenai/feathers/capability/PlayerFeathers.java +++ b/src/main/java/com/elenai/feathers/capability/PlayerFeathers.java @@ -18,7 +18,22 @@ public class PlayerFeathers { private final int MIN_COOLDOWN = 0; private boolean cold = false; + private boolean hot = true; + public int getMaxCooldown() { + return maxCooldown; + } + + public void setMaxCooldown(int cooldown) { + this.maxCooldown = cooldown; + } + public void setHot(boolean hot){ + this.hot = hot; + } + + public boolean isHot(){ + return hot; + } public int getFeathers() { return feathers; } @@ -80,7 +95,7 @@ public void loadNBTData(CompoundTag nbt) { } public int getCooldown() { - return cooldown; + return Math.round( cooldown); } public void setCooldown(int cooldown) { @@ -90,7 +105,6 @@ public void setCooldown(int cooldown) { public void addCooldown(int ticks) { this.cooldown = Math.min(this.cooldown + ticks, maxCooldown); } - public void subCooldown(int ticks) { this.cooldown = Math.max(this.cooldown - ticks, MIN_COOLDOWN); } diff --git a/src/main/java/com/elenai/feathers/capability/PlayerFeathersProvider.java b/src/main/java/com/elenai/feathers/capability/PlayerFeathersProvider.java index 92ea611..2f32dc7 100644 --- a/src/main/java/com/elenai/feathers/capability/PlayerFeathersProvider.java +++ b/src/main/java/com/elenai/feathers/capability/PlayerFeathersProvider.java @@ -12,9 +12,7 @@ import org.jetbrains.annotations.Nullable; public class PlayerFeathersProvider implements ICapabilityProvider, INBTSerializable { - public static Capability PLAYER_FEATHERS = CapabilityManager - .get(new CapabilityToken() { - }); + public static Capability PLAYER_FEATHERS = CapabilityManager.get(new CapabilityToken<>() {}); private PlayerFeathers feathers = null; private final LazyOptional optional = LazyOptional.of(this::createPlayerFeathers); diff --git a/src/main/java/com/elenai/feathers/client/ClientFeathersData.java b/src/main/java/com/elenai/feathers/client/ClientFeathersData.java index 67590b3..29de159 100644 --- a/src/main/java/com/elenai/feathers/client/ClientFeathersData.java +++ b/src/main/java/com/elenai/feathers/client/ClientFeathersData.java @@ -10,10 +10,12 @@ public class ClientFeathersData { private static int animationCooldown = 0; private static int fadeCooldown = 0; private static boolean cold = false; + private static boolean hot = false; private static boolean energized = false; private static boolean overflowing = false; + private static int maxCooldown; - public static void setFeathers(int feathers) { + public static void setFeathers(int feathers) { ClientFeathersData.feathers = feathers; } @@ -55,6 +57,14 @@ public static void setCold(boolean cold) { ClientFeathersData.cold = cold; } + public static boolean isHot() { + return hot; + } + + public static void setHot(boolean hot) { + ClientFeathersData.hot = hot; + } + public static boolean isOverflowing() { return overflowing; } @@ -86,4 +96,12 @@ public static int getPreviousFeathers() { public static void setPreviousFeathers(int previousFeathers) { ClientFeathersData.previousFeathers = previousFeathers; } + + public static void setMaxCooldown(int maxCooldown) { + ClientFeathersData.maxCooldown = maxCooldown; + } + + public static int getMaxCooldown() { + return maxCooldown; + } } diff --git a/src/main/java/com/elenai/feathers/client/gui/FeathersHudOverlay.java b/src/main/java/com/elenai/feathers/client/gui/FeathersHudOverlay.java index 56083f1..6fa528b 100644 --- a/src/main/java/com/elenai/feathers/client/gui/FeathersHudOverlay.java +++ b/src/main/java/com/elenai/feathers/client/gui/FeathersHudOverlay.java @@ -13,17 +13,50 @@ public class FeathersHudOverlay { public final static ResourceLocation ICONS = new ResourceLocation(Feathers.MODID, "textures/gui/icons.png"); - public final static int NONE = 16; public final static int FULL = 34; - public final static int FULL_FLOW = 70; public final static int HALF = 25; - public final static int HALF_FLOW = 61; - public final static int ARMORED = 52; - public final static int HALF_ARMORED = 43; + + private static GuiIconCoord NORMAL_BACKGROUND = new GuiIconCoord(16, 0, 9, 9); + private static GuiIconCoord NORMAL_HALF_FEATHER = new GuiIconCoord(25, 0, 9, 9); + private static GuiIconCoord NORMAL_FULL_FEATHER = new GuiIconCoord(34, 0, 9, 9); + + private static GuiIconCoord ENDURANCE_HALF_FEATHER = new GuiIconCoord(25, 9, 9, 9); + private static GuiIconCoord ENDURANCE_FULL_FEATHER = new GuiIconCoord(34, 9, 9, 9); + + private static GuiIconCoord HALF_RED_FEATHER = new GuiIconCoord(61, 9, 9, 9); + private static GuiIconCoord FULL_RED_FEATHER = new GuiIconCoord(70, 9, 9, 9); + + + private static GuiIconCoord ARMORED_HALF_FEATHER = new GuiIconCoord(43, 0, 9, 9); + private static GuiIconCoord ARMORED_FULL_FEATHER = new GuiIconCoord(52, 0, 9, 9); + + + private static GuiIconCoord REGEN_BACKGROUND = new GuiIconCoord(16, 9, 9, 9); + private static GuiIconCoord ENERGIZED_HALF_FEATHER = new GuiIconCoord(43, 27, 9, 9); + private static GuiIconCoord ENERGIZED_FULL_FEATHER = new GuiIconCoord(52, 27, 9, 9); + + + private static GuiIconCoord COLD_BACKGROUND = new GuiIconCoord(16, 18, 9, 9); + private static GuiIconCoord COLD_HALF_FEATHER = new GuiIconCoord(25, 18, 9, 9); + private static GuiIconCoord COLD_FULL_FEATHER = new GuiIconCoord(34, 18, 9, 9); + + private static GuiIconCoord ALTER_FULL_FEATHER = new GuiIconCoord(34, 27, 9, 9); + private static GuiIconCoord ALTER_HALF_FEATHER = new GuiIconCoord(25, 27, 9, 9); + + private static GuiIconCoord HOT_HALF_FEATHER = new GuiIconCoord(61, 0, 9, 9); + private static GuiIconCoord HOT_FULL_FEATHER = new GuiIconCoord(70, 0, 9, 9); + + + private static GuiIconCoord OVERFLOW_HALF_FEATHER = new GuiIconCoord(61, 18, 9, 9); + private static GuiIconCoord OVERFLOW_FULL_FEATHER = new GuiIconCoord(70, 18, 9, 9); + + public static int k = 0; static float alpha = 1.0f; + public static final int ICON_WIDTH = 9; + public static final int ICON_HEIGHT = 9; /** * Renders the Feathers to the hotbar */ @@ -66,30 +99,33 @@ public class FeathersHudOverlay { /* * Always render the background up to the maximum feather amount */ + for (int i = 0; i < 10; i++) { if ((i + 1 <= Math.ceil((double) ClientFeathersData.getMaxFeathers() / 2.0d))) { - int cold = ((ClientFeathersData.isCold()) ? 18 : 0); - int height = (k > i * 10 && k < (i + 1) * 10) ? 2 : 0; - guiGraphics.blit(ICONS, x + 81 - (i * 8) + xOffset, y - rightOffset - height + yOffset, NONE, - cold, 9, 9, 256, 256); + + GuiIconCoord icon = ((ClientFeathersData.isCold()) ? COLD_BACKGROUND : NORMAL_BACKGROUND); + + int height = getHeight(i); + + guiGraphics.blit(ICONS, getXPos(x, i, xOffset), getYPos(y, rightOffset, height, yOffset), + icon.x, icon.y, icon.width, icon.height, 256, 256); } } /* * Only render the currently active feathers */ + double halvedFeathers = Math.ceil((double) ClientFeathersData.getFeathers() / 2.0d); for (int i = 0; i < 10; i++) { - if ((i + 1 <= Math.ceil((double) ClientFeathersData.getFeathers() / 2.0d)) - && ClientFeathersData.getFeathers() > 0) { - // Check if feather is half or full - int type = ((i + 1 == Math.ceil((double) ClientFeathersData.getFeathers() / 2.0d) - && (ClientFeathersData.getFeathers() % 2 != 0)) ? HALF : FULL); + if ((i + 1 <= halvedFeathers) && ClientFeathersData.getFeathers() > 0) { - int height = (k > i * 10 && k < (i + 1) * 10) ? 2 : 0; + GuiIconCoord icon = (i + 1 == Math.ceil((double) ClientFeathersData.getFeathers() / 2.0d) + && (ClientFeathersData.getFeathers() % 2 != 0)) ? getIconHalf() : getIconFull(); - int cold = ((ClientFeathersData.isCold()) ? 18 : 0); - guiGraphics.blit(ICONS, x + 81 - (i * 8) + xOffset, y- rightOffset - height + yOffset, - type, cold, 9, 9, 256, 256); + int height = getHeight(i); + + guiGraphics.blit(ICONS, getXPos(x, i, xOffset), getYPos(y, rightOffset, height, yOffset), + icon.x, icon.y, icon.width, icon.height, 256, 256); } else { break; } @@ -100,23 +136,20 @@ public class FeathersHudOverlay { */ //if (Math.ceil(ClientFeathersData.getFeathers() / 20.0d) <= Math.ceil(ClientFeathersData.getWeight() / 20.0d)) { for (int i = 0; i < 10; i++) { - if ((i + 1 <= Math.ceil((double) ClientFeathersData.getWeight() / 2.0d)) - && (i + 1 <= Math.ceil((double) ClientFeathersData.getFeathers() / 2.0d))) { - int height = (k > i * 10 && k < (i + 1) * 10) ? 2 : 0; + if ((i + 1 <= Math.ceil((double) ClientFeathersData.getWeight() / 2.0d)) && (i + 1 <= halvedFeathers)) { - // Check if feather is half or full - int type = ((i + 1 == Math.ceil((double) ClientFeathersData.getWeight() / 2.0d) - && (ClientFeathersData.getWeight() % 2 != 0)) ? HALF_ARMORED : ARMORED); + GuiIconCoord icon = (i + 1 == Math.ceil((double) ClientFeathersData.getWeight() / 2.0d) + && (ClientFeathersData.getWeight() % 2 != 0)) ? ARMORED_HALF_FEATHER : ARMORED_FULL_FEATHER; - int lowerFeathers = (i >= Math.floor((double) ClientFeathersData.getFeathers() / 2.0d)) ? 9 : 0; + int height = getHeight(i); - guiGraphics.blit(ICONS, x + 81 - (i * 8) + xOffset, y - rightOffset - height + yOffset, - type, lowerFeathers, 9, 9, 256, 256); + guiGraphics.blit(ICONS, getXPos(x, i, xOffset), getYPos(y, rightOffset, height, yOffset), + icon.x, icon.y, icon.width, icon.height, 256, 256); } else { break; } } - //} + /* * Render feathers past 20 in a different color @@ -124,13 +157,14 @@ public class FeathersHudOverlay { if (ClientFeathersData.isOverflowing()) { for (int i = 0; i < 10; i++) { if (i + 1 <= Math.ceil((double) (ClientFeathersData.getFeathers() - 20) / 2.0d)) { - // Check if feather is half or full - int type = (i + 1 == Math.ceil((double) (ClientFeathersData.getFeathers() - 20) / 2.0d) - && ClientFeathersData.getFeathers() % 2 != 0 ? HALF_FLOW : FULL_FLOW); - int height = (k > i * 10 && k < (i + 1) * 10) ? 2 : 0; - int cold = ((ClientFeathersData.isCold()) ? 18 : 0); - guiGraphics.blit(ICONS, x + 81 - (i * 8) + xOffset, y- rightOffset - height + yOffset, - type, cold, 9, 9, 256, 256); + + GuiIconCoord icon = (i + 1 == Math.ceil((double) (ClientFeathersData.getFeathers() - 20) / 2.0d) + && ClientFeathersData.getFeathers() % 2 != 0) ? OVERFLOW_HALF_FEATHER : OVERFLOW_FULL_FEATHER; + + int height = getHeight(i); + + guiGraphics.blit(ICONS, getXPos(x, i, xOffset), getYPos(y, rightOffset, height, yOffset), + icon.x, icon.y, icon.width, icon.height, 256, 256); } else { break; } @@ -141,12 +175,12 @@ public class FeathersHudOverlay { * Render the Regeneration effect */ for (int i = 0; i < 10; i++) { - if (ClientFeathersData.getAnimationCooldown() >= 18 - || ClientFeathersData.getAnimationCooldown() == 10) { + if (ClientFeathersData.getAnimationCooldown() >= 18|| ClientFeathersData.getAnimationCooldown() == 10) { if ((i + 1 <= Math.ceil((double) ClientFeathersData.getMaxFeathers() / 2.0d))) { - int height = (k > i * 10 && k < (i + 1) * 10) ? 2 : 0; - guiGraphics.blit(ICONS, x + 81 - (i * 8) + xOffset, y - rightOffset - height + yOffset, - NONE, 9, 9, 9, 256, 256); + int height = getHeight(i); + GuiIconCoord icon = REGEN_BACKGROUND; + guiGraphics.blit(ICONS, getXPos(x, i, xOffset), getYPos(y, rightOffset, height, yOffset), + icon.x, icon.y, icon.width, icon.height, 256, 256); } } } @@ -173,16 +207,15 @@ public class FeathersHudOverlay { for (int i = 0; i < Math.ceil((double) ClientFeathersData.getEnduranceFeathers() / 20.0d); i++) { //TODO: fix half feathers lines += 10; for (int j = 0; j < 10; j++) { - if ((((i) * 10.0d) + (j + 1) <= Math - .ceil((double) ClientFeathersData.getEnduranceFeathers() / 2.0d)) + if ((((i) * 10.0d) + (j + 1) <= Math.ceil((double) ClientFeathersData.getEnduranceFeathers() / 2.0d)) && ClientFeathersData.getEnduranceFeathers() > 0) { - // Check if feather is half or full - int type = (((j + 1) + (10 * i) == Math.ceil((double) ClientFeathersData.getEnduranceFeathers() / 2.0d) - && (ClientFeathersData.getEnduranceFeathers() % 2 != 0)) ? HALF : FULL); + GuiIconCoord icon = (((j + 1) + (10 * i) == Math.ceil((double) ClientFeathersData.getEnduranceFeathers() / 2.0d) + && (ClientFeathersData.getEnduranceFeathers() % 2 != 0)) ? ENDURANCE_HALF_FEATHER : ENDURANCE_FULL_FEATHER); - guiGraphics.blit(ICONS, x + 81 - (j * 8) + xOffset, - y /*- 58*/ - rightOffset + yOffset - ((i) * 10), type, 9, 9, 9, 256, 256); + guiGraphics.blit(ICONS, getXPos(x, j, xOffset), + y /*- 58*/ - rightOffset + yOffset - ((i) * 10), + icon.x, icon.y, icon.width, icon.height, 256, 256); } else { break; } @@ -193,7 +226,8 @@ public class FeathersHudOverlay { } if (Feathers.OB_LOADED) { - RowCountRenderer.drawBarRowCount(guiGraphics, x + 100 + xOffset, y - rightOffset + 10 + yOffset, ClientFeathersData.getFeathers(), true, minecraft.font); + RowCountRenderer.drawBarRowCount(guiGraphics, x + 100 + xOffset, y - rightOffset + 10 + yOffset, + ClientFeathersData.getFeathers(), true, minecraft.font); } } @@ -202,4 +236,44 @@ public class FeathersHudOverlay { }; + private static int getYPos(int y, int rightOffset, int height, int yOffset) { + return y - rightOffset - height + yOffset; + } + + private static int getXPos(int x, int i, int xOffset) { + return x + 81 - (i * 8) + xOffset; + } + + private static int getHeight(int i) { + return (k > i * 10 && k < (i + 1) * 10) ? 2 : 0; + } + + private static GuiIconCoord getIconFull(){ + if (ClientFeathersData.isCold()) { + return COLD_FULL_FEATHER; + } + if (ClientFeathersData.isHot()) { + return HOT_FULL_FEATHER; + } + if(ClientFeathersData.isEnergized()){ + return ENERGIZED_FULL_FEATHER; + } + return FeathersClientConfig.ALTERNATIVE_FEATHER_COLOR.get() ? ALTER_FULL_FEATHER : NORMAL_FULL_FEATHER; + } + + private static GuiIconCoord getIconHalf(){ + if (ClientFeathersData.isCold()) { + return COLD_HALF_FEATHER; + } + if (ClientFeathersData.isHot()) { + return HOT_HALF_FEATHER; + } + if(ClientFeathersData.isEnergized()){ + return ENERGIZED_HALF_FEATHER; + } + return FeathersClientConfig.ALTERNATIVE_FEATHER_COLOR.get() ? ALTER_HALF_FEATHER : NORMAL_HALF_FEATHER; + } + + + } \ No newline at end of file diff --git a/src/main/java/com/elenai/feathers/client/gui/GuiIconCoord.java b/src/main/java/com/elenai/feathers/client/gui/GuiIconCoord.java new file mode 100644 index 0000000..c9f6163 --- /dev/null +++ b/src/main/java/com/elenai/feathers/client/gui/GuiIconCoord.java @@ -0,0 +1,19 @@ +package com.elenai.feathers.client.gui; + +public class GuiIconCoord { + + public final int x; + public final int y; + + public final int width; + + public final int height; + + public GuiIconCoord(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + +} diff --git a/src/main/java/com/elenai/feathers/command/CommandGetFeathers.java b/src/main/java/com/elenai/feathers/command/CommandGetFeathers.java new file mode 100644 index 0000000..cf449a3 --- /dev/null +++ b/src/main/java/com/elenai/feathers/command/CommandGetFeathers.java @@ -0,0 +1,4 @@ +package com.elenai.feathers.command; + +public class CommandGetFeathers { +} diff --git a/src/main/java/com/elenai/feathers/command/CommandSetFeathers.java b/src/main/java/com/elenai/feathers/command/CommandSetFeathers.java new file mode 100644 index 0000000..255bb36 --- /dev/null +++ b/src/main/java/com/elenai/feathers/command/CommandSetFeathers.java @@ -0,0 +1,6 @@ +package com.elenai.feathers.command; + +public class CommandSetFeathers { + + +} diff --git a/src/main/java/com/elenai/feathers/command/FeathersCommands.java b/src/main/java/com/elenai/feathers/command/FeathersCommands.java new file mode 100644 index 0000000..578455c --- /dev/null +++ b/src/main/java/com/elenai/feathers/command/FeathersCommands.java @@ -0,0 +1,18 @@ +package com.elenai.feathers.command; + +import net.minecraftforge.event.RegisterCommandsEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber( + bus = Mod.EventBusSubscriber.Bus.FORGE +) +public class FeathersCommands { + + public FeathersCommands(){} + + @SubscribeEvent + public static void onCommandsRegistered(RegisterCommandsEvent event) { + + } +} diff --git a/src/main/java/com/elenai/feathers/config/FeathersClientConfig.java b/src/main/java/com/elenai/feathers/config/FeathersClientConfig.java index 8f56a20..675f19e 100644 --- a/src/main/java/com/elenai/feathers/config/FeathersClientConfig.java +++ b/src/main/java/com/elenai/feathers/config/FeathersClientConfig.java @@ -20,6 +20,8 @@ public class FeathersClientConfig { public static final ForgeConfigSpec.ConfigValue FADE_OUT_COOLDOWN; public static final ForgeConfigSpec.ConfigValue FADE_COOLDOWN; + public static final ForgeConfigSpec.ConfigValue ALTERNATIVE_FEATHER_COLOR; + static { BUILDER.push("Feathers' Config"); @@ -55,7 +57,10 @@ public class FeathersClientConfig { Y_OFFSET = BUILDER.comment("How far up or down you want the feathers to be. TIP: use this for compatibility with mods that add other bars such as thirst") .define("HUD Y Offset", 0); - + + ALTERNATIVE_FEATHER_COLOR = BUILDER + .comment("Whether the feathers UI color should be changed to a green color.") + .define("Alternative Feather Color", false); BUILDER.pop(); SPEC = BUILDER.build(); } diff --git a/src/main/java/com/elenai/feathers/config/FeathersCommonConfig.java b/src/main/java/com/elenai/feathers/config/FeathersCommonConfig.java index 846b272..bfc0ae1 100644 --- a/src/main/java/com/elenai/feathers/config/FeathersCommonConfig.java +++ b/src/main/java/com/elenai/feathers/config/FeathersCommonConfig.java @@ -3,48 +3,156 @@ import java.util.ArrayList; import java.util.List; +import com.elenai.feathers.Feathers; import com.google.common.collect.Lists; import net.minecraft.world.item.ArmorItem; import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.fml.ModList; import net.minecraftforge.registries.ForgeRegistries; public class FeathersCommonConfig { - public static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder(); - public static final ForgeConfigSpec SPEC; - - public static final ForgeConfigSpec.ConfigValue COOLDOWN; - public static final ForgeConfigSpec.ConfigValue ENABLE_ARMOR_WEIGHTS; - public static final ForgeConfigSpec.ConfigValue> ARMOR_WEIGHTS; - public static final ForgeConfigSpec.ConfigValue ENABLE_FROST_EFFECTS; - public static final ForgeConfigSpec.ConfigValue ENABLE_LIGHTWEIGHT_ENCHANTMENT; - - public static List armorWeightBuilder = new ArrayList<>(); - - static { - BUILDER.push("Feathers' Config"); - - COOLDOWN = BUILDER.comment("How many ticks it takes to regenerate half a feather.") - .define("Feathers Cooldown", 40); - - /* - * Add all current armor types on config creation - */ - ForgeRegistries.ITEMS.forEach(i -> { - if(i.asItem() instanceof ArmorItem armor) { - int def = armor.getDefense(); - FeathersCommonConfig.armorWeightBuilder.add(i.getDescriptionId() + ":" + def); - } - }); - ARMOR_WEIGHTS = BUILDER.comment("How many half feathers each item weighs.").defineList("Armor Weights Override", Lists.newArrayList(armorWeightBuilder), o -> o instanceof String); - - ENABLE_ARMOR_WEIGHTS = BUILDER.comment("If enabled, armor types have weight, this reduces the amount of feathers you can use based on how heavy your armor is").define("Enable Armor Weights", true); - ENABLE_FROST_EFFECTS = BUILDER.comment("Whether feathers freeze in cold biomes. If they do, they don't regenerate until in a different biome") - .define("Enable Frost In Cold Biomes", false); - ENABLE_LIGHTWEIGHT_ENCHANTMENT = BUILDER.comment("Whether the Lightweight enchantment can be enhanted in an enchantment table, or if it is treasure only.") - .define("Enable Lightweight Enchantment in Table", true); - - BUILDER.pop(); - SPEC = BUILDER.build(); - } + public static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder(); + public static final ForgeConfigSpec SPEC; + + public static final ForgeConfigSpec.ConfigValue COOLDOWN; + + public static final ForgeConfigSpec.ConfigValue ENABLE_ARMOR_WEIGHTS; + public static final ForgeConfigSpec.ConfigValue> ARMOR_WEIGHTS; + + public static final ForgeConfigSpec.ConfigValue ENABLE_COLD_EFFECTS; + public static final ForgeConfigSpec.ConfigValue COLD_EFFECT_COOLDOWN_MULTIPLIER; + + public static final ForgeConfigSpec.ConfigValue ENABLE_HOT_EFFECTS; + public static final ForgeConfigSpec.ConfigValue HOT_FEATHER_REDUCTION; + + public static final ForgeConfigSpec.ConfigValue SLEEPING_ALWAYS_RESTORES_FEATHERS; + + public static final ForgeConfigSpec.ConfigValue ENABLE_LIGHTWEIGHT_ENCHANTMENT; + public static final ForgeConfigSpec.ConfigValue ENABLE_ENDURANCE; + public static final ForgeConfigSpec.ConfigValue ENDURANCE_ENCHANTMENT_REGEN; + + public static final ForgeConfigSpec.ConfigValue COLD_LINGER; + + + + + + //Configs for Cold Sweat + + public static final ForgeConfigSpec.ConfigValue COLD_SWEAT_COMPATIBILITY; + + + //Configs for Thirst Was Taken + public static final ForgeConfigSpec.ConfigValue THIRST_COMPATIBILITY; + public static final ForgeConfigSpec.ConfigValue THIRST_REGEN_REDUCTION_MULTIPLIER; + public static final ForgeConfigSpec.ConfigValue QUENCH_REGEN_BONUS_MULTIPLIER; + + + public static List armorWeightBuilder = new ArrayList<>(); + + static { + + boolean isThirstLoaded = ModList.get().isLoaded("thirst"); + boolean isColdSweatLoaded = ModList.get().isLoaded("cold_sweat"); + BUILDER.push("Feathers' Config"); + + COOLDOWN = BUILDER + .comment("How many ticks it takes to regenerate half a feather.") + .define("Feathers Cooldown", 40); + + /* + * Add all current armor types on config creation + */ + ForgeRegistries.ITEMS.forEach(i -> { + if (i.asItem() instanceof ArmorItem armor) { + int def = armor.getDefense(); + FeathersCommonConfig.armorWeightBuilder.add(i.getDescriptionId() + ":" + def); + } + }); + + ARMOR_WEIGHTS = BUILDER + .comment("How many half feathers each item weighs.") + .defineList("Armor Weights Override", Lists.newArrayList(armorWeightBuilder), o -> o instanceof String); + + ENABLE_ARMOR_WEIGHTS = BUILDER + .comment("If enabled, armor types have weight, this reduces the amount of feathers you can use based on how heavy your armor is") + .define("Enable Armor Weights", true); + + ENABLE_COLD_EFFECTS = BUILDER + .comment("Whether the Cold Effect is enabled. When the effect is active, feathers regenerate slower.") + .define("Enable Cold Effect", true); + + COLD_EFFECT_COOLDOWN_MULTIPLIER = BUILDER + .comment("How muc does the cooldown multiply by when Cold Effect is applied. Values can range from 1 (which would have no effect) up to 20. " + + "Set to 1 to have no effect, set to 20 to have the feathers regenerate 20 times slower. Set to 21 to have feathers not regenerate at all.") + .defineInRange("Cold Multiplier", 21, 1, 21); + + ENABLE_HOT_EFFECTS = BUILDER + .comment("Whether the Hot Effect is enabled. When the effect is active, feathers are reduced. Fatigue is applied when the player is hot or burning") + .define("Enable Hot Effect", true); + + HOT_FEATHER_REDUCTION = BUILDER. + comment("Multiplier for the feather reduction when affected by heat. Values can range from 0 to 20." + + "The higher the value, the more feathers are reduced. The lower the value, the less feathers are reduced." + + "A value of 0 means no feathers are reduced. A value of 20 means all feathers are reduced.") + .defineInRange("Fatigue Feather Reduction Multiplier", 6, 0, 20); + + ENABLE_LIGHTWEIGHT_ENCHANTMENT = BUILDER + .comment("Whether the Lightweight enchantment can be applied in an enchantment table, or if it is treasure only.") + .define("Enable Lightweight Enchantment in Table", true); + + ENABLE_ENDURANCE = BUILDER + .comment("Whether the Endurance effect is enabled and the potions registered.") + .define("Enable Endurance effect", true); + + ENDURANCE_ENCHANTMENT_REGEN = BUILDER + .comment("Whether the Endurance effect also regenerates the extra feathers while active. " + + "If false, the effect only adds temporal extra feathers.") + .define("Endurance Enchantment Regeneration", true); + + COLD_LINGER = BUILDER + .comment("How long does the Cold Effect linger after stopping being cold") + .define("Cold Lingering time in ticks", 60); + + SLEEPING_ALWAYS_RESTORES_FEATHERS = BUILDER + .comment("Whether sleeping always restores feathers to the maximum amount.") + .define("Sleeping Always Restores Feathers", true); + + + + BUILDER.pop(); + + if(Feathers.COLD_SWEAT_LOADED){ + BUILDER.push("Cold Sweat compatibility settings"); + COLD_SWEAT_COMPATIBILITY = BUILDER + .comment("Enable compatibility with mod \"Cold Sweat\". " + + "If enabled, Cold Sweat will determine if the player gets the Hot or the Cold effect depending on body temperature.") + .define("Cold Sweat Compatibility", true); + BUILDER.pop(); + }else{ + COLD_SWEAT_COMPATIBILITY = BUILDER.define("Cold Sweat Compatibility", false); + } + + BUILDER.push("Thirst Was Taken compatibility settings"); + + THIRST_COMPATIBILITY = BUILDER + .comment("Enable compatibility with mod \"Thirst Was Taken\".") + .define("Determine Cold With Thirst", true); + + THIRST_REGEN_REDUCTION_MULTIPLIER = BUILDER + .comment("How many ticks of half-feather regeneration be increased by level missing of Thirst. " + + "Maximum Thirst is 20 and minimum is 0." ) + .define("Thirst Reduces Regen", 5); + + QUENCH_REGEN_BONUS_MULTIPLIER = BUILDER + .comment("How many ticks of half-feather regeneration be decreased by level of Quench. " + + "Maximum Quench is whatever your current Thirst is and minimum is 0." ) + .define("Thirst Increases Regen", 2); + + BUILDER.pop(); + + + SPEC = BUILDER.build(); + } } diff --git a/src/main/java/com/elenai/feathers/effect/ColdEffect.java b/src/main/java/com/elenai/feathers/effect/ColdEffect.java index f987b98..19e7ae3 100644 --- a/src/main/java/com/elenai/feathers/effect/ColdEffect.java +++ b/src/main/java/com/elenai/feathers/effect/ColdEffect.java @@ -3,43 +3,42 @@ import com.elenai.feathers.capability.PlayerFeathersProvider; import com.elenai.feathers.networking.FeathersMessages; import com.elenai.feathers.networking.packet.ColdSyncSTCPacket; - import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectCategory; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.AttributeMap; +import org.jetbrains.annotations.NotNull; -public class ColdEffect extends MobEffect{ +public class ColdEffect extends MobEffect { public ColdEffect(MobEffectCategory mobEffectCategory, int color) { super(mobEffectCategory, color); } - + @Override - public void addAttributeModifiers(LivingEntity target, AttributeMap map, int strength) { - if(target instanceof ServerPlayer player) { - player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { - if (!f.isCold()) { - f.setCold(true); - FeathersMessages.sendToPlayer(new ColdSyncSTCPacket(f.isCold()), - player); - } - }); - } - super.addAttributeModifiers(target, map, strength); + public void addAttributeModifiers(@NotNull LivingEntity target, @NotNull AttributeMap map, int strength) { + if (target instanceof ServerPlayer player) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + if (!f.isCold()) { + f.setCold(true); + FeathersMessages.sendToPlayer(new ColdSyncSTCPacket(f.isCold()), player); + } + }); + } + super.addAttributeModifiers(target, map, strength); } - + @Override - public void removeAttributeModifiers(LivingEntity target, AttributeMap map, int strength) { - if(target instanceof ServerPlayer player) { - player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { - if (f.isCold()) { - f.setCold(false); - FeathersMessages.sendToPlayer(new ColdSyncSTCPacket(f.isCold()), player); - } - }); - } - super.removeAttributeModifiers(target, map, strength); + public void removeAttributeModifiers(@NotNull LivingEntity target, @NotNull AttributeMap map, int strength) { + if (target instanceof ServerPlayer player) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + if (f.isCold()) { + f.setCold(false); + FeathersMessages.sendToPlayer(new ColdSyncSTCPacket(f.isCold()), player); + } + }); + } + super.removeAttributeModifiers(target, map, strength); } } diff --git a/src/main/java/com/elenai/feathers/effect/EnduranceEffect.java b/src/main/java/com/elenai/feathers/effect/EnduranceEffect.java index b89d256..f41a67f 100644 --- a/src/main/java/com/elenai/feathers/effect/EnduranceEffect.java +++ b/src/main/java/com/elenai/feathers/effect/EnduranceEffect.java @@ -22,7 +22,7 @@ public void addAttributeModifiers(LivingEntity target, AttributeMap map, int str player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { f.setEnduranceFeathers((strength + 1) * 8); FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), - FeathersHelper.getPlayerWeight(player), f.getEnduranceFeathers()), player); + FeathersHelper.getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); }); } super.addAttributeModifiers(target, map, strength); @@ -34,7 +34,7 @@ public void removeAttributeModifiers(LivingEntity target, AttributeMap map, int player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { f.setEnduranceFeathers(0); FeathersMessages.sendToPlayer(new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), - FeathersHelper.getPlayerWeight(player), f.getEnduranceFeathers()), player); + FeathersHelper.getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); }); } super.removeAttributeModifiers(target, map, strength); diff --git a/src/main/java/com/elenai/feathers/effect/FeathersEffects.java b/src/main/java/com/elenai/feathers/effect/FeathersEffects.java index ec6ceb0..8d63c99 100644 --- a/src/main/java/com/elenai/feathers/effect/FeathersEffects.java +++ b/src/main/java/com/elenai/feathers/effect/FeathersEffects.java @@ -13,12 +13,18 @@ public class FeathersEffects { public static final DeferredRegister EFFECTS = DeferredRegister.create(ForgeRegistries.MOB_EFFECTS, Feathers.MODID); - public static final RegistryObject ENDURANCE = EFFECTS.register("endurance", () -> new EnduranceEffect(MobEffectCategory.BENEFICIAL, 16776960)); - public static final RegistryObject COLD = EFFECTS.register("cold", () -> new ColdEffect(MobEffectCategory.HARMFUL, 11993087)); - public static final RegistryObject ENERGIZED = EFFECTS.register("energized", () -> new EnergizedEffect(MobEffectCategory.BENEFICIAL, 7458303)); + public static final RegistryObject ENDURANCE = EFFECTS + .register("endurance", () -> new EnduranceEffect(MobEffectCategory.BENEFICIAL, 16776960)); + public static final RegistryObject COLD = EFFECTS + .register("cold", () -> new ColdEffect(MobEffectCategory.HARMFUL, 11993087)); + public static final RegistryObject ENERGIZED = EFFECTS + .register("energized", () -> new EnergizedEffect(MobEffectCategory.BENEFICIAL, 7458303)); + + public static final RegistryObject HOT = EFFECTS + .register("hot", () -> new HotEffect(MobEffectCategory.HARMFUL, 0x7e5d48)); - public static void register(IEventBus eventBus) { + EFFECTS.register(eventBus); } } diff --git a/src/main/java/com/elenai/feathers/effect/HotEffect.java b/src/main/java/com/elenai/feathers/effect/HotEffect.java new file mode 100644 index 0000000..ed900f2 --- /dev/null +++ b/src/main/java/com/elenai/feathers/effect/HotEffect.java @@ -0,0 +1,41 @@ +package com.elenai.feathers.effect; + +import com.elenai.feathers.capability.PlayerFeathersProvider; +import com.elenai.feathers.networking.FeathersMessages; +import com.elenai.feathers.networking.packet.HotSyncSTCPacket; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.AttributeMap; +import org.jetbrains.annotations.NotNull; + +public class HotEffect extends MobEffect { + public HotEffect(MobEffectCategory mobEffectCategory, int color) {super(mobEffectCategory, color);} + + @Override + public void addAttributeModifiers(@NotNull LivingEntity target, @NotNull AttributeMap map, int strength) { + if (target instanceof ServerPlayer player) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + if (!f.isHot()) { + f.setHot(true); + FeathersMessages.sendToPlayer(new HotSyncSTCPacket(f.isHot()), player); + } + }); + } + super.addAttributeModifiers(target, map, strength); + } + + @Override + public void removeAttributeModifiers(@NotNull LivingEntity target, @NotNull AttributeMap map, int strength) { + if (target instanceof ServerPlayer player) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + if (f.isHot()) { + f.setHot(false); + FeathersMessages.sendToPlayer(new HotSyncSTCPacket(f.isHot()), player); + } + }); + } + super.removeAttributeModifiers(target, map, strength); + } +} diff --git a/src/main/java/com/elenai/feathers/effect/PlayerSituationProvider.java b/src/main/java/com/elenai/feathers/effect/PlayerSituationProvider.java new file mode 100644 index 0000000..efbf4eb --- /dev/null +++ b/src/main/java/com/elenai/feathers/effect/PlayerSituationProvider.java @@ -0,0 +1,61 @@ +package com.elenai.feathers.effect; + +import com.elenai.feathers.Feathers; +import com.elenai.feathers.config.FeathersCommonConfig; +import com.momosoftworks.coldsweat.api.util.Temperature; +import com.momosoftworks.coldsweat.util.registries.ModEffects; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.player.Player; + +public class PlayerSituationProvider { + + + public static boolean isInColdSituation(Player player){ + + boolean isInSnow = player.isInPowderSnow || player.wasInPowderSnow; + + if(Feathers.COLD_SWEAT_LOADED && FeathersCommonConfig.COLD_SWEAT_COMPATIBILITY.get()){ + return Temperature.get(player, Temperature.Trait.BODY) <= -100 || isInSnow; + } + + boolean isInColdBiome = player.level().getBiome(player.blockPosition()).get().coldEnoughToSnow(player.blockPosition()); + + return isInSnow || isInColdBiome; + } + + + public static boolean isInHotSituation(ServerPlayer player){ + + boolean isBurning = player.wasOnFire || player.isOnFire() || player.isInLava(); + + if(Feathers.COLD_SWEAT_LOADED && FeathersCommonConfig.COLD_SWEAT_COMPATIBILITY.get()){ + return Temperature.get(player, Temperature.Trait.BODY) >= 100 || isBurning; + } + + boolean isInHotBiome = player.level().getBiome(player.blockPosition()).get().getModifiedClimateSettings().temperature() > 0.45f; + + return isBurning || isInHotBiome; + } + + public static boolean canBeCold(ServerPlayer player){ + if(!FeathersCommonConfig.ENABLE_COLD_EFFECTS.get() || player.getAbilities().invulnerable || player.isCreative()) return false; + + if(Feathers.COLD_SWEAT_LOADED && FeathersCommonConfig.COLD_SWEAT_COMPATIBILITY.get()){ + if(player.hasEffect(ModEffects.GRACE) || player.hasEffect(ModEffects.ICE_RESISTANCE)){ + return false; + } + } + + return !player.hasEffect(FeathersEffects.ENERGIZED.get()); + } + + public static boolean canBeHot(ServerPlayer player){ + if(!FeathersCommonConfig.ENABLE_HOT_EFFECTS.get() || player.getAbilities().invulnerable || player.isCreative()) return false; + boolean hasResistance = player.hasEffect(MobEffects.FIRE_RESISTANCE); + if(Feathers.COLD_SWEAT_LOADED && FeathersCommonConfig.COLD_SWEAT_COMPATIBILITY.get()){ + return !player.hasEffect(ModEffects.GRACE) && !hasResistance; + } + return !hasResistance; + } +} diff --git a/src/main/java/com/elenai/feathers/enchantment/FeathersEnchantments.java b/src/main/java/com/elenai/feathers/enchantment/FeathersEnchantments.java index 93c4b67..749d44d 100644 --- a/src/main/java/com/elenai/feathers/enchantment/FeathersEnchantments.java +++ b/src/main/java/com/elenai/feathers/enchantment/FeathersEnchantments.java @@ -16,12 +16,12 @@ public class FeathersEnchantments { .create(ForgeRegistries.ENCHANTMENTS, Feathers.MODID); public static RegistryObject LIGHTWEIGHT = ENCHANTMENTS.register("lightweight", - () -> new LightweightEnchantment(Rarity.UNCOMMON, EnchantmentCategory.ARMOR, new EquipmentSlot[] { - EquipmentSlot.CHEST, EquipmentSlot.FEET, EquipmentSlot.HEAD, EquipmentSlot.LEGS })); + () -> new LightweightEnchantment(Rarity.UNCOMMON, EnchantmentCategory.ARMOR, + EquipmentSlot.CHEST, EquipmentSlot.FEET, EquipmentSlot.HEAD, EquipmentSlot.LEGS)); public static RegistryObject HEAVY = ENCHANTMENTS.register("heavy", - () -> new HeavyCurse(Rarity.RARE, EnchantmentCategory.ARMOR, new EquipmentSlot[] { - EquipmentSlot.CHEST, EquipmentSlot.FEET, EquipmentSlot.HEAD, EquipmentSlot.LEGS })); + () -> new HeavyCurse(Rarity.RARE, EnchantmentCategory.ARMOR, + EquipmentSlot.CHEST, EquipmentSlot.FEET, EquipmentSlot.HEAD, EquipmentSlot.LEGS)); public static void register(IEventBus eventBus) { ENCHANTMENTS.register(eventBus); diff --git a/src/main/java/com/elenai/feathers/event/ClientEvents.java b/src/main/java/com/elenai/feathers/event/ClientEvents.java index 03ba57e..7c4f735 100644 --- a/src/main/java/com/elenai/feathers/event/ClientEvents.java +++ b/src/main/java/com/elenai/feathers/event/ClientEvents.java @@ -37,6 +37,7 @@ public static class ClientModBusEvents { public static void registerGuiOverlays(RegisterGuiOverlaysEvent event) { event.registerAbove(VanillaGuiOverlay.FOOD_LEVEL.id(), "feathers", FeathersHudOverlay.FEATHERS); } + } @Mod.EventBusSubscriber(modid = Feathers.MODID, value = Dist.CLIENT) @@ -104,5 +105,6 @@ public static void tooltipRenderer(ItemTooltipEvent event) { } } } + } } \ No newline at end of file diff --git a/src/main/java/com/elenai/feathers/event/CommonEvents.java b/src/main/java/com/elenai/feathers/event/CommonEvents.java index 52ecf1c..65660a8 100644 --- a/src/main/java/com/elenai/feathers/event/CommonEvents.java +++ b/src/main/java/com/elenai/feathers/event/CommonEvents.java @@ -7,11 +7,13 @@ import com.elenai.feathers.capability.PlayerFeathersProvider; import com.elenai.feathers.config.FeathersCommonConfig; import com.elenai.feathers.effect.FeathersEffects; +import com.elenai.feathers.effect.PlayerSituationProvider; import com.elenai.feathers.networking.FeathersMessages; import com.elenai.feathers.networking.packet.ColdSyncSTCPacket; import com.elenai.feathers.networking.packet.EnergizedSyncSTCPacket; import com.elenai.feathers.networking.packet.FeatherSyncSTCPacket; - +import com.elenai.feathers.networking.packet.HotSyncSTCPacket; +import dev.ghen.thirst.foundation.common.capability.ModCapabilities; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.effect.MobEffectInstance; @@ -25,125 +27,259 @@ import net.minecraftforge.event.TickEvent.PlayerTickEvent; import net.minecraftforge.event.entity.EntityJoinLevelEvent; import net.minecraftforge.event.entity.living.LivingEquipmentChangeEvent; +import net.minecraftforge.event.entity.living.MobEffectEvent; import net.minecraftforge.event.entity.player.PlayerEvent; +import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.LogicalSide; import net.minecraftforge.fml.common.Mod; +import org.checkerframework.checker.units.qual.A; + +import java.util.concurrent.atomic.AtomicInteger; @Mod.EventBusSubscriber(modid = Feathers.MODID) public class CommonEvents { - @SubscribeEvent - public static void onPlayerJoinWorld(EntityJoinLevelEvent event) { - Level level = event.getLevel(); - if (!level.isClientSide && (event.getEntity() instanceof ServerPlayer player)) { - player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { - FeathersMessages.sendToPlayer( - new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), FeathersHelper.getPlayerWeight(player), f.getEnduranceFeathers()), player); - FeathersMessages.sendToPlayer(new ColdSyncSTCPacket(f.isCold()), player); - FeathersMessages.sendToPlayer(new EnergizedSyncSTCPacket(player.hasEffect(FeathersEffects.ENERGIZED.get())), player); - }); - } - } - - /** - * Handle the beta cold mechanic here - */ - private static void handleFrostEffect(PlayerTickEvent event) { - if (FeathersCommonConfig.ENABLE_FROST_EFFECTS.get()) { - Level level = event.player.level(); - if ((event.player.isInPowderSnow || event.player.wasInPowderSnow - || level.getBiome(event.player.blockPosition()).get() - .coldEnoughToSnow(event.player.blockPosition()))) { //TODO: Make fire stop ice effect AND make this a potion effect instead - if(!event.player.hasEffect(FeathersEffects.COLD.get()) || event.player.getActiveEffectsMap().get(FeathersEffects.COLD.get()).getDuration() < 1000) { - event.player.addEffect(new MobEffectInstance(FeathersEffects.COLD.get(), 999999, 0, false, true)); - } - } else if (event.player.hasEffect(FeathersEffects.COLD.get()) && event.player.getActiveEffectsMap().get(FeathersEffects.COLD.get()).getDuration() > 201){ - event.player.removeEffect(FeathersEffects.COLD.get()); - event.player.addEffect(new MobEffectInstance(FeathersEffects.COLD.get(), 200, 0, false, true)); - } - } - } - - /** - * Handle the Endurance mechanic here, where the potion leaves if the player has no endurance feathers left - */ - private static void handleEnduranceEffect(PlayerTickEvent event) { - if(event.player.hasEffect(FeathersEffects.ENDURANCE.get()) && FeathersHelper.getEndurance((ServerPlayer) event.player) == 0) { - event.player.removeEffect(FeathersEffects.ENDURANCE.get()); - } - } - - /** - * Regenerate the player's feathers, taking the energized potion into account - * @param event Player Tick Event - */ - private static void regenerateFeathers(PlayerTickEvent event) { - event.player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { - syncFeatherAttributes((ServerPlayer) event.player); - if (f.getFeathers() < f.getMaxFeathers() && (!f.isCold())) { - if(!event.player.hasEffect(FeathersEffects.ENERGIZED.get())) { - f.addCooldown(f.getRegen()); - } else { - f.addCooldown(event.player.getActiveEffectsMap().get(FeathersEffects.ENERGIZED.get()).getAmplifier()+1+f.getRegen()); - } - } - if (f.getCooldown() >= FeathersCommonConfig.COOLDOWN.get()) { - FeathersHelper.addFeathers((ServerPlayer) event.player, 1); - } - }); - } - - private static void syncFeatherAttributes(ServerPlayer player) { - int maxFeathers = (int) player.getAttributeValue(FeathersAttributes.MAX_FEATHERS.get()); - int regen = (int) player.getAttributeValue(FeathersAttributes.FEATHER_REGEN.get()); - FeathersHelper.setMaxFeathers(player, maxFeathers); - FeathersHelper.setFeatherRegen(player, regen); - } - - @SubscribeEvent - public static void playerTickEvent(PlayerTickEvent event) { - if (event.side == LogicalSide.SERVER && event.phase == TickEvent.Phase.START) { - regenerateFeathers(event); - handleFrostEffect(event); - handleEnduranceEffect(event); - } - } - - @SubscribeEvent - public static void onPlayerChangeArmor(LivingEquipmentChangeEvent event) { - if (event.getEntity() instanceof ServerPlayer player && event.getSlot().getType() == EquipmentSlot.Type.ARMOR) { - player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { - FeathersMessages.sendToPlayer( - new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), FeathersHelper.getPlayerWeight(player), f.getEnduranceFeathers()), player); - }); - } - } - - @SubscribeEvent - public static void onAttachCapabilitiesPlayer(AttachCapabilitiesEvent event) { - if (event.getObject() instanceof Player) { - if (!event.getObject().getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).isPresent()) { - event.addCapability(new ResourceLocation(Feathers.MODID, "properties"), new PlayerFeathersProvider()); - } - } - } - - //TODO: Repair this - @SubscribeEvent - public static void onPlayerCloned(PlayerEvent.Clone event) { - if (!event.isWasDeath()) { - event.getOriginal().getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(oldStore -> { - event.getOriginal().getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(newStore -> { - newStore.copyFrom(oldStore); - }); - }); - } - } - - @SubscribeEvent - public static void onRegisterCapabilities(RegisterCapabilitiesEvent event) { - event.register(PlayerFeathers.class); - } + @SubscribeEvent + public static void onPlayerJoinWorld(EntityJoinLevelEvent event) { + Level level = event.getLevel(); + if (!level.isClientSide && (event.getEntity() instanceof ServerPlayer player)) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + FeathersMessages.sendToPlayer( + new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), FeathersHelper.getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); + FeathersMessages.sendToPlayer(new ColdSyncSTCPacket(f.isCold()), player); + FeathersMessages.sendToPlayer(new HotSyncSTCPacket(f.isHot()), player); + FeathersMessages.sendToPlayer(new EnergizedSyncSTCPacket(player.hasEffect(FeathersEffects.ENERGIZED.get())), player); + }); + } + } + + + /** + * Handle the beta cold mechanic here + */ + private static void handleColdEffect(PlayerTickEvent event) { + ServerPlayer player = (ServerPlayer) event.player; + if (PlayerSituationProvider.isInColdSituation(player)) { + + if (!player.hasEffect(FeathersEffects.COLD.get()) || + player.getActiveEffectsMap().get(FeathersEffects.COLD.get()).getDuration() <= 201) { + + if (player.hasEffect(FeathersEffects.HOT.get())) + player.removeEffect(FeathersEffects.HOT.get()); + + player.addEffect(new MobEffectInstance(FeathersEffects.COLD.get(), 1200, 0, false, true)); + } + + } else if (player.hasEffect(FeathersEffects.COLD.get()) && + player.getActiveEffectsMap().get(FeathersEffects.COLD.get()).getDuration() > FeathersCommonConfig.COLD_LINGER.get()) { + + player.removeEffect(FeathersEffects.COLD.get()); + player.addEffect(new MobEffectInstance(FeathersEffects.COLD.get(), + FeathersCommonConfig.COLD_LINGER.get(), 0, false, true)); + } + if (player.isCreative() && player.hasEffect(FeathersEffects.COLD.get())) { + player.removeEffect(FeathersEffects.COLD.get()); + } + } + + /** + * Handle the Fatigue mechanic here + * + * @param event + */ + private static void handleHotEffect(PlayerTickEvent event) { + ServerPlayer player = (ServerPlayer) event.player; + if (PlayerSituationProvider.isInHotSituation(player)) { + + if (!player.hasEffect(FeathersEffects.HOT.get()) || + player.getActiveEffectsMap().get(FeathersEffects.HOT.get()).getDuration() <= 201) { + + if (player.hasEffect(FeathersEffects.COLD.get())) + player.removeEffect(FeathersEffects.COLD.get()); + + player.addEffect(new MobEffectInstance(FeathersEffects.HOT.get(), 1200, 0, false, true)); + } + } else if (player.hasEffect(FeathersEffects.HOT.get())) { + player.removeEffect(FeathersEffects.HOT.get()); + } + + if (player.isCreative() && player.hasEffect(FeathersEffects.HOT.get())) { + player.removeEffect(FeathersEffects.HOT.get()); + } + } + + /** + * Handle the Endurance mechanic here, where the potion leaves if the player has no endurance feathers left + */ + private static void handleEnduranceEffect(PlayerTickEvent event) { + if (FeathersCommonConfig.ENABLE_ENDURANCE.get()) { + if (event.player.hasEffect(FeathersEffects.ENDURANCE.get()) && FeathersHelper.getEndurance((ServerPlayer) event.player) == 0) { + event.player.removeEffect(FeathersEffects.ENDURANCE.get()); + } + } + } + + /** + * Regenerate the player's feathers, taking the energized potion and the cold effect into account + * + * @param event Player Tick Event + */ + private static void regenerateFeathers(PlayerTickEvent event) { + + Player player = event.player; + + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + + int maxCooldown = FeathersCommonConfig.COOLDOWN.get(); + + if (Feathers.THIRST_LOADED && FeathersCommonConfig.THIRST_COMPATIBILITY.get()) { + AtomicInteger thirstReduction = new AtomicInteger(0); + AtomicInteger quenchBonus = new AtomicInteger(0); + + player.getCapability(ModCapabilities.PLAYER_THIRST).ifPresent(iThirst -> { + thirstReduction.set((20-iThirst.getThirst()) * FeathersCommonConfig.THIRST_REGEN_REDUCTION_MULTIPLIER.get()); + quenchBonus.set(iThirst.getQuenched() * FeathersCommonConfig.QUENCH_REGEN_BONUS_MULTIPLIER.get()); + }); + maxCooldown += thirstReduction.get() - quenchBonus.get(); + + } + + syncFeatherAttributes((ServerPlayer) player); + + if (f.getFeathers() < f.getMaxFeathers()) { + + int regen = f.getRegen(); + + if (player.hasEffect(FeathersEffects.ENERGIZED.get())) { + regen += player.getActiveEffectsMap().get(FeathersEffects.ENERGIZED.get()).getAmplifier() + 1; + } + + f.addCooldown(regen); + } + + if (player.hasEffect(FeathersEffects.COLD.get())) { + maxCooldown *= FeathersCommonConfig.COLD_EFFECT_COOLDOWN_MULTIPLIER.get(); + } + + + if (f.getCooldown() >= maxCooldown) { + FeathersHelper.addFeathers((ServerPlayer) player, 1); + } + + f.setMaxCooldown(maxCooldown); + }); + } + + private static void syncFeatherAttributes(ServerPlayer player) { + int maxFeathers = (int) player.getAttributeValue(FeathersAttributes.MAX_FEATHERS.get()); + int regen = (int) player.getAttributeValue(FeathersAttributes.FEATHER_REGEN.get()); + FeathersHelper.setMaxFeathers(player, maxFeathers); + FeathersHelper.setFeatherRegen(player, regen); + } + + @SubscribeEvent + public static void playerTickEvent(PlayerTickEvent event) { + if (event.side == LogicalSide.SERVER && event.phase == TickEvent.Phase.START) { + regenerateFeathers(event); + + if (FeathersCommonConfig.ENABLE_HOT_EFFECTS.get()) + handleHotEffect(event); + + if (FeathersCommonConfig.ENABLE_COLD_EFFECTS.get()) + handleColdEffect(event); + + handleEnduranceEffect(event); + } + } + + @SubscribeEvent + public static void onPlayerChangeArmor(LivingEquipmentChangeEvent event) { + if (event.getEntity() instanceof ServerPlayer player && event.getSlot().getType() == EquipmentSlot.Type.ARMOR) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + FeathersMessages.sendToPlayer( + new FeatherSyncSTCPacket(f.getFeathers(), f.getMaxFeathers(), f.getRegen(), FeathersHelper.getPlayerWeight(player), f.getEnduranceFeathers(), f.getMaxCooldown()), player); + }); + } + } + + @SubscribeEvent + public static void onAttachCapabilitiesPlayer(AttachCapabilitiesEvent event) { + if (event.getObject() instanceof Player) { + if (!event.getObject().getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).isPresent()) { + event.addCapability(new ResourceLocation(Feathers.MODID, "properties"), new PlayerFeathersProvider()); + } + } + } + + //TODO: Repair this + @SubscribeEvent + public static void onPlayerCloned(PlayerEvent.Clone event) { + if (!event.isWasDeath()) { + event.getOriginal().getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(oldStore -> { + event.getOriginal().getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(newStore -> { + newStore.copyFrom(oldStore); + }); + }); + } + } + + @SubscribeEvent + public static void canApplyEffect(MobEffectEvent.Applicable event) { + if (event.getEntity() instanceof ServerPlayer player) { + if (event.getEffectInstance().getEffect() == FeathersEffects.HOT.get()) { + event.setResult(PlayerSituationProvider.canBeHot(player) ? Event.Result.ALLOW : Event.Result.DENY); + } + + if (event.getEffectInstance().getEffect() == FeathersEffects.COLD.get()) { + event.setResult(PlayerSituationProvider.canBeCold(player) ? Event.Result.ALLOW : Event.Result.DENY); + } + } + } + + @SubscribeEvent + public static void onEffectApplied(MobEffectEvent.Added event) { + if (event.getEntity() instanceof ServerPlayer player) { + if (FeathersCommonConfig.ENABLE_HOT_EFFECTS.get() && + event.getEffectInstance().getEffect() == FeathersEffects.HOT.get()) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + FeathersHelper.setHot(player, true); + int maxFeathers = FeathersHelper.getMaxFeathers(player); + if (maxFeathers >= (int) Math.round(FeathersAttributes.MAX_FEATHERS.get().getDefaultValue())) { + FeathersHelper.setMaxFeathers(player, maxFeathers - FeathersCommonConfig.HOT_FEATHER_REDUCTION.get()); + } + + }); + } + + if (FeathersCommonConfig.ENABLE_COLD_EFFECTS.get() && + event.getEffectInstance().getEffect() == FeathersEffects.COLD.get()) { + FeathersHelper.setCold(player, true); + + } + } + + } + + @SubscribeEvent + public static void onEffectRemoved(MobEffectEvent.Remove event) { + if (event.getEntity() instanceof ServerPlayer player) { + if (event.getEffectInstance().getEffect() == FeathersEffects.HOT.get()) { + + FeathersHelper.setHot(player, false); + FeathersHelper.setMaxFeathers(player, (int) Math.round(FeathersAttributes.MAX_FEATHERS.get().getDefaultValue())); + } + if (event.getEffectInstance().getEffect() == FeathersEffects.COLD.get()) { + player.getCapability(PlayerFeathersProvider.PLAYER_FEATHERS).ifPresent(f -> { + FeathersHelper.setCold(player, false); + }); + } + } + } + + @SubscribeEvent + public static void onRegisterCapabilities(RegisterCapabilitiesEvent event) { + event.register(PlayerFeathers.class); + } } \ No newline at end of file diff --git a/src/main/java/com/elenai/feathers/networking/FeathersMessages.java b/src/main/java/com/elenai/feathers/networking/FeathersMessages.java index 997d542..5e0569e 100644 --- a/src/main/java/com/elenai/feathers/networking/FeathersMessages.java +++ b/src/main/java/com/elenai/feathers/networking/FeathersMessages.java @@ -1,12 +1,7 @@ package com.elenai.feathers.networking; import com.elenai.feathers.Feathers; -import com.elenai.feathers.networking.packet.ColdSyncSTCPacket; -import com.elenai.feathers.networking.packet.EnergizedSyncSTCPacket; -import com.elenai.feathers.networking.packet.FeatherSyncCTSPacket; -import com.elenai.feathers.networking.packet.FeatherSyncSTCPacket; -import com.elenai.feathers.networking.packet.ReplyWithWeightSTCPacket; -import com.elenai.feathers.networking.packet.RequestWeightCTSPacket; +import com.elenai.feathers.networking.packet.*; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; @@ -16,63 +11,70 @@ import net.minecraftforge.network.simple.SimpleChannel; public class FeathersMessages { - private static SimpleChannel INSTANCE; + private static SimpleChannel INSTANCE; - private static int packetId = 0; + private static int packetId = 0; - private static int id() { - return packetId++; - } + private static int id() { + return packetId++; + } + + public static void register() { + SimpleChannel network = NetworkRegistry.ChannelBuilder.named(new ResourceLocation(Feathers.MODID, "messages")) + .networkProtocolVersion(() -> "1.0").clientAcceptedVersions(s -> true) + .serverAcceptedVersions(s -> true) + .simpleChannel(); + INSTANCE = network; - public static void register() { - SimpleChannel network = NetworkRegistry.ChannelBuilder.named(new ResourceLocation(Feathers.MODID, "messages")) - .networkProtocolVersion(() -> "1.0").clientAcceptedVersions(s -> true).serverAcceptedVersions(s -> true) - .simpleChannel(); - INSTANCE = network; - network.messageBuilder(FeatherSyncCTSPacket.class, id(), NetworkDirection.PLAY_TO_SERVER) - .decoder(FeatherSyncCTSPacket::new) - .encoder(FeatherSyncCTSPacket::toBytes) - .consumerMainThread(FeatherSyncCTSPacket::handle) - .add(); - + .decoder(FeatherSyncCTSPacket::new) + .encoder(FeatherSyncCTSPacket::toBytes) + .consumerMainThread(FeatherSyncCTSPacket::handle) + .add(); + network.messageBuilder(RequestWeightCTSPacket.class, id(), NetworkDirection.PLAY_TO_SERVER) - .decoder(RequestWeightCTSPacket::new) - .encoder(RequestWeightCTSPacket::toBytes) - .consumerMainThread(RequestWeightCTSPacket::handle) - .add(); - + .decoder(RequestWeightCTSPacket::new) + .encoder(RequestWeightCTSPacket::toBytes) + .consumerMainThread(RequestWeightCTSPacket::handle) + .add(); + network.messageBuilder(ReplyWithWeightSTCPacket.class, id(), NetworkDirection.PLAY_TO_CLIENT) - .decoder(ReplyWithWeightSTCPacket::new) - .encoder(ReplyWithWeightSTCPacket::toBytes) - .consumerMainThread(ReplyWithWeightSTCPacket::handle) - .add(); - + .decoder(ReplyWithWeightSTCPacket::new) + .encoder(ReplyWithWeightSTCPacket::toBytes) + .consumerMainThread(ReplyWithWeightSTCPacket::handle) + .add(); + network.messageBuilder(FeatherSyncSTCPacket.class, id(), NetworkDirection.PLAY_TO_CLIENT) - .decoder(FeatherSyncSTCPacket::new) - .encoder(FeatherSyncSTCPacket::toBytes) - .consumerMainThread(FeatherSyncSTCPacket::handle) - .add(); - + .decoder(FeatherSyncSTCPacket::new) + .encoder(FeatherSyncSTCPacket::toBytes) + .consumerMainThread(FeatherSyncSTCPacket::handle) + .add(); + network.messageBuilder(ColdSyncSTCPacket.class, id(), NetworkDirection.PLAY_TO_CLIENT) - .decoder(ColdSyncSTCPacket::new) - .encoder(ColdSyncSTCPacket::toBytes) - .consumerMainThread(ColdSyncSTCPacket::handle) - .add(); - + .decoder(ColdSyncSTCPacket::new) + .encoder(ColdSyncSTCPacket::toBytes) + .consumerMainThread(ColdSyncSTCPacket::handle) + .add(); + network.messageBuilder(EnergizedSyncSTCPacket.class, id(), NetworkDirection.PLAY_TO_CLIENT) - .decoder(EnergizedSyncSTCPacket::new) - .encoder(EnergizedSyncSTCPacket::toBytes) - .consumerMainThread(EnergizedSyncSTCPacket::handle) - .add(); - - } - - public static void sendToServer(MSG message) { - INSTANCE.sendToServer(message); - } - - public static void sendToPlayer(MSG message, ServerPlayer player) { - INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message); - } + .decoder(EnergizedSyncSTCPacket::new) + .encoder(EnergizedSyncSTCPacket::toBytes) + .consumerMainThread(EnergizedSyncSTCPacket::handle) + .add(); + + network.messageBuilder(HotSyncSTCPacket.class, id(), NetworkDirection.PLAY_TO_CLIENT) + .decoder(HotSyncSTCPacket::new) + .encoder(HotSyncSTCPacket::toBytes) + .consumerMainThread(HotSyncSTCPacket::handle) + .add(); + + } + + public static void sendToServer(MSG message) { + INSTANCE.sendToServer(message); + } + + public static void sendToPlayer(MSG message, ServerPlayer player) { + INSTANCE.send(PacketDistributor.PLAYER.with(() -> player), message); + } } diff --git a/src/main/java/com/elenai/feathers/networking/packet/ColdSyncSTCPacket.java b/src/main/java/com/elenai/feathers/networking/packet/ColdSyncSTCPacket.java index 5e1b812..108d2dd 100644 --- a/src/main/java/com/elenai/feathers/networking/packet/ColdSyncSTCPacket.java +++ b/src/main/java/com/elenai/feathers/networking/packet/ColdSyncSTCPacket.java @@ -16,7 +16,7 @@ public class ColdSyncSTCPacket { private final boolean cold; public ColdSyncSTCPacket(boolean cold) { - this.cold = cold; + this.cold = cold; } public ColdSyncSTCPacket(FriendlyByteBuf buf) { diff --git a/src/main/java/com/elenai/feathers/networking/packet/FeatherSyncSTCPacket.java b/src/main/java/com/elenai/feathers/networking/packet/FeatherSyncSTCPacket.java index 6fbce45..7f28e9c 100644 --- a/src/main/java/com/elenai/feathers/networking/packet/FeatherSyncSTCPacket.java +++ b/src/main/java/com/elenai/feathers/networking/packet/FeatherSyncSTCPacket.java @@ -1,52 +1,57 @@ package com.elenai.feathers.networking.packet; -import java.util.function.Supplier; - import com.elenai.feathers.client.ClientFeathersData; - import net.minecraft.network.FriendlyByteBuf; import net.minecraftforge.network.NetworkEvent; +import java.util.function.Supplier; + public class FeatherSyncSTCPacket { - private final int feathers; - private final int maxFeathers; - private final int regenRate; - private final int weight; - private final int endurance; - - public FeatherSyncSTCPacket(int feathers, int maxFeathers, int regenRate, int weight, int endurance) { - this.feathers = feathers; - this.maxFeathers = maxFeathers; - this.regenRate = regenRate; - this.weight = weight; - this.endurance = endurance; - } - - public FeatherSyncSTCPacket(FriendlyByteBuf buf) { - this.feathers = buf.readInt(); - this.maxFeathers = buf.readInt(); - this.regenRate = buf.readInt(); - this.weight = buf.readInt(); - this.endurance = buf.readInt(); - } - - public void toBytes(FriendlyByteBuf buf) { - buf.writeInt(feathers); - buf.writeInt(maxFeathers); - buf.writeInt(regenRate); - buf.writeInt(weight); - buf.writeInt(endurance); - } - - public boolean handle(Supplier supplier) { - NetworkEvent.Context context = supplier.get(); - context.enqueueWork(() -> { - ClientFeathersData.setFeathers(feathers); - ClientFeathersData.setMaxFeathers(maxFeathers); - ClientFeathersData.setRegenRate(regenRate); - ClientFeathersData.setWeight(weight); - ClientFeathersData.setEnduranceFeathers(endurance); - }); - return true; - } + private final int feathers; + private final int maxFeathers; + private final int regenRate; + private final int weight; + private final int endurance; + + private final int maxCooldown; + + public FeatherSyncSTCPacket(int feathers, int maxFeathers, int regenRate, int weight, int endurance, int maxCooldown) { + this.feathers = feathers; + this.maxFeathers = maxFeathers; + this.regenRate = regenRate; + this.weight = weight; + this.endurance = endurance; + this.maxCooldown = maxCooldown; + } + + public FeatherSyncSTCPacket(FriendlyByteBuf buf) { + this.feathers = buf.readInt(); + this.maxFeathers = buf.readInt(); + this.regenRate = buf.readInt(); + this.weight = buf.readInt(); + this.endurance = buf.readInt(); + this.maxCooldown = buf.readInt(); + } + + public void toBytes(FriendlyByteBuf buf) { + buf.writeInt(feathers); + buf.writeInt(maxFeathers); + buf.writeInt(regenRate); + buf.writeInt(weight); + buf.writeInt(endurance); + buf.writeInt(maxCooldown); + } + + public boolean handle(Supplier supplier) { + NetworkEvent.Context context = supplier.get(); + context.enqueueWork(() -> { + ClientFeathersData.setFeathers(feathers); + ClientFeathersData.setMaxFeathers(maxFeathers); + ClientFeathersData.setRegenRate(regenRate); + ClientFeathersData.setWeight(weight); + ClientFeathersData.setEnduranceFeathers(endurance); + ClientFeathersData.setMaxCooldown(maxCooldown); + }); + return true; + } } diff --git a/src/main/java/com/elenai/feathers/networking/packet/HotSyncSTCPacket.java b/src/main/java/com/elenai/feathers/networking/packet/HotSyncSTCPacket.java new file mode 100644 index 0000000..7de5467 --- /dev/null +++ b/src/main/java/com/elenai/feathers/networking/packet/HotSyncSTCPacket.java @@ -0,0 +1,33 @@ +package com.elenai.feathers.networking.packet; + +import com.elenai.feathers.client.ClientFeathersData; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.network.NetworkEvent; + +import java.util.function.Supplier; + +public class HotSyncSTCPacket { + + private final boolean hot; + + public HotSyncSTCPacket(boolean hot) { + this.hot = hot; + } + + public HotSyncSTCPacket(FriendlyByteBuf buf) { + this.hot = buf.readBoolean(); + } + + public void toBytes(FriendlyByteBuf buf) { + buf.writeBoolean(hot); + } + + public boolean handle(Supplier supplier) { + NetworkEvent.Context context = supplier.get(); + context.enqueueWork(() -> { + ClientFeathersData.setHot(hot); + }); + return true; + } + +} diff --git a/src/main/java/com/elenai/feathers/potion/FeathersPotions.java b/src/main/java/com/elenai/feathers/potion/FeathersPotions.java index 4d8c98e..4796e51 100644 --- a/src/main/java/com/elenai/feathers/potion/FeathersPotions.java +++ b/src/main/java/com/elenai/feathers/potion/FeathersPotions.java @@ -19,11 +19,13 @@ public class FeathersPotions { public static final RegistryObject LONG_ENDURANCE_POTION = POTIONS.register("long_endurance_potion", () -> new Potion(new MobEffectInstance(FeathersEffects.ENDURANCE.get(), 4200, 0))); public static final RegistryObject COLD_POTION = POTIONS.register("cold_potion", () -> new Potion(new MobEffectInstance(FeathersEffects.COLD.get(), 5000, 0))); - + public static final RegistryObject HOT_POTION = POTIONS.register("hot_potion", () -> new Potion(new MobEffectInstance(FeathersEffects.HOT.get(), 5000, 0))); + public static final RegistryObject ENERGIZED_POTION = POTIONS.register("energized_potion", () -> new Potion(new MobEffectInstance(FeathersEffects.ENERGIZED.get(), 1600, 0))); public static final RegistryObject STRONG_ENERGIZED_POTION = POTIONS.register("strong_energized_potion", () -> new Potion(new MobEffectInstance(FeathersEffects.ENERGIZED.get(), 1000, 1))); public static final RegistryObject LONG_ENERGIZED_POTION = POTIONS.register("long_energized_potion", () -> new Potion(new MobEffectInstance(FeathersEffects.ENERGIZED.get(), 2600, 0))); + public static void register(IEventBus eventBus) { POTIONS.register(eventBus); } diff --git a/src/main/resources/assets/feathers/lang/de_de.json b/src/main/resources/assets/feathers/lang/de_de.json new file mode 100644 index 0000000..71e2e0a --- /dev/null +++ b/src/main/resources/assets/feathers/lang/de_de.json @@ -0,0 +1,47 @@ +{ + "feathers.max_feathers": "Maximale Federn", + "feathers.feather_regen": "Feder Regeneration", + + "effect.feathers.endurance": "Ausdauer", + "item.minecraft.potion.effect.endurance_potion": "Trank der Ausdauer", + "item.minecraft.splash_potion.effect.endurance_potion": "Wurftrank der Ausdauer", + "item.minecraft.lingering_potion.effect.endurance_potion": "Linger Trank der Ausdauer", + "item.minecraft.tipped_arrow.effect.endurance_potion": "Pfeil der Ausdauer", + + "item.minecraft.potion.effect.long_endurance_potion": "Trank der Ausdauer", + "item.minecraft.splash_potion.effect.long_endurance_potion": "Wurftrank der Ausdauer", + "item.minecraft.lingering_potion.effect.long_endurance_potion": "Linger Trank der Ausdauer", + "item.minecraft.tipped_arrow.effect.long_endurance_potion": "Pfeil der Ausdauer", + + "item.minecraft.potion.effect.strong_endurance_potion": "Trank der Ausdauer", + "item.minecraft.splash_potion.effect.strong_endurance_potion": "Wurftrank der Ausdauer", + "item.minecraft.lingering_potion.effect.strong_endurance_potion": "Linger Trank der Ausdauer", + "item.minecraft.tipped_arrow.effect.strong_endurance_potion": "Pfeil der Ausdauer", + + "effect.feathers.cold": "Kälte", + "item.minecraft.potion.effect.cold_potion": "Trank der Kälte", + "item.minecraft.splash_potion.effect.cold_potion": "Wurftrank der Kälte", + "item.minecraft.lingering_potion.effect.cold_potion": "Linger Trank der Kälte", + "item.minecraft.tipped_arrow.effect.cold_potion": "Pfeil der Kälte", + + "effect.feathers.energized": "Energiegeladen", + "item.minecraft.potion.effect.energized_potion": "Trank der Energie", + "item.minecraft.splash_potion.effect.energized_potion": "Wurftrank der Energie", + "item.minecraft.lingering_potion.effect.energized_potion": "Linger Trank der Energie", + "item.minecraft.tipped_arrow.effect.energized_potion": "Pfeil der Energie", + + "item.minecraft.potion.effect.strong_energized_potion": "Trank der Energie", + "item.minecraft.splash_potion.effect.strong_energized_potion": "Wurftrank der Energie", + "item.minecraft.lingering_potion.effect.strong_energized_potion": "Linger Trank der Energie", + "item.minecraft.tipped_arrow.effect.strong_energized_potion": "Pfeil der Ausdauer", + + "item.minecraft.potion.effect.long_energized_potion": "Trank der Energie", + "item.minecraft.splash_potion.effect.long_energized_potion": "Wurftrank der Energie", + "item.minecraft.lingering_potion.effect.long_energized_potion": "Linger Trank der Energie", + "item.minecraft.tipped_arrow.effect.long_energized_potion": "Pfeil der Energie", + + "enchantment.feathers.lightweight": "Leichtgewicht", + "enchantment.feathers.heavy": "Fluch der Schwere", + + "text.feathers.tooltip": "+%s Gewicht" +} diff --git a/src/main/resources/assets/feathers/lang/en_us.json b/src/main/resources/assets/feathers/lang/en_us.json index f3e022a..dbca4b7 100644 --- a/src/main/resources/assets/feathers/lang/en_us.json +++ b/src/main/resources/assets/feathers/lang/en_us.json @@ -24,6 +24,12 @@ "item.minecraft.lingering_potion.effect.cold_potion": "Lingering Potion of Coldness", "item.minecraft.tipped_arrow.effect.cold_potion": "Arrow of Coldness", + "effect.feathers.hot": "Hot", + "item.minecraft.potion.effect.hot_potion": "Potion of Heat", + "item.minecraft.splash_potion.effect.hot_potion": "Splash Potion of Heat", + "item.minecraft.lingering_potion.effect.hot_potion": "Lingering Potion of Heat", + "item.minecraft.tipped_arrow.effect.hot_potion": "Arrow of Heat", + "effect.feathers.energized": "Energized", "item.minecraft.potion.effect.energized_potion": "Potion of Energy", "item.minecraft.splash_potion.effect.energized_potion": "Splash Potion of Energy", diff --git a/src/main/resources/assets/feathers/lang/es_es.json b/src/main/resources/assets/feathers/lang/es_es.json new file mode 100644 index 0000000..63e09a7 --- /dev/null +++ b/src/main/resources/assets/feathers/lang/es_es.json @@ -0,0 +1,47 @@ +{ + "feathers.max_feathers": "Plumas Máximas", + "feathers.feather_regen": "Recuperación de Plumas", + + "effect.feathers.endurance": "Resistencia", + "item.minecraft.potion.effect.endurance_potion": "Poción de Resistencia", + "item.minecraft.splash_potion.effect.endurance_potion": "Poción Arrojadiza de Resistencia", + "item.minecraft.lingering_potion.effect.endurance_potion": "Poción Persistente de Resistencia", + "item.minecraft.tipped_arrow.effect.endurance_potion": "Flecha de Resistencia", + + "item.minecraft.potion.effect.long_endurance_potion": "Poción de Resistencia", + "item.minecraft.splash_potion.effect.long_endurance_potion": "Poción Arrojadiza de Resistencia", + "item.minecraft.lingering_potion.effect.long_endurance_potion": "Poción Persistente de Resistencia", + "item.minecraft.tipped_arrow.effect.long_endurance_potion": "Flecha de Resistencia", + + "item.minecraft.potion.effect.strong_endurance_potion": "Poción de Resistencia", + "item.minecraft.splash_potion.effect.strong_endurance_potion": "Poción Arrojadiza de Resistencia", + "item.minecraft.lingering_potion.effect.strong_endurance_potion": "Poción Persistente de Resistencia", + "item.minecraft.tipped_arrow.effect.strong_endurance_potion": "Flecha de Resistencia", + + "effect.feathers.cold": "Frío", + "item.minecraft.potion.effect.cold_potion": "Poción de Frialdad", + "item.minecraft.splash_potion.effect.cold_potion": "Poción Arrojadiza de Frialdad", + "item.minecraft.lingering_potion.effect.cold_potion": "Poción Persistente de Frialdad", + "item.minecraft.tipped_arrow.effect.cold_potion": "Flecha de Frialdad", + + "effect.feathers.energized": "Energizado", + "item.minecraft.potion.effect.energized_potion": "Poción de Energía", + "item.minecraft.splash_potion.effect.energized_potion": "Poción Arrojadiza de Energía", + "item.minecraft.lingering_potion.effect.energized_potion": "Poción Persistente de Energía", + "item.minecraft.tipped_arrow.effect.energized_potion": "Flecha de Energía", + + "item.minecraft.potion.effect.strong_energized_potion": "Poción de Energía", + "item.minecraft.splash_potion.effect.strong_energized_potion": "Poción Arrojadiza de Energía", + "item.minecraft.lingering_potion.effect.strong_energized_potion": "Poción Persistente de Energía", + "item.minecraft.tipped_arrow.effect.strong_energized_potion": "Flecha de Resistencia", + + "item.minecraft.potion.effect.long_energized_potion": "Poción de Energía", + "item.minecraft.splash_potion.effect.long_energized_potion": "Poción Arrojadiza de Energía", + "item.minecraft.lingering_potion.effect.long_energized_potion": "Poción Persistente de Energía", + "item.minecraft.tipped_arrow.effect.long_energized_potion": "Flecha de Energía", + + "enchantment.feathers.lightweight": "Ligero", + "enchantment.feathers.heavy": "Maldición de Pesadez", + + "text.feathers.tooltip": "+%s Peso" +} diff --git a/src/main/resources/assets/feathers/textures/gui/icons.png b/src/main/resources/assets/feathers/textures/gui/icons.png index df3d344..56d1f18 100644 Binary files a/src/main/resources/assets/feathers/textures/gui/icons.png and b/src/main/resources/assets/feathers/textures/gui/icons.png differ diff --git a/src/main/resources/assets/feathers/textures/mob_effect/hot.png b/src/main/resources/assets/feathers/textures/mob_effect/hot.png new file mode 100644 index 0000000..0a8cdee Binary files /dev/null and b/src/main/resources/assets/feathers/textures/mob_effect/hot.png differ