diff --git a/src/main/kotlin/me/clip/voteparty/conf/sections/VoteSettings.kt b/src/main/kotlin/me/clip/voteparty/conf/sections/VoteSettings.kt index 62c794d6..3279f4a3 100644 --- a/src/main/kotlin/me/clip/voteparty/conf/sections/VoteSettings.kt +++ b/src/main/kotlin/me/clip/voteparty/conf/sections/VoteSettings.kt @@ -46,6 +46,46 @@ internal object VoteSettings : SettingsHolder "Note: A FULL reboot is required for this to take effect if changed after the plugin has been loaded.") val REMINDER_INTERVAL_SECONDS: Property = newProperty("voting.reminder_interval_seconds", 600) + @JvmField + @Comment("What message type to send the reminder as? Options are: chat, actionbar, title, bossbar.", + "If the value is missing or is invalid, chat is used.") + val REMINDER_MESSAGE_TYPE: Property = newProperty("voting.reminder_message_type", "chat") + + @JvmField + @Comment("What percentage of the bossbar should be filled? The value should be between 0.0 and 1.0.", + "Defaults to 1.0 which represents a full bossbar.", "This is only used if the reminder message type is set to bossbar.") + val REMINDER_BOSSBAR_FILL: Property = newProperty("voting.reminder_bossbar_fill", 1.0) + + @JvmField + @Comment("What color should the bossbar be? Options are: pink, blue, red, green, yellow, purple, white.", + "Defaults to purple.", "This is only used if the reminder message type is set to bossbar.") + val REMINDER_BOSSBAR_COLOR: Property = newProperty("voting.reminder_bossbar_color", "purple") + + @JvmField + @Comment("What overlay should the bossbar have? Options are: progress, notched_6, notched_10, notched_12, notched_20.", + "Defaults to progress.", "This is only used if the reminder message type is set to bossbar.") + val REMINDER_BOSSBAR_OVERLAY: Property = newProperty("voting.reminder_bossbar_overlay", "progress") + + @JvmField + @Comment("How long should the bossbar stay on the screen? (in ticks, 1 second = 20 ticks)", + "Defaults to 3 seconds.", "This is only used if the reminder message type is set to bossbar.") + val REMINDER_BOSSBAR_STAY_TIME: Property = newProperty("voting.reminder_bossbar_stay_time", 60) + + @JvmField + @Comment("How long should the title take to fade in? (in ticks, 1 second = 20 ticks)", + "Defaults to half a second.", "This is only used if the reminder message type is set to title.") + val REMINDER_TITLE_FADE_IN: Property = newProperty("voting.reminder_title_fade_in", 10) + + @JvmField + @Comment("How long should the title stay on the screen? (in ticks, 1 second = 20 ticks)", + "Defaults to 3 and a half seconds.", "This is only used if the reminder message type is set to title.") + val REMINDER_TITLE_STAY: Property = newProperty("voting.reminder_title_stay", 70) + + @JvmField + @Comment("How long should the title take to fade out? (in ticks, 1 second = 20 ticks)", + "Defaults to a second.", "This is only used if the reminder message type is set to title.") + val REMINDER_TITLE_FADE_OUT: Property = newProperty("voting.reminder_title_fade_out", 20) + @JvmField @Comment("If a player's inventory is full when voting, do you want to send the vote to a /vote claim?") val CLAIMABLE_IF_FULL: Property = newProperty("voting.claim_if_full", true) diff --git a/src/main/kotlin/me/clip/voteparty/exte/funcs.kt b/src/main/kotlin/me/clip/voteparty/exte/funcs.kt index 19e910e9..191b3d8b 100644 --- a/src/main/kotlin/me/clip/voteparty/exte/funcs.kt +++ b/src/main/kotlin/me/clip/voteparty/exte/funcs.kt @@ -4,12 +4,17 @@ import co.aikar.commands.ACFUtil import co.aikar.commands.CommandIssuer import co.aikar.locales.MessageKeyProvider import me.clip.placeholderapi.PlaceholderAPI +import me.clip.voteparty.VoteParty import me.clip.voteparty.base.Addon import me.clip.voteparty.conf.objects.Command import me.clip.voteparty.conf.sections.PluginSettings +import me.clip.voteparty.conf.sections.VoteSettings +import net.kyori.adventure.bossbar.BossBar import net.kyori.adventure.identity.Identity import net.kyori.adventure.text.Component import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer +import net.kyori.adventure.title.Title +import net.kyori.adventure.util.Ticks import org.bukkit.Bukkit import org.bukkit.ChatColor import org.bukkit.Material @@ -36,18 +41,52 @@ internal fun formMessage(player: OfflinePlayer, message: String): String return color(PlaceholderAPI.setPlaceholders(player, message)) } -internal fun Addon.sendMessage(receiver: CommandIssuer, message: MessageKeyProvider, placeholderTarget: OfflinePlayer? = null, vararg replacements: Any = emptyArray()) +private fun parseMessage(party: VoteParty, receiver: CommandIssuer, message: MessageKeyProvider, placeholderTarget: OfflinePlayer? = null, vararg replacements: Any = emptyArray()): String { var msg = receiver.manager.locales.getMessage(receiver, message) - + if (replacements.isNotEmpty() && replacements.size % 2 == 0) { msg = ACFUtil.replaceStrings(msg, *replacements.map(Any::toString).toTypedArray()) } - - val result = formMessage(Bukkit.getOfflinePlayer(placeholderTarget?.uniqueId ?: receiver.uniqueId), (party.conf().getProperty(PluginSettings.PREFIX) ?: PREFIX) + msg) - - party.audiences().sender(receiver.getIssuer()).sendMessage(Identity.nil(), serializer.deserialize(result)) + + return formMessage(Bukkit.getOfflinePlayer(placeholderTarget?.uniqueId ?: receiver.uniqueId), (party.conf().getProperty(PluginSettings.PREFIX) ?: PREFIX) + msg) +} + +internal fun Addon.sendActionBar(receiver: CommandIssuer, message: MessageKeyProvider, placeholderTarget: OfflinePlayer? = null, vararg replacements: Any = emptyArray()) +{ + val msg = parseMessage(party, receiver, message, placeholderTarget, *replacements) + party.audiences().sender(receiver.getIssuer()).sendActionBar(serializer.deserialize(msg)) +} + +internal fun Addon.sendTitle(receiver: CommandIssuer, title: MessageKeyProvider, subtitle: MessageKeyProvider, placeholderTarget: OfflinePlayer? = null, vararg replacements: Any = emptyArray()) +{ + val titleMsg = parseMessage(party, receiver, title, placeholderTarget, *replacements) + val subtitleMsg = parseMessage(party, receiver, subtitle, placeholderTarget, *replacements) + val fadeIn = Ticks.duration(party.conf().getProperty(VoteSettings.REMINDER_TITLE_FADE_IN).toLong()) + val stay = Ticks.duration(party.conf().getProperty(VoteSettings.REMINDER_TITLE_STAY).toLong()) + val fadeOut = Ticks.duration(party.conf().getProperty(VoteSettings.REMINDER_TITLE_FADE_OUT).toLong()) + val times = Title.Times.times(fadeIn, stay, fadeOut) + party.audiences().sender(receiver.getIssuer()).showTitle(Title.title(serializer.deserialize(titleMsg), serializer.deserialize(subtitleMsg), times)) +} + +internal fun Addon.sendBossBar(receiver: CommandIssuer, message: MessageKeyProvider, placeholderTarget: OfflinePlayer? = null, vararg replacements: Any = emptyArray()) +{ + val msg = parseMessage(party, receiver, message, placeholderTarget, *replacements) + val progress = getZeroToOne(party.conf().getProperty(VoteSettings.REMINDER_BOSSBAR_FILL)) + val color = BossBar.Color.NAMES.valueOr(party.conf().getProperty(VoteSettings.REMINDER_BOSSBAR_COLOR).lowercase(), BossBar.Color.PURPLE) + val overlay = BossBar.Overlay.NAMES.valueOr(party.conf().getProperty(VoteSettings.REMINDER_BOSSBAR_OVERLAY).lowercase(), BossBar.Overlay.PROGRESS) + val bossBar = BossBar.bossBar(serializer.deserialize(msg), progress, color, overlay) + party.audiences().sender(receiver.getIssuer()).showBossBar(bossBar) + plugin.runTaskLater(party.conf().getProperty(VoteSettings.REMINDER_BOSSBAR_STAY_TIME).toLong()){ + party.audiences().sender(receiver.getIssuer()).hideBossBar(bossBar) + } +} + +internal fun Addon.sendMessage(receiver: CommandIssuer, message: MessageKeyProvider, placeholderTarget: OfflinePlayer? = null, vararg replacements: Any = emptyArray()) +{ + val msg = parseMessage(party, receiver, message, placeholderTarget, *replacements) + party.audiences().sender(receiver.getIssuer()).sendMessage(Identity.nil(), serializer.deserialize(msg)) } internal fun msgAsString(issuer: CommandIssuer, key: MessageKeyProvider): String @@ -108,3 +147,13 @@ internal var ItemMeta.name: String { setDisplayName(color(value)) } + +private fun getZeroToOne(value: Double): Float +{ + return when + { + value < 0.0 -> 0.0f + value > 1.0 -> 1.0f + else -> value.toFloat() + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/clip/voteparty/handler/VotesHandler.kt b/src/main/kotlin/me/clip/voteparty/handler/VotesHandler.kt index c8e89dfc..a16a27e0 100644 --- a/src/main/kotlin/me/clip/voteparty/handler/VotesHandler.kt +++ b/src/main/kotlin/me/clip/voteparty/handler/VotesHandler.kt @@ -7,7 +7,10 @@ import me.clip.voteparty.conf.sections.PartySettings import me.clip.voteparty.conf.sections.VoteData import me.clip.voteparty.conf.sections.VoteSettings import me.clip.voteparty.exte.formMessage +import me.clip.voteparty.exte.sendActionBar +import me.clip.voteparty.exte.sendBossBar import me.clip.voteparty.exte.sendMessage +import me.clip.voteparty.exte.sendTitle import me.clip.voteparty.exte.takeRandomly import me.clip.voteparty.leaderboard.LeaderboardType import me.clip.voteparty.messages.Messages @@ -274,7 +277,12 @@ class VotesHandler(override val plugin: VotePartyPlugin) : Addon, State } players.forEach { - sendMessage(party.manager().getCommandIssuer(it), Messages.VOTES__REMINDER) + when(party.conf().getProperty(VoteSettings.REMINDER_MESSAGE_TYPE)) { + "actionbar" -> sendActionBar(party.manager().getCommandIssuer(it), Messages.VOTES__REMINDER) + "bossbar" -> sendBossBar(party.manager().getCommandIssuer(it), Messages.VOTES__REMINDER) + "title" -> sendTitle(party.manager().getCommandIssuer(it), Messages.VOTES__REMINDER, Messages.VOTES__REMINDER_SUBTITLE) + else -> sendMessage(party.manager().getCommandIssuer(it), Messages.VOTES__REMINDER) + } } } diff --git a/src/main/kotlin/me/clip/voteparty/messages/Messages.kt b/src/main/kotlin/me/clip/voteparty/messages/Messages.kt index 282254e9..ded5ec82 100644 --- a/src/main/kotlin/me/clip/voteparty/messages/Messages.kt +++ b/src/main/kotlin/me/clip/voteparty/messages/Messages.kt @@ -29,6 +29,7 @@ enum class Messages : MessageKeyProvider VOTES__ADDED_TO_PLAYER, VOTES__INVENTORY_FULL, VOTES__REMINDER, + VOTES__REMINDER_SUBTITLE, CRATE__CRATE_GIVEN, CRATE__CRATE_RECEIVED, diff --git a/src/main/resources/languages/de-DE.yml b/src/main/resources/languages/de-DE.yml index 8c98ae61..d8f92fd5 100644 --- a/src/main/resources/languages/de-DE.yml +++ b/src/main/resources/languages/de-DE.yml @@ -37,6 +37,8 @@ votes: added-to-player: "&fDu hast {count} Stimmen für %player_name% gegeben!" inventory-full: "&fDein Inventar scheint voll zu sein! Wir haben deine Vote Belohnung in dein Rucksack gepackt! Mache /vp claim, sobald dein Inventar nicht voll ist!" reminder: "&fDon't forget to vote for our server!" + # The subtitle only works when the reminder message type is set to title. + reminder-subtitle: "&fYou can vote by using &d/vote&f!" crate: crate-given: "&fDu hast &d%player_name% &fvote bekommen oder erstellt!" crate-received: "Du hast ein Vote erstellt!" diff --git a/src/main/resources/languages/en-US.yml b/src/main/resources/languages/en-US.yml index d8737048..3e7fee1f 100644 --- a/src/main/resources/languages/en-US.yml +++ b/src/main/resources/languages/en-US.yml @@ -36,6 +36,8 @@ votes: added-to-player: "&fYou've given {count} votes to %player_name%!" inventory-full: "&fYour inventory seems to be full! We've put this vote in your claimables! Do /vp claim once your inventory isn't full!" reminder: "&fDon't forget to vote for our server!" + # The subtitle only works when the reminder message type is set to title. + reminder-subtitle: "&fYou can vote by using &d/vote&f!" crate: crate-given: "&fYou've given &d%player_name% &fvote crate(s)!" crate-received: "&fYou've received a vote crate!" diff --git a/src/main/resources/languages/fr-FR.yml b/src/main/resources/languages/fr-FR.yml index c865c096..ad105712 100644 --- a/src/main/resources/languages/fr-FR.yml +++ b/src/main/resources/languages/fr-FR.yml @@ -37,6 +37,8 @@ votes: added-to-player: "&fVous avez donné {count} votes à %player_name%!" inventory-full: "&fYour inventory seems to be full! We've put this vote in your claimables! Do /vp claim once your inventory isn't full!" reminder: "&fDon't forget to vote for our server!" + # The subtitle only works when the reminder message type is set to title. + reminder-subtitle: "&fYou can vote by using &d/vote&f!" crate: crate-given: "&fVous avez donné à &d%player_name% &f une vote crate(s)!" crate-received: "&fVous avez reçu une caisse de vote !" diff --git a/src/main/resources/languages/nl-NL.yml b/src/main/resources/languages/nl-NL.yml index 9eae5066..55011f7a 100644 --- a/src/main/resources/languages/nl-NL.yml +++ b/src/main/resources/languages/nl-NL.yml @@ -37,6 +37,8 @@ votes: added-to-player: "&fJe hebt {count} stemmen aan %player_name% gegeven!" inventory-full: "&fJou inventaris is vol! We hebben deze stem in je claimables geplaats! Doe /vp claim wanneer je inventaris niet vol is!" reminder: "&fDon't forget to vote for our server!" + # The subtitle only works when the reminder message type is set to title. + reminder-subtitle: "&fYou can vote by using &d/vote&f!" crate: crate-given: "&fJe hebt &d%player_name% &fvote crate(s) gegeven!" crate-received: "&fJe hebt een vote crate ontvangen!" diff --git a/src/main/resources/languages/sv-SE.yml b/src/main/resources/languages/sv-SE.yml index df89c2e9..772df23e 100644 --- a/src/main/resources/languages/sv-SE.yml +++ b/src/main/resources/languages/sv-SE.yml @@ -37,6 +37,8 @@ votes: added-to-player: "&fDu har gett {count} röster till %player_name%!" inventory-full: "&fYour inventory seems to be full! We've put this vote in your claimables! Do /vp claim once your inventory isn't full!" reminder: "&fDon't forget to vote for our server!" + # The subtitle only works when the reminder message type is set to title. + reminder-subtitle: "&fYou can vote by using &d/vote&f!" crate: crate-given: "&fDu har gett &d%player_name% röstlådor!" crate-received: "&fDu har fått en röstlåda!"