From 3738651e8294eb264e8103ea287c25980ea8d3d1 Mon Sep 17 00:00:00 2001 From: Bibi Reden <redwitblue@gmail.com> Date: Mon, 12 Aug 2024 11:16:44 -0500 Subject: [PATCH 1/3] crowdin.yml --- crowdin.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 crowdin.yml diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 00000000..1df3d57b --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,3 @@ +files: + - source: /src/main/resources/assets/playerex/lang/en_us.json + translation: /src/main/resources/assets/playerex/lang/%locale%.json From 5d3f63ab7d4541cdefcd701eff0cad78a5342dee Mon Sep 17 00:00:00 2001 From: Bibi Reden <redwitblue@gmail.com> Date: Mon, 12 Aug 2024 11:31:18 -0500 Subject: [PATCH 2/3] Update crowdin.yml --- crowdin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crowdin.yml b/crowdin.yml index 1df3d57b..6fd0cd30 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,3 +1,3 @@ files: - source: /src/main/resources/assets/playerex/lang/en_us.json - translation: /src/main/resources/assets/playerex/lang/%locale%.json + translation: /src/main/resources/assets/playerex/lang/%locale_with_underscore%.json From 2f7137cb5bbd02b464eeafba8c7102f4b6519b13 Mon Sep 17 00:00:00 2001 From: Bibi Reden <redwitblue@gmail.com> Date: Tue, 13 Aug 2024 00:15:35 -0500 Subject: [PATCH 3/3] Beta Release Preparation (#33) * Make everything go through event invoker for SHOULD_DAMAGE * UP DA Version * Housekeeping, changing `data` extension -> `dataComponent` * Force lazy singleton init (by adding to API) * Add a color changer (default is gold still) Along with visual options * Implement new sorting algorithm for screens * Component adjustments, fix Knockback Resistance * Write contributor information, separate entries, stage version * Fields are forced to be UInt or empty * Deprecate predicates, made bar faster * Crowdin * Format translations * amend * [chore] cleanup data-driven attributes * [chore] update data attributes version * [chore] update CL * [feat] update all attributes with new format system * [fix] Applied `lifesteal` properly to attacker(s). * [ref] Using map over if condition for evasion * [ref] Trimming return guard @ `shouldDamage` * [fix] resolved refund to be valid * [ref] mapped `onCritAttack` * [change] `AttributeButtonComponentType` -> `ButtonType` * [chore] update CL and increase `max_health` --- CHANGELOG.md | 17 ++- crowdin.yml | 2 +- gradle.properties | 4 +- .../playerex/mixin/EntityRendererMixin.java | 5 +- .../playerex/mixin/ItemStackMixin.java | 43 ++----- .../playerex/mixin/LocalPlayerMixin.java | 2 +- .../registry/PlayerEXMenuRegistry.java | 20 ++- .../bibireden/playerex/ui/PlayerEXScreen.kt | 28 ++-- .../ui/components/AttributeComponent.kt | 8 +- .../ui/components/AttributeListComponent.kt | 25 +--- .../components/AttributeListEntryComponent.kt | 21 +-- .../buttons/AttributeButtonComponent.kt | 8 +- .../playerex/ui/helper/InputHelper.kt | 5 + .../ui/menus/PlayerEXAttributesMenu.kt | 69 +++++----- .../playerex/ui/util/FormattingPredicates.kt | 2 + .../playerex/mixin/LivingEntityMixin.java | 8 +- .../bibireden/playerex/mixin/PlayerMixin.java | 4 +- .../playerex/mixin/ServerPlayerMixin.java | 2 +- .../kotlin/com/bibireden/playerex/PlayerEX.kt | 14 +- .../bibireden/playerex/PlayerEXCommands.kt | 12 +- .../com/bibireden/playerex/api/PlayerEXAPI.kt | 12 ++ .../api/attribute/PlayerEXAttributes.kt | 53 ++++---- .../api/attribute/TradeSkillAttributes.kt | 16 +-- .../components/player/PlayerDataComponent.kt | 1 - .../playerex/config/PlayerEXConfigModel.kt | 35 +++-- .../bibireden/playerex/ext/PlayerEntity.kt | 9 +- .../playerex/factory/EventFactory.kt | 51 +++----- .../resources/assets/playerex/lang/en_us.json | 5 +- .../data_attributes/functions/stock.json | 4 +- .../data_attributes/overrides/minecraft.json | 24 ++++ .../overrides/ranged_weapon.json | 9 ++ .../overrides/spell_power.json | 22 ++++ .../data_attributes/overrides/stock.json | 120 ++++-------------- src/main/resources/fabric.mod.json | 53 +++++++- 34 files changed, 369 insertions(+), 344 deletions(-) create mode 100644 src/client/kotlin/com/bibireden/playerex/ui/helper/InputHelper.kt create mode 100644 src/main/resources/data/playerex/data_attributes/overrides/minecraft.json create mode 100644 src/main/resources/data/playerex/data_attributes/overrides/ranged_weapon.json create mode 100644 src/main/resources/data/playerex/data_attributes/overrides/spell_power.json diff --git a/CHANGELOG.md b/CHANGELOG.md index e0855ec7..d5003586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,15 @@ +## Additions 🍎 +- Added the ability to customize the color of the label (default is still gold). + ## Changes 🌽 -- Using the latest data-attributes with a supplied "stock" data-pack. -- You can clear your config if you wish to use stock, or keep your config with all the entries. -- Applied a patch for missing id's, which is an edge-case (will be labeled `unresolved:id`). \ No newline at end of file +- The UI has gone through a breaking change. recent alpha builds of WizardEX will not work with this version, though `alpha.3` will. +- Switching to the beta channel as most components of the mod are stable. + - Required changes before release is the UI and re-adjusting the config for the last time. +- Rebalanced knockback resistance to a proper 1% gain and displayed it properly. +- Added author & contributor information according to who assisted in the development of the project's codebase. +- Fixed `lifesteal` attribute not applying to attacker(s). +- Fixed refund issues on the screen. + +## Later Objectives ⚡ +- Fixing tooltips +- Adjusting more attributes \ No newline at end of file diff --git a/crowdin.yml b/crowdin.yml index 6fd0cd30..a4249abf 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,3 +1,3 @@ files: - source: /src/main/resources/assets/playerex/lang/en_us.json - translation: /src/main/resources/assets/playerex/lang/%locale_with_underscore%.json + translation: /src/main/resources/assets/playerex/lang/%locale_with_underscore%.json \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 2d8648de..9e4b33f5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,7 +17,7 @@ parchment_version=1.20.1:2023.09.03 quilt_mappings_version=23 # Mod Properties -mod_version=4.0.0+1.20.1-alpha.14 +mod_version=4.0.0+1.20.1-beta.1 maven_group=com.bibireden.playerex archives_base_name=playerex-directors-cut @@ -31,7 +31,7 @@ ranged_weapon_api_version=1.1.2+1.20.1 # in-house opc_version=2.0.0+1.20.1-beta.4-fabric -data_attributes_version=2.0.0+1.20.1-beta.10-fabric +data_attributes_version=2.0.0+1.20.1-beta.13-fabric # owo owo_version=0.11.2+1.20 diff --git a/src/client/java/com/bibireden/playerex/mixin/EntityRendererMixin.java b/src/client/java/com/bibireden/playerex/mixin/EntityRendererMixin.java index 993889bf..fadcf8dd 100644 --- a/src/client/java/com/bibireden/playerex/mixin/EntityRendererMixin.java +++ b/src/client/java/com/bibireden/playerex/mixin/EntityRendererMixin.java @@ -25,7 +25,10 @@ abstract class EntityRendererMixin<T extends Entity> { if (playerex$shouldRenderLevel() && entity instanceof Player livingEntity) { Optional<Double> maybeLevel = DataAttributesAPI.getValue(PlayerEXAttributes.LEVEL, livingEntity); if (maybeLevel.isPresent()) { - text = text.copy().append(" ").append(Component.translatable("playerex.ui.nameplate.level", maybeLevel.get().intValue()).withStyle((style) -> style.withColor(0xFFAA00))); + text = text.copy().append(" ").append( + Component.translatable("playerex.ui.nameplate.level", maybeLevel.get().intValue()) + .withStyle((style) -> style.withColor(PlayerEX.CONFIG.getVisualSettings().getNameplateColor().rgb())) + ); } } return text; diff --git a/src/client/java/com/bibireden/playerex/mixin/ItemStackMixin.java b/src/client/java/com/bibireden/playerex/mixin/ItemStackMixin.java index e09db198..e79f7c6a 100644 --- a/src/client/java/com/bibireden/playerex/mixin/ItemStackMixin.java +++ b/src/client/java/com/bibireden/playerex/mixin/ItemStackMixin.java @@ -4,6 +4,7 @@ import com.bibireden.playerex.PlayerEX; import com.bibireden.playerex.config.PlayerEXConfigModel; import com.google.common.collect.Multimap; +import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -78,25 +79,17 @@ abstract class ItemStackMixin { private double playerex$modifyAdditionAttributeKnockback(double original) { return original / 10.0; } // todo: not sure about the implementation(s) here... - @Inject(method = "getTooltipLines", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 7, shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD) + @Inject(method = "getTooltipLines", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 7, shift = At.Shift.AFTER)) private void playerex$insertModifierEqualsTooltip( Player player, TooltipFlag context, CallbackInfoReturnable<List<Component>> info, - List<Component> list, - MutableComponent arg3, - int arg4, - EquipmentSlot[] arg5, - int arg6, - int arg7, - EquipmentSlot arg8, - Multimap<?, ?> arg9, - Iterator<?> arg10, - Map.Entry<Attribute, AttributeModifier> entry, - AttributeModifier entityAttributeModifier, - double arg13, double e + @Local List<Component> list, + @Local Map.Entry<Attribute, AttributeModifier> entry, + @Local AttributeModifier modifier, + @Local(ordinal = 1) double e ) { list.set(list.size() - 1, Component.literal(" ") - .append(Component.translatable("attribute.modifier.equals." + entityAttributeModifier.getOperation().toValue(), playerex$value(e, entry, entityAttributeModifier), Component.translatable(entry.getKey().getDescriptionId()))) + .append(Component.translatable("attribute.modifier.equals." + modifier.getOperation().toValue(), playerex$value(e, entry, modifier), Component.translatable(entry.getKey().getDescriptionId()))) .withStyle(ChatFormatting.DARK_GREEN) ); } @@ -122,27 +115,19 @@ abstract class ItemStackMixin { ); } - @Inject(method = "getTooltipLines", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 9, shift = At.Shift.AFTER), locals = LocalCapture.CAPTURE_FAILHARD) + @Inject(method = "getTooltipLines", at = @At(value = "INVOKE", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 9, shift = At.Shift.AFTER)) private void playerex$insertModifierTakeTooltip( Player player, TooltipFlag context, CallbackInfoReturnable<List<Component>> info, - List<Component> list, - MutableComponent arg3, - int arg4, - EquipmentSlot[] arg5, - int arg6, - int arg7, - EquipmentSlot arg8, - Multimap<?, ?> arg9, - Iterator<?> arg10, - Map.Entry<Attribute, AttributeModifier> entry, - AttributeModifier entityAttributeModifier, - double arg13, double e + @Local List<Component> list, + @Local Map.Entry<Attribute, AttributeModifier> entry, + @Local AttributeModifier modifier, + @Local(ordinal = 1) double e ) { list.set( list.size() - 1, - Component.translatable("attribute.modifier.take." + entityAttributeModifier.getOperation().toValue(), - playerex$value(e, entry, entityAttributeModifier), + Component.translatable("attribute.modifier.take." + modifier.getOperation().toValue(), + playerex$value(e, entry, modifier), Component.translatable(entry.getKey().getDescriptionId())).withStyle(ChatFormatting.RED) ); } diff --git a/src/client/java/com/bibireden/playerex/mixin/LocalPlayerMixin.java b/src/client/java/com/bibireden/playerex/mixin/LocalPlayerMixin.java index b5872e8c..1d52d384 100644 --- a/src/client/java/com/bibireden/playerex/mixin/LocalPlayerMixin.java +++ b/src/client/java/com/bibireden/playerex/mixin/LocalPlayerMixin.java @@ -15,7 +15,7 @@ abstract class LocalPlayerMixin { @Shadow @Final protected Minecraft minecraft; @Inject(method = "setExperienceValues", at = @At("TAIL")) - private void setExperience(CallbackInfo ci) { + private void playerex$setExperienceValues(CallbackInfo ci) { if (minecraft.screen instanceof PlayerEXScreen screen) screen.onExperienceUpdated(); } } diff --git a/src/client/java/com/bibireden/playerex/registry/PlayerEXMenuRegistry.java b/src/client/java/com/bibireden/playerex/registry/PlayerEXMenuRegistry.java index 2488195b..32f497a7 100644 --- a/src/client/java/com/bibireden/playerex/registry/PlayerEXMenuRegistry.java +++ b/src/client/java/com/bibireden/playerex/registry/PlayerEXMenuRegistry.java @@ -29,12 +29,20 @@ public final class PlayerEXMenuRegistry { * which will be applied to the {@link PlayerEXScreen} as a page. */ public static void register(ResourceLocation id, @NotNull Class<? extends MenuComponent> menu) { - ENTRIES.add(new Pair<>(id, menu)); - ENTRIES.sort((a, b) -> { - var order = PRIORITY_ORDER.getOrDefault(a.getFirst().getNamespace(), Integer.MAX_VALUE); - var order2 = PRIORITY_ORDER.getOrDefault(b.getFirst().getNamespace(), Integer.MAX_VALUE); - return order.compareTo(order2); - }); + Pair<ResourceLocation, Class<? extends MenuComponent>> pair = new Pair<>(id, menu); + Integer insertingPriority = PRIORITY_ORDER.get(pair.getFirst().toString()); + + if (!ENTRIES.isEmpty()) { + for (int i = 0, size = ENTRIES.size(); i < size; i++) { + Pair<ResourceLocation, Class<? extends MenuComponent>> entry = ENTRIES.get(i); + Integer priority = PRIORITY_ORDER.get(entry.getFirst().toString()); + if (priority > insertingPriority) { + ENTRIES.add(i, pair); + return; + } + } + } + ENTRIES.add(pair); } @NotNull diff --git a/src/client/kotlin/com/bibireden/playerex/ui/PlayerEXScreen.kt b/src/client/kotlin/com/bibireden/playerex/ui/PlayerEXScreen.kt index f1d10c6c..d4412c51 100644 --- a/src/client/kotlin/com/bibireden/playerex/ui/PlayerEXScreen.kt +++ b/src/client/kotlin/com/bibireden/playerex/ui/PlayerEXScreen.kt @@ -2,7 +2,7 @@ package com.bibireden.playerex.ui import com.bibireden.playerex.PlayerEXClient import com.bibireden.playerex.components.player.IPlayerDataComponent -import com.bibireden.playerex.ext.data +import com.bibireden.playerex.ext.component import com.bibireden.playerex.ext.level import com.bibireden.playerex.networking.NetworkingChannels import com.bibireden.playerex.networking.NetworkingPackets @@ -11,6 +11,7 @@ import com.bibireden.playerex.registry.PlayerEXMenuRegistry import com.bibireden.playerex.ui.components.MenuComponent import com.bibireden.playerex.ui.components.MenuComponent.OnLevelUpdated import com.bibireden.playerex.ui.components.buttons.AttributeButtonComponent +import com.bibireden.playerex.ui.helper.InputHelper import com.bibireden.playerex.ui.util.Colors import com.bibireden.playerex.util.PlayerEXUtil import io.wispforest.owo.ui.base.BaseUIModelScreen @@ -40,7 +41,9 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat private val content by lazy { uiAdapter.rootComponent.childById(FlowLayout::class, "content")!! } private val footer by lazy { uiAdapter.rootComponent.childById(FlowLayout::class, "footer")!! } + private val currentLevel by lazy { uiAdapter.rootComponent.childById(LabelComponent::class, "level:current")!! } private val levelAmount by lazy { uiAdapter.rootComponent.childById(TextBoxComponent::class, "level:amount")!! } + private val levelButton by lazy { uiAdapter.rootComponent.childById(ButtonComponent::class, "level:button")!! } private val onLevelUpdatedEvents = OnLevelUpdated.stream private val onLevelUpdated: EventSource<OnLevelUpdated> = onLevelUpdatedEvents.source() @@ -51,7 +54,7 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat fun onLevelUpdated(level: Int) { val root = this.uiAdapter.rootComponent - root.childById(LabelComponent::class, "level:current")?.apply { + currentLevel.apply { text(Component.translatable("playerex.ui.current_level", player.level.toInt(), PlayerEXUtil.getRequiredXpForNextLevel(player))) } @@ -77,10 +80,13 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat private fun updatePointsAvailable() { this.uiAdapter.rootComponent.childById(LabelComponent::class, "points_available")?.apply { text(Component.translatable("playerex.ui.main.skill_points_header").append(": [").append( - Component.literal("${player.data.skillPoints}").withStyle { - it.withColor(when (player.data.skillPoints) { - 0 -> Colors.GRAY else -> Colors.SATURATED_BLUE - }) + Component.literal("${player.component.skillPoints}").withStyle { + it.withColor( + when (player.component.skillPoints) { + 0 -> Colors.GRAY + else -> Colors.SATURATED_BLUE + } + ) }).append("]") ) } @@ -100,7 +106,7 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat val amount = levelAmount.value.toIntOrNull() ?: return val result = player.level + amount - this.uiAdapter.rootComponent.childById(ButtonComponent::class, "level:button")!! + levelButton .active(player.experienceLevel >= PlayerEXUtil.getRequiredXpForLevel(player, result)) .tooltip(Component.translatable("playerex.ui.level_button", PlayerEXUtil.getRequiredXpForLevel(player, result), amount, player.experienceLevel)) } @@ -112,7 +118,7 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat result = Mth.clamp((player.experienceLevel.toDouble() / required) * 100, 0.0, 100.0) } footer.childById(BoxComponent::class, "progress")!! - .horizontalSizing().animate(1000, Easing.CUBIC, Sizing.fill(result.toInt())).forwards() + .horizontalSizing().animate(250, Easing.CUBIC, Sizing.fill(result.toInt())).forwards() } override fun build(rootComponent: FlowLayout) { @@ -121,6 +127,8 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat val levelUpButton = rootComponent.childById(ButtonComponent::class, "level:button")!! updateLevelUpButton() + + levelAmount.setFilter(InputHelper::isUIntInput) levelAmount.onChanged().subscribe { updateLevelUpButton() } val previousPage = rootComponent.childById(ButtonComponent::class, "previous")!! @@ -130,7 +138,7 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat PlayerEXMenuRegistry.get().forEach { (_, clazz) -> val instance = clazz.getDeclaredConstructor().newInstance() - instance.init(minecraft!!, this, player.data) + instance.init(minecraft!!, this, player.component) instance.build(content) pages.add(instance) } @@ -179,7 +187,7 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat return super.keyPressed(keyCode, scanCode, modifiers) } - enum class AttributeButtonComponentType { + enum class ButtonType { Add, Remove; diff --git a/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeComponent.kt b/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeComponent.kt index 216ddc3a..afbffaf5 100644 --- a/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeComponent.kt +++ b/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeComponent.kt @@ -7,7 +7,7 @@ import com.bibireden.data_attributes.api.attribute.StackingBehavior import com.bibireden.data_attributes.api.attribute.StackingFormula import com.bibireden.playerex.components.player.IPlayerDataComponent import com.bibireden.playerex.ext.id -import com.bibireden.playerex.ui.PlayerEXScreen.AttributeButtonComponentType +import com.bibireden.playerex.ui.PlayerEXScreen.ButtonType import com.bibireden.playerex.ui.components.buttons.AttributeButtonComponent import com.bibireden.playerex.ui.components.labels.AttributeLabelComponent import com.bibireden.playerex.ui.util.Colors @@ -65,18 +65,16 @@ class AttributeComponent(private val attribute: Attribute, private val player: P .id("${attribute.id}:label") ) - child(AttributeButtonComponent(attribute, player, component, AttributeButtonComponentType.Remove)) + child(AttributeButtonComponent(attribute, player, component, ButtonType.Remove)) child( AttributeLabelComponent(attribute, player).also { label = it } .horizontalSizing(Sizing.fill(34)) ) - child(AttributeButtonComponent(attribute, player, component, AttributeButtonComponentType.Add)) + child(AttributeButtonComponent(attribute, player, component, ButtonType.Add)) horizontalAlignment(HorizontalAlignment.RIGHT) verticalAlignment(VerticalAlignment.CENTER) - verticalAlignment(VerticalAlignment.CENTER) - refresh() } } \ No newline at end of file diff --git a/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeListComponent.kt b/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeListComponent.kt index 9bb8468e..943e0537 100644 --- a/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeListComponent.kt +++ b/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeListComponent.kt @@ -5,31 +5,18 @@ import io.wispforest.owo.ui.component.Components import io.wispforest.owo.ui.container.Containers import io.wispforest.owo.ui.container.FlowLayout import io.wispforest.owo.ui.core.Sizing -import net.minecraft.world.entity.ai.attributes.Attribute import net.minecraft.world.entity.player.Player import net.minecraft.network.chat.Component +import kotlin.jvm.optionals.getOrNull -private fun transform(array: List<Pair<EntityAttributeSupplier, FormattingPredicate>>): List<Pair<Attribute, FormattingPredicate>> { - val filtered = mutableListOf<Pair<Attribute, FormattingPredicate>>() - for ((attribute, pred) in array) { - if (attribute.get().isPresent) filtered.add(Pair(attribute.get().get(), pred)) - } - return filtered -} - -class AttributeListComponent(translationKey: String, private val player: Player, private val gimmie: List<Pair<EntityAttributeSupplier, FormattingPredicate>>) : FlowLayout(Sizing.fill(25), Sizing.content(), Algorithm.VERTICAL) { +class AttributeListComponent(translationKey: String, private val player: Player, val attributes: List<EntityAttributeSupplier>) : FlowLayout(Sizing.fill(25), Sizing.content(), Algorithm.VERTICAL) { val entriesSection: FlowLayout init { - child( - Components.label(Component.translatable(translationKey)) - .horizontalSizing(Sizing.fill(100)) - ) + child(Components.label(Component.translatable(translationKey)).horizontalSizing(Sizing.fill(100))) child(Components.box(Sizing.fill(100), Sizing.fixed(2))) entriesSection = Containers.verticalFlow(Sizing.fill(100), Sizing.content()) - .apply { - gap(4) - }.also(::child) + .apply { gap(4) }.also(::child) gap(4) refresh() @@ -37,8 +24,8 @@ class AttributeListComponent(translationKey: String, private val player: Player, fun refresh() { entriesSection.children().filterIsInstance<AttributeListEntryComponent>().forEach(::removeChild) - entriesSection.children(transform(gimmie).map { - Containers.horizontalScroll(Sizing.fill(100), Sizing.content(), AttributeListEntryComponent(it.first, player, it.second)).scrollbarThiccness(2) + entriesSection.children(attributes.mapNotNull { it.get().getOrNull() }.map { + Containers.horizontalScroll(Sizing.fill(100), Sizing.content(), AttributeListEntryComponent(it, player)).scrollbarThiccness(2) }) } } \ No newline at end of file diff --git a/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeListEntryComponent.kt b/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeListEntryComponent.kt index a9e125db..3ac64edc 100644 --- a/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeListEntryComponent.kt +++ b/src/client/kotlin/com/bibireden/playerex/ui/components/AttributeListEntryComponent.kt @@ -1,6 +1,7 @@ package com.bibireden.playerex.ui.components import com.bibireden.data_attributes.api.DataAttributesAPI +import com.bibireden.playerex.ext.id import com.bibireden.playerex.ui.util.Colors import io.wispforest.owo.ui.component.LabelComponent import io.wispforest.owo.ui.core.HorizontalAlignment @@ -11,11 +12,9 @@ import net.minecraft.network.chat.Component typealias FormattingPredicate = (Double) -> String -class AttributeListEntryComponent( - val attribute: Attribute, - val player: Player, - private val formattingPredicate: FormattingPredicate -) : LabelComponent(Component.empty()) { +class AttributeListEntryComponent(val attribute: Attribute, val player: Player) : LabelComponent(Component.empty()) { + private val BASE_VALUE_FACTOR_IDS = setOf("ranged_weapon:haste") + init { horizontalTextAlignment(HorizontalAlignment.CENTER) verticalTextAlignment(VerticalAlignment.CENTER) @@ -24,13 +23,17 @@ class AttributeListEntryComponent( } fun refresh() { + val formattedValue = if (attribute.id.toString() in BASE_VALUE_FACTOR_IDS) { + // this is literally to handle an edge case. + val value = DataAttributesAPI.getValue(attribute, player).orElse(0.0) + attribute.`data_attributes$format`().function(attribute.defaultValue, attribute.defaultValue * 2, value) + } + else DataAttributesAPI.getFormattedValue(attribute, player) + text( Component.translatable(attribute.descriptionId) .append(": ") - .append(Component.literal( - DataAttributesAPI.getValue(attribute, player).map { formattingPredicate(it) } - .orElse("N/A")).withStyle { it.withColor(Colors.GOLD) } - ) + .append(Component.literal(formattedValue).withStyle { it.withColor(Colors.GOLD) }) ) } } \ No newline at end of file diff --git a/src/client/kotlin/com/bibireden/playerex/ui/components/buttons/AttributeButtonComponent.kt b/src/client/kotlin/com/bibireden/playerex/ui/components/buttons/AttributeButtonComponent.kt index b98d7f79..0b1a724f 100644 --- a/src/client/kotlin/com/bibireden/playerex/ui/components/buttons/AttributeButtonComponent.kt +++ b/src/client/kotlin/com/bibireden/playerex/ui/components/buttons/AttributeButtonComponent.kt @@ -15,10 +15,10 @@ import net.minecraft.world.entity.ai.attributes.Attribute import net.minecraft.world.entity.player.Player import net.minecraft.network.chat.Component -class AttributeButtonComponent(val attribute: Attribute, private val player: Player, private val component: IPlayerDataComponent, val type: PlayerEXScreen.AttributeButtonComponentType) : ButtonComponent( +class AttributeButtonComponent(val attribute: Attribute, private val player: Player, private val component: IPlayerDataComponent, val type: PlayerEXScreen.ButtonType) : ButtonComponent( Component.literal(type.symbol), { - // reference text-box to get needed value to send to server + // reference text-box to get the necessary value to send to server it.parent()?.parent()?.childById(TextBoxComponent::class, "input")?.let { box -> val amount = box.value.toDoubleOrNull() ?: return@let val points = type.getPointsFromComponent(component) @@ -41,8 +41,8 @@ class AttributeButtonComponent(val attribute: Attribute, private val player: Pla DataAttributesAPI.getValue(attribute, player).ifPresent { value -> val max = (attribute as IEntityAttribute).`data_attributes$max`(); this.active(when (type) { - PlayerEXScreen.AttributeButtonComponentType.Add -> component.skillPoints > 0 && max > value - PlayerEXScreen.AttributeButtonComponentType.Remove -> component.refundablePoints > 0 && value > 0 + PlayerEXScreen.ButtonType.Add -> component.skillPoints > 0 && max > value + PlayerEXScreen.ButtonType.Remove -> component.refundablePoints > 0 && value > 0 }) } } diff --git a/src/client/kotlin/com/bibireden/playerex/ui/helper/InputHelper.kt b/src/client/kotlin/com/bibireden/playerex/ui/helper/InputHelper.kt new file mode 100644 index 00000000..4b1d135e --- /dev/null +++ b/src/client/kotlin/com/bibireden/playerex/ui/helper/InputHelper.kt @@ -0,0 +1,5 @@ +package com.bibireden.playerex.ui.helper + +object InputHelper { + fun isUIntInput(str: String) = str.isEmpty() || str.toUIntOrNull() != null +} \ No newline at end of file diff --git a/src/client/kotlin/com/bibireden/playerex/ui/menus/PlayerEXAttributesMenu.kt b/src/client/kotlin/com/bibireden/playerex/ui/menus/PlayerEXAttributesMenu.kt index 313c5ba0..c5109784 100644 --- a/src/client/kotlin/com/bibireden/playerex/ui/menus/PlayerEXAttributesMenu.kt +++ b/src/client/kotlin/com/bibireden/playerex/ui/menus/PlayerEXAttributesMenu.kt @@ -2,17 +2,15 @@ package com.bibireden.playerex.ui.menus import com.bibireden.data_attributes.api.DataAttributesAPI import com.bibireden.data_attributes.api.attribute.EntityAttributeSupplier -import com.bibireden.data_attributes.api.attribute.IEntityAttribute import com.bibireden.playerex.api.attribute.PlayerEXAttributes import com.bibireden.playerex.components.player.IPlayerDataComponent import com.bibireden.playerex.ext.id -import com.bibireden.playerex.ext.level import com.bibireden.playerex.ui.PlayerEXScreen import com.bibireden.playerex.ui.childById import com.bibireden.playerex.ui.components.* import com.bibireden.playerex.ui.components.buttons.AttributeButtonComponent import com.bibireden.playerex.ui.components.labels.AttributeLabelComponent -import com.bibireden.playerex.ui.util.FormattingPredicates +import com.bibireden.playerex.ui.helper.InputHelper import de.dafuqs.additionalentityattributes.AdditionalEntityAttributes import io.wispforest.owo.ui.component.Components import io.wispforest.owo.ui.component.TextBoxComponent @@ -28,44 +26,42 @@ import org.jetbrains.annotations.ApiStatus @ApiStatus.Internal class PlayerEXAttributesMenu : MenuComponent(algorithm = Algorithm.HORIZONTAL) { - private val MELEE_COMBAT_STATS: List<Pair<EntityAttributeSupplier, FormattingPredicate>> = listOf( - EntityAttributeSupplier(Attributes.ATTACK_DAMAGE.id) to FormattingPredicates.NORMAL, - EntityAttributeSupplier(Attributes.ATTACK_SPEED.id) to FormattingPredicates.NORMAL, - EntityAttributeSupplier(PlayerEXAttributes.MELEE_CRITICAL_DAMAGE.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(PlayerEXAttributes.MELEE_CRITICAL_CHANCE.id) to FormattingPredicates.PERCENTAGE_MULTIPLY + private val MELEE_COMBAT_STATS: List<EntityAttributeSupplier> = listOf( + EntityAttributeSupplier(Attributes.ATTACK_DAMAGE.id), + EntityAttributeSupplier(Attributes.ATTACK_SPEED.id), + EntityAttributeSupplier(PlayerEXAttributes.MELEE_CRITICAL_DAMAGE.id), + EntityAttributeSupplier(PlayerEXAttributes.MELEE_CRITICAL_CHANCE.id) ) - private val RANGED_COMBAT_STATS: List<Pair<EntityAttributeSupplier, FormattingPredicate>> = listOf( - EntityAttributeSupplier(PlayerEXAttributes.RANGED_CRITICAL_DAMAGE.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(PlayerEXAttributes.RANGED_CRITICAL_CHANCE.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(EntityAttributes_RangedWeapon.HASTE.id) to FormattingPredicates.fromBaseValue(EntityAttributes_RangedWeapon.HASTE.attribute, true), - EntityAttributeSupplier(EntityAttributes_RangedWeapon.DAMAGE.id) to FormattingPredicates.NORMAL, + private val RANGED_COMBAT_STATS: List<EntityAttributeSupplier> = listOf( + EntityAttributeSupplier(PlayerEXAttributes.RANGED_CRITICAL_DAMAGE.id), + EntityAttributeSupplier(PlayerEXAttributes.RANGED_CRITICAL_CHANCE.id), + EntityAttributeSupplier(EntityAttributes_RangedWeapon.HASTE.id), + EntityAttributeSupplier(EntityAttributes_RangedWeapon.DAMAGE.id), ) - private val DEFENSE_COMBAT_STATS: List<Pair<EntityAttributeSupplier, FormattingPredicate>> = listOf( - EntityAttributeSupplier(Attributes.ARMOR.id) to FormattingPredicates.NORMAL, - EntityAttributeSupplier(AdditionalEntityAttributes.MAGIC_PROTECTION.id) to FormattingPredicates.NORMAL, - EntityAttributeSupplier(Attributes.ARMOR_TOUGHNESS.id) to FormattingPredicates.NORMAL, - EntityAttributeSupplier(Attributes.KNOCKBACK_RESISTANCE.id) to FormattingPredicates.PERCENTAGE_DIVIDE, - EntityAttributeSupplier(PlayerEXAttributes.EVASION.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, + private val DEFENSE_COMBAT_STATS: List<EntityAttributeSupplier> = listOf( + EntityAttributeSupplier(Attributes.ARMOR.id), + EntityAttributeSupplier(AdditionalEntityAttributes.MAGIC_PROTECTION.id), + EntityAttributeSupplier(Attributes.ARMOR_TOUGHNESS.id), + EntityAttributeSupplier(Attributes.KNOCKBACK_RESISTANCE.id), + EntityAttributeSupplier(PlayerEXAttributes.EVASION.id), ) - private val VITALITY_STATS: List<Pair<EntityAttributeSupplier, FormattingPredicate>> = listOf( - EntityAttributeSupplier(PlayerEXAttributes.HEALTH_REGENERATION.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(PlayerEXAttributes.HEAL_AMPLIFICATION.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(PlayerEXAttributes.LIFESTEAL.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(Attributes.MOVEMENT_SPEED.id) to FormattingPredicates.NORMAL, + private val VITALITY_STATS: List<EntityAttributeSupplier> = listOf( + EntityAttributeSupplier(PlayerEXAttributes.HEALTH_REGENERATION.id), + EntityAttributeSupplier(PlayerEXAttributes.HEAL_AMPLIFICATION.id), + EntityAttributeSupplier(PlayerEXAttributes.LIFESTEAL.id), + EntityAttributeSupplier(Attributes.MOVEMENT_SPEED.id), ) - private val RESISTANCE_STATS: List<Pair<EntityAttributeSupplier, FormattingPredicate>> = listOf( - EntityAttributeSupplier(PlayerEXAttributes.FIRE_RESISTANCE.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(PlayerEXAttributes.FREEZE_RESISTANCE.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(PlayerEXAttributes.LIGHTNING_RESISTANCE.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, - EntityAttributeSupplier(PlayerEXAttributes.POISON_RESISTANCE.id) to FormattingPredicates.PERCENTAGE_MULTIPLY, + private val RESISTANCE_STATS: List<EntityAttributeSupplier> = listOf( + EntityAttributeSupplier(PlayerEXAttributes.FIRE_RESISTANCE.id), + EntityAttributeSupplier(PlayerEXAttributes.FREEZE_RESISTANCE.id), + EntityAttributeSupplier(PlayerEXAttributes.LIGHTNING_RESISTANCE.id), + EntityAttributeSupplier(PlayerEXAttributes.POISON_RESISTANCE.id), ) - private fun onLevelUpdate(level: Int) {} - /** Whenever ANY attribute gets updated. */ private fun onAttributeUpdate() { // refresh all attribute labels @@ -84,11 +80,11 @@ class PlayerEXAttributesMenu : MenuComponent(algorithm = Algorithm.HORIZONTAL) { val result = it.value.toDoubleOrNull() ?: return@also this.forEachDescendant { descendant -> if (descendant is AttributeButtonComponent) { - val max = (descendant.attribute as IEntityAttribute).`data_attributes$max`() + val max = descendant.attribute.`data_attributes$max`() val current = DataAttributesAPI.getValue(descendant.attribute, player).orElse(0.0) when (descendant.type) { - PlayerEXScreen.AttributeButtonComponentType.Add -> descendant.active(result > 0 && component.skillPoints >= result && (current + result) <= max) - PlayerEXScreen.AttributeButtonComponentType.Remove -> descendant.active(result > 0 && component.refundablePoints > 0 && (current - result > 0)) + PlayerEXScreen.ButtonType.Add -> descendant.active(result > 0 && component.skillPoints >= result && (current + result) <= max) + PlayerEXScreen.ButtonType.Remove -> descendant.active(result > 0 && component.refundablePoints > 0 && (current - result >= 0)) } } } @@ -108,11 +104,12 @@ class PlayerEXAttributesMenu : MenuComponent(algorithm = Algorithm.HORIZONTAL) { child(Components.label(Component.translatable("playerex.ui.category.primary_attributes"))) child( Components.textBox(Sizing.fixed(27)) + .text("1") .also { it.setMaxLength(4) + it.setFilter(InputHelper::isUIntInput) it.onChanged().subscribe { onInputFieldUpdated(player, component) } } - .text("1") .verticalSizing(Sizing.fixed(10)) .positioning(Positioning.relative(100, 0)) .id("input") @@ -154,11 +151,9 @@ class PlayerEXAttributesMenu : MenuComponent(algorithm = Algorithm.HORIZONTAL) { padding(Insets.both(8, 8)) - onLevelUpdate(player.level.toInt()) onAttributeUpdate() onInputFieldUpdated(player, component) - onLevelUpdated.subscribe(::onLevelUpdate) onAttributeUpdated.subscribe { _, _ -> onAttributeUpdate() onInputFieldUpdated(player, component) diff --git a/src/client/kotlin/com/bibireden/playerex/ui/util/FormattingPredicates.kt b/src/client/kotlin/com/bibireden/playerex/ui/util/FormattingPredicates.kt index b8b7d45d..19d18055 100644 --- a/src/client/kotlin/com/bibireden/playerex/ui/util/FormattingPredicates.kt +++ b/src/client/kotlin/com/bibireden/playerex/ui/util/FormattingPredicates.kt @@ -4,6 +4,8 @@ import com.bibireden.playerex.ui.components.FormattingPredicate import net.minecraft.world.entity.ai.attributes.Attribute import kotlin.math.round +@Suppress("UNUSED") +@Deprecated("Use DataAttributes value formatting instead.", level = DeprecationLevel.WARNING) object FormattingPredicates { @JvmField val NORMAL: FormattingPredicate = { "%.2f".format(it) } diff --git a/src/main/java/com/bibireden/playerex/mixin/LivingEntityMixin.java b/src/main/java/com/bibireden/playerex/mixin/LivingEntityMixin.java index d65c0e5f..19f2648a 100644 --- a/src/main/java/com/bibireden/playerex/mixin/LivingEntityMixin.java +++ b/src/main/java/com/bibireden/playerex/mixin/LivingEntityMixin.java @@ -13,8 +13,6 @@ @Mixin(LivingEntity.class) public abstract class LivingEntityMixin { - @Unique - final private int TICKS_UNTIL_RESET = 20; @Unique private int playerex_ticks; @@ -32,7 +30,8 @@ public abstract class LivingEntityMixin { @Inject(method = "tick", at = @At("TAIL")) private void playerex$tick(CallbackInfo ci) { - if (this.playerex_ticks < this.TICKS_UNTIL_RESET) { + final int TICKS_UNTIL_RESET = 20; + if (this.playerex_ticks < TICKS_UNTIL_RESET) { this.playerex_ticks++; } else { @@ -47,7 +46,6 @@ public abstract class LivingEntityMixin { @ModifyReturnValue(method = "hurt", at = @At("RETURN")) private boolean playerex$damage(boolean original, DamageSource source, float damage) { - boolean cancelled = LivingEntityEvents.SHOULD_DAMAGE.invoker().shouldDamage((LivingEntity) (Object) this, source, damage); - return cancelled && original; + return LivingEntityEvents.SHOULD_DAMAGE.invoker().shouldDamage((LivingEntity) (Object) this, source, damage); } } diff --git a/src/main/java/com/bibireden/playerex/mixin/PlayerMixin.java b/src/main/java/com/bibireden/playerex/mixin/PlayerMixin.java index 01678415..62ad7a04 100644 --- a/src/main/java/com/bibireden/playerex/mixin/PlayerMixin.java +++ b/src/main/java/com/bibireden/playerex/mixin/PlayerMixin.java @@ -10,12 +10,12 @@ @Mixin(Player.class) public abstract class PlayerMixin { @ModifyVariable(method = "attack", at = @At("STORE"), name = "bl3", ordinal = 2) - private boolean playerex_attack(boolean bl3, Entity target) { + private boolean playerex$attack(boolean bl3, Entity target) { return PlayerEntityEvents.SHOULD_CRITICAL.invoker().shouldCritical((Player)(Object) this, target, bl3); } @ModifyVariable(method = "attack", at = @At(value = "STORE", ordinal = 2), name = "f", ordinal = 0) - private float playerex_attack(float f, Entity target) { + private float playerex$attack(float f, Entity target) { return PlayerEntityEvents.ON_CRITICAL.invoker().onCriticalDamage((Player) (Object) this, target, f); } } diff --git a/src/main/java/com/bibireden/playerex/mixin/ServerPlayerMixin.java b/src/main/java/com/bibireden/playerex/mixin/ServerPlayerMixin.java index eb4c7b5b..43dea03f 100644 --- a/src/main/java/com/bibireden/playerex/mixin/ServerPlayerMixin.java +++ b/src/main/java/com/bibireden/playerex/mixin/ServerPlayerMixin.java @@ -22,7 +22,7 @@ public ServerPlayerMixin(Level level, BlockPos pos, float yRot, GameProfile game } @Inject(method = "giveExperienceLevels", at = @At("TAIL")) - private void addExperienceLevels(int levels, CallbackInfo ci) { + private void playerex$giveExperienceLevels(int levels, CallbackInfo ci) { PlayerDataComponent component = (PlayerDataComponent) this.getComponent(PlayerEXComponents.PLAYER_DATA); if (this.experienceLevel >= PlayerEXUtil.getRequiredXpForNextLevel(this)) { diff --git a/src/main/kotlin/com/bibireden/playerex/PlayerEX.kt b/src/main/kotlin/com/bibireden/playerex/PlayerEX.kt index c6a8af51..0ded06c7 100644 --- a/src/main/kotlin/com/bibireden/playerex/PlayerEX.kt +++ b/src/main/kotlin/com/bibireden/playerex/PlayerEX.kt @@ -8,12 +8,11 @@ import com.bibireden.playerex.api.PlayerEXAPI import com.bibireden.playerex.api.PlayerEXCachedKeys import com.bibireden.playerex.api.PlayerEXCachedKeys.Level import com.bibireden.playerex.api.attribute.PlayerEXAttributes -import com.bibireden.playerex.api.attribute.TradeSkillAttributes import com.bibireden.playerex.api.event.LivingEntityEvents import com.bibireden.playerex.api.event.PlayerEXSoundEvents import com.bibireden.playerex.api.event.PlayerEntityEvents -import com.bibireden.playerex.components.PlayerEXComponents import com.bibireden.playerex.config.PlayerEXConfig +import com.bibireden.playerex.ext.component import com.bibireden.playerex.factory.* import com.bibireden.playerex.networking.NetworkingChannels import com.bibireden.playerex.networking.NetworkingPackets @@ -41,10 +40,6 @@ object PlayerEX : ModInitializer { @JvmField val CONFIG = PlayerEXConfig.createAndLoad() - // this is literally here to initialize the singletons... - val PRIMARY_ATTRIBUTE_IDS = PlayerEXAttributes.PRIMARY_ATTRIBUTE_IDS - val TRADE_SKILL_IDS = TradeSkillAttributes.IDS - fun id(path: String) = ResourceLocation.tryBuild(MOD_ID, path)!! private val gimmick = listOf( @@ -56,15 +51,16 @@ object PlayerEX : ModInitializer { NetworkingChannels.NOTIFICATIONS.registerClientboundDeferred(NetworkingPackets.Notify::class.java) NetworkingChannels.MODIFY.registerServerbound(NetworkingPackets.Update::class) { (type, id, amount), ctx -> + val component = ctx.player.component EntityAttributeSupplier(id).get().ifPresent { when (type) { - UpdatePacketType.Skill -> PlayerEXComponents.PLAYER_DATA.get(ctx.player).skillUp(it, amount) - UpdatePacketType.Refund -> PlayerEXComponents.PLAYER_DATA.get(ctx.player).refund(it, amount) + UpdatePacketType.Skill -> component.skillUp(it, amount) + UpdatePacketType.Refund -> component.refund(it, amount) } } } NetworkingChannels.MODIFY.registerServerbound(NetworkingPackets.Level::class) { (amount), ctx -> - PlayerEXComponents.PLAYER_DATA.get(ctx.player).levelUp(amount) + ctx.player.component.levelUp(amount) } CommandRegistrationCallback.EVENT.register(PlayerEXCommands::register) diff --git a/src/main/kotlin/com/bibireden/playerex/PlayerEXCommands.kt b/src/main/kotlin/com/bibireden/playerex/PlayerEXCommands.kt index c163d29c..bf10133c 100644 --- a/src/main/kotlin/com/bibireden/playerex/PlayerEXCommands.kt +++ b/src/main/kotlin/com/bibireden/playerex/PlayerEXCommands.kt @@ -6,7 +6,7 @@ import com.bibireden.data_attributes.api.attribute.IEntityAttribute import com.bibireden.playerex.api.attribute.PlayerEXAttributes import com.bibireden.playerex.api.attribute.TradeSkillAttributes import com.bibireden.playerex.components.PlayerEXComponents -import com.bibireden.playerex.ext.data +import com.bibireden.playerex.ext.component import com.mojang.brigadier.CommandDispatcher import com.mojang.brigadier.arguments.IntegerArgumentType import com.mojang.brigadier.builder.RequiredArgumentBuilder @@ -119,7 +119,7 @@ object PlayerEXCommands { private fun executeRefundGetCommand(ctx: Context): Int { val player = EntityArgument.getPlayer(ctx, "player") - ctx.source.sendSuccess({ Component.translatable("playerex.command.refund.get", player.name, player.data.refundablePoints) }, false) + ctx.source.sendSuccess({ Component.translatable("playerex.command.refund.get", player.name, player.component.refundablePoints) }, false) return 1 } @@ -132,7 +132,7 @@ object PlayerEXCommands { val attribute = supplier.get().get() val computed = Mth.clamp(amount, 0, it.toInt()) - if (player.data.refund(attribute, computed)) { + if (player.component.refund(attribute, computed)) { ctx.source.sendSuccess({ Component.translatable("playerex.command.refunded", amount, Component.translatable(attribute.descriptionId), player.name) }, false) ctx.source.sendSuccess(updatedValueText(attribute, it - amount), false) 1 @@ -146,7 +146,7 @@ object PlayerEXCommands { private fun executeRefundAddCommand(ctx: Context, amount: Int = 1): Int { val player = EntityArgument.getPlayer(ctx, "player") - player.data.addRefundablePoints(amount) + player.component.addRefundablePoints(amount) ctx.source.sendSuccess({ Component.translatable("playerex.command.refund.add", amount, player.name) }, false) @@ -161,7 +161,7 @@ object PlayerEXCommands { val attribute = supplier.get().get() val computed = Mth.clamp(amount, 0, (attribute as IEntityAttribute).`data_attributes$max`().toInt() - it.toInt()) - if (player.data.skillUp(attribute, computed, true)) { + if (player.component.skillUp(attribute, computed, true)) { ctx.source.sendSuccess({ Component.translatable("playerex.command.skill_up", computed, Component.translatable(attribute.descriptionId), player.name) }, false) ctx.source.sendSuccess(updatedValueText(attribute, it + computed), false) 1 @@ -180,7 +180,7 @@ object PlayerEXCommands { val attribute = PlayerEXAttributes.LEVEL val computed = Mth.clamp(amount, 0, (attribute as IEntityAttribute).`data_attributes$max`().toInt() - value.toInt()) - if (!player.data.levelUp(computed, true)) { + if (!player.component.levelUp(computed, true)) { // todo: err message, for now just -1 return@map -1 } diff --git a/src/main/kotlin/com/bibireden/playerex/api/PlayerEXAPI.kt b/src/main/kotlin/com/bibireden/playerex/api/PlayerEXAPI.kt index 59ba3b88..247c3b92 100644 --- a/src/main/kotlin/com/bibireden/playerex/api/PlayerEXAPI.kt +++ b/src/main/kotlin/com/bibireden/playerex/api/PlayerEXAPI.kt @@ -1,10 +1,22 @@ package com.bibireden.playerex.api +import com.bibireden.playerex.api.attribute.PlayerEXAttributes +import com.bibireden.playerex.api.attribute.TradeSkillAttributes import com.bibireden.playerex.api.damage.DamageFunction import com.bibireden.playerex.api.damage.DamagePredicate import com.bibireden.playerex.registry.* +import net.minecraft.resources.ResourceLocation +@Suppress("UNUSED") object PlayerEXAPI { + /** Contains the attribute ids that are "skills", and are present on the main screens first page. */ + @JvmField + val PRIMARY_ATTRIBUTE_IDS: Collection<ResourceLocation> = PlayerEXAttributes.PRIMARY_ATTRIBUTE_IDS + + /** Passive trade skill ids. */ + @JvmField + val TRADE_SKILL_IDS: Collection<ResourceLocation> = TradeSkillAttributes.IDS + /** * Registers a damage modification condition that is applied to living entities * under specific circumstances. diff --git a/src/main/kotlin/com/bibireden/playerex/api/attribute/PlayerEXAttributes.kt b/src/main/kotlin/com/bibireden/playerex/api/attribute/PlayerEXAttributes.kt index 78ecd556..b31236ef 100644 --- a/src/main/kotlin/com/bibireden/playerex/api/attribute/PlayerEXAttributes.kt +++ b/src/main/kotlin/com/bibireden/playerex/api/attribute/PlayerEXAttributes.kt @@ -8,81 +8,78 @@ import net.minecraft.resources.ResourceLocation import net.minecraft.world.entity.ai.attributes.RangedAttribute object PlayerEXAttributes { + @JvmField + val PRIMARY_ATTRIBUTE_IDS: Set<ResourceLocation> + @JvmField val LEVEL = register("level", 0.0, 0.0, 100.0) @JvmField - val CONSTITUTION = register("constitution", 0.0, 0.0, 100.0); + val CONSTITUTION = register("constitution", 0.0, 0.0, 100.0) @JvmField - val STRENGTH = register("strength", 0.0, 0.0, 100.0); + val STRENGTH = register("strength", 0.0, 0.0, 100.0) @JvmField - val DEXTERITY = register("dexterity", 0.0, 0.0, 100.0); + val DEXTERITY = register("dexterity", 0.0, 0.0, 100.0) @JvmField - val INTELLIGENCE = register("intelligence", 0.0, 0.0, 100.0); + val INTELLIGENCE = register("intelligence", 0.0, 0.0, 100.0) @JvmField - val LUCKINESS = register("luckiness", 0.0, 0.0, 100.0); + val LUCKINESS = register("luckiness", 0.0, 0.0, 100.0) @JvmField val FOCUS = register("focus", 0.0, 0.0, 100.0) @JvmField - val HEALTH_REGENERATION = register("health_regeneration", 0.0, 0.0, 100.0); + val HEALTH_REGENERATION = register("health_regeneration", 0.0, 0.0, 1.0) @JvmField - val HEAL_AMPLIFICATION = register("heal_amplification", 0.0, 0.0, 100.0); + val HEAL_AMPLIFICATION = register("heal_amplification", 0.0, 0.0, 1.0) @JvmField - val LIFESTEAL = register("lifesteal", 0.0, 0.0, 100.0); + val LIFESTEAL = register("lifesteal", 0.0, 0.0, 1.0) @JvmField - val MELEE_CRITICAL_DAMAGE = register("melee_crit_damage", 0.0, 0.0, 1.0); + val BREAKING_SPEED = register("breaking_speed", 0.0, 0.0, 100.0) @JvmField - val MELEE_CRITICAL_CHANCE = register("melee_crit_chance", 0.0, 0.0, 1.0); + val FIRE_RESISTANCE = register("fire_resistance", 0.0, 0.0, 1.0) @JvmField - val BREAKING_SPEED = register("breaking_speed", 0.0, 0.0, 100.0); + val FREEZE_RESISTANCE = register("freeze_resistance", 0.0, 0.0, 1.0) @JvmField - val FIRE_RESISTANCE = register("fire_resistance", 0.0, 0.0, 1.0); + val LIGHTNING_RESISTANCE = register("lightning_resistance", 0.0, 0.0, 1.0) @JvmField - val FREEZE_RESISTANCE = register("freeze_resistance", 0.0, 0.0, 1.0); + val WITHER_RESISTANCE = register("wither_resistance", 0.0, 0.0, 1.0) @JvmField - val LIGHTNING_RESISTANCE = register("lightning_resistance", 0.0, 0.0, 1.0); + val POISON_RESISTANCE = register("poison_resistance", 0.0, 0.0, 1.0) @JvmField - val WITHER_RESISTANCE = register("wither_resistance", 0.0, 0.0, 1.0); + val EVASION = register("evasion", 0.0, 0.0, 1.0) @JvmField - val POISON_RESISTANCE = register("poison_resistance", 0.0, 0.0, 1.0); + val MELEE_CRITICAL_CHANCE = register("melee_crit_chance", 0.0, 0.0, 1.0) @JvmField - val EVASION = register("evasion", 0.0, 0.0, 100.0); + val MELEE_CRITICAL_DAMAGE = register("melee_crit_damage", 0.0, 0.0, 1_000_000.0) @JvmField val RANGED_CRITICAL_CHANCE = register("ranged_crit_chance", 0.0, 0.0, 1.0) @JvmField - val RANGED_CRITICAL_DAMAGE = register("ranged_crit_damage", 0.0, 0.0, 1000000.0) + val RANGED_CRITICAL_DAMAGE = register("ranged_crit_damage", 0.0, 0.0, 1_000_000.0) fun register(path: String, base: Double, min: Double, max: Double): RangedAttribute { val attribute = RangedAttribute("attribute.name.${PlayerEX.MOD_ID}.$path", base, min, max) return Registry.register(BuiltInRegistries.ATTRIBUTE, ResourceLocation.tryBuild(PlayerEX.MOD_ID, path)!!, attribute) } - - @JvmField - val PRIMARY_ATTRIBUTE_IDS: Set<ResourceLocation> = setOf( - CONSTITUTION.id, - STRENGTH.id, - DEXTERITY.id, - INTELLIGENCE.id, - LUCKINESS.id, - FOCUS.id, - ) + + init { + PRIMARY_ATTRIBUTE_IDS = setOf(CONSTITUTION.id, STRENGTH.id, DEXTERITY.id, INTELLIGENCE.id, LUCKINESS.id, FOCUS.id) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/bibireden/playerex/api/attribute/TradeSkillAttributes.kt b/src/main/kotlin/com/bibireden/playerex/api/attribute/TradeSkillAttributes.kt index 950f0137..9f0de9f5 100644 --- a/src/main/kotlin/com/bibireden/playerex/api/attribute/TradeSkillAttributes.kt +++ b/src/main/kotlin/com/bibireden/playerex/api/attribute/TradeSkillAttributes.kt @@ -5,6 +5,9 @@ import com.bibireden.playerex.ext.id import net.minecraft.resources.ResourceLocation object TradeSkillAttributes { + @JvmField + val IDS: Set<ResourceLocation> + @JvmField val MINING = register("mining", 0.0, 0.0, 100.0); @@ -26,14 +29,7 @@ object TradeSkillAttributes { @JvmField val FARMING = register("farming", 0.0, 0.0, 100.0); - @JvmField - val IDS: Set<ResourceLocation> = setOf( - MINING.id, - ALCHEMY.id, - FISHING.id, - FARMING.id, - LOGGING.id, - ENCHANTING.id, - ENCHANTING.id - ) + init { + IDS = setOf(MINING.id, ALCHEMY.id, FISHING.id, FARMING.id, LOGGING.id, ENCHANTING.id, ENCHANTING.id) + } } \ No newline at end of file diff --git a/src/main/kotlin/com/bibireden/playerex/components/player/PlayerDataComponent.kt b/src/main/kotlin/com/bibireden/playerex/components/player/PlayerDataComponent.kt index bcad87c6..562abf68 100644 --- a/src/main/kotlin/com/bibireden/playerex/components/player/PlayerDataComponent.kt +++ b/src/main/kotlin/com/bibireden/playerex/components/player/PlayerDataComponent.kt @@ -2,7 +2,6 @@ package com.bibireden.playerex.components.player import com.bibireden.data_attributes.api.DataAttributesAPI import com.bibireden.data_attributes.api.attribute.IEntityAttribute -import com.bibireden.data_attributes.api.attribute.IEntityAttributeInstance import com.bibireden.data_attributes.endec.Endecs import com.bibireden.data_attributes.endec.nbt.NbtDeserializer import com.bibireden.data_attributes.endec.nbt.NbtSerializer diff --git a/src/main/kotlin/com/bibireden/playerex/config/PlayerEXConfigModel.kt b/src/main/kotlin/com/bibireden/playerex/config/PlayerEXConfigModel.kt index eb344453..46f72688 100644 --- a/src/main/kotlin/com/bibireden/playerex/config/PlayerEXConfigModel.kt +++ b/src/main/kotlin/com/bibireden/playerex/config/PlayerEXConfigModel.kt @@ -1,9 +1,10 @@ package com.bibireden.playerex.config import com.bibireden.playerex.PlayerEX -import io.wispforest.owo.config.Option +import io.wispforest.owo.config.Option.SyncMode import io.wispforest.owo.config.annotation.* +import io.wispforest.owo.ui.core.Color @Suppress("UNUSED") @Modmenu(modId = PlayerEX.MOD_ID) @@ -11,26 +12,26 @@ import io.wispforest.owo.config.annotation.* class PlayerEXConfigModel { @SectionHeader("client_options") - @Sync(Option.SyncMode.NONE) + @Sync(SyncMode.NONE) @JvmField var tooltip: Tooltip = Tooltip.Vanilla - @Sync(Option.SyncMode.NONE) + @Sync(SyncMode.NONE) @JvmField var showLevelOnNameplates: Boolean = true data class SoundSettings( - @Sync(Option.SyncMode.NONE) + @Sync(SyncMode.NONE) @JvmField @RangeConstraint(min = 0.0, max = 150.0) var levelUpVolume: Int = 100, - @Sync(Option.SyncMode.NONE) + @Sync(SyncMode.NONE) @JvmField @RangeConstraint(min = 0.0, max = 150.0) var skillUpVolume: Int = 100, - @Sync(Option.SyncMode.NONE) + @Sync(SyncMode.NONE) @JvmField @RangeConstraint(min = 0.0, max = 150.0) var refundVolume: Int = 100 @@ -38,20 +39,28 @@ class PlayerEXConfigModel { @JvmField @Nest var soundSettings = SoundSettings() + data class VisualSettings( + @Sync(SyncMode.NONE) + @JvmField + var nameplateColor: Color = Color.ofRgb(0xFFAA00), + ) + + @JvmField @Nest var visualSettings = VisualSettings() + @SectionHeader("server_options") - @Sync(Option.SyncMode.OVERRIDE_CLIENT) + @Sync(SyncMode.OVERRIDE_CLIENT) @JvmField var resetOnDeath: Boolean = false - @Sync(Option.SyncMode.OVERRIDE_CLIENT) + @Sync(SyncMode.OVERRIDE_CLIENT) @JvmField var disableUI: Boolean = false - @Sync(Option.SyncMode.OVERRIDE_CLIENT) + @Sync(SyncMode.OVERRIDE_CLIENT) @JvmField var skillPointsPerLevelUp: Int = 1 - @Sync(Option.SyncMode.OVERRIDE_CLIENT) + @Sync(SyncMode.OVERRIDE_CLIENT) @JvmField @Hook var levelFormula: String = "stairs(x,0.2,2.4,17,10,25)" @@ -59,15 +68,15 @@ class PlayerEXConfigModel { // @JvmField // var expression: Expression - @Sync(Option.SyncMode.OVERRIDE_CLIENT) + @Sync(SyncMode.OVERRIDE_CLIENT) @JvmField var restorativeForceTicks: Int = 600 - @Sync(Option.SyncMode.OVERRIDE_CLIENT) + @Sync(SyncMode.OVERRIDE_CLIENT) @JvmField var restorativeForceMultiplier: Int = 110 - @Sync(Option.SyncMode.OVERRIDE_CLIENT) + @Sync(SyncMode.OVERRIDE_CLIENT) @JvmField var expNegationFactor: Int = 95 diff --git a/src/main/kotlin/com/bibireden/playerex/ext/PlayerEntity.kt b/src/main/kotlin/com/bibireden/playerex/ext/PlayerEntity.kt index 0b88c9c9..fe2bf149 100644 --- a/src/main/kotlin/com/bibireden/playerex/ext/PlayerEntity.kt +++ b/src/main/kotlin/com/bibireden/playerex/ext/PlayerEntity.kt @@ -4,15 +4,10 @@ import com.bibireden.data_attributes.api.DataAttributesAPI import com.bibireden.playerex.api.attribute.PlayerEXAttributes import com.bibireden.playerex.components.PlayerEXComponents import com.bibireden.playerex.components.player.IPlayerDataComponent -import com.bibireden.playerex.util.PlayerEXUtil import net.minecraft.world.entity.player.Player val Player.level: Double get() = DataAttributesAPI.getValue(PlayerEXAttributes.LEVEL, this).orElse(1.0) -val Player.data: IPlayerDataComponent - get() = this.getComponent(PlayerEXComponents.PLAYER_DATA) - -fun Player.canLevelUp(amount: Int = 1): Boolean { - return this.experienceLevel >= PlayerEXUtil.getRequiredXpForLevel(this, this.level + amount) -} \ No newline at end of file +val Player.component: IPlayerDataComponent + get() = this.getComponent(PlayerEXComponents.PLAYER_DATA) \ No newline at end of file diff --git a/src/main/kotlin/com/bibireden/playerex/factory/EventFactory.kt b/src/main/kotlin/com/bibireden/playerex/factory/EventFactory.kt index 82860c96..7c03ff1c 100644 --- a/src/main/kotlin/com/bibireden/playerex/factory/EventFactory.kt +++ b/src/main/kotlin/com/bibireden/playerex/factory/EventFactory.kt @@ -3,7 +3,7 @@ package com.bibireden.playerex.factory import com.bibireden.data_attributes.api.DataAttributesAPI import com.bibireden.playerex.PlayerEX import com.bibireden.playerex.api.attribute.PlayerEXAttributes -import com.bibireden.playerex.components.PlayerEXComponents +import com.bibireden.playerex.ext.component import com.bibireden.playerex.registry.DamageModificationRegistry import net.minecraft.server.level.ServerPlayer import net.minecraft.world.damagesource.DamageSource @@ -16,26 +16,26 @@ import net.minecraft.world.entity.projectile.AbstractArrow object EventFactory { fun reset(oldPlayer: ServerPlayer, newPlayer: ServerPlayer, isAlive: Boolean) { - PlayerEXComponents.PLAYER_DATA.get(newPlayer).reset(if (PlayerEX.CONFIG.resetOnDeath) 0 else 100) + newPlayer.component.reset(if (PlayerEX.CONFIG.resetOnDeath) 0 else 100) } - fun healed(livingEntity: LivingEntity, amount: Float): Float + fun healed(entity: LivingEntity, amount: Float): Float { - return DataAttributesAPI.getValue(PlayerEXAttributes.HEAL_AMPLIFICATION, livingEntity).map { (amount * (1.0 + it)).toFloat() }.orElse(amount) + return DataAttributesAPI.getValue(PlayerEXAttributes.HEAL_AMPLIFICATION, entity).map { (amount * (1 + it)).toFloat() }.orElse(amount) } - fun healthRegeneration(livingEntity: LivingEntity) + fun healthRegeneration(entity: LivingEntity) { - if (!livingEntity.level().isClientSide()) { - val healthRegenerationOption = DataAttributesAPI.getValue(PlayerEXAttributes.HEALTH_REGENERATION, livingEntity) + if (!entity.level().isClientSide()) { + val healthRegenerationOption = DataAttributesAPI.getValue(PlayerEXAttributes.HEALTH_REGENERATION, entity) if (healthRegenerationOption.isPresent) { val healthRegeneration = healthRegenerationOption.get() - if (healthRegeneration > 0.0 && livingEntity.health < livingEntity.maxHealth) + if (healthRegeneration > 0.0 && entity.health < entity.maxHealth) { - livingEntity.heal(healthRegeneration.toFloat()) + entity.heal(healthRegeneration.toFloat()) } return @@ -62,44 +62,29 @@ object EventFactory { fun shouldDamage(livingEntity: LivingEntity, source: DamageSource, original: Float): Boolean { - if (original == 0.0F) - { - return true - } + if (original == 0.0F) return true val origin: Entity? = source.directEntity val attacker: Entity? = source.entity if (attacker is LivingEntity && (origin is LivingEntity || origin is AbstractArrow)) { - DataAttributesAPI.getValue(PlayerEXAttributes.LIFESTEAL, livingEntity).ifPresent { - attacker.heal((original * it * 10.0).toFloat()) + DataAttributesAPI.getValue(PlayerEXAttributes.LIFESTEAL, attacker).ifPresent { + attacker.heal((original * it).toFloat()) } } - val evasionOption = DataAttributesAPI.getValue(PlayerEXAttributes.EVASION, livingEntity) - - if (evasionOption.isPresent) - { - val chance = livingEntity.random.nextFloat() - return !(chance < evasionOption.get() && origin is AbstractArrow) - } - - return true + return DataAttributesAPI.getValue(PlayerEXAttributes.EVASION, livingEntity).map { + !(livingEntity.random.nextFloat() < it && origin is AbstractArrow) + }.orElse(true) } fun onCritAttack(player: Player, target: Entity, amount: Float): Float { if (target !is LivingEntity) return amount - - val meleeCritOption = DataAttributesAPI.getValue(PlayerEXAttributes.MELEE_CRITICAL_DAMAGE, player) - - if (meleeCritOption.isPresent) - { - return (amount * (1.0 + (meleeCritOption.get() * 10.0)) / 1.5).toFloat() - } - - return amount + return DataAttributesAPI.getValue(PlayerEXAttributes.MELEE_CRITICAL_DAMAGE, player) + .map { (amount * (1.0 + (it * 10.0)) / 1.5).toFloat() } + .orElse(amount) } fun attackIsCrit(player: Player, target: Entity, original: Boolean): Boolean diff --git a/src/main/resources/assets/playerex/lang/en_us.json b/src/main/resources/assets/playerex/lang/en_us.json index 7f511e20..33212281 100644 --- a/src/main/resources/assets/playerex/lang/en_us.json +++ b/src/main/resources/assets/playerex/lang/en_us.json @@ -21,7 +21,7 @@ {"index": 0}, {"text": " (", "color": "#757575"}, {"index": 1, "color": "#757575", "italic": true, "underline": true }, - {"text": " XP until the next level)", "color": "#757575", "italic": true } + {"text": " XP required until the next level)", "color": "#757575", "italic": true } ], "playerex.ui.level_button": [ {"text": "", "color": "#F0C25E"}, @@ -177,6 +177,9 @@ "text.config.playerex-config.option.soundSettings.skillUpVolume": "Skill Up Volume", "text.config.playerex-config.option.soundSettings.refundVolume": "Refund Volume", + "text.config.playerex-config.category.visualSettings": "Visual Options", + "text.config.playerex-config.option.visualSettings.nameplateColor": "Nameplate Color", + "text.config.playerex-config.option.resetOnDeath": "Reset on Death", "text.config.playerex-config.option.skillPointsPerLevelUp": "Skill Points per. Level Up", "text.config.playerex-config.option.levelFormula": "Leveling Formula", diff --git a/src/main/resources/data/playerex/data_attributes/functions/stock.json b/src/main/resources/data/playerex/data_attributes/functions/stock.json index 57e991d4..3f786cbf 100644 --- a/src/main/resources/data/playerex/data_attributes/functions/stock.json +++ b/src/main/resources/data/playerex/data_attributes/functions/stock.json @@ -102,7 +102,7 @@ { "id": "playerex:heal_amplification", "behavior": "Add", - "value": 2.0E-4 + "value": 0.0020 }, { "id": "playerex:freeze_resistance", @@ -129,7 +129,7 @@ { "id": "minecraft:generic.knockback_resistance", "behavior": "Add", - "value": 0.1 + "value": 0.01 }, { "id": "playerex:melee_crit_damage", diff --git a/src/main/resources/data/playerex/data_attributes/overrides/minecraft.json b/src/main/resources/data/playerex/data_attributes/overrides/minecraft.json new file mode 100644 index 00000000..5bd68de9 --- /dev/null +++ b/src/main/resources/data/playerex/data_attributes/overrides/minecraft.json @@ -0,0 +1,24 @@ +{ + "entries": { + "minecraft:generic.knockback_resistance": { + "enabled": true, + "min": 0.0, + "max": 1.0, + "smoothness": 1.0, + "formula": "Diminished", + "format": "Percentage" + }, + "minecraft:generic.luck": { + "enabled": true, + "smoothness": 1.0, + "formula": "Diminished" + }, + "minecraft:generic.max_health": { + "enabled": true, + "min": 0.0, + "max": 1000000.0, + "smoothness": 1.0, + "formula": "Flat" + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/playerex/data_attributes/overrides/ranged_weapon.json b/src/main/resources/data/playerex/data_attributes/overrides/ranged_weapon.json new file mode 100644 index 00000000..b9aa1f33 --- /dev/null +++ b/src/main/resources/data/playerex/data_attributes/overrides/ranged_weapon.json @@ -0,0 +1,9 @@ +{ + "entries": { + "ranged_weapon:haste": { + "enabled": true, + "smoothness": 1, + "format": "Percentage" + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/playerex/data_attributes/overrides/spell_power.json b/src/main/resources/data/playerex/data_attributes/overrides/spell_power.json new file mode 100644 index 00000000..ad6cdc5a --- /dev/null +++ b/src/main/resources/data/playerex/data_attributes/overrides/spell_power.json @@ -0,0 +1,22 @@ +{ + "entries": { + "spell_power:haste": { + "enabled": true, + "min": 100.0, + "max": 1000.0, + "smoothness": 1.0, + "min_fallback": 100.0, + "max_fallback": 1000.0, + "formula": "Diminished" + }, + "spell_power:critical_chance": { + "enabled": true, + "min": 100.0, + "max": 1000.0, + "smoothness": 1.0, + "min_fallback": 100.0, + "max_fallback": 1000.0, + "formula": "Diminished" + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/playerex/data_attributes/overrides/stock.json b/src/main/resources/data/playerex/data_attributes/overrides/stock.json index 8124a16f..54eb44cc 100644 --- a/src/main/resources/data/playerex/data_attributes/overrides/stock.json +++ b/src/main/resources/data/playerex/data_attributes/overrides/stock.json @@ -2,147 +2,77 @@ "entries": { "playerex:lightning_resistance": { "enabled": true, - "min": 0.0, - "max": 1.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, - "formula": "Diminished" - }, - "spell_power:haste": { - "enabled": true, - "min": 100.0, - "max": 1000.0, - "smoothness": 1.0, - "min_fallback": 100.0, - "max_fallback": 1000.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, "playerex:ranged_crit_damage": { "enabled": true, - "min": 0.0, - "max": 1000000.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1000000.0, - "formula": "Diminished" - }, - "minecraft:generic.knockback_resistance": { - "enabled": true, - "min": 0.0, - "max": 1.0, - "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, - "formula": "Diminished" - }, - "minecraft:generic.luck": { - "enabled": true, - "min": -1024.0, - "max": 1024.0, - "smoothness": 1.0, - "min_fallback": -1024.0, - "max_fallback": 1024.0, "formula": "Diminished" }, "playerex:poison_resistance": { "enabled": true, - "min": 0.0, - "max": 1.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, "playerex:melee_crit_damage": { "enabled": true, - "min": 0.0, - "max": 1.0, - "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, + "smoothness": 1, "formula": "Diminished" }, "playerex:wither_resistance": { "enabled": true, - "min": 0.0, - "max": 1.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, "playerex:freeze_resistance": { "enabled": true, - "min": 0.0, - "max": 1.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, "playerex:health_regeneration": { "enabled": true, - "min": 0.0, - "max": 100.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 100.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, "playerex:heal_amplification": { "enabled": true, - "min": 0.0, - "max": 100.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 100.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, "playerex:ranged_crit_chance": { "enabled": true, - "min": 0.0, - "max": 1.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, "playerex:evasion": { "enabled": true, - "min": 0.0, - "max": 100.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 100.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, - "playerex:melee_crit_chance": { + "playerex:lifesteal": { "enabled": true, - "min": 0.0, - "max": 1.0, - "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, - "formula": "Diminished" + "format": "Percentage" }, - "playerex:fire_resistance": { + "playerex:melee_crit_chance": { "enabled": true, - "min": 0.0, - "max": 1.0, "smoothness": 1.0, - "min_fallback": 0.0, - "max_fallback": 1.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" }, - "spell_power:critical_chance": { + "playerex:fire_resistance": { "enabled": true, - "min": 100.0, - "max": 1000.0, "smoothness": 1.0, - "min_fallback": 100.0, - "max_fallback": 1000.0, - "formula": "Diminished" + "formula": "Diminished", + "format": "Percentage" } } } \ No newline at end of file diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 31f768b4..7c29df0a 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -3,14 +3,51 @@ "id": "playerex", "version": "${version}", "name": "PlayerEX: Directors Cut", - "description": "TBD", + "description": "Adds RPG-themed attributes to the game, and a leveling and skill mechanic to the player.", "authors": [ - "Bare Minimum Studios", - "CleverNucleus (former author)" + { + "name": "bibireden", + "contact": { + "homepage": "https://github.com/bibi-reden" + } + }, + { + "name": "naomi", + "contact": { + "homepage": "https://github.com/naomieow" + } + }, + { + "name": "DataEncoded", + "contact": { + "homepage": "https://github.com/DataEncoded" + } + } + ], + "contributors": [ + { + "name": "pokesmells", + "contact": { + "homepage": "https://github.com/pokesmells" + } + }, + { + "name": "OverlordsIII", + "contact": { + "homepage": "https://github.com/OverlordsIII" + } + }, + { + "name": "CleverNucleus [former author]", + "contact": { + "homepage": "https://github.com/CleverNucleus" + } + } ], "contact": { "homepage": "https://github.com/BareMinimumStudios/playerex", - "sources": "https://github.com/BareMinimumStudios/playerex" + "sources": "https://github.com/BareMinimumStudios/playerex", + "issues": "https://github.com/BareMinimumStudios/playerex/issues" }, "license": "MIT", "icon": "assets/playerex/icon.png", @@ -66,6 +103,14 @@ "cardinal-components@5.2.2(embedded){modrinth:K01OU20C}{curseforge:318449}#(ignore:github)", "spell-engine@>=0.15.8+1.20.1(optional){modrinth:XvoWJaA2}{curseforge:807653}#(ignore:github)" ] + }, + "modmenu": { + "links": { + "modmenu.discord": "https://discord.gg/pcRw79hwey", + "modmenu.wiki": "https://bareminimumstudios.github.io/Bare-Minimum-Docs/", + "modmenu.kofi": "https://ko-fi.com/bibiredens", + "modmenu.modrinth": "https://modrinth.com/mod/playerex-directors-cut" + } } } } \ No newline at end of file