Skip to content

Commit

Permalink
Implement more UI elements, proper XP level function
Browse files Browse the repository at this point in the history
  • Loading branch information
bibi-reden committed Jul 22, 2024
1 parent 1412cdc commit b5a63df
Show file tree
Hide file tree
Showing 21 changed files with 193 additions and 131 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ all_the_trims_version=3.4.2
placeholder_api_version=2.1.1+1.20

opc_version=1.0.0+1.20.1-fabric
data_attributes_version=2.0.0-beta.2+1.20.1-fabric
data_attributes_version=2.0.0-beta.3+1.20.1-fabric

# owo
owo_version=0.11.2+1.20
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ abstract class LivingEntityRendererMixin<T extends LivingEntity, M extends Entit
private void playerex$onRender(T entity, float f, float g, MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, CallbackInfo info) {
if (this.playerex$shouldRenderLevel(entity) && PlayerEX.CONFIG.getShowLevelNameplates()) {
DataAttributesAPI.getValue(PlayerEXAttributes.LEVEL, entity).ifPresent((value) -> {
Text tag = Text.translatable("playerex.gui.text.nameplate", String.valueOf(Math.round(value))).formatted(Formatting.WHITE);
Text tag = Text.translatable("playerex.ui.text.nameplate", String.valueOf(Math.round(value))).formatted(Formatting.WHITE);
this.playerex$renderLevel(entity, tag, matrixStack, vertexConsumerProvider, i);
});
}
Expand Down
3 changes: 2 additions & 1 deletion src/client/kotlin/com/bibireden/playerex/PlayerEXClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ object PlayerEXClient : ClientModInitializer {
override fun onInitializeClient() {
NetworkingChannels.NOTIFICATIONS.registerClientbound(NetworkingPackets.Notify::class) { (type), ctx ->
when (type) {
NotificationType.LevelUp -> ctx.player().playSound(PlayerEXSoundEvents.LEVEL_UP_SOUND, SoundCategory.NEUTRAL, PlayerEX.CONFIG.levelUpVolume.toFloat(), 1.5F)
NotificationType.LevelUp -> ctx.player().playSound(PlayerEXSoundEvents.LEVEL_UP_SOUND, SoundCategory.NEUTRAL, PlayerEX.CONFIG.levelUpVolume.toFloat(), 1F)
NotificationType.Spent -> ctx.player().playSound(PlayerEXSoundEvents.SPEND_SOUND, SoundCategory.NEUTRAL, PlayerEX.CONFIG.skillUpVolume.toFloat(), 1F)
}
}

Expand Down
22 changes: 18 additions & 4 deletions src/client/kotlin/com/bibireden/playerex/ui/PlayerEXScreen.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.bibireden.playerex.ui

import com.bibireden.data_attributes.api.DataAttributesAPI
import com.bibireden.playerex.PlayerEX
import com.bibireden.playerex.PlayerEXClient
import com.bibireden.playerex.api.attribute.PlayerEXAttributes
import com.bibireden.playerex.components.PlayerEXComponents
import com.bibireden.playerex.ext.level
import com.bibireden.playerex.networking.NetworkingChannels
import com.bibireden.playerex.networking.NetworkingPackets
import com.bibireden.playerex.util.PlayerEXUtil
Expand All @@ -16,6 +16,7 @@ import io.wispforest.owo.ui.component.TextBoxComponent
import io.wispforest.owo.ui.container.FlowLayout
import io.wispforest.owo.ui.core.Component
import io.wispforest.owo.ui.core.ParentComponent
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.text.Text
import net.minecraft.util.Formatting
import kotlin.reflect.KClass
Expand All @@ -36,12 +37,11 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat
fun onLevelUpdated() {
val player = client?.player ?: return
val data = PlayerEXComponents.PLAYER_DATA.get(player)
val level = DataAttributesAPI.getValue(PlayerEXAttributes.LEVEL, player).map(Double::toInt).orElse(0)

val root = this.uiAdapter.rootComponent

root.childById(LabelComponent::class, "level:current")?.apply {
text(Text.translatable("playerex.ui.current_level", level, PlayerEXUtil.getRequiredExperienceForLevel(level + 1.0)))
text(Text.translatable("playerex.ui.current_level", player.level.toInt(), PlayerEXUtil.getRequiredXpForNextLevel(player)))
}
root.childById(LabelComponent::class, "points_available")?.apply {
text(Text.literal(data.skillPoints.toString())
Expand All @@ -51,6 +51,7 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat
}
))
}
updateLevelUpButton(player, root.childById(TextBoxComponent::class, "level:amount")!!.text, root.childById(ButtonComponent::class, "level:button")!!)
}

/** Whenever any attribute is updated, this will be called. */
Expand All @@ -59,7 +60,7 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat

}

