Skip to content

Commit

Permalink
New Config Option - players.minPower (#1726)
Browse files Browse the repository at this point in the history
## Description
The `players.minPower` config option has been added, allowing players to
have negative power.

closes #1660 

## Testing
This has been tested on a local 1.19.4 minecraft server.

---------

Co-authored-by: Ren Binden <ren.binden@gmail.com>
  • Loading branch information
dmccoystephenson and renbinden authored Jul 6, 2023
1 parent 886dfe0 commit 43babd1
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 53 deletions.
87 changes: 52 additions & 35 deletions src/main/kotlin/com/dansplugins/factionsystem/MedievalFactions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -346,42 +346,12 @@ class MedievalFactions : JavaPlugin() {
server.scheduler.runTaskAsynchronously(
this,
Runnable {
val originalOnlinePlayerPower =
onlineMfPlayerIds.associateWith { playerService.getPlayer(it)?.power ?: initialPower }
playerService.updatePlayerPower(onlineMfPlayerIds).onFailure {
logger.log(SEVERE, "Failed to update player power: ${it.reason.message}", it.reason.cause)
return@Runnable
}
val newOnlinePlayerPower =
onlineMfPlayerIds.associateWith { playerService.getPlayer(it)?.power ?: initialPower }
server.scheduler.runTask(
this,
Runnable {
onlinePlayers.forEach { onlinePlayer ->
val playerId = MfPlayerId.fromBukkitPlayer(onlinePlayer)
val newPower = newOnlinePlayerPower[playerId] ?: initialPower
val originalPower = originalOnlinePlayerPower[playerId] ?: initialPower
val powerIncrease = floor(newPower).roundToInt() - floor(originalPower).roundToInt()
if (powerIncrease > 0) {
onlinePlayer.sendMessage("$GREEN${language["PowerIncreased", powerIncrease.toString()]}")
}
}
}
onPowerCycle(
onlineMfPlayerIds,
initialPower,
onlinePlayers,
disbandZeroPowerFactions
)
if (disbandZeroPowerFactions) {
factionService.factions.forEach { faction ->
if (faction.power <= 0.0) {
faction.sendMessage(
language["FactionDisbandedZeroPowerNotificationTitle"],
language["FactionDisbandedZeroPowerNotificationBody"]
)
factionService.delete(faction.id).onFailure {
logger.log(SEVERE, "Failed to delete faction: ${it.reason.message}", it.reason.cause)
return@Runnable
}
}
}
}
}
)
}, (15 - (LocalTime.now().minute % 15)) * 60 * 20L, 18000L)
Expand Down Expand Up @@ -491,6 +461,53 @@ class MedievalFactions : JavaPlugin() {
}
}

internal fun onPowerCycle(
onlineMfPlayerIds: List<MfPlayerId>,
initialPower: Double,
onlinePlayers: Collection<Player>,
disbandZeroPowerFactions: Boolean
) {
val playerService = services.playerService
val factionService = services.factionService

val originalOnlinePlayerPower =
onlineMfPlayerIds.associateWith { playerService.getPlayer(it)?.power ?: initialPower }
playerService.updatePlayerPower(onlineMfPlayerIds).onFailure {
logger.log(SEVERE, "Failed to update player power: ${it.reason.message}", it.reason.cause)
return
}
val newOnlinePlayerPower =
onlineMfPlayerIds.associateWith { playerService.getPlayer(it)?.power ?: initialPower }
server.scheduler.runTask(
this,
Runnable {
onlinePlayers.forEach { onlinePlayer ->
val playerId = MfPlayerId.fromBukkitPlayer(onlinePlayer)
val newPower = newOnlinePlayerPower[playerId] ?: initialPower
val originalPower = originalOnlinePlayerPower[playerId] ?: initialPower
val powerIncrease = floor(newPower).roundToInt() - floor(originalPower).roundToInt()
if (powerIncrease > 0) {
onlinePlayer.sendMessage("$GREEN${language["PowerIncreased", powerIncrease.toString()]}")
}
}
}
)
if (disbandZeroPowerFactions) {
factionService.factions.forEach { faction ->
if (faction.power <= 0.0) {
faction.sendMessage(
language["FactionDisbandedZeroPowerNotificationTitle"],
language["FactionDisbandedZeroPowerNotificationBody"]
)
factionService.delete(faction.id).onFailure {
logger.log(SEVERE, "Failed to delete faction: ${it.reason.message}", it.reason.cause)
return
}
}
}
}
}

