summaryrefslogtreewikicommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2026-03-28 23:09:18 -0400
committerFreya Murphy <freya@freyacat.org>2026-03-28 23:09:18 -0400
commit2352b5324ae1f7a37361f067de836c3da6b1f1e5 (patch)
tree4153b8c74f84dffc9863d29c12d253a2ca857463 /core/src
parentadd wiki (diff)
downloadkenshinshideandseek2-2352b5324ae1f7a37361f067de836c3da6b1f1e5.tar.gz
kenshinshideandseek2-2352b5324ae1f7a37361f067de836c3da6b1f1e5.tar.bz2
kenshinshideandseek2-2352b5324ae1f7a37361f067de836c3da6b1f1e5.zip
2.0.0-alpha2v2.0.0-alpha2
- Added command /hs map blockhunt disguise - Auto complete block names in blockhunt commands - Fixed void generating chunks in non map save worlds - Fixed onDamage having no attacker - Fixed onDamage not respawning seeker properly - Fixed config deserialize not handeling nulls - Fixed config deserialize looking at more properties then it should
Diffstat (limited to 'core/src')
-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
7 files changed, 69 insertions, 16 deletions
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)