minecraft-mod/Essentials/src/main/kotlin/com/beemer/essentials/event/PlayerEvents.kt

157 lines
5.9 KiB
Kotlin
Raw Normal View History

package com.beemer.essentials.event
import com.beemer.essentials.config.PlayerConfig
import com.beemer.essentials.config.SpawnConfig
import com.beemer.essentials.data.Location
import com.beemer.essentials.util.ChatUtils
import com.beemer.essentials.util.DimensionUtils
import net.minecraft.ChatFormatting
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.neoforged.bus.api.SubscribeEvent
import net.neoforged.neoforge.event.entity.player.PlayerEvent
object PlayerEvents {
@SubscribeEvent
fun onPlayerRespawn(event: PlayerEvent.PlayerRespawnEvent) {
val player = event.entity as? ServerPlayer ?: return
val target = SpawnConfig.getCustomSpawn() ?: SpawnConfig.getDefaultSpawn() ?: return
val level = DimensionUtils.getLevelById(player.server, target.dimension) ?: return
player.teleportTo(level, target.x, target.y, target.z, player.yRot, player.xRot)
}
@SubscribeEvent
fun onPlayerLoggedIn(event: PlayerEvent.PlayerLoggedInEvent) {
val player = event.entity as? ServerPlayer ?: return
val existing = PlayerConfig.getPlayer(player)
val isFirstJoin = existing == null
ChatUtils.broadcastJoin(player, isFirstJoin)
PlayerConfig.recordLogin(player)
if (isFirstJoin) {
val spawn = SpawnConfig.getCustomSpawn() ?: SpawnConfig.getDefaultSpawn() ?: return
val level = DimensionUtils.getLevelById(player.server, spawn.dimension) ?: return
player.teleportTo(level, spawn.x, spawn.y, spawn.z, player.yRot, player.xRot)
// 신규 플레이어 도움말 (약간의 딜레이 후 표시)
player.server.execute {
sendWelcomeGuide(player)
// 알림 사운드 재생
playNotificationSound(player)
}
}
}
/** 알림 사운드 재생 */
private fun playNotificationSound(player: ServerPlayer) {
val notificationSound =
net.minecraft.sounds.SoundEvent.createVariableRangeEvent(
net.minecraft.resources.ResourceLocation.parse(
"minecraft:custom.notification"
)
)
player.playNotifySound(
notificationSound,
net.minecraft.sounds.SoundSource.MASTER,
0.5f,
1.0f
)
}
/** 신규 플레이어 도움말 */
private fun sendWelcomeGuide(player: ServerPlayer) {
val separator =
Component.literal("═══════════════════════════════").withStyle {
it.withColor(ChatFormatting.DARK_AQUA)
}
player.sendSystemMessage(Component.empty())
player.sendSystemMessage(separator)
player.sendSystemMessage(
Component.literal("🎉 서버에 오신 것을 환영합니다!").withStyle {
it.withColor(ChatFormatting.AQUA).withBold(true)
}
)
player.sendSystemMessage(Component.empty())
// 기본 명령어 안내
player.sendSystemMessage(
Component.literal("▸ 기본 명령어").withStyle {
it.withColor(ChatFormatting.YELLOW).withBold(true)
}
)
sendGuideItem(player, "/도움말", "명령어 목록 보기")
sendGuideItem(player, "/메뉴", "메뉴 GUI 열기")
sendGuideItem(player, "/스폰", "스폰으로 이동")
player.sendSystemMessage(Component.empty())
// 단축키 안내
player.sendSystemMessage(
Component.literal("▸ 단축키").withStyle {
it.withColor(ChatFormatting.YELLOW).withBold(true)
}
)
sendGuideItem(player, "Shift + F", "메뉴 GUI 열기")
player.sendSystemMessage(separator)
player.sendSystemMessage(Component.empty())
}
private fun sendGuideItem(player: ServerPlayer, key: String, desc: String) {
player.sendSystemMessage(
Component.literal(" ")
.append(
Component.literal(key).withStyle {
it.withColor(ChatFormatting.WHITE)
}
)
.append(
Component.literal(" - $desc").withStyle {
it.withColor(ChatFormatting.GRAY)
}
)
)
}
@SubscribeEvent
fun onPlayerLoggedOut(event: PlayerEvent.PlayerLoggedOutEvent) {
val player = event.entity as? ServerPlayer ?: return
ChatUtils.broadcastQuit(player)
PlayerConfig.recordLogout(player)
}
@SubscribeEvent
fun onPlayerClone(event: PlayerEvent.Clone) {
if (!event.isWasDeath) return
val oldPlayer = event.original as? ServerPlayer ?: return
val pos = oldPlayer.blockPosition()
val dimension = oldPlayer.level().dimension().location().toString()
val biome =
oldPlayer
.level()
.getBiome(pos)
.unwrapKey()
.map { it.location().toString() }
.orElse("minecraft:plains")
val lastLoc =
Location(
dimension = dimension,
biome = biome,
x = pos.x.toDouble(),
y = pos.y.toDouble(),
z = pos.z.toDouble()
)
PlayerConfig.recordLastLocation(oldPlayer, lastLoc)
}
}