fun onPagesUpdated() {
private fun onPagesUpdated() {
val root = this.uiAdapter.rootComponent
val pageCounter = root.childById(LabelComponent::class, "counter")!!
val content = root.childById(FlowLayout::class, "content")!!
Expand All @@ -69,11 +70,24 @@ class PlayerEXScreen : BaseUIModelScreen<FlowLayout>(FlowLayout::class.java, Dat
content.children(pages[currentPage])
}

private fun updateLevelUpButton(player: PlayerEntity, text: String, levelUpButton: ButtonComponent) {
val amount = text.toIntOrNull() ?: return
val result = player.level + amount

if (result > PlayerEXAttributes.LEVEL.maxValue) return

levelUpButton.tooltip(Text.translatable("playerex.ui.level_button", PlayerEXUtil.getRequiredXpForLevel(player, result), amount, player.experienceLevel))
}

override fun build(rootComponent: FlowLayout) {
val player = client?.player ?: return

val levelAmount = rootComponent.childById(TextBoxComponent::class, "level:amount")!!
val levelUpButton = rootComponent.childById(ButtonComponent::class, "level:button")!!

updateLevelUpButton(player, levelAmount.text, levelUpButton)
levelAmount.onChanged().subscribe { updateLevelUpButton(player, it, levelUpButton) }

val previousPage = rootComponent.childById(ButtonComponent::class, "previous")!!
val pageCounter = rootComponent.childById(LabelComponent::class, "counter")!!
val nextPage = rootComponent.childById(ButtonComponent::class, "next")!!
Expand Down
11 changes: 8 additions & 3 deletions src/client/resources/assets/playerex/owo_ui/main_ui_model.xml
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@

<!-- content -->
<flow-layout direction="horizontal" id="content">
<children/>
<children>
<stack-layout>
<children>

</children>
</stack-layout>
</children>

<sizing><vertical method="fill">85</vertical><horizontal method="fill">100</horizontal></sizing>
<positioning type="relative">0,50</positioning>
Expand All @@ -98,7 +104,7 @@
<children>
<label id="level:current"/>
<text-box id="level:amount">
<text>0</text>
<text>1</text>

<sizing>
<vertical method="fixed">10</vertical>
Expand All @@ -110,7 +116,6 @@
</text-box>
<button id="level:button">
<text>+</text>
<tooltip-text>Click here to level up based on the amount you entered.</tooltip-text>

<renderer><flat color="black" hovered-color="black" disabled-color="dark-red"/></renderer>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ private void addExperienceLevels(int levels, CallbackInfo ci) {
PlayerDataComponent component = (PlayerDataComponent) PlayerEXComponents.PLAYER_DATA.get(player);

int current = player.experienceLevel;
int required = PlayerEXUtil.getRequiredXp(player);
int required = PlayerEXUtil.getRequiredXpForNextLevel(player);

boolean isAmountReached = current >= required;
if (isAmountReached && !component.isLevelUpNotified()) {
NetworkFactory.sendLevelUpNotification(player);
if (current >= required) {
if (!component.isLevelUpNotified()) {
component.setLevelUpNotified(true);
NetworkFactory.sendLevelUpNotification(player);
}
}
else {
component.setLevelUpNotified(false);
}
component.setLevelUpNotified(isAmountReached);
}
}
77 changes: 49 additions & 28 deletions src/main/kotlin/com/bibireden/playerex/PlayerEXCommands.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ 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.id
import com.bibireden.playerex.networking.NetworkingChannels
import com.bibireden.playerex.networking.NetworkingPackets
import com.bibireden.playerex.networking.types.NotificationType
import com.mojang.brigadier.CommandDispatcher
import com.mojang.brigadier.arguments.IntegerArgumentType
import com.mojang.brigadier.builder.RequiredArgumentBuilder
Expand All @@ -19,19 +23,18 @@ import net.minecraft.command.argument.EntityArgumentType
import net.minecraft.command.argument.IdentifierArgumentType
import net.minecraft.entity.attribute.EntityAttribute
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.registry.Registries
import net.minecraft.server.command.CommandManager
import net.minecraft.server.command.CommandManager.RegistrationEnvironment
import net.minecraft.server.command.ServerCommandSource
import net.minecraft.text.MutableText
import net.minecraft.text.Text
import net.minecraft.util.Formatting
import net.minecraft.util.Identifier

private typealias Context = CommandContext<ServerCommandSource>

// todo: overlords will complete this
object PlayerEXCommands {
val MODIFIABLE_ATTRIBUTES_SUGGESTIONS = SuggestionProvider<ServerCommandSource> { _, builder ->
private val MODIFIABLE_ATTRIBUTES_SUGGESTIONS = SuggestionProvider<ServerCommandSource> { _, builder ->
CommandSource.suggestIdentifiers(PlayerEXAttributes.PRIMARY_ATTRIBUTE_IDS, builder)
CommandSource.suggestIdentifiers(TradeSkillAttributes.IDS, builder)
}
Expand All @@ -48,41 +51,36 @@ object PlayerEXCommands {
fun register(dispatcher: CommandDispatcher<ServerCommandSource>, access: CommandRegistryAccess, environment: RegistrationEnvironment) {
dispatcher.register(CommandManager.literal("playerex")
.requires(::isOp)
.then(CommandManager.literal("level").then(
playerArgument.then(
CommandManager.literal("get").executes(::executeLevelGetCommand)
).then(
CommandManager.literal("add").executes(::executeLevelUpCommand)
.then(CommandManager.literal("level")
.then(CommandManager.literal("get").then(playerArgument.executes(::executeLevelGetCommand)))
.then(CommandManager.literal("add").then(
playerArgument.executes(::executeLevelUpCommand)
.then(amountArgument.executes { executeLevelUpCommand(it, IntegerArgumentType.getInteger(it, "amount")) })
)
)
)
.then(CommandManager.literal("reset")
.then(playerArgument.executes(::executeResetCommand)
.then(CommandManager.argument("amount", IntegerArgumentType.integer(0, 100)).executes { executeResetCommand(it, IntegerArgumentType.getInteger(it, "amount")) })
)
.then(CommandManager.literal("@all").executes(::executeResetAllCommand)
.then(amountArgument.executes { executeResetAllCommand(it, IntegerArgumentType.getInteger(it, "amount")) })
)
.then(playerArgument.executes(::executeResetCommand)
.then(amountArgument.executes { executeResetCommand(it, IntegerArgumentType.getInteger(it, "amount")) })
)
)
.then(CommandManager.literal("skill")
.then(
playerArgument.then(
CommandManager.literal("get").then(
identifierArgument.suggests(MODIFIABLE_ATTRIBUTES_SUGGESTIONS).executes(::executeSkillGetCommand)
)
).then(CommandManager.literal("add").then(
identifierArgument
.suggests(MODIFIABLE_ATTRIBUTES_SUGGESTIONS)
.then(identifierArgument.suggests(MODIFIABLE_ATTRIBUTES_SUGGESTIONS)
.then(CommandManager.literal("get").then(playerArgument.executes(::executeSkillGetCommand)))
.then(CommandManager.literal("add")
.then(playerArgument
.executes(::executeSkillUpCommand)
.then(amountArgument.executes { executeSkillUpCommand(it, IntegerArgumentType.getInteger(it, "amount")) })
)
).then(CommandManager.literal("refund").then(
identifierArgument
.suggests(MODIFIABLE_ATTRIBUTES_SUGGESTIONS)
).then(CommandManager.literal("refund")
.then(playerArgument
.executes(::executeRefundCommand)
.then(amountArgument.executes { executeRefundCommand(it, IntegerArgumentType.getInteger(it, "amount")) })
))
)
)
)
)
)
Expand All @@ -93,7 +91,7 @@ object PlayerEXCommands {
private fun executeLevelGetCommand(ctx: Context): Int {
val player = EntityArgumentType.getPlayer(ctx, "player")
return DataAttributesAPI.getValue(PlayerEXAttributes.LEVEL, player).map {
ctx.source.sendFeedback({ Text.translatable("playerex.command.level_get", player.name, it.toInt()) }, false)
ctx.source.sendFeedback({ Text.translatable("playerex.command.level_get", player.name, it.toInt()).append(Text.of("/${PlayerEXAttributes.LEVEL.maxValue.toInt()}")) }, false)
1
}.orElse(-1)
}
Expand All @@ -109,7 +107,25 @@ object PlayerEXCommands {
}

private fun executeRefundCommand(ctx: Context, amount: Int = 1): Int {
return 1
val player = EntityArgumentType.getPlayer(ctx, "player")
val component = PlayerEXComponents.PLAYER_DATA.get(player)
val supplier = EntityAttributeSupplier(IdentifierArgumentType.getIdentifier(ctx, "id"))

return DataAttributesAPI.getValue(supplier, player).map {
val attribute = supplier.get()!!
if (it < amount) {
ctx.source.sendFeedback({ Text.translatable("playerex.command.refund_error", player.name) }, false)
-1
}
else {
val result = it - amount
component.addSkillPoints(amount)
component.set(attribute, result)
ctx.source.sendFeedback({ Text.translatable("playerex.command.refunded", amount, Text.translatable(attribute.translationKey), player.name) }, false)
ctx.source.sendFeedback(updatedValueText(attribute, result), false)
1
}
}.orElse(-1)
}

private fun executeSkillUpCommand(ctx: Context, amount: Int = 1): Int {
Expand All @@ -121,6 +137,7 @@ object PlayerEXCommands {
val attribute = supplier.get()!!
if (component.skillUp(attribute, amount, true)) {
ctx.source.sendFeedback({ Text.translatable("playerex.command.skill_up", amount, Text.translatable(attribute.translationKey), player.name) }, false)
ctx.source.sendFeedback(updatedValueText(attribute, it + amount), false)
1
}
else {
Expand Down Expand Up @@ -148,7 +165,8 @@ object PlayerEXCommands {
return@map -1
}

ctx.source.sendFeedback({ Text.translatable("playerex.command.level_up", amount, player.getName()) }, false)
ctx.source.sendFeedback({ Text.translatable("playerex.command.level_up", amount, player.name) }, false)
ctx.source.sendFeedback(updatedValueText(attribute, value + amount), false)

return@map 1
}.orElse(-1)
Expand All @@ -161,8 +179,7 @@ object PlayerEXCommands {

ctx.source.sendFeedback(
{
Text.translatable("playerex.command.reset", player.name)
.also { if (retained > 0) it.append(", ${retained}%") }
Text.translatable("playerex.command.reset", player.name).also { if (retained > 0) it.append(" [${retained}%]") }
},
false
)
Expand All @@ -187,4 +204,8 @@ object PlayerEXCommands {
private fun maxErrorMessage(player: PlayerEntity, attribute: EntityAttribute): () -> MutableText = {
Text.translatable("playerex.command.max_error", Text.translatable(attribute.translationKey), player.name)
}

private fun updatedValueText(attribute: EntityAttribute, value: Double): () -> MutableText = {
Text.translatable("playerex.command.updated_result", value.toInt()).append(Text.of("/${(attribute as IEntityAttribute).`data_attributes$max`().toInt()}"))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ object DefaultAttributeImpl {
PlayerEXAttributes.LUCKINESS.id to 0.0,
PlayerEXAttributes.EVASION.id to 0.0,
PlayerEXAttributes.LIFESTEAL.id to 0.0,
PlayerEXAttributes.FOCUS.id to 0.0,
PlayerEXAttributes.HEALTH_REGENERATION.id to 0.0,
PlayerEXAttributes.HEAL_AMPLIFICATION.id to 0.0,
PlayerEXAttributes.HEAL_AMPLIFICATION.id to 0.0,
PlayerEXAttributes.MELEE_CRIT_DAMAGE.id to 0.0,
PlayerEXAttributes.MELEE_CRIT_CHANCE.id to 0.0,
PlayerEXAttributes.RANGED_CRITICAL_DAMAGE.id to 0.0,
PlayerEXAttributes.RANGED_CRITICAL_CHANCE.id to 0.0,
PlayerEXAttributes.RANGED_DAMAGE.id to 0.0,
PlayerEXAttributes.FIRE_RESISTANCE.id to 0.0,
PlayerEXAttributes.FREEZE_RESISTANCE.id to 0.0,
PlayerEXAttributes.LIGHTNING_RESISTANCE.id to 0.0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import com.bibireden.playerex.components.player.IPlayerDataComponent
import com.bibireden.playerex.components.player.PlayerDataComponent
import dev.onyxstudios.cca.api.v3.chunk.ChunkComponentFactoryRegistry
import dev.onyxstudios.cca.api.v3.chunk.ChunkComponentInitializer
import dev.onyxstudios.cca.api.v3.component.ComponentKey
import dev.onyxstudios.cca.api.v3.component.ComponentRegistry
import dev.onyxstudios.cca.api.v3.entity.EntityComponentFactoryRegistry
import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer
import dev.onyxstudios.cca.api.v3.entity.RespawnCopyStrategy
import net.minecraft.util.Identifier

class PlayerEXComponents : EntityComponentInitializer, ChunkComponentInitializer {
companion object {
@JvmField
val PLAYER_DATA = ComponentRegistry.getOrCreate(PlayerEX.id("player-data"), IPlayerDataComponent::class.java)
val PLAYER_DATA: ComponentKey<IPlayerDataComponent> = ComponentRegistry.getOrCreate(PlayerEX.id("player-data"), IPlayerDataComponent::class.java)
@JvmField
val EXPERIENCE_DATA = ComponentRegistry.getOrCreate(PlayerEX.id("experience-data"), IExperienceDataComponent::class.java)
val EXPERIENCE_DATA: ComponentKey<IExperienceDataComponent> = ComponentRegistry.getOrCreate(PlayerEX.id("experience-data"), IExperienceDataComponent::class.java)
}

override fun registerEntityComponentFactories(registry: EntityComponentFactoryRegistry) {
Expand Down
Loading

0 comments on commit b5a63df

Please sign in to comment.