private fun setupNotificationService(): MfNotificationService = when {
server.pluginManager.getPlugin("Mailboxes") != null -> MailboxesNotificationService(this)
server.pluginManager.getPlugin("rpk-notification-lib-bukkit") != null -> RpkNotificationService(this)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ import org.bukkit.command.TabCompleter
class MfFactionDevCommand(private val plugin: MedievalFactions) : CommandExecutor, TabCompleter {

private val factionDevGenerateCommand = MfFactionDevGenerateCommand(plugin)
private val factionDevPowerCycleCommand = MfFactionDevPowerCycleCommand(plugin)

private val generateAliases = listOf("generate")
private val powerCycleAliases = listOf("powercycle")

private val subcommands = generateAliases
private val subcommands = generateAliases + powerCycleAliases

override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
return when (args.firstOrNull()?.lowercase()) {
in generateAliases -> factionDevGenerateCommand.onCommand(sender, command, label, args.drop(1).toTypedArray())
in powerCycleAliases -> factionDevPowerCycleCommand.onCommand(sender, command, label, args.drop(1).toTypedArray())
else -> {
sender.sendMessage("${RED}Usage: /faction dev [generate]")
sender.sendMessage("${RED}Usage: /faction dev [generate|powercycle]")
true
}
}
Expand All @@ -35,6 +38,7 @@ class MfFactionDevCommand(private val plugin: MedievalFactions) : CommandExecuto
args.size == 1 -> subcommands.filter { it.startsWith(args[0].lowercase()) }
else -> when (args.first().lowercase()) {
in generateAliases -> factionDevGenerateCommand.onTabComplete(sender, command, label, args.drop(1).toTypedArray())
in powerCycleAliases -> factionDevPowerCycleCommand.onTabComplete(sender, command, label, args.drop(1).toTypedArray())
else -> emptyList()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.dansplugins.factionsystem.command.faction.dev

import com.dansplugins.factionsystem.MedievalFactions
import com.dansplugins.factionsystem.player.MfPlayerId
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter

class MfFactionDevPowerCycleCommand(private val plugin: MedievalFactions) : CommandExecutor, TabCompleter {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
val onlinePlayers = plugin.server.onlinePlayers
val onlineMfPlayerIds = onlinePlayers.map(MfPlayerId.Companion::fromBukkitPlayer)
val disbandZeroPowerFactions = plugin.config.getBoolean("factions.zeroPowerFactionsGetDisbanded")
val initialPower = plugin.config.getDouble("players.initialPower")
plugin.server.scheduler.runTaskAsynchronously(
plugin,
Runnable {
plugin.onPowerCycle(
onlineMfPlayerIds,
initialPower,
onlinePlayers,
disbandZeroPowerFactions
)
}
)
return true
}

override fun onTabComplete(
sender: CommandSender,
command: Command,
label: String,
args: Array<out String>
) = emptyList<String>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ class MfPowerSetCommand(private val plugin: MedievalFactions) : CommandExecutor,
sender.sendMessage("$RED${plugin.language["CommandPowerSetInvalidPowerMustBeNumber"]}")
return true
}
if (power < 0) {
sender.sendMessage("$RED${plugin.language["CommandPowerSetInvalidPowerCannotBeNegative"]}")
val minPower = plugin.config.getDouble("players.minPower")
if (power < minPower) {
sender.sendMessage("$RED${plugin.language["CommandPowerSetInvalidPowerTooLow", decimalFormat.format(minPower)]}")
return true
}
val maxPower = plugin.config.getDouble("players.maxPower")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class JooqMfPlayerRepository(private val plugin: MedievalFactions, private val d
}

override fun increaseOnlinePlayerPower(onlinePlayerIds: List<MfPlayerId>) {
val minPower = plugin.config.getDouble("players.minPower")
val maxPower = plugin.config.getDouble("players.maxPower")
val hoursToReachMax = plugin.config.getDouble("players.hoursToReachMaxPower")
val timeIncrementHours = 0.25
Expand All @@ -55,7 +56,7 @@ class JooqMfPlayerRepository(private val plugin: MedievalFactions, private val d
least(
value(maxPower),
greatest(
value(0.0),
value(minPower),
value((hoursToReachMax * 2) + timeIncrementHours)
.minus(
MF_PLAYER.POWER.div(maxPower)
Expand All @@ -82,6 +83,7 @@ class JooqMfPlayerRepository(private val plugin: MedievalFactions, private val d

override fun decreaseOfflinePlayerPower(onlinePlayerIds: List<MfPlayerId>) {
val maxPower = plugin.config.getDouble("players.maxPower")
val minPower = plugin.config.getDouble("players.minPower")
val hoursToReachMin = plugin.config.getDouble("players.hoursToReachMinPower")
val timeIncrementHours = 0.25
dsl.update(MF_PLAYER)
Expand All @@ -90,25 +92,31 @@ class JooqMfPlayerRepository(private val plugin: MedievalFactions, private val d
least(
value(maxPower),
greatest(
value(0.0),
least(MF_PLAYER.POWER, MF_PLAYER.POWER_AT_LOGOUT, maxPower).div(MF_PLAYER.POWER_AT_LOGOUT)
value(minPower),
// Determine the current time by running the inverse
least(MF_PLAYER.POWER, MF_PLAYER.POWER_AT_LOGOUT, maxPower)
.minus(minPower)
.div(MF_PLAYER.POWER_AT_LOGOUT.minus(minPower))
.minus(1)
.div(-1)
.pow(0.25)
.times(hoursToReachMin)
// Add the time increment to the time value we've determined
.plus(timeIncrementHours)
.div(hoursToReachMin)
.pow(4)
.times(-1)
.plus(1)
.times(MF_PLAYER.POWER_AT_LOGOUT)
// Run the formula normally on the new time to determine the new power value
.div(hoursToReachMin) // extend the graph from reaching the minimum value at 1 to hoursToReachMin
.pow(4) // exp4 curve
.times(-1) // flip the graph (exp4 is normally U-shaped)
.plus(1) // shift the graph up above the x axis (it will usually peak at the minimum value)
.times(MF_PLAYER.POWER_AT_LOGOUT.minus(minPower)) // scale the graph to the range of the power values
.plus(minPower) // shift the graph back down to the minimum power value
)
)
)
.set(MF_PLAYER.VERSION, MF_PLAYER.VERSION.plus(1))
.where(MF_PLAYER.ID.notIn(onlinePlayerIds.map { it.value }))
.and(MF_PLAYER.POWER_AT_LOGOUT.gt(0.0))
.and(MF_PLAYER.POWER.gt(0.0))
.and(MF_PLAYER.POWER_AT_LOGOUT.gt(minPower))
.and(MF_PLAYER.POWER.gt(minPower))
.execute()
}

Expand Down
1 change: 1 addition & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ database:
players:
initialPower: 5
maxPower: 20
minPower: -5
hoursToReachMaxPower: 12
hoursToReachMinPower: 72
powerLostOnDeath: 1
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/lang/lang_de_DE.properties
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ CommandPowerSetNoPermission=Du hast nicht die Erlaubnis, die Spielerkraft zu set
CommandPowerSetUsage=Benutzung: /kraft setzen [player] [power]
CommandPowerSetInvalidTarget=Ein Spieler mit diesem Namen hat noch nie gespielt.
CommandPowerSetInvalidPowerMustBeNumber=Die Kraft muss eine Zahl sein.
CommandPowerSetInvalidPowerCannotBeNegative=Die Kraft muss über Null liegen.
CommandPowerSetInvalidPowerTooLow=Die Kraft muss größer als {0} sein.
CommandPowerSetInvalidPowerTooHigh=Die maximale Leistung ist {0}.
CommandPowerSetFailedToSaveTargetPlayer=Die Informationen zum Zielspieler konnten nicht gespeichert werden.
CommandPowerSetSuccess=Setze die Kraft von {0} auf {1}/{2}.
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/lang/lang_en_GB.properties
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ CommandPowerSetNoPermission=You do not have permission to set player power.
CommandPowerSetUsage=Usage: /power set [player] [power]
CommandPowerSetInvalidTarget=No player by that name has played before.
CommandPowerSetInvalidPowerMustBeNumber=Power must be a number.
CommandPowerSetInvalidPowerCannotBeNegative=Power must be above zero.
CommandPowerSetInvalidPowerTooLow=The minimum power is {0}.
CommandPowerSetInvalidPowerTooHigh=The maximum power is {0}.
CommandPowerSetFailedToSaveTargetPlayer=Failed to save target player information.
CommandPowerSetSuccess=Set {0}''s power to {1}/{2}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/lang/lang_en_US.properties
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ CommandPowerSetNoPermission=You do not have permission to set player power.
CommandPowerSetUsage=Usage: /power set [player] [power]
CommandPowerSetInvalidTarget=No player by that name has played before.
CommandPowerSetInvalidPowerMustBeNumber=Power must be a number.
CommandPowerSetInvalidPowerCannotBeNegative=Power must be above zero.
CommandPowerSetInvalidPowerTooLow=The minimum power is {0}.
CommandPowerSetInvalidPowerTooHigh=The maximum power is {0}.
CommandPowerSetFailedToSaveTargetPlayer=Failed to save target player information.
CommandPowerSetSuccess=Set {0}''s power to {1}/{2}
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/lang/lang_fr_FR.properties
Original file line number Diff line number Diff line change
Expand Up @@ -749,7 +749,7 @@ CommandPowerSetNoPermission=Vous n''avez pas la permission de d
CommandPowerSetUsage=Usage : /power set [player] [power]
CommandPowerSetInvalidTarget=Aucun joueur de ce nom n''a déjà joué.
CommandPowerSetInvalidPowerMustBeNumber=Le pouvoir doit être un nombre.
CommandPowerSetInvalidPowerCannotBeNegative=Le pouvoir doit être supérieure à zéro.
CommandPowerSetInvalidPowerTooLow=Le pouvoir doit être supérieur ou égal à {0}.
CommandPowerSetInvalidPowerTooHigh=Le pouvoir maximal est {0}.
CommandPowerSetFailedToSaveTargetPlayer=L''enregistrement des informations relatives au joueur cible a échoué.
CommandPowerSetSuccess=Fixe le pouvoir de {0} à {1}/{2}.
Expand Down

0 comments on commit 43babd1

Please sign in to comment.