Add BackupKit and mid-game kit selection
Introduce a BackupKit and allow players holding it to change kits mid-game while preventing normal kits from being picked once the game started. Changes: - Add BackupKit implementation (kit with no abilities/items used for mid-round kit selection). - Update KitCommand: import BackupKit and GameState, add isIngame helper, disallow normal kit picks during INGAME/INVINCIBILITY, permit BackupKit to swap kits mid-game (but prevent picking the same kit) and apply playstyles accordingly. - Fix GoblinKit to also copy/restore the target's playstyle when stealing a kit and restore the player's original playstyle after timeout. - Tweak IceMageKit slow effect chance (now ~1/3 chance using random.nextInt(3) < 1). - Update en_US.yml: add messages and kit strings for backup and icemage, adjust ability_charged color, and add game/cannot-pick messages. Also includes small import and formatting adjustments.
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
package club.mcscrims.speedhg.command
|
package club.mcscrims.speedhg.command
|
||||||
|
|
||||||
import club.mcscrims.speedhg.SpeedHG
|
import club.mcscrims.speedhg.SpeedHG
|
||||||
|
import club.mcscrims.speedhg.game.GameState
|
||||||
import club.mcscrims.speedhg.kit.Playstyle
|
import club.mcscrims.speedhg.kit.Playstyle
|
||||||
|
import club.mcscrims.speedhg.kit.impl.BackupKit
|
||||||
import club.mcscrims.speedhg.util.legacySerializer
|
import club.mcscrims.speedhg.util.legacySerializer
|
||||||
import club.mcscrims.speedhg.util.sendMsg
|
import club.mcscrims.speedhg.util.sendMsg
|
||||||
import org.bukkit.command.Command
|
import org.bukkit.command.Command
|
||||||
@@ -52,6 +54,30 @@ class KitCommand : CommandExecutor, TabCompleter {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val playerKit = plugin.kitManager.getSelectedKit( player )
|
||||||
|
val isBackup = playerKit != null && playerKit is BackupKit
|
||||||
|
|
||||||
|
if ( !isBackup && isIngame() )
|
||||||
|
{
|
||||||
|
player.sendMsg("commands.kit.gameHasStarted")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else if ( isBackup && isIngame() )
|
||||||
|
{
|
||||||
|
if ( kit is BackupKit )
|
||||||
|
{
|
||||||
|
player.sendMsg( "commands.kit.cannotPickSameKit" )
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.kitManager.selectKit( player, kit )
|
||||||
|
plugin.kitManager.selectPlaystyle( player, playstyle )
|
||||||
|
plugin.kitManager.applyKit( player )
|
||||||
|
|
||||||
|
player.sendMsg( "commands.kit.selected", "playstyle" to playstyle.displayName, "kit" to legacySerializer.serialize( kit.displayName ))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
plugin.kitManager.selectKit( player, kit )
|
plugin.kitManager.selectKit( player, kit )
|
||||||
plugin.kitManager.selectPlaystyle( player, playstyle )
|
plugin.kitManager.selectPlaystyle( player, playstyle )
|
||||||
|
|
||||||
@@ -78,4 +104,10 @@ class KitCommand : CommandExecutor, TabCompleter {
|
|||||||
return listOf()
|
return listOf()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isIngame(): Boolean = when ( plugin.gameManager.currentState )
|
||||||
|
{
|
||||||
|
GameState.INGAME, GameState.INVINCIBILITY -> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
85
src/main/kotlin/club/mcscrims/speedhg/kit/impl/BackupKit.kt
Normal file
85
src/main/kotlin/club/mcscrims/speedhg/kit/impl/BackupKit.kt
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package club.mcscrims.speedhg.kit.impl
|
||||||
|
|
||||||
|
import club.mcscrims.speedhg.SpeedHG
|
||||||
|
import club.mcscrims.speedhg.kit.Kit
|
||||||
|
import club.mcscrims.speedhg.kit.Playstyle
|
||||||
|
import club.mcscrims.speedhg.kit.ability.AbilityResult
|
||||||
|
import club.mcscrims.speedhg.kit.ability.ActiveAbility
|
||||||
|
import club.mcscrims.speedhg.kit.ability.PassiveAbility
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class BackupKit : Kit() {
|
||||||
|
|
||||||
|
private val plugin get() = SpeedHG.instance
|
||||||
|
|
||||||
|
override val id: String
|
||||||
|
get() = "backup"
|
||||||
|
|
||||||
|
override val displayName: Component
|
||||||
|
get() = plugin.languageManager.getDefaultComponent( "kits.backup.name", mapOf() )
|
||||||
|
|
||||||
|
override val lore: List<String>
|
||||||
|
get() = plugin.languageManager.getDefaultRawMessageList( "kits.backup.lore" )
|
||||||
|
|
||||||
|
override val icon: Material
|
||||||
|
get() = Material.CHEST
|
||||||
|
|
||||||
|
// ── Cached ability instances (avoid allocating per event call) ────────────
|
||||||
|
private val aggressiveNoActive = NoActive( Playstyle.AGGRESSIVE )
|
||||||
|
private val defensiveNoActive = NoActive( Playstyle.DEFENSIVE )
|
||||||
|
private val aggressiveNoPassive = NoPassive( Playstyle.AGGRESSIVE )
|
||||||
|
private val defensiveNoPassive = NoPassive( Playstyle.DEFENSIVE )
|
||||||
|
|
||||||
|
// ── Playstyle routing ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
override fun getActiveAbility(
|
||||||
|
playstyle: Playstyle
|
||||||
|
): ActiveAbility = when( playstyle )
|
||||||
|
{
|
||||||
|
Playstyle.AGGRESSIVE -> aggressiveNoActive
|
||||||
|
Playstyle.DEFENSIVE -> defensiveNoActive
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPassiveAbility(
|
||||||
|
playstyle: Playstyle
|
||||||
|
): PassiveAbility = when( playstyle )
|
||||||
|
{
|
||||||
|
Playstyle.AGGRESSIVE -> aggressiveNoPassive
|
||||||
|
Playstyle.DEFENSIVE -> defensiveNoPassive
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Item distribution ─────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
override fun giveItems( player: Player, playstyle: Playstyle ) {}
|
||||||
|
|
||||||
|
private class NoActive( playstyle: Playstyle ) : ActiveAbility( playstyle ) {
|
||||||
|
|
||||||
|
override val name: String
|
||||||
|
get() = "None"
|
||||||
|
|
||||||
|
override val description: String
|
||||||
|
get() = "None"
|
||||||
|
|
||||||
|
override val hitsRequired: Int
|
||||||
|
get() = 0
|
||||||
|
|
||||||
|
override val triggerMaterial: Material
|
||||||
|
get() = Material.BARRIER
|
||||||
|
|
||||||
|
override fun execute( player: Player ): AbilityResult { return AbilityResult.Success }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NoPassive( playstyle: Playstyle ) : PassiveAbility( playstyle ) {
|
||||||
|
|
||||||
|
override val name: String
|
||||||
|
get() = "None"
|
||||||
|
|
||||||
|
override val description: String
|
||||||
|
get() = "None"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -129,16 +129,17 @@ class GoblinKit : Kit() {
|
|||||||
val lineOfSight = player.getTargetEntity( 3 ) as? Player
|
val lineOfSight = player.getTargetEntity( 3 ) as? Player
|
||||||
?: return AbilityResult.ConditionNotMet( "No player in line of sight" )
|
?: return AbilityResult.ConditionNotMet( "No player in line of sight" )
|
||||||
|
|
||||||
val targetKit = plugin.kitManager.getSelectedKit( lineOfSight )
|
val targetKit = plugin.kitManager.getSelectedKit( lineOfSight ) ?: return AbilityResult.ConditionNotMet( "Target has no kit" )
|
||||||
?: return AbilityResult.ConditionNotMet( "Target has no kit" )
|
val targetPlaystyle = plugin.kitManager.getSelectedPlaystyle( lineOfSight )
|
||||||
|
|
||||||
val currentKit = plugin.kitManager.getSelectedKit( player )
|
val currentKit = plugin.kitManager.getSelectedKit( player ) ?: return AbilityResult.ConditionNotMet( "Error while copying kit" )
|
||||||
?: return AbilityResult.ConditionNotMet( "Error while copying kit" )
|
val currentPlaystyle = plugin.kitManager.getSelectedPlaystyle( player )
|
||||||
|
|
||||||
activeStealTasks.remove( player.uniqueId )
|
activeStealTasks.remove( player.uniqueId )
|
||||||
|
|
||||||
plugin.kitManager.removeKit( player )
|
plugin.kitManager.removeKit( player )
|
||||||
plugin.kitManager.selectKit( player, targetKit )
|
plugin.kitManager.selectKit( player, targetKit )
|
||||||
|
plugin.kitManager.selectPlaystyle( player, targetPlaystyle )
|
||||||
plugin.kitManager.applyKit( player )
|
plugin.kitManager.applyKit( player )
|
||||||
|
|
||||||
val task = Bukkit.getScheduler().runTaskLater( plugin, { ->
|
val task = Bukkit.getScheduler().runTaskLater( plugin, { ->
|
||||||
@@ -148,6 +149,7 @@ class GoblinKit : Kit() {
|
|||||||
{
|
{
|
||||||
plugin.kitManager.removeKit( player )
|
plugin.kitManager.removeKit( player )
|
||||||
plugin.kitManager.selectKit( player, currentKit )
|
plugin.kitManager.selectKit( player, currentKit )
|
||||||
|
plugin.kitManager.selectPlaystyle( player, currentPlaystyle )
|
||||||
plugin.kitManager.applyKit( player )
|
plugin.kitManager.applyKit( player )
|
||||||
}
|
}
|
||||||
}, 20L * 60)
|
}, 20L * 60)
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ class IceMageKit : Kit() {
|
|||||||
victim: Player,
|
victim: Player,
|
||||||
event: EntityDamageByEntityEvent
|
event: EntityDamageByEntityEvent
|
||||||
) {
|
) {
|
||||||
if ( random.nextBoolean() )
|
if (random.nextInt( 3 ) < 1 )
|
||||||
victim.addPotionEffect(PotionEffect( PotionEffectType.SLOWNESS, 60, 0 ))
|
victim.addPotionEffect(PotionEffect( PotionEffectType.SLOWNESS, 60, 0 ))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ commands:
|
|||||||
usage: '<red>Usage: /kit <kitName> <playstyle></red>'
|
usage: '<red>Usage: /kit <kitName> <playstyle></red>'
|
||||||
kitNotFound: '<red><kit> is not a registered kit!</red>'
|
kitNotFound: '<red><kit> is not a registered kit!</red>'
|
||||||
playstyleNotFound: '<red><playstyle> is not an available playstyle!</red>'
|
playstyleNotFound: '<red><playstyle> is not an available playstyle!</red>'
|
||||||
|
gameHasStarted: '<red>The game has already started. You cannot select a kit right now!</red>'
|
||||||
|
cannotPickSameKit: '<red>You cannot pick the same kit!</red>'
|
||||||
selected: '<green>You have selected <kit> as your Kit with playstyle <playstyle>!</green>'
|
selected: '<green>You have selected <kit> as your Kit with playstyle <playstyle>!</green>'
|
||||||
|
|
||||||
scoreboard:
|
scoreboard:
|
||||||
@@ -71,6 +73,17 @@ scoreboard:
|
|||||||
- "<yellow>play.mcscrims.club"
|
- "<yellow>play.mcscrims.club"
|
||||||
|
|
||||||
kits:
|
kits:
|
||||||
|
backup:
|
||||||
|
name: '<gradient:gold:#ff841f>Backup</gradient>'
|
||||||
|
lore:
|
||||||
|
- ' '
|
||||||
|
- 'Select a kit mid-round at any time.'
|
||||||
|
- 'All kits are available to pick.'
|
||||||
|
- ' '
|
||||||
|
- 'PlayStyle: §e%playstyle%'
|
||||||
|
- ' '
|
||||||
|
- 'Left-click to select'
|
||||||
|
- 'Right-click to change playstyle'
|
||||||
goblin:
|
goblin:
|
||||||
name: '<gradient:dark_green:gray><bold>Goblin</bold></gradient>'
|
name: '<gradient:dark_green:gray><bold>Goblin</bold></gradient>'
|
||||||
lore:
|
lore:
|
||||||
@@ -92,4 +105,23 @@ kits:
|
|||||||
messages:
|
messages:
|
||||||
stole_kit: '<green>You have stolen the kit of your opponent (Kit: <kit>)!</green>'
|
stole_kit: '<green>You have stolen the kit of your opponent (Kit: <kit>)!</green>'
|
||||||
spawn_bunker: '<green>You have created a bunker around yourself!'
|
spawn_bunker: '<green>You have created a bunker around yourself!'
|
||||||
ability_charged: '<aqua>Your ability has been recharged!</aqua>'
|
ability_charged: '<yellow>Your ability has been recharged!</yellow>'
|
||||||
|
icemage:
|
||||||
|
name: '<gradient:dark_aqua:aqua>IceMage</gradient>'
|
||||||
|
lore:
|
||||||
|
- ' '
|
||||||
|
- 'Use your abilities to freeze players'
|
||||||
|
- 'or gain speed in ice biomes and slow'
|
||||||
|
- 'enemies.'
|
||||||
|
- ' '
|
||||||
|
- 'PlayStyle: §e%playstyle%'
|
||||||
|
- ' '
|
||||||
|
- 'Left-click to select'
|
||||||
|
- 'Right-click to change playstyle'
|
||||||
|
items:
|
||||||
|
snowball:
|
||||||
|
name: '§bFreeze'
|
||||||
|
description: 'Freeze your enemies by throwing snowballs in all directions'
|
||||||
|
messages:
|
||||||
|
shoot_snowballs: '<aqua>You have shot frozen snowballs in all directions!</aqua>'
|
||||||
|
ability_charged: '<yellow>Your ability has been recharged!</yellow>'
|
||||||
Reference in New Issue
Block a user