- 클릭 사운드 (custom.click) - GUI 버튼 클릭 시 - 에러 사운드 (custom.error) - 오류 메시지 시 자동 재생 - 알림 사운드 (custom.notification) - 신규 플레이어 환영 시 - 텔레포트 사운드 (custom.teleport) - 스폰, 좌표이동, TPA, back - 메뉴 사운드 (custom.menu) - 메뉴 GUI 열기 시 기타 변경: - 닉네임 변경 시 동일 닉네임 예외처리 추가 - TPA 오류 메시지 빨간색으로 변경
156 lines
5.9 KiB
Kotlin
156 lines
5.9 KiB
Kotlin
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)
|
|
}
|
|
}
|