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.network.SpigotNetworkManager
|
||||
import club.mcscrims.spigot.scheduler.SchedulerManager
|
||||
import club.mcscrims.spigot.util.WorldEditUtils
|
||||
import com.mongodb.client.model.Indexes
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.luckperms.api.LuckPerms
|
||||
@@ -44,6 +45,8 @@ class SpeedHG : JavaPlugin() {
|
||||
internal lateinit var gameManager: GameManager
|
||||
internal lateinit var worldManager: WorldManager
|
||||
|
||||
internal lateinit var worldEditUtils: WorldEditUtils
|
||||
|
||||
internal lateinit var luckPerms: LuckPerms
|
||||
internal var isReady: Boolean = false
|
||||
|
||||
@@ -74,6 +77,8 @@ class SpeedHG : JavaPlugin() {
|
||||
|
||||
schedulerManager = SchedulerManager( this )
|
||||
|
||||
worldEditUtils = WorldEditUtils( this )
|
||||
|
||||
gameManager = GameManager( this )
|
||||
gameManager.initialize()
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package club.mcscrims.speedhg.game
|
||||
|
||||
import club.mcscrims.speedhg.SpeedHG
|
||||
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.ImmunityState
|
||||
import club.mcscrims.speedhg.game.impl.PreStartState
|
||||
@@ -16,7 +18,7 @@ class GameManager(
|
||||
) {
|
||||
|
||||
private var currentState: GameState? = null
|
||||
private val gameStateTypes = ConcurrentHashMap<GameStateTypes, GameState>()
|
||||
internal val gameStateTypes = ConcurrentHashMap<GameStateTypes, GameState>()
|
||||
|
||||
private val winners = ArrayList<Player>()
|
||||
|
||||
@@ -33,20 +35,20 @@ class GameManager(
|
||||
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 {
|
||||
currentState?.onEnter( null )
|
||||
} catch ( e: Exception ) {
|
||||
plugin.logger.severe("Error during onEnter for state ${currentState?.name}: ${e.message}")
|
||||
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(
|
||||
@@ -85,6 +87,8 @@ class GameManager(
|
||||
winners.forEach { this.winners.add( it ) }
|
||||
}
|
||||
|
||||
fun getWinners(): List<Player> = winners.toList()
|
||||
|
||||
fun getCurrentState(): GameState? = currentState
|
||||
|
||||
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 org.bukkit.Bukkit
|
||||
import org.bukkit.entity.Player
|
||||
import org.bukkit.event.HandlerList
|
||||
import org.bukkit.event.Listener
|
||||
|
||||
abstract class GameState(
|
||||
val name: String,
|
||||
@@ -17,7 +15,6 @@ abstract class GameState(
|
||||
protected val durationSeconds: Int? = null
|
||||
) {
|
||||
|
||||
private val listeners = mutableListOf<Listener>()
|
||||
private var tickTask: TaskRegistration? = null
|
||||
var remainingSeconds: Int = durationSeconds ?: 0
|
||||
private var isActive: Boolean = false
|
||||
@@ -41,7 +38,6 @@ abstract class GameState(
|
||||
) {
|
||||
isActive = false
|
||||
stopTicking()
|
||||
unregisterAllListeners()
|
||||
}
|
||||
|
||||
private fun startTicking()
|
||||
@@ -63,7 +59,7 @@ abstract class GameState(
|
||||
|
||||
if ( durationSeconds != null && remainingSeconds > 0 )
|
||||
{
|
||||
if (plugin.pluginConfig.data.getDuration( name ).type == DurationType.INCREASING)
|
||||
if (plugin.pluginConfig.data.getDuration( name ).type == DurationType.INCREASING )
|
||||
{
|
||||
remainingSeconds++
|
||||
return@runRepeating
|
||||
@@ -87,25 +83,6 @@ abstract class GameState(
|
||||
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(
|
||||
messageKey: String,
|
||||
vararg placeholders: Pair<String, String>
|
||||
|
||||
@@ -32,6 +32,7 @@ class BattleState(
|
||||
{
|
||||
300 ->
|
||||
{
|
||||
gameManager.gameStateTypes[ GameStateTypes.BATTLE ] = this
|
||||
gameManager.transitionTo( GameStateTypes.FEAST )
|
||||
afterFeast = true
|
||||
}
|
||||
@@ -51,7 +52,7 @@ class BattleState(
|
||||
|
||||
private fun checkForWinners(): Boolean
|
||||
{
|
||||
val players = Bukkit.getOnlinePlayers()
|
||||
val players = Bukkit.getOnlinePlayers().filter { !it.isDead }
|
||||
|
||||
if ( players.size > 1 )
|
||||
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.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.speedhg.util.RandomCollection
|
||||
import club.mcscrims.spigot.item.ItemBuilder
|
||||
import club.mcscrims.spigot.scheduler.SchedulerManager
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer
|
||||
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 java.util.Random
|
||||
import java.util.*
|
||||
|
||||
class FeastState(
|
||||
gameManager: GameManager,
|
||||
@@ -18,18 +29,181 @@ class FeastState(
|
||||
private val world = plugin.worldManager.getWorld()
|
||||
private val random = Random()
|
||||
|
||||
internal lateinit var feastLocation: Location
|
||||
internal var feastLocation: Location
|
||||
internal lateinit var feastBox: BoundingBox
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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 )
|
||||
2 -> announce( AnnouncementType.SECONDS, 2 )
|
||||
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(
|
||||
type: AnnouncementType,
|
||||
|
||||
@@ -60,15 +60,16 @@ class PreStartState(
|
||||
3 -> announce( AnnouncementType.SECONDS, 3 )
|
||||
2 -> announce( AnnouncementType.SECONDS, 2 )
|
||||
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(
|
||||
next: GameState?
|
||||
) {
|
||||
@@ -76,8 +77,6 @@ class PreStartState(
|
||||
Bukkit.getOnlinePlayers().forEach { it.inventory.clear() }
|
||||
}
|
||||
|
||||
override fun onEndOfDuration() {}
|
||||
|
||||
private fun announce(
|
||||
type: AnnouncementType,
|
||||
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