Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optional per-world healthbar config #25

Merged
merged 3 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog

## [Unreleased]
### Added
- Add optional per-world healthbar config

### Changed
- Switch java target from Java 11 to 1.8
- Update gradle to 6.5
Expand Down
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,31 @@ Simple, easy-to-use healthbar plugin with optional player and mob healthbars
## Config Overview

```yaml
# global defaults
player-bar:
type: SCOREBOARD # healthbar type (AKA location, can be SCOREBOARD or ACTION)
style: ABSOLUTE # style of healthbar (ABSOLUTE, PERCENT, or BAR)
useMainScoreboard: false # use the main scoreboard (true) or a new scoreboard (false)
duration: 5 # duration (in seconds) of the healthbar (for NAME or SCOREBOARD type)

mob-bar:
type: NAME # healthbar type (AKA location, can be SCOREBOARD, NAME, or ACTION)
type: NAME # healthbar type (AKA location, can be NAME or ACTION)
style: BAR # style of healthbar (ABSOLUTE, PERCENT, or BAR)
length: 20 # length of the bar (number of characters)
char: 0x25ae # character to use for the bar
showMobNames: true # if the mob's name should show alongside the healthbar (for NAME or ACTION type)
duration: 5 # duration (in seconds) of the healthbar (for NAME or SCOREBOARD type)

# per world configs/overrides
worlds:
world: # world name
mob-bar:
type: ACTION
style: BAR
length: 20
char: 0x25ae
showMobNames: true
duration: 5
```

### Available `type`s
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import java.util.UUID

class DamageListener(
private val plugin: Plugin,
private val playerHealthbar: PlayerHealthbar?,
private val mobHealthbar: MobHealthbar?
private val playerHealthbars: Map<String?, PlayerHealthbar?>,
private val mobHealthbars: Map<String?, MobHealthbar?>
) : Listener, AutoCloseable {
private data class RemoveHealthbarTask(val taskId: Int, val task: () -> Unit)

Expand All @@ -40,8 +40,8 @@ class DamageListener(
}

val healthbar = when (target) {
is Player -> playerHealthbar
else -> mobHealthbar
is Player -> playerHealthbars[target.world.name] ?: playerHealthbars[null]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for reviewing: world configs are keyed by world name, with null being the global default.

else -> mobHealthbars[target.world.name] ?: mobHealthbars[null]
}

// update healthbar and schedule its removal task if available
Expand Down
77 changes: 52 additions & 25 deletions src/main/kotlin/org/simplemc/simplehealthbars2/SimpleHealthbars2.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,40 +23,67 @@ class SimpleHealthbars2 : JavaPlugin() {
// ensure config file exists
saveDefaultConfig()

listener = DamageListener(
this,
config.getConfigurationSection("player-bar")?.let {
loadBar(it)?.let { bar ->
checkNotNull(bar as? PlayerHealthbar) { "Invalid player healthbar type! Must be one of: SCOREBOARD, ACTION" }
val playerHealthbars = mutableMapOf<String?, PlayerHealthbar>()
loadBar(config.getConfigurationSection("player-bar"))?.let { bar ->
playerHealthbars[null] =
checkNotNull(bar as? PlayerHealthbar) { "Invalid player healthbar type! Must be one of: SCOREBOARD, ACTION" }
}

val mobHealthbars = mutableMapOf<String?, MobHealthbar>()
loadBar(config.getConfigurationSection("mob-bar"))?.let { bar ->
mobHealthbars[null] =
checkNotNull(bar as? MobHealthbar) { "Invalid mob healthbar type! Must be one of: NAME, ACTION" }
}

config.getConfigurationSection("worlds")?.let { worlds ->
worlds.getKeys(false).forEach { worldName ->
val worldConfig = worlds.getConfigurationSection(worldName)
val playerBar = loadBar(worldConfig?.getConfigurationSection("player-bar"))
val mobBar = loadBar(worldConfig?.getConfigurationSection("mob-bar"))

playerBar?.also { bar ->
playerHealthbars[worldName] =
checkNotNull(bar as? PlayerHealthbar) { "Invalid player healthbar type! Must be one of: SCOREBOARD, ACTION" }
}
},
config.getConfigurationSection("mob-bar")?.let {
loadBar(it)?.let { bar ->
checkNotNull(bar as? MobHealthbar) { "Invalid mob healthbar type! Must be one of: NAME, ACTION" }

mobBar?.also { bar ->
mobHealthbars[worldName] =
checkNotNull(bar as? MobHealthbar) { "Invalid mob healthbar type! Must be one of: NAME, ACTION" }
}
}
)
}

logger.fine { "Loaded Healthbar configs:\n" +
"Player bars:\n" +
barsConfigToString(playerHealthbars) +
"\n\n" +
"Mob bars:\n" +
barsConfigToString(mobHealthbars) + "\n"
}

server.pluginManager.registerEvents(
listener,
this
)
listener = DamageListener(this, playerHealthbars, mobHealthbars)
server.pluginManager.registerEvents(listener, this)

logger.info("${description.name} version ${description.version} enabled!")
}

private fun loadBar(config: ConfigurationSection) =
when (Healthbar.Type.valueOf(checkNotNull(config.getString("type")))) {
Healthbar.Type.NAME -> NameHealthbar(loadStringBar(config))
Healthbar.Type.ACTION -> ActionHealthbar(loadStringBar(config))
Healthbar.Type.SCOREBOARD -> ScoreboardHealthbar(
ScoreboardHealthbar.Config(
useMainScoreboard = config.getBoolean("useMainScoreboard", false),
style = Healthbar.Style.valueOf(checkNotNull(config.getString("style", "ABSOLUTE"))),
duration = Duration.ofSeconds(config.getLong("duration", 5))
private fun barsConfigToString(bars: Map<String?, Healthbar>) =
bars.entries.joinToString(separator = "\n") { "World: ${it.key}, Config: ${it.value.config}" }.prependIndent()

private fun loadBar(config: ConfigurationSection?) =
config?.let {
when (Healthbar.Type.valueOf(checkNotNull(config.getString("type")))) {
Healthbar.Type.NAME -> NameHealthbar(loadStringBar(config))
Healthbar.Type.ACTION -> ActionHealthbar(loadStringBar(config))
Healthbar.Type.SCOREBOARD -> ScoreboardHealthbar(
ScoreboardHealthbar.Config(
useMainScoreboard = config.getBoolean("useMainScoreboard", false),
style = Healthbar.Style.valueOf(checkNotNull(config.getString("style", "ABSOLUTE"))),
duration = Duration.ofSeconds(config.getLong("duration", 5))
)
)
)
Healthbar.Type.NONE -> null
Healthbar.Type.NONE -> null
}
}

private fun loadStringBar(config: ConfigurationSection) = StringHealthbar.Config(
Expand Down
12 changes: 12 additions & 0 deletions src/main/resources/config.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# global defaults
player-bar:
type: SCOREBOARD # healthbar type (AKA location, can be SCOREBOARD or ACTION)
style: ABSOLUTE # style of healthbar (ABSOLUTE, PERCENT, or BAR)
Expand All @@ -11,3 +12,14 @@ mob-bar:
char: 0x25ae # character to use for the bar
showMobNames: true # if the mob's name should show alongside the healthbar (for NAME or ACTION type)
duration: 5 # duration (in seconds) of the healthbar (for NAME or SCOREBOARD type)

# per world configs/overrides
worlds:
world: # world name
mob-bar:
type: ACTION
style: BAR
length: 20
char: 0x25ae
showMobNames: true
duration: 5