diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/CustomItems.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/CustomItems.kt index 7755df2..883f3a0 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/CustomItems.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/CustomItems.kt @@ -13,6 +13,9 @@ object CustomItems { val jackal = Material.LIGHT_BLUE_STAINED_GLASS_PANE val sidekick = Material.LIGHT_BLUE_STAINED_GLASS_PANE + // Special Items + val cloakingDevice = Material.COBWEB + // Weapons val deagle = Material.GOLDEN_HOE val glock = Material.STONE_HOE @@ -20,4 +23,5 @@ object CustomItems { val shotgun = Material.IRON_AXE val knife = Material.IRON_SWORD val baseballBat = Material.STICK + val rifle = Material.DIAMOND_HOE } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/GeneralGameEventsListener.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/GeneralGameEventsListener.kt index d4132d3..949b557 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/GeneralGameEventsListener.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/GeneralGameEventsListener.kt @@ -52,6 +52,13 @@ object GeneralGameEventsListener: Listener { if (GameManager.phase !== GamePhase.COMBAT) { event.isCancelled = true } + + val player = event.entity + if (player is Player) { + plugin.server.scheduler.runTask(plugin, fun() { + player.noDamageTicks = 0 + }) + } } @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/PlayerManager.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/PlayerManager.kt index 6403844..7e032ab 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/PlayerManager.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/PlayerManager.kt @@ -30,7 +30,6 @@ object PlayerManager { fun letRemainingRoleWin() { GameManager.ensurePhase(GamePhase.COMBAT) - println(stillLivingRoles) if (stillLivingRoles.count() == 1) { GameManager.letRoleWin(stillLivingRoles[0]) } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayer.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayer.kt index 66574f3..0616dcc 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayer.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/game/players/TTTPlayer.kt @@ -17,19 +17,36 @@ import org.bukkit.ChatColor import org.bukkit.GameMode import org.bukkit.Material import org.bukkit.entity.Player +import org.bukkit.potion.PotionEffect +import org.bukkit.potion.PotionEffectType import kotlin.properties.Delegates class TTTPlayer(player: Player, role: Role) { var alive = true var lastDeathReason: DeathReason? = null - var player by Delegates.observable(player) { _, _, player -> player.scoreboard = scoreboard.scoreboard } + var player by Delegates.observable(player) { _, _, _ -> initializePlayer() } - var role by Delegates.observable(role) { _, _, _ -> scoreboard.updateRole() } + var role by Delegates.observable(Role.TRAITOR) { _, _, _ -> scoreboard.updateRole() } val roleHistory = mutableListOf() var itemInHand by Delegates.observable(null) { _, oldItem, newItem -> onItemInHandChanged(oldItem, newItem) } var credits by Delegates.observable(10) { _, _, _ -> scoreboard.updateCredits() } + var invisible by Delegates.observable(false) { _, _, value -> + if (value) { + PlayerManager.tttPlayers.forEach { + if (it.alive && it.role != role) { + it.player.hidePlayer(plugin, player) + } + } + + // for the translucent effect seen by teammates + player.addPotionEffect(PotionEffect(PotionEffectType.INVISIBILITY, 1000000, 0, false, false)) + } else { + plugin.server.onlinePlayers.forEach { it.showPlayer(plugin, player) } + player.removePotionEffect(PotionEffectType.INVISIBILITY) + } + } val scoreboard = TTTScoreboard(this) val stateContainer = StateContainer() @@ -37,10 +54,14 @@ class TTTPlayer(player: Player, role: Role) { private val discordUser get() = DiscordInterface.getUserByPlayerUUID(player.uniqueId) init { - player.scoreboard = scoreboard.scoreboard + initializePlayer() scoreboard.initialize() } + private fun initializePlayer() { + player.scoreboard = scoreboard.scoreboard + } + private fun onItemInHandChanged(oldItem: TTTItem?, newItem: TTTItem?) { if (oldItem !== null && oldItem is SelectableItem) { oldItem.onDeselect(this) @@ -90,6 +111,7 @@ class TTTPlayer(player: Player, role: Role) { stateContainer.clear() setMuted(false) + invisible = false alive = true player.gameMode = GameMode.SURVIVAL diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/ItemManager.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/ItemManager.kt index 82ac297..ce4df19 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/ItemManager.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/ItemManager.kt @@ -1,11 +1,13 @@ package de.moritzruth.spigot_ttt.items import de.moritzruth.spigot_ttt.game.GameManager +import de.moritzruth.spigot_ttt.items.cloaking_device.CloakingDevice import de.moritzruth.spigot_ttt.items.weapons.baseball_bat.BaseballBat import de.moritzruth.spigot_ttt.items.weapons.guns.deagle.Deagle import de.moritzruth.spigot_ttt.items.weapons.guns.deagle.GoldenDeagle import de.moritzruth.spigot_ttt.items.weapons.guns.glock.Glock import de.moritzruth.spigot_ttt.items.weapons.guns.pistol.Pistol +import de.moritzruth.spigot_ttt.items.weapons.guns.pistol.Rifle import de.moritzruth.spigot_ttt.items.weapons.guns.shotgun.Shotgun import de.moritzruth.spigot_ttt.items.weapons.knife.Knife import de.moritzruth.spigot_ttt.plugin @@ -21,7 +23,7 @@ object ItemManager { private val spawnLocationsConfig = ConfigurationFile("spawnLocations") - val items: Set = setOf(Pistol, Knife, Glock, Deagle, Shotgun, GoldenDeagle, BaseballBat) + val items: Set = setOf(Pistol, Knife, Glock, Deagle, Shotgun, GoldenDeagle, BaseballBat, CloakingDevice, Rifle) private val spawningItems = items.filter(TTTItem::spawning) fun registerListeners() { diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/TTTItem.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/TTTItem.kt index b00b5b4..29f05a3 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/TTTItem.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/TTTItem.kt @@ -23,9 +23,10 @@ interface TTTItem { val type: Type enum class Type(val maxItemsOfTypeInInventory: Int?) { - NORMAL_WEAPON(2), - SPECIAL_WEAPON(2), - OTHER(null); + MELEE(1), + PISTOL_LIKE(1), + HEAVY_WEAPON(1), + SPECIAL(null); val position by lazy { values().indexOf(this) } } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDevice.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDevice.kt new file mode 100644 index 0000000..8a6534a --- /dev/null +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDevice.kt @@ -0,0 +1,70 @@ +package de.moritzruth.spigot_ttt.items.cloaking_device + +import de.moritzruth.spigot_ttt.CustomItems +import de.moritzruth.spigot_ttt.game.players.TTTPlayer +import de.moritzruth.spigot_ttt.game.players.TTTPlayer.Role.* +import de.moritzruth.spigot_ttt.items.BuyableItem +import de.moritzruth.spigot_ttt.items.SelectableItem +import de.moritzruth.spigot_ttt.items.TTTItem +import org.bukkit.ChatColor +import org.bukkit.inventory.ItemFlag +import org.bukkit.inventory.ItemStack +import org.bukkit.potion.PotionEffect +import org.bukkit.potion.PotionEffectType +import java.util.* + +object CloakingDevice: TTTItem, BuyableItem, SelectableItem { + override val displayName = "${ChatColor.GRAY}${ChatColor.MAGIC}###${ChatColor.RESET}${ChatColor.GRAY} Cloaking Device ${ChatColor.MAGIC}###" + override val itemStack = ItemStack(CustomItems.cloakingDevice) + override val type = TTTItem.Type.SPECIAL + override val listener = CloakingDeviceListener + override val spawning = false + override val price = 2 + override val buyableBy = EnumSet.of(DETECTIVE, TRAITOR, JACKAL) + + init { + val meta = itemStack.itemMeta!! + + meta.setDisplayName(displayName) + meta.lore = listOf( + "", + "${ChatColor.GOLD}Macht dich unsichtbar" + ) + + meta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES) + itemStack.itemMeta = meta + } + + override fun onSelect(tttPlayer: TTTPlayer) {} + override fun onDeselect(tttPlayer: TTTPlayer) = setEnabled(tttPlayer, false) + + fun getState(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.get(CloakingDeviceState::class) { CloakingDeviceState() } + + fun setEnabled(tttPlayer: TTTPlayer, value: Boolean?) { + val state = getState(tttPlayer) + if (state.enabled == value) return + + if (value ?: !state.enabled) { + tttPlayer.player.apply { + isSprinting = false + walkSpeed = 0.1F + + // To prevent jumping (amplifier 200) + addPotionEffect(PotionEffect(PotionEffectType.JUMP, 1000000, 200, false, false)) + } + + tttPlayer.invisible = true + state.enabled = true + } else { + tttPlayer.player.apply { + walkSpeed = 0.2F + removePotionEffect(PotionEffectType.JUMP) + } + + tttPlayer.invisible = false + state.enabled = false + } + + // TODO: Play sound + } +} diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDeviceListener.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDeviceListener.kt new file mode 100644 index 0000000..0f83dd5 --- /dev/null +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDeviceListener.kt @@ -0,0 +1,27 @@ +package de.moritzruth.spigot_ttt.items.cloaking_device + +import de.moritzruth.spigot_ttt.game.players.PlayerManager +import de.moritzruth.spigot_ttt.items.isRelevant +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerInteractEvent +import org.bukkit.event.player.PlayerToggleSprintEvent + +object CloakingDeviceListener: Listener { + @EventHandler + fun onPlayerToggleSprint(event: PlayerToggleSprintEvent) { + val tttPlayer = PlayerManager.getTTTPlayer(event.player) ?: return + + if (event.isSprinting && CloakingDevice.getState(tttPlayer).enabled) { + event.isCancelled = true + } + } + + @EventHandler + fun onPlayerInteract(event: PlayerInteractEvent) { + if (!event.isRelevant(CloakingDevice.displayName)) return + val tttPlayer = PlayerManager.getTTTPlayer(event.player) ?: return + + CloakingDevice.setEnabled(tttPlayer, null) + } +} diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDeviceState.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDeviceState.kt new file mode 100644 index 0000000..388a833 --- /dev/null +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/cloaking_device/CloakingDeviceState.kt @@ -0,0 +1,7 @@ +package de.moritzruth.spigot_ttt.items.cloaking_device + +import de.moritzruth.spigot_ttt.game.players.State + +class CloakingDeviceState: State { + var enabled: Boolean = false +} diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/baseball_bat/BaseballBat.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/baseball_bat/BaseballBat.kt index d30eb08..0af4982 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/baseball_bat/BaseballBat.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/baseball_bat/BaseballBat.kt @@ -15,7 +15,7 @@ import java.util.* object BaseballBat: TTTItem, BuyableItem, SelectableItem { override val displayName = "${ChatColor.RESET}${ChatColor.BOLD}Baseball-Schläger" override val spawning = false - override val type = TTTItem.Type.SPECIAL_WEAPON + override val type = TTTItem.Type.MELEE override val itemStack = ItemStack(CustomItems.baseballBat) override val listener = BaseballBatListener override val buyableBy = EnumSet.of(TRAITOR, JACKAL) diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/deagle/Deagle.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/deagle/Deagle.kt index fb24ca3..412bb62 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/deagle/Deagle.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/deagle/Deagle.kt @@ -26,7 +26,7 @@ object Deagle: Gun(), BuyableItem { override val recoil = 10 override val buyableBy: EnumSet = EnumSet.of(TRAITOR, DETECTIVE) override val price = 1 - override val type = TTTItem.Type.NORMAL_WEAPON + override val type = TTTItem.Type.PISTOL_LIKE override fun getState(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.get(DeagleState::class) { DeagleState() } } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/glock/Glock.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/glock/Glock.kt index 1fc0afa..8926a52 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/glock/Glock.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/glock/Glock.kt @@ -20,7 +20,7 @@ object Glock: Gun() { itemMeta = getItemMeta(this) } override val recoil = 2 - override val type = TTTItem.Type.NORMAL_WEAPON + override val type = TTTItem.Type.PISTOL_LIKE override fun getState(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.get(GlockState::class) { GlockState() } } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/goldendeagle/GoldenDeagle.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/goldendeagle/GoldenDeagle.kt index ce13b21..aba15a0 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/goldendeagle/GoldenDeagle.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/goldendeagle/GoldenDeagle.kt @@ -34,7 +34,7 @@ object GoldenDeagle: Gun(), BuyableItem { override val recoil = 10 override val buyableBy: EnumSet = EnumSet.of(TRAITOR, DETECTIVE) override val price = 3 - override val type = TTTItem.Type.SPECIAL_WEAPON + override val type = TTTItem.Type.PISTOL_LIKE override fun computeActualDamage(tttPlayer: TTTPlayer, receiver: Player) = 1000.0 override fun getState(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.get(GoldenDeagleState::class) { GoldenDeagleState() } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/pistol/Pistol.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/pistol/Pistol.kt index f817bff..14d6c5c 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/pistol/Pistol.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/pistol/Pistol.kt @@ -20,7 +20,7 @@ object Pistol: Gun() { itemMeta = getItemMeta(this) } override val recoil = 5 - override val type = TTTItem.Type.NORMAL_WEAPON + override val type = TTTItem.Type.PISTOL_LIKE override fun getState(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.get(PistolState::class) { PistolState() } } diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/rifle/Rifle.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/rifle/Rifle.kt new file mode 100644 index 0000000..7f7b9f4 --- /dev/null +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/rifle/Rifle.kt @@ -0,0 +1,32 @@ +package de.moritzruth.spigot_ttt.items.weapons.guns.pistol + +import de.moritzruth.spigot_ttt.CustomItems +import de.moritzruth.spigot_ttt.game.players.TTTPlayer +import de.moritzruth.spigot_ttt.items.BuyableItem +import de.moritzruth.spigot_ttt.items.TTTItem +import de.moritzruth.spigot_ttt.items.weapons.guns.Gun +import de.moritzruth.spigot_ttt.utils.heartsToHealth +import org.bukkit.ChatColor +import org.bukkit.inventory.ItemStack +import java.util.* + +object Rifle: Gun(), BuyableItem { + override val spawning = true + override val displayName = "${ChatColor.YELLOW}${ChatColor.BOLD}Rifle" + override val damage = heartsToHealth(0.5) + override val cooldown = 0.1 + override val magazineSize = 40 + override val reloadTime = 2.0 + override val itemMaterial = CustomItems.rifle + override val itemStack = ItemStack(itemMaterial).apply { + itemMeta = getItemMeta(this) + } + override val recoil = 1 + override val type = TTTItem.Type.HEAVY_WEAPON + override val price = 1 + override val buyableBy = EnumSet.of(TTTPlayer.Role.TRAITOR) + + override fun getState(tttPlayer: TTTPlayer) = tttPlayer.stateContainer.get(RifleState::class) { RifleState() } +} + + diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/rifle/RifleState.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/rifle/RifleState.kt new file mode 100644 index 0000000..756dbff --- /dev/null +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/rifle/RifleState.kt @@ -0,0 +1,5 @@ +package de.moritzruth.spigot_ttt.items.weapons.guns.pistol + +import de.moritzruth.spigot_ttt.items.weapons.guns.GunState + +class RifleState: GunState(Rifle.magazineSize) diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/shotgun/Shotgun.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/shotgun/Shotgun.kt index 0659d2b..d491998 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/shotgun/Shotgun.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/guns/shotgun/Shotgun.kt @@ -24,7 +24,7 @@ object Shotgun: Gun() { override val magazineSize = 8 override val reloadTime get() = reloadTimePerBullet * magazineSize override val recoil = 20 - override val type = TTTItem.Type.NORMAL_WEAPON + override val type = TTTItem.Type.HEAVY_WEAPON override val itemMaterial = CustomItems.shotgun override val itemStack = ItemStack(itemMaterial).apply { diff --git a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/knife/Knife.kt b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/knife/Knife.kt index 6178f4b..5195a0c 100644 --- a/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/knife/Knife.kt +++ b/src/main/kotlin/de/moritzruth/spigot_ttt/items/weapons/knife/Knife.kt @@ -18,7 +18,7 @@ object Knife: TTTItem, BuyableItem { override val itemStack = ItemStack(CustomItems.knife) override val buyableBy: EnumSet = EnumSet.of(TRAITOR) override val price = 1 - override val type = TTTItem.Type.SPECIAL_WEAPON + override val type = TTTItem.Type.MELEE init { val meta = itemStack.itemMeta!!