Remove legacy modules, add language & scoreboard
Large refactor removing many legacy subsystems (abilities, kit system, database repos, recraft, world manager, extensive config classes, lunar/luckperms integrations and various listeners/commands). Introduces a lightweight LanguageManager, AntiRunningManager, ScoreboardManager, ConnectListener and a SoupListener; simplifies the main SpeedHG plugin to initialize these components and register the connection listener. Build changes: update Gradle wrapper to 8.10, remove paperweight and several external dependencies, add fr.mrmicky:fastboard and simplify shadowJar/build task configuration. Adds default language resource (languages/en_US.yml) and updates plugin/config resources. Purpose: simplify and decouple the plugin, reduce dependency surface and prepare for a leaner, modular rewrite.
This commit is contained in:
101
src/main/kotlin/club/mcscrims/speedhg/util/AbilityUtils.kt
Normal file
101
src/main/kotlin/club/mcscrims/speedhg/util/AbilityUtils.kt
Normal file
@@ -0,0 +1,101 @@
|
||||
package club.mcscrims.speedhg.util
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import org.bukkit.Color
|
||||
import org.bukkit.GameMode
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Particle
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.scheduler.BukkitRunnable
|
||||
import org.bukkit.util.Vector
|
||||
import java.util.function.Consumer
|
||||
|
||||
object AbilityUtils {
|
||||
|
||||
private val plugin = SpeedHG.instance
|
||||
|
||||
fun createBeam(
|
||||
startLocation: Location,
|
||||
direction: Vector,
|
||||
particle: Particle,
|
||||
range: Double,
|
||||
step: Double,
|
||||
onHit: (Player) -> Unit
|
||||
) {
|
||||
val normalizedDirection = direction.normalize()
|
||||
|
||||
object : BukkitRunnable()
|
||||
{
|
||||
var traveledDistance = 0.0
|
||||
var currentLocation = startLocation.clone()
|
||||
|
||||
override fun run()
|
||||
{
|
||||
if ( traveledDistance >= range)
|
||||
{
|
||||
this.cancel()
|
||||
return
|
||||
}
|
||||
|
||||
currentLocation.world.spawnParticle( particle, currentLocation, 5, 0.0, 0.0, 0.0, 0.0 )
|
||||
|
||||
val nearestPlayer = currentLocation.world.getNearbyEntities( currentLocation, 0.5, 0.5, 0.5 )
|
||||
.filterIsInstance<Player>().minByOrNull { it.location.distance( currentLocation ) }
|
||||
|
||||
if ( nearestPlayer != null )
|
||||
{
|
||||
onHit( nearestPlayer )
|
||||
this.cancel()
|
||||
return
|
||||
}
|
||||
|
||||
currentLocation.add(normalizedDirection.multiply( step ))
|
||||
traveledDistance += step
|
||||
}
|
||||
|
||||
}.runTaskTimer( plugin, 0L, 1L )
|
||||
}
|
||||
|
||||
fun drawParticleLine(
|
||||
startLocation: Location,
|
||||
endLocation: Location,
|
||||
particle: Particle,
|
||||
steps: Int,
|
||||
dustColor: Color
|
||||
) {
|
||||
if ( steps <= 0 ) throw IllegalArgumentException( "Steps must be greater than 0." )
|
||||
val world = startLocation.world ?: throw IllegalStateException( "World cannot be null." )
|
||||
if ( startLocation.world != endLocation.world ) throw IllegalStateException( "Locations must be in the same world." )
|
||||
|
||||
val diffX = ( endLocation.x - startLocation.x ) / steps
|
||||
val diffY = ( endLocation.y - startLocation.y ) / steps
|
||||
val diffZ = ( endLocation.z - startLocation.z ) / steps
|
||||
|
||||
for ( i in 0..steps )
|
||||
{
|
||||
val x = startLocation.x + diffX * i
|
||||
val y = startLocation.y + diffY * i
|
||||
val z = startLocation.z + diffZ * i
|
||||
|
||||
world.spawnParticle( particle, x, y, z, 1, Particle.DustOptions( dustColor, 1f ))
|
||||
}
|
||||
}
|
||||
|
||||
fun runForNearbyPlayers(
|
||||
player: Player,
|
||||
radius: Double,
|
||||
filter: (Player) -> Boolean,
|
||||
runnable: Consumer<in Player>
|
||||
): MutableCollection<Player>
|
||||
{
|
||||
if ( radius <= 0.0 ) throw IllegalArgumentException( "Radius must be greater than 0.0." )
|
||||
|
||||
val world = player.world
|
||||
val nearbyPlayers = world.getNearbyPlayers( player.location, radius ).filter( filter )
|
||||
.filter { it != player && it.gameMode == GameMode.SURVIVAL }.toMutableList()
|
||||
|
||||
nearbyPlayers.forEach( runnable )
|
||||
return nearbyPlayers
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package club.mcscrims.speedhg.util
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import net.kyori.adventure.text.Component
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.util.Vector
|
||||
import kotlin.math.atan2
|
||||
|
||||
object DirectionUtil {
|
||||
|
||||
private val plugin = SpeedHG.instance
|
||||
private val directions = arrayOf("north", "northEast", "east", "southEast", "south", "southWest", "west", "northWest")
|
||||
|
||||
fun getDirectionToPlayer(
|
||||
player: Player,
|
||||
nearestPlayer: Player
|
||||
): Component
|
||||
{
|
||||
val yaw = getDirection( player, nearestPlayer )
|
||||
var normalizedYaw = yaw % 360
|
||||
|
||||
if ( normalizedYaw < 0 )
|
||||
normalizedYaw += 360
|
||||
|
||||
val index = (( normalizedYaw + 22.5 ) / 45 ).toInt() % 8
|
||||
return plugin.chatFormatter.format( "compass.directions.${directions[ index ]}" )
|
||||
}
|
||||
|
||||
private fun getDirection(
|
||||
fromPlayer: Player,
|
||||
toPlayer: Player
|
||||
): Double
|
||||
{
|
||||
val fromLocation = fromPlayer.location
|
||||
val toLocation = toPlayer.location
|
||||
|
||||
val directionVector = Vector( toLocation.x - fromLocation.x, 0.0, toLocation.z - fromLocation.z ).normalize()
|
||||
|
||||
val angle = atan2( directionVector.x, directionVector.z )
|
||||
val yaw = Math.toDegrees( angle )
|
||||
|
||||
var adjustedYaw = yaw + 180
|
||||
|
||||
if ( adjustedYaw < 0)
|
||||
adjustedYaw += 360
|
||||
|
||||
return adjustedYaw
|
||||
}
|
||||
|
||||
fun getTargetPlayerInLineOfSight(
|
||||
player: Player,
|
||||
maxDistance: Double,
|
||||
width: Double
|
||||
): Player?
|
||||
{
|
||||
val direction = player.eyeLocation.direction.normalize()
|
||||
val origin = player.eyeLocation.toVector()
|
||||
val world = player.world
|
||||
|
||||
val nearbyPlayers = world.getNearbyEntitiesByType( Player::class.java, player.location, maxDistance, maxDistance, maxDistance )
|
||||
|
||||
return nearbyPlayers
|
||||
.filter { it.uniqueId != player.uniqueId }
|
||||
.filter { nearby ->
|
||||
val nearbyLocation = nearby.location.add( 0.0, 0.5, 0.0 ).toVector()
|
||||
|
||||
val toEntitiy = nearbyLocation.subtract( origin )
|
||||
|
||||
val distanceAlongLine = toEntitiy.dot( direction )
|
||||
if ( distanceAlongLine !in 0.0..maxDistance ) return@filter false
|
||||
|
||||
val perpendicularDistance = toEntitiy.subtract(direction.multiply( distanceAlongLine )).length()
|
||||
perpendicularDistance <= width
|
||||
}
|
||||
.minByOrNull { it.location.distanceSquared( player.location ) }
|
||||
}
|
||||
|
||||
}
|
||||
55
src/main/kotlin/club/mcscrims/speedhg/util/Extensions.kt
Normal file
55
src/main/kotlin/club/mcscrims/speedhg/util/Extensions.kt
Normal file
@@ -0,0 +1,55 @@
|
||||
package club.mcscrims.speedhg.util
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import net.kyori.adventure.text.Component
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
|
||||
import org.bukkit.entity.Player
|
||||
|
||||
private val langManager get() = SpeedHG.instance.languageManager
|
||||
|
||||
private val legacySerializer = LegacyComponentSerializer.builder()
|
||||
.character('§')
|
||||
.hexColors()
|
||||
.useUnusualXRepeatedCharacterHexFormat()
|
||||
.build()
|
||||
|
||||
fun Player.sendMsg(
|
||||
key: String,
|
||||
vararg placeholders: Pair<String, String>
|
||||
) {
|
||||
val component = langManager.getComponent( this, key, placeholders.toMap() )
|
||||
this.sendMessage( component )
|
||||
}
|
||||
|
||||
fun Player.trans(
|
||||
key: String,
|
||||
vararg placeholders: Pair<String, String>
|
||||
): Component
|
||||
{
|
||||
return langManager.getComponent( this, key, placeholders.toMap() )
|
||||
}
|
||||
|
||||
fun Player.transList(
|
||||
key: String,
|
||||
placeholders: Map<String, String>
|
||||
): List<Component>
|
||||
{
|
||||
val rawList = langManager.getRawMessageList( this, key )
|
||||
|
||||
return rawList.map { line ->
|
||||
var replaced = line
|
||||
placeholders.forEach { (k, v) ->
|
||||
replaced = replaced.replace( "<$k>", v )
|
||||
}
|
||||
MiniMessage.miniMessage().deserialize( replaced )
|
||||
}
|
||||
}
|
||||
|
||||
fun Component.toLegacyString(): String
|
||||
{
|
||||
return legacySerializer.serialize( this )
|
||||
}
|
||||
|
||||
val Player.getDisplayName: String
|
||||
get() = legacySerializer.serialize( this.displayName() )
|
||||
@@ -1,61 +0,0 @@
|
||||
package club.mcscrims.speedhg.util
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
import net.luckperms.api.cacheddata.CachedDataManager
|
||||
import net.luckperms.api.model.group.Group
|
||||
import net.luckperms.api.model.user.User
|
||||
import org.bukkit.entity.Player
|
||||
import java.util.UUID
|
||||
|
||||
object LuckPermsUtils {
|
||||
|
||||
private val plugin = SpeedHG.instance
|
||||
private val luckPerms = plugin.luckPerms
|
||||
|
||||
fun getUser(
|
||||
player: Player
|
||||
): User?
|
||||
{
|
||||
return luckPerms.userManager.getUser( player.uniqueId )
|
||||
}
|
||||
|
||||
fun editUser(
|
||||
player: Player,
|
||||
action: (User) -> Unit
|
||||
) {
|
||||
luckPerms.userManager.loadUser( player.uniqueId ).thenAcceptAsync( action )
|
||||
}
|
||||
|
||||
fun getGroup(
|
||||
groupName: String
|
||||
): Group?
|
||||
{
|
||||
return luckPerms.groupManager.getGroup( groupName )
|
||||
}
|
||||
|
||||
fun getCachedData(
|
||||
player: Player
|
||||
): CachedDataManager?
|
||||
{
|
||||
return getUser( player )?.cachedData
|
||||
}
|
||||
|
||||
fun hasPermission(
|
||||
uniqueId: UUID,
|
||||
permission: String
|
||||
): Boolean
|
||||
{
|
||||
val cachedData = luckPerms.userManager.loadUser( uniqueId ).get().cachedData
|
||||
return cachedData.permissionData.checkPermission( permission ).asBoolean()
|
||||
}
|
||||
|
||||
fun hasPermission(
|
||||
player: Player,
|
||||
permission: String
|
||||
): Boolean
|
||||
{
|
||||
return getCachedData( player )?.permissionData?.checkPermission( permission )?.asBoolean()
|
||||
?: player.hasPermission( permission )
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
package club.mcscrims.speedhg.util
|
||||
|
||||
import java.util.*
|
||||
|
||||
class RandomCollection<E> {
|
||||
|
||||
private val map = TreeMap<Double, List<E>>()
|
||||
private val names = hashMapOf<List<E>, String>()
|
||||
|
||||
private val random = Random()
|
||||
private var total = 0.0
|
||||
|
||||
fun add(
|
||||
weight: Double,
|
||||
result: E
|
||||
) {
|
||||
if ( weight <= 0 ) return
|
||||
total += weight
|
||||
map[ total ] = listOf( result )
|
||||
}
|
||||
|
||||
fun add(
|
||||
name: String,
|
||||
weight: Double,
|
||||
result: E
|
||||
) {
|
||||
if ( weight <= 0 ) return
|
||||
total += weight
|
||||
map[ total ] = listOf( result )
|
||||
names[listOf( result )] = name
|
||||
}
|
||||
|
||||
fun add(
|
||||
weight: Double,
|
||||
result: List<E>
|
||||
) {
|
||||
if ( weight <= 0 ) return
|
||||
total += weight
|
||||
map[ total ] = result
|
||||
}
|
||||
|
||||
fun add(
|
||||
name: String,
|
||||
weight: Double,
|
||||
result: List<E>
|
||||
) {
|
||||
if ( weight <= 0 ) return
|
||||
total += weight
|
||||
map[ total ] = result
|
||||
names[ result ] = name
|
||||
}
|
||||
|
||||
fun getName(
|
||||
key: E
|
||||
): String
|
||||
{
|
||||
return names.getOrDefault(listOf( key ), "" )
|
||||
}
|
||||
|
||||
fun getName(
|
||||
key: List<E>
|
||||
): String
|
||||
{
|
||||
return names.getOrDefault( key, "" )
|
||||
}
|
||||
|
||||
fun getRandom(): List<E>
|
||||
{
|
||||
val value = random.nextDouble() * total
|
||||
return map.higherEntry( value ).value
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
package club.mcscrims.speedhg.util
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
|
||||
object TimeUtils {
|
||||
|
||||
private val plugin = SpeedHG.instance
|
||||
|
||||
fun scoreboardTimeFromState(): String
|
||||
{
|
||||
val currentTime = plugin.gameManager.getCurrentState()?.getRemainingSeconds()
|
||||
?: throw IllegalArgumentException("Remaining seconds for state is null!")
|
||||
return scoreboardTime( currentTime )
|
||||
}
|
||||
|
||||
fun scoreboardTime(
|
||||
totalSeconds: Int
|
||||
): String
|
||||
{
|
||||
val hours = totalSeconds / 3600
|
||||
val minutes = (totalSeconds % 3600) / 60
|
||||
val seconds = totalSeconds % 60
|
||||
|
||||
if ( totalSeconds > 3600 )
|
||||
return String.format( "%02d:%02d:%02d", hours, minutes, seconds )
|
||||
return String.format( "%02d:%02d", minutes, seconds )
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user