From 0bfbacfc9d81285dd28e9cb238511edf9f751820 Mon Sep 17 00:00:00 2001 From: Javier Darkona Date: Sat, 25 May 2024 07:47:57 -0400 Subject: [PATCH] Added compatibility with Thirst Was Taken: Thirst reduces regeneration speed, being quenched increases it. Added compatibility with Cold Sweat: Being cold induces Cold effect, being hot induces Hot effect. Added new effect and potion "Hot", which reduces maximum feathers. Added Spanish and German localizations. Added alternate green feathers texture. Added golden texture for Energized effect. Refactored some code in overlay for easier addition of elements in the future. --- build.gradle | 25 ++ gradle.properties | 64 +--- .../java/com/elenai/feathers/Feathers.java | 4 + .../elenai/feathers/api/FeathersHelper.java | 38 +- .../attributes/FeathersAttributes.java | 6 +- .../feathers/capability/PlayerFeathers.java | 18 +- .../capability/PlayerFeathersProvider.java | 4 +- .../feathers/client/ClientFeathersData.java | 20 +- .../client/gui/FeathersHudOverlay.java | 170 +++++--- .../feathers/client/gui/GuiIconCoord.java | 19 + .../feathers/command/CommandGetFeathers.java | 4 + .../feathers/command/CommandSetFeathers.java | 6 + .../feathers/command/FeathersCommands.java | 18 + .../feathers/config/FeathersClientConfig.java | 7 +- .../feathers/config/FeathersCommonConfig.java | 182 +++++++-- .../elenai/feathers/effect/ColdEffect.java | 49 ++- .../feathers/effect/EnduranceEffect.java | 4 +- .../feathers/effect/FeathersEffects.java | 14 +- .../com/elenai/feathers/effect/HotEffect.java | 41 ++ .../effect/PlayerSituationProvider.java | 61 +++ .../enchantment/FeathersEnchantments.java | 8 +- .../elenai/feathers/event/ClientEvents.java | 2 + .../elenai/feathers/event/CommonEvents.java | 362 ++++++++++++------ .../feathers/networking/FeathersMessages.java | 114 +++--- .../networking/packet/ColdSyncSTCPacket.java | 2 +- .../packet/FeatherSyncSTCPacket.java | 93 ++--- .../networking/packet/HotSyncSTCPacket.java | 33 ++ .../feathers/potion/FeathersPotions.java | 4 +- .../resources/assets/feathers/lang/de_de.json | 47 +++ .../resources/assets/feathers/lang/en_us.json | 6 + .../resources/assets/feathers/lang/es_es.json | 47 +++ .../assets/feathers/textures/gui/icons.png | Bin 2021 -> 6127 bytes .../feathers/textures/mob_effect/hot.png | Bin 0 -> 4556 bytes 33 files changed, 1067 insertions(+), 405 deletions(-) create mode 100644 src/main/java/com/elenai/feathers/client/gui/GuiIconCoord.java create mode 100644 src/main/java/com/elenai/feathers/command/CommandGetFeathers.java create mode 100644 src/main/java/com/elenai/feathers/command/CommandSetFeathers.java create mode 100644 src/main/java/com/elenai/feathers/command/FeathersCommands.java create mode 100644 src/main/java/com/elenai/feathers/effect/HotEffect.java create mode 100644 src/main/java/com/elenai/feathers/effect/PlayerSituationProvider.java create mode 100644 src/main/java/com/elenai/feathers/networking/packet/HotSyncSTCPacket.java create mode 100644 src/main/resources/assets/feathers/lang/de_de.json create mode 100644 src/main/resources/assets/feathers/lang/es_es.json create mode 100644 src/main/resources/assets/feathers/textures/mob_effect/hot.png 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 df3d344c26e5fc4283e341393f09c09d0e22dca0..56d1f184e62e75f5fc539e4ede8097836ca93c15 100644 GIT binary patch literal 6127 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 SU2O$r5gB8r8|tQH6#WP4A(R3D literal 0 HcmV?d00001