diff --git a/build.gradle b/build.gradle index 548bf9d3..f2dc820b 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,9 @@ repositories { maven { url "https://maven.terraformersmc.com/" } + maven { + url "https://maven.nucleoid.xyz/" + } maven { url = "https://www.cursemaven.com" } @@ -50,6 +53,8 @@ dependencies { implementation 'net.objecthunter:exp4j:0.4.8' include 'net.objecthunter:exp4j:0.4.8' + + modImplementation include("eu.pb4:placeholder-api:${project.placeholder_api}") } processResources { diff --git a/gradle.properties b/gradle.properties index 03fbb323..aaa0b6fc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.11.6 # Mod Properties - mod_version = 3.0.1 + mod_version = 3.0.2 maven_group = com.github.clevernucleus archives_base_name = playerex @@ -16,4 +16,5 @@ org.gradle.jvmargs=-Xmx1G fabric_version=0.37.1+1.17 cardinal_components_version=3.1.1 cloth_config_version=5.0.38 + placeholder_api=1.1.1+1.17.1 modmenu_version=2.0.4 diff --git a/src/main/java/com/github/clevernucleus/playerex/PlayerEx.java b/src/main/java/com/github/clevernucleus/playerex/PlayerEx.java index ada6c165..caf8a95a 100644 --- a/src/main/java/com/github/clevernucleus/playerex/PlayerEx.java +++ b/src/main/java/com/github/clevernucleus/playerex/PlayerEx.java @@ -11,7 +11,9 @@ import com.github.clevernucleus.playerex.handler.EventHandler; import com.github.clevernucleus.playerex.handler.NetworkHandler; import com.github.clevernucleus.playerex.impl.ModifierJsonLoader; +import com.github.clevernucleus.playerex.util.StoredPlaceholder; +import eu.pb4.placeholders.PlaceholderAPI; import me.shedaniel.autoconfig.AutoConfig; import me.shedaniel.autoconfig.serializer.GsonConfigSerializer; import net.fabricmc.api.ModInitializer; @@ -31,7 +33,7 @@ public final class PlayerEx implements ModInitializer { public static final ModifierJsonLoader MANAGER = new ModifierJsonLoader(); /** Manual; ugh, I know. */ - public static final String VERSION = "3.0.1"; + public static final String VERSION = "3.0.2"; public static final ConfigCache CONFIG = new ConfigCache(); public static final SoundEvent LEVEL_UP_SOUND = new SoundEvent(new Identifier(ExAPI.MODID, "level_up")); public static final SoundEvent SP_SPEND_SOUND = new SoundEvent(new Identifier(ExAPI.MODID, "sp_spend")); @@ -58,5 +60,7 @@ public void onInitialize() { Registry.register(Registry.SOUND_EVENT, LEVEL_UP_SOUND.getId(), LEVEL_UP_SOUND); Registry.register(Registry.SOUND_EVENT, SP_SPEND_SOUND.getId(), SP_SPEND_SOUND); + + StoredPlaceholder.STORE.forEach(PlaceholderAPI::register); } } diff --git a/src/main/java/com/github/clevernucleus/playerex/util/PlayerLevelPair.java b/src/main/java/com/github/clevernucleus/playerex/util/PlayerLevelPair.java new file mode 100644 index 00000000..2af3faef --- /dev/null +++ b/src/main/java/com/github/clevernucleus/playerex/util/PlayerLevelPair.java @@ -0,0 +1,26 @@ +package com.github.clevernucleus.playerex.util; + +import java.util.Arrays; +import java.util.Comparator; + +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Pair; +import net.minecraft.util.math.MathHelper; + +public final class PlayerLevelPair extends Pair { + public PlayerLevelPair(PlayerEntity player, int level) { + super(player, level); + } + + public int cast() { + return this.getRight(); + } + + public static PlayerLevelPair sort(PlayerLevelPair[] pairs, final int place) { + Arrays.sort(pairs, Comparator.comparing(PlayerLevelPair::cast)); + + int index = MathHelper.clamp(place, 1, pairs.length); + + return pairs[pairs.length - index]; + } +} diff --git a/src/main/java/com/github/clevernucleus/playerex/util/StoredPlaceholder.java b/src/main/java/com/github/clevernucleus/playerex/util/StoredPlaceholder.java new file mode 100644 index 00000000..e7a08dcc --- /dev/null +++ b/src/main/java/com/github/clevernucleus/playerex/util/StoredPlaceholder.java @@ -0,0 +1,77 @@ +package com.github.clevernucleus.playerex.util; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.github.clevernucleus.playerex.api.ExAPI; + +import eu.pb4.placeholders.PlaceholderHandler; +import eu.pb4.placeholders.PlaceholderResult; +import net.minecraft.entity.attribute.AttributeContainer; +import net.minecraft.entity.attribute.EntityAttribute; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; + +public final class StoredPlaceholder { + public static final Map STORE = new HashMap(); + + private static void register(final String key, final PlaceholderHandler handler) { + STORE.put(new Identifier(ExAPI.MODID, key), handler); + } + + private static PlaceholderHandler specificLevelPlacement(final int place) { + return ctx -> { + MinecraftServer server = ctx.getServer(); + PlayerManager manager = server.getPlayerManager(); + EntityAttribute attribute = ExAPI.LEVEL.get(); + + if(attribute == null) return PlaceholderResult.value(""); + + List players = manager.getPlayerList(); + int size = players.size(); + + PlayerLevelPair[] pairs = new PlayerLevelPair[size]; + + if(place > size) return PlaceholderResult.value(""); + + for(int i = 0; i < size; i++) { + ServerPlayerEntity player = players.get(i); + AttributeContainer container = player.getAttributes(); + + if(!container.hasAttribute(attribute)) continue; + + int level = Math.round((float)container.getValue(attribute)); + pairs[i] = new PlayerLevelPair(player, level); + } + + PlayerEntity result = PlayerLevelPair.sort(pairs, place).getLeft(); + + return PlaceholderResult.value(result.getName()); + }; + } + + static { + register("level", ctx -> { + PlayerEntity player = ctx.getPlayer(); + + if(player == null) return PlaceholderResult.value("n/a"); + + AttributeContainer container = player.getAttributes(); + EntityAttribute attribute = ExAPI.LEVEL.get(); + + if(attribute == null || !container.hasAttribute(attribute)) return PlaceholderResult.value("n/a"); + + int level = Math.round((float)container.getValue(attribute)); + + return PlaceholderResult.value(String.valueOf(level)); + }); + + for(int i = 1; i < 11; i++) { + register("level_top_" + i, specificLevelPlacement(i)); + } + } +} diff --git a/src/main/resources/assets/playerex/lang/en_us.json b/src/main/resources/assets/playerex/lang/en_us.json index 1d8d628e..5b5e2c69 100644 --- a/src/main/resources/assets/playerex/lang/en_us.json +++ b/src/main/resources/assets/playerex/lang/en_us.json @@ -4,14 +4,14 @@ "text.autoconfig.playerex.category.client": "Client Options", "text.autoconfig.playerex.option.resetOnDeath": "Reset On Death", "text.autoconfig.playerex.option.resetOnDeath.@Tooltip[0]": "Resets all attributes to their default value on respawn.", - "text.autoconfig.playerex.option.resetOnDeath.@Tooltip[1]": "(Requires world restart)", + "text.autoconfig.playerex.option.resetOnDeath.@Tooltip[1]": "(Requires restart)", "text.autoconfig.playerex.option.showLevelNameplates": "Level Nameplates", "text.autoconfig.playerex.option.showLevelNameplates.@Tooltip[0]": "Displays a nameplate above the player showing their level.", - "text.autoconfig.playerex.option.showLevelNameplates.@Tooltip[1]": "(Requires world restart)", + "text.autoconfig.playerex.option.showLevelNameplates.@Tooltip[1]": "(Requires restart)", "text.autoconfig.playerex.option.levelFormula": "Level Up Formula", "text.autoconfig.playerex.option.levelFormula.@Tooltip[0]": "The number of experience points required to level up. The 'x' ", "text.autoconfig.playerex.option.levelFormula.@Tooltip[1]": "variable refers to the entity's current level; 'x' is required.", - "text.autoconfig.playerex.option.levelFormula.@Tooltip[2]": "(Requires world restart)", + "text.autoconfig.playerex.option.levelFormula.@Tooltip[2]": "(Requires restart)", "text.autoconfig.playerex.option.levelUpVolume": "Level Up Volume", "text.autoconfig.playerex.option.levelUpVolume.@Tooltip": "Volume multiplier as a percentage.", "text.autoconfig.playerex.option.skillUpVolume": "Skill Up Volume", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 2617aaba..835d08d1 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -41,11 +41,9 @@ "depends": { "fabricloader": ">=0.11.3", - "fabric": "*", + "fabric": ">=0.37.1", "minecraft": "1.17.x", - "java": ">=16" - }, - "suggests": { - "another-mod": "*" + "java": ">=16", + "dataattributes": ">=1.0.1" } }