summaryrefslogtreewikicommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle.kts2
-rw-r--r--bukkit/res/plugin.yml4
-rw-r--r--bukkit/src/Shim.kt4
-rw-r--r--bukkit/src/World.kt4
-rw-r--r--bukkit/src/event/DamageListener.kt33
-rw-r--r--core/src/Khs.kt1
-rw-r--r--core/src/KhsShim.kt3
-rw-r--r--core/src/command/map/blockhunt/Disguise.kt31
-rw-r--r--core/src/command/map/blockhunt/block/Add.kt2
-rw-r--r--core/src/config/util/Deserialize.kt45
-rw-r--r--core/src/events/onDamage.kt2
-rw-r--r--core/src/game/Game.kt1
12 files changed, 89 insertions, 43 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 642d180..919c7ea 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -4,7 +4,7 @@ plugins {
allprojects {
group = "cat.freya.khs"
- version = "2.0.0-alpha1"
+ version = "2.0.0-alpha2"
repositories {
mavenCentral()
diff --git a/bukkit/res/plugin.yml b/bukkit/res/plugin.yml
index 5e22371..b37d938 100644
--- a/bukkit/res/plugin.yml
+++ b/bukkit/res/plugin.yml
@@ -1,6 +1,6 @@
name: KenshinsHideAndSeek
main: cat.freya.khs.bukkit.KhsPlugin
-version: 2.0.0-alpha1
+version: 2.0.0-alpha2
author: KenshinEto
website: freya.cat
load: STARTUP
@@ -50,6 +50,8 @@ permissions:
default: op
hs.map.blockhunt.debug:
default: op
+ hs.map.blockhunt.disguise:
+ default: op
hs.map.blockhunt.enabled:
default: op
hs.map.blockhunt.block.add:
diff --git a/bukkit/src/Shim.kt b/bukkit/src/Shim.kt
index 4e53344..0dc5a0e 100644
--- a/bukkit/src/Shim.kt
+++ b/bukkit/src/Shim.kt
@@ -16,6 +16,7 @@ import java.io.InputStream
import java.util.UUID
import kotlin.jvm.optionals.getOrNull
import org.bukkit.ChatColor
+import org.bukkit.Material
import org.bukkit.World as BukkitWorld
import org.bukkit.WorldCreator
import org.bukkit.WorldType
@@ -70,6 +71,9 @@ class BukkitKhsShim(val plugin: KhsPlugin) : KhsShim {
}
.map { it.name }
+ override val blocks: List<String>
+ get() = Material.values().map { it.toString().uppercase() }
+
override val sqliteDatabasePath: String
get() {
val legacy = File(plugin.dataFolder.path, "database.db")
diff --git a/bukkit/src/World.kt b/bukkit/src/World.kt
index afda77a..e9eb1b1 100644
--- a/bukkit/src/World.kt
+++ b/bukkit/src/World.kt
@@ -93,7 +93,9 @@ class BukkitKhsWorldLoader(val plugin: KhsPlugin, val worldName: String) : KhsWo
get() = File(plugin.server.worldContainer, "temp_hs_$name")
override fun load() {
- plugin.server.createWorld(WorldCreator(name).generator(VoidGenerator()))
+ var creator = WorldCreator(name)
+ if (worldName.startsWith("hs_")) creator = creator.generator(VoidGenerator())
+ plugin.server.createWorld(creator)
val world = plugin.server.getWorld(name)
if (world == null) {
plugin.shim.logger.error("could not load world: $name")
diff --git a/bukkit/src/event/DamageListener.kt b/bukkit/src/event/DamageListener.kt
index 81d5d12..667cfab 100644
--- a/bukkit/src/event/DamageListener.kt
+++ b/bukkit/src/event/DamageListener.kt
@@ -18,37 +18,22 @@ class DamageListener(val plugin: KhsPlugin) : Listener {
plugin.server.pluginManager.registerEvents(this, plugin)
}
- @EventHandler(priority = EventPriority.HIGHEST)
- fun onEntityDamageByEntity(event: EntityDamageByEntityEvent) {
- val bukkitPlayer = (event.entity as? BukkitPlayer) ?: return
-
- // get attacker
- val damager = event.damager
- val attackerEntity: BukkitPlayer? =
- when {
- damager is Projectile -> damager.shooter as? BukkitPlayer
- else -> damager as? BukkitPlayer
- }
-
- if (attackerEntity == null) {
- onEntityDamage(event)
- return
+ private fun getAttacker(event: EntityDamageEvent): BukkitPlayer? {
+ val damager = (event as? EntityDamageByEntityEvent)?.damager ?: return null
+ return when {
+ damager is Projectile -> damager.shooter as? BukkitPlayer
+ else -> damager as? BukkitPlayer
}
-
- val khsPlayer = BukkitKhsPlayer(plugin.shim, bukkitPlayer)
- val khsAttacker = BukkitKhsPlayer(plugin.shim, attackerEntity)
- val khsEvent = DamageEvent(plugin.khs, khsPlayer, khsAttacker, event.damage)
- onDamage(khsEvent)
-
- if (khsEvent.cancelled) event.setCancelled(true)
}
- @EventHandler(priority = EventPriority.HIGH)
+ @EventHandler(priority = EventPriority.HIGHEST)
fun onEntityDamage(event: EntityDamageEvent) {
val bukkitPlayer = (event.entity as? BukkitPlayer) ?: return
+ val attackerPlayer = getAttacker(event)
val khsPlayer = BukkitKhsPlayer(plugin.shim, bukkitPlayer)
- val khsEvent = DamageEvent(plugin.khs, khsPlayer, null, event.damage)
+ val khsAttacker = attackerPlayer?.let { BukkitKhsPlayer(plugin.shim, it) }
+ val khsEvent = DamageEvent(plugin.khs, khsPlayer, khsAttacker, event.damage)
onDamage(khsEvent)
if (khsEvent.cancelled) event.setCancelled(true)
diff --git a/core/src/Khs.kt b/core/src/Khs.kt
index 1863e2b..1ac6bf4 100644
--- a/core/src/Khs.kt
+++ b/core/src/Khs.kt
@@ -103,6 +103,7 @@ class Khs(val shim: KhsShim) {
this,
"blockhunt",
KhsMapBlockHuntDebug(),
+ KhsMapBlockHuntDisguise(),
KhsMapBlockHuntEnabled(),
CommandGroup(
this,
diff --git a/core/src/KhsShim.kt b/core/src/KhsShim.kt
index 9a31523..fe2cc3c 100644
--- a/core/src/KhsShim.kt
+++ b/core/src/KhsShim.kt
@@ -41,6 +41,9 @@ interface KhsShim {
/// @returns list of world names
val worlds: List<String>
+ /// @returns list of supported blocks
+ val blocks: List<String>
+
/// were the khs.db is stored
val sqliteDatabasePath: String
diff --git a/core/src/command/map/blockhunt/Disguise.kt b/core/src/command/map/blockhunt/Disguise.kt
new file mode 100644
index 0000000..8ee715a
--- /dev/null
+++ b/core/src/command/map/blockhunt/Disguise.kt
@@ -0,0 +1,31 @@
+package cat.freya.khs.command.map.blockhunt.block
+
+import cat.freya.khs.Khs
+import cat.freya.khs.command.util.Command
+import cat.freya.khs.player.Player
+import cat.freya.khs.runChecks
+
+class KhsMapBlockHuntDisguise : Command {
+ override val label = "disguise"
+ override val usage = listOf("block")
+ override val description = "Disguise oneself as any block"
+
+ override fun execute(plugin: Khs, player: Player, args: List<String>) {
+ val (blockName) = args
+ runChecks(plugin, player) { blockHuntSupported() }
+
+ val material = plugin.shim.parseMaterial(blockName)
+ if (material == null) {
+ player.message(plugin.locale.prefix.error + plugin.locale.blockHunt.block.unknown)
+ return
+ }
+
+ player.disguise(material)
+ }
+
+ override fun autoComplete(plugin: Khs, parameter: String, typed: String): List<String> =
+ when (parameter) {
+ "block" -> plugin.shim.blocks.filter { it.startsWith(typed) }
+ else -> listOf()
+ }
+}
diff --git a/core/src/command/map/blockhunt/block/Add.kt b/core/src/command/map/blockhunt/block/Add.kt
index 6ed17be..c39cee9 100644
--- a/core/src/command/map/blockhunt/block/Add.kt
+++ b/core/src/command/map/blockhunt/block/Add.kt
@@ -49,7 +49,7 @@ class KhsMapBlockHuntBlockAdd : Command {
.filter { it.value.config.blockHunt.enabled }
.map { it.key }
.filter { it.startsWith(typed) }
- "block" -> listOf(parameter)
+ "block" -> plugin.shim.blocks.filter { it.startsWith(typed) }
else -> listOf()
}
}
diff --git a/core/src/config/util/Deserialize.kt b/core/src/config/util/Deserialize.kt
index 8a5be59..58e23ce 100644
--- a/core/src/config/util/Deserialize.kt
+++ b/core/src/config/util/Deserialize.kt
@@ -12,26 +12,40 @@ import kotlin.reflect.full.createInstance
import kotlin.reflect.full.declaredFunctions
import kotlin.reflect.full.isSubclassOf
import kotlin.reflect.full.memberProperties
+import kotlin.reflect.full.primaryConstructor
import org.yaml.snakeyaml.Yaml
fun <T : Any> deserializeClass(type: KClass<T>, data: Map<String, Any?>): T {
require(type.isData) { "$type is not a data class" }
+ val props = type.memberProperties.associateBy { it.name }
+
val propValues =
- type.memberProperties.associateWith { prop ->
- val value = data[prop.name] ?: return@associateWith null
- val propType = prop.returnType.classifier as KClass<*>
- val innerTypes =
- prop.returnType.arguments.map { it.type?.classifier as? KClass<*> }.filterNotNull()
- deserializeField(propType, innerTypes, prop.name, value)
- }
+ type.primaryConstructor!!
+ .parameters
+ .map { props[it.name]!! }
+ .associateWith { prop ->
+ val value = data[prop.name]
+ val propType = prop.returnType.classifier as KClass<*>
+ val innerTypes =
+ prop.returnType.arguments
+ .map { it.type?.classifier as? KClass<*> }
+ .filterNotNull()
+
+ // allow null if type is null
+ if (prop.returnType.isMarkedNullable == true && value == null)
+ return@associateWith null
+
+ deserializeField(propType, innerTypes, prop.name, value)
+ }
val instance = type.createInstance()
for ((prop, value) in propValues) {
- if (value != null) {
- (prop as? KMutableProperty1<*, *>)?.setter?.call(instance, value)
- ?: error("${prop.name} is not mutable")
- }
+ if (value == null && !prop.returnType.isMarkedNullable)
+ error("${prop.name} cannot be null")
+
+ (prop as? KMutableProperty1<*, *>)?.setter?.call(instance, value)
+ ?: error("${prop.name} is not mutable")
}
val migrateFunction = instance::class.declaredFunctions.singleOrNull { it.name == "migrate" }
@@ -92,14 +106,15 @@ fun <T : Any> deserializeField(
type.isData ->
deserializeClass<T>(
type,
- value as? Map<String, Any?> ?: error("$key: expected map for data class $type"),
+ value as? Map<String, Any?>
+ ?: error("$key: expected map for data class $type, got $value"),
)
type.java.isEnum ->
deserializeEnum(
type as KClass<Enum<*>>,
key,
- value as? String ?: error("$key: expected string for enum value"),
+ value as? String ?: error("$key: expected string for enum value, got $value"),
)
as T
@@ -107,7 +122,7 @@ fun <T : Any> deserializeField(
deserializeList(
innerTypes?.firstOrNull() ?: error("$key: innerType not set"),
key,
- value as? List<*> ?: error("$key: expected list for type $type"),
+ value as? List<*> ?: error("$key: expected list for type $type, got $value"),
)
as T
@@ -116,7 +131,7 @@ fun <T : Any> deserializeField(
innerTypes?.firstOrNull() ?: error("key type not set"),
innerTypes.getOrNull(1) ?: error("value type not set"),
key,
- value as? Map<*, *> ?: error("$key: expected map for type $type"),
+ value as? Map<*, *> ?: error("$key: expected map for type $type, got $value"),
)
as T
diff --git a/core/src/events/onDamage.kt b/core/src/events/onDamage.kt
index 1377922..84e29dd 100644
--- a/core/src/events/onDamage.kt
+++ b/core/src/events/onDamage.kt
@@ -106,6 +106,8 @@ fun onDamage(event: DamageEvent) {
// broadcast death and update team
if (game.isSeeker(player)) {
game.broadcast(plugin.locale.game.player.death.with(player.name))
+ game.resetPlayer(player)
+ game.giveSeekerItems(player)
} else {
val msg =
if (attacker == null) {
diff --git a/core/src/game/Game.kt b/core/src/game/Game.kt
index 70187e3..18568f4 100644
--- a/core/src/game/Game.kt
+++ b/core/src/game/Game.kt
@@ -639,6 +639,7 @@ class Game(val plugin: Khs) {
player.inventory.clear()
player.clearEffects()
player.hunger = 20u
+ player.health = 20.0
player.heal()
player.revealDisguise()
hidePlayer(player, false)