Add new game states and update
This commit is contained in:
@@ -16,6 +16,7 @@ import club.mcscrims.spigot.chat.ChatFormatter
|
|||||||
import club.mcscrims.spigot.chat.ChatManager
|
import club.mcscrims.spigot.chat.ChatManager
|
||||||
import club.mcscrims.spigot.network.SpigotNetworkManager
|
import club.mcscrims.spigot.network.SpigotNetworkManager
|
||||||
import club.mcscrims.spigot.scheduler.SchedulerManager
|
import club.mcscrims.spigot.scheduler.SchedulerManager
|
||||||
|
import club.mcscrims.spigot.util.WorldEditUtils
|
||||||
import com.mongodb.client.model.Indexes
|
import com.mongodb.client.model.Indexes
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import net.luckperms.api.LuckPerms
|
import net.luckperms.api.LuckPerms
|
||||||
@@ -44,6 +45,8 @@ class SpeedHG : JavaPlugin() {
|
|||||||
internal lateinit var gameManager: GameManager
|
internal lateinit var gameManager: GameManager
|
||||||
internal lateinit var worldManager: WorldManager
|
internal lateinit var worldManager: WorldManager
|
||||||
|
|
||||||
|
internal lateinit var worldEditUtils: WorldEditUtils
|
||||||
|
|
||||||
internal lateinit var luckPerms: LuckPerms
|
internal lateinit var luckPerms: LuckPerms
|
||||||
internal var isReady: Boolean = false
|
internal var isReady: Boolean = false
|
||||||
|
|
||||||
@@ -74,6 +77,8 @@ class SpeedHG : JavaPlugin() {
|
|||||||
|
|
||||||
schedulerManager = SchedulerManager( this )
|
schedulerManager = SchedulerManager( this )
|
||||||
|
|
||||||
|
worldEditUtils = WorldEditUtils( this )
|
||||||
|
|
||||||
gameManager = GameManager( this )
|
gameManager = GameManager( this )
|
||||||
gameManager.initialize()
|
gameManager.initialize()
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package club.mcscrims.speedhg.game
|
|||||||
|
|
||||||
import club.mcscrims.speedhg.SpeedHG
|
import club.mcscrims.speedhg.SpeedHG
|
||||||
import club.mcscrims.speedhg.game.impl.BattleState
|
import club.mcscrims.speedhg.game.impl.BattleState
|
||||||
|
import club.mcscrims.speedhg.game.impl.DeathmatchState
|
||||||
|
import club.mcscrims.speedhg.game.impl.EndState
|
||||||
import club.mcscrims.speedhg.game.impl.FeastState
|
import club.mcscrims.speedhg.game.impl.FeastState
|
||||||
import club.mcscrims.speedhg.game.impl.ImmunityState
|
import club.mcscrims.speedhg.game.impl.ImmunityState
|
||||||
import club.mcscrims.speedhg.game.impl.PreStartState
|
import club.mcscrims.speedhg.game.impl.PreStartState
|
||||||
@@ -16,7 +18,7 @@ class GameManager(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
private var currentState: GameState? = null
|
private var currentState: GameState? = null
|
||||||
private val gameStateTypes = ConcurrentHashMap<GameStateTypes, GameState>()
|
internal val gameStateTypes = ConcurrentHashMap<GameStateTypes, GameState>()
|
||||||
|
|
||||||
private val winners = ArrayList<Player>()
|
private val winners = ArrayList<Player>()
|
||||||
|
|
||||||
@@ -33,20 +35,20 @@ class GameManager(
|
|||||||
plugin.pluginConfig.data.getDuration( "waiting" ).seconds
|
plugin.pluginConfig.data.getDuration( "waiting" ).seconds
|
||||||
)
|
)
|
||||||
|
|
||||||
|
gameStateTypes[ GameStateTypes.WAITING ] = currentState!!
|
||||||
|
gameStateTypes[ GameStateTypes.PRE_START ] = PreStartState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "pre_start" ).seconds )
|
||||||
|
gameStateTypes[ GameStateTypes.IMMUNITY ] = ImmunityState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "immunity" ).seconds )
|
||||||
|
gameStateTypes[ GameStateTypes.BATTLE ] = BattleState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "battle" ).seconds )
|
||||||
|
gameStateTypes[ GameStateTypes.FEAST ] = FeastState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "feast" ).seconds )
|
||||||
|
gameStateTypes[ GameStateTypes.DEATHMATCH ] = DeathmatchState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "deathmatch" ).seconds )
|
||||||
|
gameStateTypes[ GameStateTypes.END ] = EndState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "end" ).seconds )
|
||||||
|
|
||||||
try {
|
try {
|
||||||
currentState?.onEnter( null )
|
currentState?.onEnter( null )
|
||||||
} catch ( e: Exception ) {
|
} catch ( e: Exception ) {
|
||||||
plugin.logger.severe("Error during onEnter for state ${currentState?.name}: ${e.message}")
|
plugin.logger.severe("Error during onEnter for state ${currentState?.name}: ${e.message}")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
}
|
}
|
||||||
|
|
||||||
gameStateTypes[ GameStateTypes.WAITING ] = currentState!!
|
|
||||||
gameStateTypes[ GameStateTypes.PRE_START ] = PreStartState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "pre_start" ).seconds )
|
|
||||||
gameStateTypes[ GameStateTypes.IMMUNITY ] = ImmunityState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "immunity" ).seconds )
|
|
||||||
gameStateTypes[ GameStateTypes.BATTLE ] = BattleState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "battle" ).seconds )
|
|
||||||
gameStateTypes[ GameStateTypes.FEAST ] = FeastState( this, plugin, plugin.schedulerManager, plugin.pluginConfig.data.getDuration( "feast" ).seconds )
|
|
||||||
gameStateTypes[ GameStateTypes.DEATHMATCH ] = TODO()
|
|
||||||
gameStateTypes[ GameStateTypes.END ] = TODO()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun transitionTo(
|
fun transitionTo(
|
||||||
@@ -85,6 +87,8 @@ class GameManager(
|
|||||||
winners.forEach { this.winners.add( it ) }
|
winners.forEach { this.winners.add( it ) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getWinners(): List<Player> = winners.toList()
|
||||||
|
|
||||||
fun getCurrentState(): GameState? = currentState
|
fun getCurrentState(): GameState? = currentState
|
||||||
|
|
||||||
fun getCurrentStateType(): GameStateTypes? = gameStateTypes.filter { it.value.name == currentState?.name }.keys.firstOrNull()
|
fun getCurrentStateType(): GameStateTypes? = gameStateTypes.filter { it.value.name == currentState?.name }.keys.firstOrNull()
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import club.mcscrims.spigot.scheduler.SchedulerManager
|
|||||||
import club.mcscrims.spigot.scheduler.TaskRegistration
|
import club.mcscrims.spigot.scheduler.TaskRegistration
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.event.HandlerList
|
|
||||||
import org.bukkit.event.Listener
|
|
||||||
|
|
||||||
abstract class GameState(
|
abstract class GameState(
|
||||||
val name: String,
|
val name: String,
|
||||||
@@ -17,7 +15,6 @@ abstract class GameState(
|
|||||||
protected val durationSeconds: Int? = null
|
protected val durationSeconds: Int? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private val listeners = mutableListOf<Listener>()
|
|
||||||
private var tickTask: TaskRegistration? = null
|
private var tickTask: TaskRegistration? = null
|
||||||
var remainingSeconds: Int = durationSeconds ?: 0
|
var remainingSeconds: Int = durationSeconds ?: 0
|
||||||
private var isActive: Boolean = false
|
private var isActive: Boolean = false
|
||||||
@@ -41,7 +38,6 @@ abstract class GameState(
|
|||||||
) {
|
) {
|
||||||
isActive = false
|
isActive = false
|
||||||
stopTicking()
|
stopTicking()
|
||||||
unregisterAllListeners()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startTicking()
|
private fun startTicking()
|
||||||
@@ -63,7 +59,7 @@ abstract class GameState(
|
|||||||
|
|
||||||
if ( durationSeconds != null && remainingSeconds > 0 )
|
if ( durationSeconds != null && remainingSeconds > 0 )
|
||||||
{
|
{
|
||||||
if (plugin.pluginConfig.data.getDuration( name ).type == DurationType.INCREASING)
|
if (plugin.pluginConfig.data.getDuration( name ).type == DurationType.INCREASING )
|
||||||
{
|
{
|
||||||
remainingSeconds++
|
remainingSeconds++
|
||||||
return@runRepeating
|
return@runRepeating
|
||||||
@@ -87,25 +83,6 @@ abstract class GameState(
|
|||||||
tickTask = null
|
tickTask = null
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun registerListener(
|
|
||||||
listener: Listener
|
|
||||||
) {
|
|
||||||
listeners.add( listener )
|
|
||||||
Bukkit.getPluginManager().registerEvents( listener, plugin )
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun unregisterAllListeners()
|
|
||||||
{
|
|
||||||
listeners.forEach { listener -> HandlerList.unregisterAll( listener ) }
|
|
||||||
listeners.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun transitionTo(
|
|
||||||
next: GameState
|
|
||||||
) {
|
|
||||||
gameManager.transitionTo( next )
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun broadcast(
|
protected fun broadcast(
|
||||||
messageKey: String,
|
messageKey: String,
|
||||||
vararg placeholders: Pair<String, String>
|
vararg placeholders: Pair<String, String>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ class BattleState(
|
|||||||
{
|
{
|
||||||
300 ->
|
300 ->
|
||||||
{
|
{
|
||||||
|
gameManager.gameStateTypes[ GameStateTypes.BATTLE ] = this
|
||||||
gameManager.transitionTo( GameStateTypes.FEAST )
|
gameManager.transitionTo( GameStateTypes.FEAST )
|
||||||
afterFeast = true
|
afterFeast = true
|
||||||
}
|
}
|
||||||
@@ -51,7 +52,7 @@ class BattleState(
|
|||||||
|
|
||||||
private fun checkForWinners(): Boolean
|
private fun checkForWinners(): Boolean
|
||||||
{
|
{
|
||||||
val players = Bukkit.getOnlinePlayers()
|
val players = Bukkit.getOnlinePlayers().filter { !it.isDead }
|
||||||
|
|
||||||
if ( players.size > 1 )
|
if ( players.size > 1 )
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -0,0 +1,113 @@
|
|||||||
|
package club.mcscrims.speedhg.game.impl
|
||||||
|
|
||||||
|
import club.mcscrims.speedhg.SpeedHG
|
||||||
|
import club.mcscrims.speedhg.game.GameManager
|
||||||
|
import club.mcscrims.speedhg.game.GameState
|
||||||
|
import club.mcscrims.speedhg.game.GameStateTypes
|
||||||
|
import club.mcscrims.speedhg.game.impl.PreStartState.AnnouncementType
|
||||||
|
import club.mcscrims.spigot.scheduler.SchedulerManager
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.Statistic
|
||||||
|
import org.bukkit.potion.PotionEffect
|
||||||
|
import org.bukkit.potion.PotionEffectType
|
||||||
|
|
||||||
|
class DeathmatchState(
|
||||||
|
gameManager: GameManager,
|
||||||
|
plugin: SpeedHG,
|
||||||
|
schedulerManager: SchedulerManager,
|
||||||
|
durationSeconds: Int? = null
|
||||||
|
) : GameState( "deathmatch", gameManager, plugin, schedulerManager, durationSeconds ) {
|
||||||
|
|
||||||
|
private val world = plugin.worldManager.getWorld()
|
||||||
|
private val pitLocation = Location( world, 0.0, 1.0, 0.0 )
|
||||||
|
|
||||||
|
override fun onTick()
|
||||||
|
{
|
||||||
|
checkForWinners()
|
||||||
|
|
||||||
|
when( remainingSeconds )
|
||||||
|
{
|
||||||
|
0 ->
|
||||||
|
{
|
||||||
|
plugin.chatManager.broadcast( "gameStates.deathmatch.started" )
|
||||||
|
circle()
|
||||||
|
schedulerManager.runLater( 10L ) { randomTeleport() }
|
||||||
|
}
|
||||||
|
|
||||||
|
600 -> announce( AnnouncementType.MINUTES, 5 )
|
||||||
|
660 -> announce( AnnouncementType.MINUTES, 4 )
|
||||||
|
720 -> announce( AnnouncementType.MINUTES, 3 )
|
||||||
|
780 -> announce( AnnouncementType.MINUTES, 2 )
|
||||||
|
840 -> announce( AnnouncementType.MINUTES, 1 )
|
||||||
|
870 -> announce( AnnouncementType.SECONDS, 30 )
|
||||||
|
885 -> announce( AnnouncementType.SECONDS, 15 )
|
||||||
|
890 -> announce( AnnouncementType.SECONDS, 10 )
|
||||||
|
895 -> announce( AnnouncementType.SECONDS, 5 )
|
||||||
|
896 -> announce( AnnouncementType.SECONDS, 4 )
|
||||||
|
897 -> announce( AnnouncementType.SECONDS, 3 )
|
||||||
|
898 -> announce( AnnouncementType.SECONDS, 2 )
|
||||||
|
899 -> announce( AnnouncementType.SECONDS, 1 )
|
||||||
|
|
||||||
|
900 -> try {
|
||||||
|
onEndOfDuration()
|
||||||
|
} catch ( e: Exception ) {
|
||||||
|
plugin.logger.severe("Error during onEndOfDuration for state $name: ${e.message}")
|
||||||
|
e.printStackTrace()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEndOfDuration()
|
||||||
|
{
|
||||||
|
val winner = Bukkit.getOnlinePlayers().stream()
|
||||||
|
.filter { !it.isDead }
|
||||||
|
.map { it.getStatistic( Statistic.PLAYER_KILLS ) to it }
|
||||||
|
.max(compareBy { it.first })
|
||||||
|
.get().second
|
||||||
|
|
||||||
|
gameManager.addWinners( winner )
|
||||||
|
gameManager.transitionTo( GameStateTypes.END )
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkForWinners(): Boolean
|
||||||
|
{
|
||||||
|
val players = Bukkit.getOnlinePlayers().filter { !it.isDead }
|
||||||
|
|
||||||
|
if ( players.size > 1 )
|
||||||
|
return false
|
||||||
|
|
||||||
|
gameManager.addWinners( players.first() )
|
||||||
|
gameManager.transitionTo( GameStateTypes.END )
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun announce(
|
||||||
|
type: AnnouncementType,
|
||||||
|
time: Int
|
||||||
|
) {
|
||||||
|
val arg = if ( type == AnnouncementType.MINUTES ) "M" else "S"
|
||||||
|
broadcast( "gameStates.deathmatch.ending$arg", "{time}" to time.toString() )
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun randomTeleport()
|
||||||
|
{
|
||||||
|
forAlivePlayers { player ->
|
||||||
|
player.addPotionEffect(PotionEffect( PotionEffectType.RESISTANCE, 40, 20 ))
|
||||||
|
|
||||||
|
val loc = pitLocation.clone()
|
||||||
|
loc.x = (( pitLocation.blockX - 15 )..( pitLocation.blockX + 15 )).random().toDouble()
|
||||||
|
loc.z = (( pitLocation.blockZ - 15 )..( pitLocation.blockZ + 15 )).random().toDouble()
|
||||||
|
loc.y = world!!.getHighestBlockYAt( loc.blockX, loc.blockZ ).toDouble()
|
||||||
|
player.teleport( loc )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun circle()
|
||||||
|
{
|
||||||
|
val highestLocation = plugin.worldManager.highestLocationWithRadius( pitLocation, 30 )
|
||||||
|
plugin.worldEditUtils.createCylinder( world!!, pitLocation, 30.0, highestLocation.blockY, Material.AIR, true )
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
43
src/main/kotlin/club/mcscrims/speedhg/game/impl/EndState.kt
Normal file
43
src/main/kotlin/club/mcscrims/speedhg/game/impl/EndState.kt
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package club.mcscrims.speedhg.game.impl
|
||||||
|
|
||||||
|
import club.mcscrims.speedhg.SpeedHG
|
||||||
|
import club.mcscrims.speedhg.game.GameManager
|
||||||
|
import club.mcscrims.speedhg.game.GameState
|
||||||
|
import club.mcscrims.spigot.chat.getDisplayName
|
||||||
|
import club.mcscrims.spigot.scheduler.SchedulerManager
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
|
||||||
|
class EndState(
|
||||||
|
gameManager: GameManager,
|
||||||
|
plugin: SpeedHG,
|
||||||
|
schedulerManager: SchedulerManager,
|
||||||
|
durationSeconds: Int? = null
|
||||||
|
) : GameState( "end", gameManager, plugin, schedulerManager, durationSeconds ) {
|
||||||
|
|
||||||
|
override fun onEnter(
|
||||||
|
previous: GameState?
|
||||||
|
) {
|
||||||
|
super.onEnter( previous )
|
||||||
|
val winners = gameManager.getWinners()
|
||||||
|
|
||||||
|
if ( winners.size > 1 )
|
||||||
|
plugin.chatManager.broadcast( "gameStates.end.multipleWinners", "{winners}" to winners.joinToString { it.getDisplayName } )
|
||||||
|
else if ( winners.size == 1 )
|
||||||
|
plugin.chatManager.broadcast( "gameStates.end.oneWinner", "{winner}" to winners.first().getDisplayName )
|
||||||
|
else
|
||||||
|
plugin.chatManager.broadcast( "gameStates.end.noWinners" )
|
||||||
|
|
||||||
|
runBlocking { winners.forEach {
|
||||||
|
plugin.statsRepository.addWins( it.uniqueId, 1 )
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTick() {}
|
||||||
|
|
||||||
|
override fun onEndOfDuration()
|
||||||
|
{
|
||||||
|
Bukkit.shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,10 +3,21 @@ package club.mcscrims.speedhg.game.impl
|
|||||||
import club.mcscrims.speedhg.SpeedHG
|
import club.mcscrims.speedhg.SpeedHG
|
||||||
import club.mcscrims.speedhg.game.GameManager
|
import club.mcscrims.speedhg.game.GameManager
|
||||||
import club.mcscrims.speedhg.game.GameState
|
import club.mcscrims.speedhg.game.GameState
|
||||||
|
import club.mcscrims.speedhg.game.GameStateTypes
|
||||||
|
import club.mcscrims.speedhg.game.impl.PreStartState.AnnouncementType
|
||||||
|
import club.mcscrims.speedhg.util.RandomCollection
|
||||||
|
import club.mcscrims.spigot.item.ItemBuilder
|
||||||
import club.mcscrims.spigot.scheduler.SchedulerManager
|
import club.mcscrims.spigot.scheduler.SchedulerManager
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.block.Chest
|
||||||
|
import org.bukkit.inventory.ItemStack
|
||||||
|
import org.bukkit.inventory.meta.PotionMeta
|
||||||
|
import org.bukkit.potion.PotionEffect
|
||||||
|
import org.bukkit.potion.PotionEffectType
|
||||||
import org.bukkit.util.BoundingBox
|
import org.bukkit.util.BoundingBox
|
||||||
import java.util.Random
|
import java.util.*
|
||||||
|
|
||||||
class FeastState(
|
class FeastState(
|
||||||
gameManager: GameManager,
|
gameManager: GameManager,
|
||||||
@@ -18,18 +29,181 @@ class FeastState(
|
|||||||
private val world = plugin.worldManager.getWorld()
|
private val world = plugin.worldManager.getWorld()
|
||||||
private val random = Random()
|
private val random = Random()
|
||||||
|
|
||||||
internal lateinit var feastLocation: Location
|
internal var feastLocation: Location
|
||||||
internal lateinit var feastBox: BoundingBox
|
internal lateinit var feastBox: BoundingBox
|
||||||
internal var feastHeight: Int = 1
|
internal var feastHeight: Int = 1
|
||||||
|
|
||||||
|
init
|
||||||
|
{
|
||||||
|
this.feastLocation = getLocation()
|
||||||
|
this.feastHeight = plugin.worldManager.highestLocationWithRadius( feastLocation, 11 ).blockY + 3
|
||||||
|
this.feastBox = BoundingBox.of( feastLocation, 11.0, feastHeight.toDouble(), 11.0 )
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onEnter(
|
||||||
|
previous: GameState?
|
||||||
|
) {
|
||||||
|
super.onEnter( previous )
|
||||||
|
circle()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onTick()
|
override fun onTick()
|
||||||
{
|
{
|
||||||
TODO("Not yet implemented")
|
when( remainingSeconds )
|
||||||
|
{
|
||||||
|
300 -> announce( AnnouncementType.MINUTES, 5 )
|
||||||
|
240 -> announce( AnnouncementType.MINUTES, 4 )
|
||||||
|
180 -> announce( AnnouncementType.MINUTES, 3 )
|
||||||
|
120 -> announce( AnnouncementType.MINUTES, 2 )
|
||||||
|
60 -> announce( AnnouncementType.MINUTES, 1 )
|
||||||
|
30 -> announce( AnnouncementType.SECONDS, 30 )
|
||||||
|
15 -> announce( AnnouncementType.SECONDS, 15 )
|
||||||
|
10 -> announce( AnnouncementType.SECONDS, 10 )
|
||||||
|
5 -> announce( AnnouncementType.SECONDS, 5 )
|
||||||
|
4 -> announce( AnnouncementType.SECONDS, 4 )
|
||||||
|
3 -> announce( AnnouncementType.SECONDS, 3 )
|
||||||
|
2 -> announce( AnnouncementType.SECONDS, 2 )
|
||||||
|
1 -> announce( AnnouncementType.SECONDS, 1 )
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEndOfDuration()
|
override fun onEndOfDuration()
|
||||||
{
|
{
|
||||||
TODO("Not yet implemented")
|
plugin.chatManager.broadcast( "feast.started",
|
||||||
|
"{x}" to feastLocation.blockX.toString(),
|
||||||
|
"{y}" to feastLocation.blockY.toString(),
|
||||||
|
"{z}" to feastLocation.blockZ.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
chests()
|
||||||
|
gameManager.transitionTo( GameStateTypes.BATTLE )
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun chests()
|
||||||
|
{
|
||||||
|
feastLocation.clone().block.type = Material.ENCHANTING_TABLE
|
||||||
|
|
||||||
|
val chestLocations = arrayOfNulls<Location>( 12 )
|
||||||
|
|
||||||
|
chestLocations[0] = feastLocation.clone().add( 1.0, 0.0, 1.0 )
|
||||||
|
chestLocations[1] = feastLocation.clone().add( -1.0, 0.0, 1.0 )
|
||||||
|
chestLocations[2] = feastLocation.clone().add( -1.0, 0.0, -1.0 )
|
||||||
|
chestLocations[3] = feastLocation.clone().add( 1.0, 0.0, -1.0 )
|
||||||
|
chestLocations[4] = feastLocation.clone().add( 2.0, 0.0, 2.0 )
|
||||||
|
chestLocations[5] = feastLocation.clone().add( 0.0, 0.0, 2.0 )
|
||||||
|
chestLocations[6] = feastLocation.clone().add( -2.0, 0.0, 2.0 )
|
||||||
|
chestLocations[7] = feastLocation.clone().add( 2.0, 0.0, 0.0 )
|
||||||
|
chestLocations[8] = feastLocation.clone().add( -2.0, 0.0, 0.0 )
|
||||||
|
chestLocations[9] = feastLocation.clone().add( 2.0, 0.0, -2.0 )
|
||||||
|
chestLocations[10] = feastLocation.clone().add( 0.0, 0.0, -2.0 )
|
||||||
|
chestLocations[11] = feastLocation.clone().add( -2.0, 0.0, -2.0 )
|
||||||
|
|
||||||
|
Arrays.stream( chestLocations ).forEach { it!!.block.type = Material.CHEST }
|
||||||
|
|
||||||
|
val diamondItems = RandomCollection<ItemStack>()
|
||||||
|
diamondItems.add( 1.0, ItemStack( Material.DIAMOND_BOOTS ))
|
||||||
|
diamondItems.add( 1.0, ItemStack( Material.DIAMOND_CHESTPLATE ))
|
||||||
|
diamondItems.add( 1.0, ItemStack( Material.DIAMOND_SWORD ))
|
||||||
|
|
||||||
|
val ironItems = RandomCollection<ItemStack>()
|
||||||
|
ironItems.add( 1.0, ItemStack( Material.IRON_BOOTS ))
|
||||||
|
ironItems.add( 1.0, ItemStack( Material.IRON_LEGGINGS ))
|
||||||
|
ironItems.add( 1.0, ItemStack( Material.IRON_CHESTPLATE ))
|
||||||
|
ironItems.add( 1.0, ItemStack( Material.IRON_HELMET ))
|
||||||
|
ironItems.add( 1.0, ItemStack( Material.IRON_SWORD ))
|
||||||
|
|
||||||
|
val netheriteItems = RandomCollection<ItemStack>()
|
||||||
|
netheriteItems.add( 1.0, ItemStack( Material.NETHERITE_INGOT ))
|
||||||
|
netheriteItems.add( 1.0, ItemStack( Material.SMITHING_TABLE ))
|
||||||
|
|
||||||
|
val sizeableItems = RandomCollection<ItemStack>()
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.RED_MUSHROOM ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.BROWN_MUSHROOM ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.BOWL ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.CACTUS ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.COCOA_BEANS ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.MUSHROOM_STEW ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.LAPIS_LAZULI ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.ARROW ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.COOKED_BEEF ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.COOKED_PORKCHOP ))
|
||||||
|
sizeableItems.add( 1.0, ItemStack( Material.COOKED_CHICKEN ))
|
||||||
|
|
||||||
|
val singleItems = RandomCollection<ItemStack>()
|
||||||
|
singleItems.add( 1.0, ItemStack( Material.BOW ))
|
||||||
|
singleItems.add( 1.0, ItemStack( Material.COBWEB ))
|
||||||
|
singleItems.add( 1.0, ItemStack( Material.FLINT_AND_STEEL ))
|
||||||
|
singleItems.add( 1.0, ItemStack( Material.TNT ))
|
||||||
|
singleItems.add( 1.0, ItemStack( Material.ENDER_PEARL ))
|
||||||
|
singleItems.add( 1.0, ItemStack( Material.LAVA_BUCKET ))
|
||||||
|
singleItems.add( 1.0, ItemStack( Material.WATER_BUCKET ))
|
||||||
|
|
||||||
|
val strengthPotion = ItemStack( Material.SPLASH_POTION )
|
||||||
|
val effect = PotionEffect( PotionEffectType.STRENGTH, (60..240).random(), 0 )
|
||||||
|
strengthPotion.editMeta { ( it as PotionMeta ).addCustomEffect( effect, true ) }
|
||||||
|
|
||||||
|
singleItems.add( 1.0, strengthPotion )
|
||||||
|
|
||||||
|
val cleanser = ItemBuilder( plugin, Material.SUGAR )
|
||||||
|
.name(LegacyComponentSerializer.legacySection().serialize(plugin.chatFormatter.format( "feast.cleanser.name" )))
|
||||||
|
.unbreakable( true )
|
||||||
|
.hideAttributes()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
singleItems.add( 1.0, cleanser )
|
||||||
|
|
||||||
|
val lootPool = RandomCollection<RandomCollection<ItemStack>>()
|
||||||
|
lootPool.add( 17.5, ironItems )
|
||||||
|
lootPool.add( 6.8, diamondItems )
|
||||||
|
lootPool.add( 33.0, sizeableItems )
|
||||||
|
lootPool.add( 33.0, singleItems )
|
||||||
|
lootPool.add( 1.5, netheriteItems )
|
||||||
|
|
||||||
|
for ( location in chestLocations )
|
||||||
|
{
|
||||||
|
val chest = location!!.block.state as Chest
|
||||||
|
|
||||||
|
for ( i in 0..( 6..12 ).random() )
|
||||||
|
{
|
||||||
|
val randomItemCollection = lootPool.getRandom()
|
||||||
|
val itemList = randomItemCollection.random().getRandom()
|
||||||
|
|
||||||
|
for ( item in itemList )
|
||||||
|
{
|
||||||
|
if ( randomItemCollection == sizeableItems )
|
||||||
|
item.amount = ( 1..16 ).random()
|
||||||
|
|
||||||
|
chest.inventory.setItem(random.nextInt( 26 - 1 ) + 1, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun announce(
|
||||||
|
type: AnnouncementType,
|
||||||
|
time: Int
|
||||||
|
) {
|
||||||
|
val arg = if ( type == AnnouncementType.MINUTES ) "M" else "S"
|
||||||
|
broadcast( "gameStates.feast.starting$arg", "{time}" to time.toString() )
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun circle()
|
||||||
|
{
|
||||||
|
plugin.worldEditUtils.createCylinder( world!!, feastLocation, 11.0, feastHeight, Material.GRASS_BLOCK, false )
|
||||||
|
plugin.worldEditUtils.createCylinder( world, feastLocation.add( 0.0, 1.0, 0.0 ), 11.0, feastHeight, Material.AIR, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLocation(): Location
|
||||||
|
{
|
||||||
|
val x = ( -100..100 ).random()
|
||||||
|
val z = ( -100..100 ).random()
|
||||||
|
|
||||||
|
val highestY = world!!.getHighestBlockYAt( x, z )
|
||||||
|
|
||||||
|
if ( highestY >= 70 )
|
||||||
|
return getLocation()
|
||||||
|
|
||||||
|
return Location( world, x.toDouble(), highestY.toDouble() + 5.0, z.toDouble() )
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -62,15 +62,14 @@ class ImmunityState(
|
|||||||
3 -> announce( AnnouncementType.SECONDS, 3 )
|
3 -> announce( AnnouncementType.SECONDS, 3 )
|
||||||
2 -> announce( AnnouncementType.SECONDS, 2 )
|
2 -> announce( AnnouncementType.SECONDS, 2 )
|
||||||
1 -> announce( AnnouncementType.SECONDS, 1 )
|
1 -> announce( AnnouncementType.SECONDS, 1 )
|
||||||
0 ->
|
|
||||||
{
|
|
||||||
broadcast( "gameStates.immunity.ended" )
|
|
||||||
gameManager.transitionTo( GameStateTypes.BATTLE )
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEndOfDuration() {}
|
override fun onEndOfDuration()
|
||||||
|
{
|
||||||
|
broadcast( "gameStates.immunity.ended" )
|
||||||
|
gameManager.transitionTo( GameStateTypes.BATTLE )
|
||||||
|
}
|
||||||
|
|
||||||
private fun announce(
|
private fun announce(
|
||||||
type: AnnouncementType,
|
type: AnnouncementType,
|
||||||
|
|||||||
@@ -60,15 +60,16 @@ class PreStartState(
|
|||||||
3 -> announce( AnnouncementType.SECONDS, 3 )
|
3 -> announce( AnnouncementType.SECONDS, 3 )
|
||||||
2 -> announce( AnnouncementType.SECONDS, 2 )
|
2 -> announce( AnnouncementType.SECONDS, 2 )
|
||||||
1 -> announce( AnnouncementType.SECONDS, 1 )
|
1 -> announce( AnnouncementType.SECONDS, 1 )
|
||||||
0 ->
|
|
||||||
{
|
|
||||||
broadcast( "gameStates.preStart.started" )
|
|
||||||
isStarting = false
|
|
||||||
gameManager.transitionTo( GameStateTypes.IMMUNITY )
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onEndOfDuration()
|
||||||
|
{
|
||||||
|
broadcast( "gameStates.preStart.started" )
|
||||||
|
isStarting = false
|
||||||
|
gameManager.transitionTo( GameStateTypes.IMMUNITY )
|
||||||
|
}
|
||||||
|
|
||||||
override fun onExit(
|
override fun onExit(
|
||||||
next: GameState?
|
next: GameState?
|
||||||
) {
|
) {
|
||||||
@@ -76,8 +77,6 @@ class PreStartState(
|
|||||||
Bukkit.getOnlinePlayers().forEach { it.inventory.clear() }
|
Bukkit.getOnlinePlayers().forEach { it.inventory.clear() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEndOfDuration() {}
|
|
||||||
|
|
||||||
private fun announce(
|
private fun announce(
|
||||||
type: AnnouncementType,
|
type: AnnouncementType,
|
||||||
time: Int
|
time: Int
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user