diff --git a/.github/workflows/gradle_11.yml b/.github/workflows/gradle_11.yml index c850916..b608289 100644 --- a/.github/workflows/gradle_11.yml +++ b/.github/workflows/gradle_11.yml @@ -25,10 +25,4 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew shadowJar - - name: Upload a Build Artifact - uses: actions/upload-artifact@v2.2.4 - with: - name: Bedwars Plugin JAR - path: build/libs/*.jar - if-no-files-found: error + run: ./gradlew shadowJar \ No newline at end of file diff --git a/.github/workflows/gradle_8.yml b/.github/workflows/gradle_8.yml index 043bd43..6a887b8 100644 --- a/.github/workflows/gradle_8.yml +++ b/.github/workflows/gradle_8.yml @@ -25,10 +25,4 @@ jobs: - name: Grant execute permission for gradlew run: chmod +x gradlew - name: Build with Gradle - run: ./gradlew shadowJar - - name: Upload a Build Artifact - uses: actions/upload-artifact@v2.2.4 - with: - name: Bedwars Plugin JAR - path: build/libs/*.jar - if-no-files-found: error + run: ./gradlew shadowJar \ No newline at end of file diff --git a/api/build.gradle b/api/build.gradle index 38856a5..1cd25d5 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1,9 +1,8 @@ //file:noinspection GroovyAssignabilityCheck -/*plugins { - id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' +plugins { id 'maven-publish' id 'signing' -}*/ +} archivesBaseName = "Bedwars-API" @@ -16,7 +15,6 @@ java { withJavadocJar() } -/* publishing { def project = project publications { @@ -57,18 +55,6 @@ publishing { } } -nexusPublishing { - packageGroup.set("io.github.dkim19375") - repositories { - sonatype { - nexusUrl = uri("https://s01.oss.sonatype.org/service/local/") - snapshotRepositoryUrl = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") - username = project.findProperty("mavenUsername") - password = project.findProperty("mavenPassword") - } - } -} - signing { sign publishing.publications.mavenJava -}*/ +} \ No newline at end of file diff --git a/api/src/main/java/me/dkim19375/bedwars/api/enumclass/SpecialItemType.java b/api/src/main/java/me/dkim19375/bedwars/api/enumclass/SpecialItemType.java new file mode 100644 index 0000000..248dd0e --- /dev/null +++ b/api/src/main/java/me/dkim19375/bedwars/api/enumclass/SpecialItemType.java @@ -0,0 +1,24 @@ +package me.dkim19375.bedwars.api.enumclass; + +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Nullable; + +public enum SpecialItemType { + BED_BUGS, + DREAM_DEFENDER, + MAGIC_MILK, + BRIDGE_EGGS; + + @Nullable + @Contract(value = "null -> null", pure = true) + public static SpecialItemType fromString(@Nullable String str) { + if (str == null) { + return null; + } + try { + return valueOf(str.toUpperCase()); + } catch (IllegalArgumentException ignored) { + return null; + } + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 4ecc247..9110218 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,14 @@ //file:noinspection SpellCheckingInspection //file:noinspection GroovyAssignabilityCheck plugins { + id 'io.github.gradle-nexus.publish-plugin' version '1.1.0' id 'com.github.johnrengelman.shadow' version '6.1.0' id 'org.jetbrains.kotlin.jvm' version '1.5.30' id 'org.cadixdev.licenser' version '0.6.1' + id 'org.jetbrains.dokka' version '1.4.32' id 'io.github.slimjar' version '1.3.0' + id 'maven-publish' + id 'signing' } final def basePackage = 'me.dkim19375.bedwars.libs' @@ -120,19 +124,16 @@ subprojects { repositories { addRepositories(project) - maven { - url 'https://repo.maven.apache.org/maven2' - name 'Maven Central' - } } dependencies { dependencyStrings.forEach { compileOnly it } + //noinspection GrUnresolvedAccess implementation slimjar('1.2.6') implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.5.30' - implementation('io.github.dkim19375:dkim-bukkit-core:3.3.7') { + implementation('io.github.dkim19375:dkim-bukkit-core:3.3.11') { exclude group: 'org.jetbrains.kotlin' exclude group: 'org.jetbrains.kotlinx' } @@ -157,6 +158,18 @@ subprojects { } } +nexusPublishing { + packageGroup = 'io.github.dkim19375' + repositories { + sonatype { + nexusUrl = uri 'https://s01.oss.sonatype.org/service/local/' + snapshotRepositoryUrl = uri 'https://s01.oss.sonatype.org/content/repositories/snapshots/' + username = project.findProperty 'mavenUsername' + password = project.findProperty 'mavenPassword' + } + } +} + task removeBuildJars() { new File('build/libs').deleteDir() } diff --git a/compat/src/main/kotlin/me/dkim19375/bedwars/compat/abstract/NBTUtilitiesAbstract.kt b/compat/src/main/kotlin/me/dkim19375/bedwars/compat/abstract/NBTUtilitiesAbstract.kt index 318bdef..4be6643 100644 --- a/compat/src/main/kotlin/me/dkim19375/bedwars/compat/abstract/NBTUtilitiesAbstract.kt +++ b/compat/src/main/kotlin/me/dkim19375/bedwars/compat/abstract/NBTUtilitiesAbstract.kt @@ -20,6 +20,7 @@ package me.dkim19375.bedwars.compat.abstract import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion import org.bukkit.entity.ArmorStand +import org.bukkit.entity.Entity import org.bukkit.entity.Item import org.bukkit.entity.LivingEntity import org.bukkit.inventory.ItemStack @@ -29,21 +30,23 @@ import org.bukkit.plugin.java.JavaPlugin abstract class NBTUtilitiesAbstract { companion object { - fun getInstance(plugin: JavaPlugin): NBTUtilitiesAbstract = if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) { - Class.forName("me.dkim19375.bedwars.v1_16.NBTUtilities") - .getConstructor(JavaPlugin::class.java) - .newInstance(plugin) as NBTUtilitiesAbstract - } else { - Class.forName("me.dkim19375.bedwars.v1_8.NBTUtilities") - .getConstructor() - .newInstance() as NBTUtilitiesAbstract - } + fun getInstance(plugin: JavaPlugin): NBTUtilitiesAbstract = + if (MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_16_R1)) { + Class.forName("me.dkim19375.bedwars.v1_16.NBTUtilities") + .getConstructor(JavaPlugin::class.java) + .newInstance(plugin) as NBTUtilitiesAbstract + } else { + Class.forName("me.dkim19375.bedwars.v1_8.NBTUtilities") + .getConstructor() + .newInstance() as NBTUtilitiesAbstract + } } protected val CONFIG_ITEM_KEY = "BedwarsConfigItem" protected val HOLOGRAM_KEY = "BedwarsArmorStand" + protected val MOB_DROP_KEY = "BedwarsMobDrop" + protected val GEN_DROP_KEY = "BedwarsGenDrop" protected val TRACKER_KEY = "BedwarsPlayerTracker" - protected val DROP_KEY = "BedwarsGenDrop" abstract fun addAI(entity: T) @@ -64,4 +67,8 @@ abstract class NBTUtilitiesAbstract { abstract fun setDrop(item: Item, drop: Boolean): Item abstract fun isDrop(item: Item): Pair + + abstract fun disableDrops(entity: T): T + + abstract fun isDropsDisabled(entity: T): Pair } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/BedwarsPlugin.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/BedwarsPlugin.kt index 4aba0c1..34305c3 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/BedwarsPlugin.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/BedwarsPlugin.kt @@ -66,13 +66,12 @@ val NEW_SOUND: Boolean = MinecraftVersion.isAtLeastVersion(MinecraftVersion.MC1_ class BedwarsPlugin : CoreJavaPlugin() { val mainConfigManager: MainConfigManager by lazy { MainConfigManager(this) } val shopConfigManager = ShopConfigManager(this) - val shopFile = ConfigFile(this, "shop.yml") + val shopFile by lazy { ConfigFile(this, "shop.yml") } val gameDataFiles = mutableMapOf>() - val userCache: MutableMap = Collections.synchronizedMap(mutableMapOf()) val mainDataFile: JsonFile by lazy { JsonFile( type = MainDataFile::class, - fileName = File(dataFolder, "data/data.json").path, + file = File(dataFolder, "data/data.json"), prettyPrinting = true, typeAdapters = jsonSerializers, default = { MainDataFile() } @@ -109,9 +108,9 @@ class BedwarsPlugin : CoreJavaPlugin() { val jsonSerializers by lazy { mapOf, Any>( - Location::class.java to LocationSerializer(), - MainShopConfigItem::class.java to ShopConfigItemSerializer(this), - World::class.java to WorldSerializer() + Location::class.java to LocationSerializer().nullSafe(), + MainShopConfigItem::class.java to ShopConfigItemSerializer(this).nullSafe(), + World::class.java to WorldSerializer().nullSafe() ) } @@ -166,7 +165,7 @@ class BedwarsPlugin : CoreJavaPlugin() { val data = GameBuilder(world).build(true) ?: continue val newData = JsonFile( type = GameData::class, - fileName = file.path, + file = file, prettyPrinting = true, typeAdapters = jsonSerializers, default = { data } @@ -221,7 +220,7 @@ class BedwarsPlugin : CoreJavaPlugin() { PotionConsumeListener(this), InventoryClickListener(this), PlayerPickupItemListener(this), WorldInitListener(this), CommandListeners(this), AsyncPlayerChatListener(this), PlayerCoordsChangeListener(this), EntityDamageByEntityListener(this), CraftItemListener(this), - PlayerInteractListener(this), ProjectileLaunchListener(this), + PlayerInteractListener(this), ProjectileLaunchListener(this), EntityDeathListener(), partiesListeners, scoreboardManager ) } diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/MainConfigManager.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/MainConfigManager.kt index 3bf7052..cace1c5 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/MainConfigManager.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/MainConfigManager.kt @@ -5,4 +5,4 @@ import me.dkim19375.dkimcore.file.YamlFile import java.io.File class MainConfigManager(plugin: BedwarsPlugin) : - YamlFile(MainConfigSettings, File(plugin.dataFolder, "config.yml").path) \ No newline at end of file + YamlFile(MainConfigSettings, File(plugin.dataFolder, "config.yml")) \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/MainConfigSettings.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/MainConfigSettings.kt index 2e49cb9..5a2b49e 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/MainConfigSettings.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/MainConfigSettings.kt @@ -84,11 +84,18 @@ object MainConfigSettings : SettingsHolder { @Path("map.protection") val MAP_PROTECTION: Property = Property.create(true) + // mobs + @Path("mobs.time.dream-defender") + val TIME_DREAM_DEFENDER: Property = Property.create(4800) + @Path("mobs.time.bed-bugs") + val TIME_BED_BUG: Property = Property.create(300) + override fun registerComments(conf: CommentsConfiguration) { conf.setComment( "tab.hide-players", "Players in-game won't see players not in the game and players not in the game won't see players in-game", "unless in the same world (and same-world is true)" ) + conf.setComment("mobs.time", "The time that these mobs will stay in TICKS (20 ticks = 1 second)") } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/ShopConfigManager.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/ShopConfigManager.kt index a52f637..bb0ffe3 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/ShopConfigManager.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/config/ShopConfigManager.kt @@ -37,7 +37,7 @@ class ShopConfigManager(private val plugin: BedwarsPlugin) { fun update() { mainItems = shopConfig.getKeys(false) .mapNotNull(shopConfig::getConfigurationSection) - .mapNotNull(MainShopConfigItem::deserialize) + .mapNotNull { MainShopConfigItem.deserialize(it, plugin) } .toSet() } diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/data/ItemWrapper.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/data/ItemWrapper.kt index 7245594..1a9b640 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/data/ItemWrapper.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/data/ItemWrapper.kt @@ -20,18 +20,17 @@ package me.dkim19375.bedwars.plugin.data import me.dkim19375.bedwars.plugin.BedwarsPlugin import me.dkim19375.bedwars.plugin.gui.MainShopGUI -import me.dkim19375.bedwars.plugin.util.addAllFlags -import me.dkim19375.bedwars.plugin.util.enumValueOfOrNull -import me.dkim19375.bedwars.plugin.util.setConfigItem -import me.dkim19375.bedwars.plugin.util.setUnbreakable +import me.dkim19375.bedwars.plugin.util.* import me.dkim19375.dkimbukkitcore.function.logInfo import org.bukkit.DyeColor import org.bukkit.Material import org.bukkit.configuration.ConfigurationSection import org.bukkit.enchantments.Enchantment +import org.bukkit.entity.EntityType import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.LeatherArmorMeta import org.bukkit.material.Colorable +import org.bukkit.material.SpawnEgg import org.bukkit.material.Wool import org.bukkit.plugin.java.JavaPlugin import org.bukkit.potion.Potion @@ -39,12 +38,21 @@ import org.bukkit.potion.PotionType import java.util.logging.Level data class ItemWrapper( - val material: Material, val amount: Int, val potionType: PotionType? = null, val configItem: String? = null, - val potionAmplifier: Int = 1, val potionDuration: Int = 0, val enchants: Map = emptyMap() + val material: Material, + val amount: Int, + val name: String? = null, + val lore: List? = null, + val potionType: PotionType? = null, + val configItem: String? = null, + val potionAmplifier: Int = 1, + val potionDuration: Int = 0, + val enchants: Map = emptyMap(), + val mobType: EntityType? = null, ) { fun toItemStack(color: DyeColor?): ItemStack { val plugin = JavaPlugin.getPlugin(BedwarsPlugin::class.java) val configManager = plugin.shopConfigManager + val customLore = lore if (potionType != null) { val potion = Potion(potionType, if (!(1..2).contains(potionAmplifier - 1)) 2 else (potionAmplifier - 1)) val item = potion.toItemStack(amount).setConfigItem(configItem) @@ -54,29 +62,34 @@ data class ItemWrapper( } } item.itemMeta = item.itemMeta?.apply { + if (customLore != null) { + lore = customLore + } addAllFlags() + if (name != null) { + displayName = name + } } return item } + val regularItem = ItemStack(material, amount) val type = configManager.getItemFromName(configItem) val item: ItemStack = if (material == Material.WOOL && color != null) { Wool(color).toItemStack(amount) } else { - when (ItemStack(material, amount).itemMeta) { - is LeatherArmorMeta -> ItemStack(material, amount) - is Colorable -> ItemStack(material, amount) - else -> { - @Suppress("LiftReturnOrAssignment") // fix warning = error?! - if (color == null) { - ItemStack(material, amount) - } else { - if (type != null && type.itemCategory == MainShopGUI.ItemType.BLOCKS) { - @Suppress("DEPRECATION") - ItemStack(material, amount, color.data.toShort()) - } else { - ItemStack(material, amount) - } + @Suppress("DEPRECATION") + when (regularItem.itemMeta) { + is LeatherArmorMeta -> regularItem + is Colorable -> regularItem + else -> when { + regularItem.data is SpawnEgg && mobType != null -> regularItem.apply { + durability = mobType.typeId + } + color == null -> regularItem + type != null && type.itemCategory == MainShopGUI.ItemType.BLOCKS -> regularItem.apply { + durability = color.data.toShort() } + else -> regularItem } } }.setConfigItem(configItem).setUnbreakable(true) @@ -87,7 +100,13 @@ data class ItemWrapper( if (this is LeatherArmorMeta && color != null) { this.color = color.color } + if (customLore != null) { + lore = customLore + } addAllFlags() + if (name != null) { + displayName = name + } } return item } @@ -113,6 +132,7 @@ data class ItemWrapper( result = 31 * result + amount result = 31 * result + (potionType?.hashCode() ?: 0) result = 31 * result + potionAmplifier + Material.MONSTER_EGG result = 31 * result + enchants.hashCode() return result } @@ -135,6 +155,8 @@ data class ItemWrapper( ) return null } + val displayname = config.getString("display-name") + val lore = config.getStringListOrNull("lore") val amount = config.getInt("amount", 1) val potionType = enumValueOfOrNull(config.getString("potion-type")) val potionAmplifier = config.getInt("potion-amplifier", 1) @@ -146,7 +168,20 @@ data class ItemWrapper( } Enchantment.getByName(split[0].uppercase()) to (split.getOrNull(1)?.toIntOrNull() ?: 1) }.toMap() - return ItemWrapper(material, amount, potionType, config.name, potionAmplifier, potionDuration, enchants) + logInfo("mob type (${config.currentPath}.mob-type): ${config.getString("mob-type")}") + val mobType = config.getString("mob-type")?.let { enumValueOfOrNull(it) } + return ItemWrapper( + material = material, + amount = amount, + name = displayname, + lore = lore, + potionType = potionType, + configItem = config.name, + potionAmplifier = potionAmplifier, + potionDuration = potionDuration, + enchants = enchants, + mobType = mobType + ) } } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/data/MainShopConfigItem.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/data/MainShopConfigItem.kt index 21f06cb..e482640 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/data/MainShopConfigItem.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/data/MainShopConfigItem.kt @@ -18,55 +18,37 @@ package me.dkim19375.bedwars.plugin.data +import me.dkim19375.bedwars.api.enumclass.SpecialItemType +import me.dkim19375.bedwars.plugin.BedwarsPlugin import me.dkim19375.bedwars.plugin.gui.MainShopGUI import me.dkim19375.bedwars.plugin.util.enumValueOfOrNull import me.dkim19375.bedwars.plugin.util.getIntOrNull import me.dkim19375.dkimbukkitcore.function.logInfo +import org.bukkit.ChatColor import org.bukkit.configuration.ConfigurationSection import java.util.logging.Level data class MainShopConfigItem( - val name: String, val slot: Int, val item: ItemWrapper, val cost: Int, val costItem: MainShopGUI.CostType, - val displayname: String?, val permanent: Boolean = false, val defaultOnSpawn: Boolean = false, - val itemCategory: MainShopGUI.ItemType + val name: String, + val slot: Int, + val item: ItemWrapper, + val cost: Int, + val costItem: MainShopGUI.CostType, + val itemCategory: MainShopGUI.ItemType, + val displayname: String? = null, + val permanent: Boolean = false, + val defaultOnSpawn: Boolean = false, + val downgrade: () -> MainShopConfigItem? = { null }, + val commands: List = emptyList(), + val cosmetic: Boolean = false, + val specialItem: SpecialItemType? = null ) { - @Suppress("DuplicatedCode") - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as MainShopConfigItem - - if (slot != other.slot) return false - if (item != other.item) return false - if (cost != other.cost) return false - if (costItem != other.costItem) return false - if (displayname != other.displayname) return false - if (permanent != other.permanent) return false - if (defaultOnSpawn != other.defaultOnSpawn) return false - if (itemCategory != other.itemCategory) return false - - return true - } - - override fun hashCode(): Int { - var result = slot - result = 31 * result + item.hashCode() - result = 31 * result + cost - result = 31 * result + costItem.hashCode() - result = 31 * result + (displayname?.hashCode() ?: 0) - result = 31 * result + permanent.hashCode() - result = 31 * result + defaultOnSpawn.hashCode() - result = 31 * result + itemCategory.hashCode() - return result - } - companion object { private fun logError(config: ConfigurationSection, section: String, reason: String = "does not exist!") { logInfo("Section ${config.name}.$section $reason", Level.SEVERE) } - fun deserialize(config: ConfigurationSection): MainShopConfigItem? { + fun deserialize(config: ConfigurationSection, plugin: BedwarsPlugin): MainShopConfigItem? { val row = config.getIntOrNull("row") val column = config.getIntOrNull("column") val slot = config.getIntOrNull("slot") ?: run { @@ -82,17 +64,8 @@ data class MainShopConfigItem( } val itemWrapper = ItemWrapper.fromConfig(config) ?: return null val costAmount = config.getInt("cost", 1) - val costType = enumValueOfOrNull(config.getString("cost-item")) ?: run { - logError( - config, - "cost-item", - if (config.isSet("cost-item")) "- Invalid cost-item! Valid: (${ - MainShopGUI.CostType.values().map(MainShopGUI.CostType::name).joinToString() - })" else "does not exist!" - ) - return null - } - val displayname = config.getString("display-name") + val costType = enumValueOfOrNull(config.getString("cost-item")) ?: MainShopGUI.CostType.IRON + val name = config.getString("name") val permanent = config.getBoolean("permanent") val defaultOnSpawn = config.getBoolean("default-on-spawn") val type = enumValueOfOrNull(config.getString("item-category")) ?: run { @@ -105,17 +78,27 @@ data class MainShopConfigItem( ) return null } + val downgrade = config.getString("downgrade") + val commands = config.getStringList("commands") + val cosmetic = config.getBoolean("cosmetic") + val specialItem = SpecialItemType.fromString(config.getString("special-type")) return MainShopConfigItem( name = config.name, slot = slot, item = itemWrapper, cost = costAmount, costItem = costType, - displayname = displayname, + itemCategory = type, + displayname = name, permanent = permanent, defaultOnSpawn = defaultOnSpawn, - itemCategory = type + downgrade = { downgrade?.let(plugin.shopConfigManager::getItemFromName) }, + commands = commands, + cosmetic = cosmetic, + specialItem = specialItem ) } } + + fun getFriendlyName(): String = displayname ?: ChatColor.stripColor(item.name) ?: name } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/gui/MainShopGUI.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/gui/MainShopGUI.kt index c31eeec..ec9f6f6 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/gui/MainShopGUI.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/gui/MainShopGUI.kt @@ -27,6 +27,8 @@ import me.dkim19375.bedwars.plugin.enumclass.ArmorType import me.dkim19375.bedwars.plugin.enumclass.getToolTier import me.dkim19375.bedwars.plugin.manager.BedwarsGame import me.dkim19375.bedwars.plugin.util.* +import me.dkim19375.dkimbukkitcore.function.formatAll +import org.bukkit.Bukkit import org.bukkit.ChatColor import org.bukkit.DyeColor import org.bukkit.Material @@ -159,7 +161,7 @@ class MainShopGUI(private val player: Player, private val plugin: BedwarsPlugin, plugin.dataFileManager.setQuickBuySlot(slot, player.uniqueId, null) menu.setItem(slot, ItemBuilder.from(getNoneInQuickBuyItem()).asNewGuiItem()) menu.update() - player.sendMessage("${ChatColor.GREEN}Successfully removed ${item.displayname} from Quick Buy!") + player.sendMessage("${ChatColor.GREEN}Successfully removed ${item.getFriendlyName()} from Quick Buy!") } } @@ -172,11 +174,12 @@ class MainShopGUI(private val player: Player, private val plugin: BedwarsPlugin, return } player.inventory.removeItem(ItemStack(item.costItem.material, item.cost)) - player.sendMessage("${ChatColor.GREEN}You purchased ${ChatColor.GOLD}${item.displayname}!") + player.sendMessage("${ChatColor.GREEN}You purchased ${ChatColor.GOLD}${item.getFriendlyName()}!") val armorType = ArmorType.fromMaterial(item.item.material) ?: return player.inventory.boots = ItemStack(armorType.boots) player.inventory.leggings = ItemStack(armorType.leggings) game.upgradesManager.applyUpgrades(player) + item.commands.map { it.formatAll(player) }.forEach { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), it) } player.playBoughtSound() return } @@ -204,10 +207,11 @@ class MainShopGUI(private val player: Player, private val plugin: BedwarsPlugin, } player.inventory.removeItem(ItemStack(item.costItem.material, item.cost)) val team = plugin.gameManager.getTeamOfPlayer(player) - player.sendMessage("${ChatColor.GREEN}You purchased ${ChatColor.GOLD}${item.displayname}!") + player.sendMessage("${ChatColor.GREEN}You purchased ${ChatColor.GOLD}${item.getFriendlyName()}!") player.giveItem(item.item.toItemStack(team?.color)) - player.playBoughtSound() game.upgradesManager.applyUpgrades(player) + item.commands.map { it.formatAll(player) }.forEach { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), it) } + player.playBoughtSound() } private fun getBuySlots(): List { @@ -231,6 +235,9 @@ class MainShopGUI(private val player: Player, private val plugin: BedwarsPlugin, private fun formatItem(item: MainShopConfigItem, quickBuy: Boolean = false): ItemBuilder { val team = plugin.gameManager.getTeamOfPlayer(player) val itemstack = item.item.toItemStack(team?.color) + if (item.cosmetic) { + return ItemBuilder.from(itemstack) + } val amount = player.getItemAmount(item.costItem.material) val builder: ItemBuilder val loreToAdd = mutableListOf( @@ -266,19 +273,19 @@ class MainShopGUI(private val player: Player, private val plugin: BedwarsPlugin, } builder = if (amount >= item.cost) { ItemBuilder.from(itemstack) - .name("${ChatColor.GREEN}${item.displayname}") + .name("${ChatColor.GREEN}${item.getFriendlyName()}") .lore(loreToAdd) .lore("${ChatColor.YELLOW}Click to purchase!") } else { ItemBuilder.from(itemstack) - .name("${ChatColor.RED}${item.displayname}") + .name("${ChatColor.RED}${item.getFriendlyName()}") .lore(loreToAdd) .lore("${ChatColor.RED}You do not have enough ${item.costItem.color}${item.costItem.displayname}!") } + game.upgradesManager.applyToItem(builder, player) if (getRemainingQuickSlots() < 1) { return builder } - game.upgradesManager.applyToItem(builder, player) return builder.lore("") } @@ -305,6 +312,10 @@ class MainShopGUI(private val player: Player, private val plugin: BedwarsPlugin, if (item.defaultOnSpawn) { continue } + if (item.cosmetic) { + menu.setItem(item.slot, formatItem(item).asNewGuiItem()) + continue + } menu.setItem(item.slot, formatItem(item).asNewGuiItem { if (it.isShiftClick) { if (getBuySlots().none { i -> diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/gui/TrackerGUI.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/gui/TrackerGUI.kt index ce04977..bab589d 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/gui/TrackerGUI.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/gui/TrackerGUI.kt @@ -50,7 +50,7 @@ class TrackerGUI(private val player: Player, private val game: BedwarsGame) { reset() val items = mutableListOf() val hasEnough = player.getItemAmount(Material.EMERALD) >= 2 - for (team in game.beds.filter { (_, active) -> active }.keys + for (team in game.players.keys .filter { game.getTeamOfPlayer(player) != it } .filter { game.trackers[player.uniqueId] != it }) { items.add( diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/BlockBreakListener.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/BlockBreakListener.kt index 58bf4b2..86b53e2 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/BlockBreakListener.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/BlockBreakListener.kt @@ -47,7 +47,9 @@ class BlockBreakListener(private val plugin: BedwarsPlugin) : Listener { if (loc in game.placedBlocks || !plugin.mainConfigManager.get(MainConfigSettings.MAP_PROTECTION)) { val configItem = game.placedBlocks[loc] ?: return isCancelled = true - block.drops.forEach { block.world.dropItem(block.location, it.setConfigItem(configItem)) } + block.drops.forEach { + block.world.dropItem(block.location.toWrapper().getLocation(), it.setConfigItem(configItem)) + } block.type = Material.AIR return } diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/EntityDeathListener.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/EntityDeathListener.kt new file mode 100644 index 0000000..196b945 --- /dev/null +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/EntityDeathListener.kt @@ -0,0 +1,22 @@ +package me.dkim19375.bedwars.plugin.listener + +import me.dkim19375.bedwars.plugin.util.isDropsDisabled +import org.bukkit.entity.Player +import org.bukkit.event.EventHandler +import org.bukkit.event.EventPriority +import org.bukkit.event.Listener +import org.bukkit.event.entity.EntityDeathEvent + +class EntityDeathListener : Listener { + @EventHandler(priority = EventPriority.HIGH) + private fun EntityDeathEvent.onDeath() { + if (entity is Player) { + return + } + if (!entity.isDropsDisabled().first) { + return + } + droppedExp = 0 + drops.clear() + } +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/InventoryClickListener.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/InventoryClickListener.kt index 60fb76d..08de3d2 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/InventoryClickListener.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/InventoryClickListener.kt @@ -21,7 +21,6 @@ package me.dkim19375.bedwars.plugin.listener import me.dkim19375.bedwars.plugin.BedwarsPlugin import me.dkim19375.bedwars.plugin.util.getPlayer import me.dkim19375.bedwars.plugin.util.isArmor -import org.bukkit.Bukkit import org.bukkit.event.EventHandler import org.bukkit.event.Listener import org.bukkit.event.inventory.InventoryClickEvent @@ -41,9 +40,9 @@ class InventoryClickListener(private val plugin: BedwarsPlugin) : Listener { isCancelled = true } } - if (game.eliminated.contains(whoClicked.uniqueId)) { +/* if (game.eliminated.contains(whoClicked.uniqueId)) { Bukkit.broadcastMessage("Cancelled") // isCancelled = true - } + }*/ } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PlayerDeathListener.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PlayerDeathListener.kt index e2fdd6d..ba7e8db 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PlayerDeathListener.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PlayerDeathListener.kt @@ -33,6 +33,8 @@ class PlayerDeathListener(private val plugin: BedwarsPlugin) : Listener { @EventHandler private fun PlayerDeathEvent.onDeath() { val game = plugin.gameManager.getGame(entity) ?: return + game.upgradesManager.magicMilk[entity.uniqueId]?.cancel() + game.upgradesManager.magicMilk.remove(entity.uniqueId) if (game.state !in listOf(GameState.STARTED, GameState.GAME_END)) { return } diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PlayerInteractListener.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PlayerInteractListener.kt index 2567238..12bfc2d 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PlayerInteractListener.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PlayerInteractListener.kt @@ -19,15 +19,15 @@ package me.dkim19375.bedwars.plugin.listener import me.dkim19375.bedwars.api.enumclass.GameState +import me.dkim19375.bedwars.api.enumclass.SpecialItemType import me.dkim19375.bedwars.plugin.BedwarsPlugin +import me.dkim19375.bedwars.plugin.config.MainConfigSettings import me.dkim19375.bedwars.plugin.gui.CompassGUI import me.dkim19375.bedwars.plugin.gui.MainShopGUI import me.dkim19375.bedwars.plugin.gui.TeleporterGUI import me.dkim19375.bedwars.plugin.gui.UpgradeShopGUI import me.dkim19375.bedwars.plugin.manager.BedwarsGame -import me.dkim19375.bedwars.plugin.util.default -import me.dkim19375.bedwars.plugin.util.isBed -import me.dkim19375.bedwars.plugin.util.isHologram +import me.dkim19375.bedwars.plugin.util.* import org.bukkit.Bukkit import org.bukkit.Material import org.bukkit.entity.ArmorStand @@ -39,6 +39,8 @@ import org.bukkit.event.block.Action import org.bukkit.event.player.PlayerInteractAtEntityEvent import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.inventory.ItemStack +import org.bukkit.material.SpawnEgg +import java.util.* class PlayerInteractListener(private val plugin: BedwarsPlugin) : Listener { @EventHandler(priority = EventPriority.HIGHEST) @@ -49,6 +51,52 @@ class PlayerInteractListener(private val plugin: BedwarsPlugin) : Listener { gameOverItems(game) bedPrevention() setupFireballs() + checkSpecialType(SpecialItemType.BED_BUGS, game.bedBugs) + checkSpecialType(SpecialItemType.BRIDGE_EGGS, game.bridgeEggs) + checkDreamDefenders(game) + } + + private fun PlayerInteractEvent.checkSpecialType(type: SpecialItemType, set: MutableSet) { + if (material == Material.AIR) { + return + } + if (action !in setOf(Action.RIGHT_CLICK_AIR, Action.RIGHT_CLICK_BLOCK)) { + return + } + val configItem = item?.getConfigItem() ?: return + if (configItem.specialItem != type) { + return + } + item.type.getProjectileType() ?: return + set.add(player.uniqueId) + } + + private fun PlayerInteractEvent.checkDreamDefenders(game: BedwarsGame) { + if (material == Material.AIR) { + return + } + if (action !in setOf(Action.RIGHT_CLICK_AIR, Action.RIGHT_CLICK_BLOCK)) { + return + } + val configItem = item?.getConfigItem() ?: return + if (configItem.specialItem != SpecialItemType.DREAM_DEFENDER) { + return + } + if (action.name.startsWith("LEFT")) { + return + } + if (item.type != Material.MONSTER_EGG) { + return + } + val block = blockFace?.let { clickedBlock?.getRelative(it) } ?: return + val type = (item.data as? SpawnEgg)?.spawnedType ?: return + isCancelled = true + if (item.amount <= 1) { + item.type = Material.AIR + } else { + item.amount = item.amount - 1 + } + game.createSpecialEntity(block, type, MainConfigSettings.TIME_DREAM_DEFENDER, true, player) } private fun PlayerInteractEvent.checkTracker(game: BedwarsGame) { diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PotionConsumeListener.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PotionConsumeListener.kt index 0aca923..9ea6136 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PotionConsumeListener.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/PotionConsumeListener.kt @@ -18,9 +18,13 @@ package me.dkim19375.bedwars.plugin.listener +import me.dkim19375.bedwars.api.enumclass.SpecialItemType import me.dkim19375.bedwars.plugin.BedwarsPlugin +import me.dkim19375.bedwars.plugin.util.Delay +import me.dkim19375.bedwars.plugin.util.getConfigItem import me.dkim19375.bedwars.plugin.util.toPotion import org.bukkit.Bukkit +import org.bukkit.ChatColor import org.bukkit.Material import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority @@ -32,6 +36,23 @@ import org.bukkit.potion.PotionEffectType class PotionConsumeListener(private val plugin: BedwarsPlugin) : Listener { @EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR) private fun PlayerItemConsumeEvent.onEvent() { + checkPotions() + checkMilk() + } + + private fun PlayerItemConsumeEvent.checkMilk() { + val game = plugin.gameManager.getGame(player) ?: return + val config = item.getConfigItem() ?: return + if (config.specialItem != SpecialItemType.MAGIC_MILK) { + return + } + game.upgradesManager.magicMilk[player.uniqueId] = Bukkit.getScheduler().runTaskLater(plugin, { + game.upgradesManager.magicMilk.remove(player.uniqueId) + player.sendMessage("${ChatColor.RED}Your Magic Milk wore off!") + }, Delay.fromSeconds(30).ticks) + } + + private fun PlayerItemConsumeEvent.checkPotions() { if (item.type != Material.POTION) { return } diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/ProjectileLaunchListener.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/ProjectileLaunchListener.kt index a1c88b7..5c370cb 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/ProjectileLaunchListener.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/listener/ProjectileLaunchListener.kt @@ -18,21 +18,42 @@ package me.dkim19375.bedwars.plugin.listener +import me.dkim19375.bedwars.api.enumclass.Team import me.dkim19375.bedwars.plugin.BedwarsPlugin import me.dkim19375.bedwars.plugin.NEW_SOUND +import me.dkim19375.bedwars.plugin.config.MainConfigSettings +import me.dkim19375.bedwars.plugin.manager.BedwarsGame +import me.dkim19375.dkimbukkitcore.data.toWrapper import me.dkim19375.dkimbukkitcore.function.getPlayers import me.dkim19375.dkimbukkitcore.function.playSound +import org.bukkit.Bukkit +import org.bukkit.Location +import org.bukkit.Material import org.bukkit.Sound +import org.bukkit.block.Block +import org.bukkit.block.BlockFace +import org.bukkit.entity.Entity import org.bukkit.entity.EntityType import org.bukkit.entity.Player +import org.bukkit.entity.Projectile import org.bukkit.event.EventHandler import org.bukkit.event.EventPriority import org.bukkit.event.Listener import org.bukkit.event.entity.ProjectileLaunchEvent +import org.bukkit.scheduler.BukkitRunnable +import java.util.* +import kotlin.math.abs +import kotlin.math.ceil class ProjectileLaunchListener(private val plugin: BedwarsPlugin) : Listener { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) private fun ProjectileLaunchEvent.onLaunch() { + checkPearl() + checkBridgeEgg() + checkBedBugs() + } + + private fun ProjectileLaunchEvent.checkPearl() { if (entity.type != EntityType.ENDER_PEARL) { return } @@ -43,4 +64,95 @@ class ProjectileLaunchListener(private val plugin: BedwarsPlugin) : Listener { it.playSound(sound) } } + + private fun ProjectileLaunchEvent.getSpecialItemTeam(set: (BedwarsGame) -> MutableSet): Pair? { + val player = entity.shooter as? Player ?: return null + val game = plugin.gameManager.getGame(player) ?: return null + val team = game.getTeamOfPlayer(player) ?: return null + if (player.uniqueId !in set(game)) { + return null + } + set(game).remove(player.uniqueId) + return game to team + } + + private fun ProjectileLaunchEvent.checkBridgeEgg() { + val player = entity.shooter as? Player ?: return + val game = plugin.gameManager.getGame(player) ?: return + val result = getSpecialItemTeam(BedwarsGame::bridgeEggs) ?: return + val team = result.second + + @Suppress("DEPRECATION") + val createBridge = create@{ entity: Entity -> + val loc = entity.location.clone() + val block = loc.block + if (block.type != Material.AIR) { + return@create + } + Bukkit.getScheduler().runTaskLater(plugin, { + val playerLocs = player.world.players + .map(Player::getLocation) + .map(Location::getBlock) + .map(Block::getLocation) + val newY = loc.y - 2.0 + val world = block.world + val newX = ceil(loc.x) + val newZ = ceil(loc.z) + val block1 = Location(world, loc.x, newY, newZ).block + val block2 = Location(world, newX, newY, loc.z).block + val block3 = Location(world, newX, newY, newZ).block + val blocks = setOf(block.location.subtract(0.0, 2.0, 0.0).block, block1, block2, block3).filterNot { + playerLocs.contains(it.location) || it.type != Material.AIR + } + for (loopBlock in blocks) { + loopBlock.type = Material.WOOL + loopBlock.data = team.color.data + game.placedBlocks[loopBlock.location.toWrapper()] = + plugin.shopConfigManager.getItemFromMaterial(Material.WOOL) + } + if (blocks.isNotEmpty()) { + player.playSound(if (NEW_SOUND) Sound.valueOf("ENTITY_CHICKEN_EGG") else Sound.CHICKEN_EGG_POP) + } + }, 3L) + } + entity.remove() + @Suppress("UNCHECKED_CAST") + val newEntity = player.launchProjectile(entityType.entityClass as Class) + object : BukkitRunnable() { + private var amount = 0 + override fun run() { + amount++ + if (newEntity.isDead || !newEntity.isValid || newEntity.location.y <= 2.0 || amount >= 40 + || abs(newEntity.velocity.y) >= 1.0 + ) { + newEntity.remove() + cancel() + return + } + createBridge(newEntity) + } + }.runTaskTimer(plugin, 1L, 1L) + } + + private fun ProjectileLaunchEvent.checkBedBugs() { + val player = entity.shooter as? Player ?: return + val result = getSpecialItemTeam(BedwarsGame::bedBugs) ?: return + val game = result.first + object : BukkitRunnable() { + override fun run() { + if (!entity.isDead && entity.isValid) { + return + } + cancel() + val block = entity.location.block.getRelative(BlockFace.UP) + game.createSpecialEntity( + block = block, + type = EntityType.SILVERFISH, + time = MainConfigSettings.TIME_BED_BUG, + showName = false, + player = player + ) + } + }.runTaskTimer(plugin, 1L, 1L) + } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/BedwarsGame.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/BedwarsGame.kt index e626e64..b3f2e0c 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/BedwarsGame.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/BedwarsGame.kt @@ -43,8 +43,13 @@ import me.dkim19375.dkimbukkitcore.function.formatAll import me.dkim19375.dkimbukkitcore.function.getPlayers import me.dkim19375.dkimbukkitcore.function.logInfo import me.dkim19375.dkimcore.extension.runCatchingOrNull +import me.dkim19375.dkimcore.extension.setDecimalPlaces +import me.mattstudios.config.properties.Property import org.apache.commons.io.FileUtils import org.bukkit.* +import org.bukkit.block.Block +import org.bukkit.entity.Creature +import org.bukkit.entity.EntityType import org.bukkit.entity.Item import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack @@ -77,6 +82,8 @@ class BedwarsGame(private val plugin: BedwarsPlugin, data: GameData) { val kills = mutableMapOf() val trackers = mutableMapOf() val spectators = mutableSetOf() + val bridgeEggs = mutableSetOf() + val bedBugs = mutableSetOf() var data = data private set @@ -531,32 +538,29 @@ class BedwarsGame(private val plugin: BedwarsPlugin, data: GameData) { fun giveItems(player: Player, items: List?, team: Team) { val configManager = plugin.shopConfigManager var armorType: ArmorType = ArmorType.LEATHER - var addPick = false - var addAxe = false - var addShears = false + val keepItems = mutableSetOf() player.inventory.clearAll() + for (item in configManager.mainItems.filter(MainShopConfigItem::defaultOnSpawn)) { + if (item.item.material.isArmor()) { + continue + } + keepItems.add(item) + } items?.forEach { item -> item ?: return@forEach - if (item.type.name.endsWith("PICKAXE")) { - addPick = true - return@forEach - } - if (item.type.name.endsWith("AXE")) { - addAxe = true - return@forEach + val config = item.getConfigItem() + val downgrade = config?.downgrade?.invoke() + if (downgrade != null && !downgrade.defaultOnSpawn) { + keepItems.add(downgrade) } - if (item.type == Material.SHEARS) { - addShears = true - return@forEach + if (config?.permanent == true && !config.defaultOnSpawn) { + keepItems.add(config) } val armor = ArmorType.fromMaterial(item.type) ?: return@forEach if (armor != ArmorType.LEATHER) { armorType = armor } } - configManager.getItemFromMaterial(Material.WOOD_SWORD)?.item?.toItemStack(team.color)?.let { - player.inventory.addItem(it) - } player.inventory.setItem( 17, ItemBuilder.from(Material.COMPASS) .name("${ChatColor.GREEN}Compass ${ChatColor.GRAY}(Right Click)") @@ -567,20 +571,8 @@ class BedwarsGame(private val plugin: BedwarsPlugin, data: GameData) { player.inventory.chestplate = team.getColored(ItemStack(Material.LEATHER_CHESTPLATE)) player.inventory.leggings = team.getColored(ItemStack(armorType.leggings)) player.inventory.boots = team.getColored(ItemStack(armorType.boots)) - if (addPick) { - configManager.getItemFromMaterial(Material.WOOD_PICKAXE)?.item?.toItemStack(team.color)?.let { - player.inventory.addItem(it) - } - } - if (addAxe) { - configManager.getItemFromMaterial(Material.WOOD_AXE)?.item?.toItemStack(team.color)?.let { - player.inventory.addItem(it) - } - } - if (addShears) { - configManager.getItemFromMaterial(Material.SHEARS)?.item?.toItemStack(team.color)?.let { - player.inventory.addItem(it) - } + for (item in keepItems) { + player.inventory.addItem(item.item.toItemStack(team.color)) } upgradesManager.applyUpgrades(player) } @@ -785,4 +777,65 @@ class BedwarsGame(private val plugin: BedwarsPlugin, data: GameData) { ) update() } + + fun createSpecialEntity( + block: Block, + type: EntityType, + time: Property, + showName: Boolean, + player: Player, + ) { + val entity = block.world.spawn(block.location, type.entityClass).disableDrops().let { + if (it !is Creature) { + return@createSpecialEntity + } + it + } + entity.isCustomNameVisible = showName + val totalTime = plugin.mainConfigManager.get(time) * 50 + val totalTimeSeconds = (totalTime.toDouble() / 1000.0).let { + it.setDecimalPlaces(if (it.toString().split('.')[1].length >= 2) 2 else 1) + } + player.sendMessage("${ChatColor.GREEN}Your creature will fight for you for $totalTimeSeconds seconds") + val start = System.currentTimeMillis() + object : BukkitRunnable() { + override fun run() { + if (entity.isDead || !entity.isValid) { + cancel() + return + } + val remainingTime = (((start + totalTime) - System.currentTimeMillis()).toDouble() / 1_000.0) + .setDecimalPlaces(1) + if (remainingTime <= 0.0) { + entity.remove() + cancel() + return + } + if (showName) { + entity.customName = "${remainingTime}s ${ChatColor.DARK_GRAY}[${ + getProgressBar( + current = entity.health.toInt(), + max = entity.maxHealth.toInt(), + totalBars = 10, + symbol = '■', + completedColor = ChatColor.WHITE, + notCompletedColor = ChatColor.GRAY + ) + }${ChatColor.DARK_GRAY}]" + } + val team = getTeamOfPlayer(player) ?: return + if (entity.target?.uniqueId != player.uniqueId) { + return + } + var newPlayer: Pair? = null + for (nonTeamPlayer in getPlayersInGame().minus(getPlayersInTeam(team)).getPlayers()) { + val distance = entity.location.distance(nonTeamPlayer.location) + if (newPlayer == null || newPlayer.second > distance) { + newPlayer = nonTeamPlayer to distance + } + } + entity.target = newPlayer?.first + } + }.runTaskTimer(plugin, 1L, 1L) + } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/DataFileManager.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/DataFileManager.kt index 9059a30..fc619c6 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/DataFileManager.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/DataFileManager.kt @@ -66,7 +66,7 @@ class DataFileManager(private val plugin: BedwarsPlugin) { removeGameData(data) val newData = JsonFile( type = GameData::class, - fileName = File(plugin.dataFolder, "data/games/${data.world.name}.json").path, + file = File(plugin.dataFolder, "data/games/${data.world.name}.json"), prettyPrinting = true, typeAdapters = plugin.jsonSerializers, default = { data } diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/UpgradesManager.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/UpgradesManager.kt index dff9b24..fad1ae0 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/UpgradesManager.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/manager/UpgradesManager.kt @@ -32,6 +32,7 @@ import org.bukkit.enchantments.Enchantment import org.bukkit.entity.Player import org.bukkit.potion.PotionEffect import org.bukkit.potion.PotionEffectType +import org.bukkit.scheduler.BukkitTask import java.util.* @Suppress("MemberVisibilityCanBePrivate") @@ -44,6 +45,7 @@ class UpgradesManager(private val plugin: BedwarsPlugin, private val game: Bedwa val secondTrap = mutableMapOf() val thirdTrap = mutableMapOf() private val times = mutableMapOf() + val magicMilk = mutableMapOf() fun reset() { sharpness.clear() @@ -70,19 +72,25 @@ class UpgradesManager(private val plugin: BedwarsPlugin, private val game: Bedwa } private fun applyHaste(player: Player) { + player.removePotionEffect(PotionEffectType.FAST_DIGGING) val team = game.getTeamOfPlayer(player) ?: return val haste = haste[team] ?: return player.addPotionEffect(PotionEffect(PotionEffectType.FAST_DIGGING, 120, haste - 1)) } private fun applyHealPool(player: Player) { + player.removePotionEffect(PotionEffectType.REGENERATION) val team = game.getTeamOfPlayer(player) ?: return if (!healPool.contains(team)) { return } - game.data.beds.firstOrNull { d -> - team == d.team && d.location.getSafeDistance(player.location) < 7 - } ?: return + if (game.data.beds.none { d -> + team == d.team && d.location.getSafeDistance(player.location, true) < 7 + } && game.data.teams.none { d -> + team == d.team && d.location.getSafeDistance(player.location, true) < 10 + }) { + return + } player.addPotionEffect(PotionEffect(PotionEffectType.REGENERATION, 120, 0)) } @@ -149,6 +157,10 @@ class UpgradesManager(private val plugin: BedwarsPlugin, private val game: Bedwa teamOfPlayer != d.team d.location.getSafeDistance(player.location) < 8 } ?: return + times[player.uniqueId] = System.currentTimeMillis() + if (magicMilk.containsKey(player.uniqueId)) { + return + } val team = bedData.team val trap = firstTrap[team] ?: return firstTrap.remove(team) @@ -162,9 +174,6 @@ class UpgradesManager(private val plugin: BedwarsPlugin, private val game: Bedwa this.secondTrap[team] = thirdTrap this.thirdTrap.remove(team) } - - // on trigger - times[player.uniqueId] = System.currentTimeMillis() applyToPlayer(player, trap) for (uuid in game.getPlayersInTeam(team)) { val p = Bukkit.getPlayer(uuid) ?: continue diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/BukkitFunctions.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/BukkitFunctions.kt index 1422e77..a9542e8 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/BukkitFunctions.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/BukkitFunctions.kt @@ -29,6 +29,7 @@ import org.bukkit.* import org.bukkit.block.Block import org.bukkit.configuration.ConfigurationSection import org.bukkit.entity.Entity +import org.bukkit.entity.EntityType import org.bukkit.entity.Item import org.bukkit.entity.Player import org.bukkit.event.inventory.InventoryClickEvent @@ -37,6 +38,7 @@ import org.bukkit.inventory.ItemStack import org.bukkit.inventory.PlayerInventory import org.bukkit.inventory.meta.ItemMeta import org.bukkit.material.Bed +import org.bukkit.material.SpawnEgg import org.bukkit.plugin.java.JavaPlugin import org.bukkit.potion.Potion import java.util.* @@ -135,18 +137,17 @@ fun ItemStack.toPotion(): Potion? = try { fun ItemStack.getWrapper(potionDuration: Int = 900, configItem: String? = null): ItemWrapper { val potion = toPotion() - if (potion != null) { - return ItemWrapper( - material = type, - amount = amount, - potionType = potion.type, - configItem = configItem, - potionAmplifier = potion.level + 1, - potionDuration = potionDuration, - enchants = enchantments.toMap() - ) - } - return ItemWrapper(type, amount, null, configItem, 1, potionDuration, enchantments.toMap()) + return ItemWrapper( + material = type, + amount = amount, + potionType = potion?.type, + configItem = configItem, + potionAmplifier = potion?.level?.plus(1) ?: 1, + potionDuration = potionDuration, + enchants = enchantments.toMap(), + lore = itemMeta?.lore, + mobType = (data as? SpawnEgg)?.spawnedType + ) } fun Material.isTool() = when (this) { @@ -184,7 +185,7 @@ fun Location.getOppositeYaw(): Location { fun Location.update(): Location = Location(Bukkit.getWorld(world?.name), x, y, z, yaw, pitch) -fun Location?.getSafeDistance(other: Location?): Double { +fun Location?.getSafeDistance(other: Location?, ignoreHeight: Boolean = false): Double { this ?: return Double.MAX_VALUE other ?: return Double.MAX_VALUE if (world.name != other.world.name) { @@ -193,9 +194,15 @@ fun Location?.getSafeDistance(other: Location?): Double { return try { distance( if (world.uid != other.world.uid) { - Location(world, other.x, other.y, other.z, other.yaw, other.pitch) + Location(world, other.x, if (ignoreHeight) y else other.y, other.z, other.yaw, other.pitch) } else { - other + if (ignoreHeight) { + other.clone().apply { + y = this@getSafeDistance.y + } + } else { + other + } } ) } catch (_: IllegalArgumentException) { @@ -252,4 +259,17 @@ fun checkAsync(reason: String) { if (!Bukkit.isPrimaryThread()) { throw IllegalStateException("Asynchronous $reason! (Bedwars)") } +} + +fun ConfigurationSection.getStringListOrNull(path: String): List? { + if (!isSet(path)) { + return null + } + return getStringList(path) +} + +fun Material.getProjectileType(): EntityType? = when (this) { + Material.EGG -> EntityType.EGG + Material.SNOW_BALL -> EntityType.SNOWBALL + else -> null } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/EntityFunctions.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/EntityFunctions.kt index 97aa9f4..f4145f7 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/EntityFunctions.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/EntityFunctions.kt @@ -174,7 +174,7 @@ fun Player.sendOtherTitle( subtitle: String? = null, fadeIn: Int = 10, stay: Int = 50, - fadeOut: Int = 10 + fadeOut: Int = 10, ) = sendTitle(title, subtitle, fadeIn, stay, fadeOut) fun Player.sendTitle( @@ -182,7 +182,7 @@ fun Player.sendTitle( subtitle: String? = null, fadeIn: Int = 10, stay: Int = 50, - fadeOut: Int = 10 + fadeOut: Int = 10, ) = BukkitAudiences.create(JavaPlugin.getPlugin(BedwarsPlugin::class.java)).player(this).showTitle( Title.title( LegacyComponentSerializer.legacySection().deserialize(title ?: ""), @@ -192,7 +192,7 @@ fun Player.sendTitle( ) private fun T.getTarget( - entities: Iterable + entities: Iterable, ): T? { var target: T? = null val threshold = 1.0 @@ -217,9 +217,9 @@ private fun T.getTarget( } fun ItemStack.getNewItem(player: Player?): ItemStack { - player ?: return clone() - val configItem = getConfigItem() ?: return clone() - var newItem: ItemStack = clone() + player ?: return this + val configItem = getConfigItem() ?: return this + var newItem: ItemStack = this player.inventory.contents.forEach contentLoop@{ invItem -> invItem ?: return@contentLoop val invConfigItem = invItem.getConfigItem() ?: return@contentLoop @@ -232,11 +232,9 @@ fun ItemStack.getNewItem(player: Player?): ItemStack { return newItem } -fun Player.giveItem(vararg items: ItemStack?) { - for (item in items) { - item?.getNewItem(this)?.let { inventory.addItem(it) } - } -} +fun Player.giveItem(vararg items: ItemStack?): Map = inventory.addItem(*items.mapNotNull { + it?.getNewItem(this) +}.toTypedArray()) fun Entity.teleportUpdated(location: Location): Boolean = teleport(location.update()) diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/NBTFunctions.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/NBTFunctions.kt index ddd0290..aa5fdc7 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/NBTFunctions.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/NBTFunctions.kt @@ -24,6 +24,7 @@ import me.dkim19375.bedwars.compat.abstract.NBTUtilitiesAbstract import me.dkim19375.bedwars.plugin.BedwarsPlugin import me.dkim19375.bedwars.plugin.data.MainShopConfigItem import org.bukkit.entity.ArmorStand +import org.bukkit.entity.Entity import org.bukkit.entity.Item import org.bukkit.entity.LivingEntity import org.bukkit.inventory.ItemStack @@ -57,4 +58,8 @@ fun ItemStack.setUnbreakable(unbreakable: Boolean): ItemStack = nbtUtils.setUnbr fun Item.setDrop(drop: Boolean): Item = nbtUtils.setDrop(this, drop) -fun Item.isDrop(): Pair = nbtUtils.isDrop(this) \ No newline at end of file +fun Item.isDrop(): Pair = nbtUtils.isDrop(this) + +fun T.disableDrops(): T = nbtUtils.disableDrops(this) + +fun T.isDropsDisabled(): Pair = nbtUtils.isDropsDisabled(this) \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/OtherFunctions.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/OtherFunctions.kt index 3f8f843..cf31971 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/OtherFunctions.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/OtherFunctions.kt @@ -25,7 +25,7 @@ fun T?.default(default: T): T { inline fun > enumValueOfOrNull(name: String?): T? = name?.let { try { enumValueOf(it.uppercase()) - } catch (e: Throwable) { + } catch (e: IllegalArgumentException) { null } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/StringFunctions.kt b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/StringFunctions.kt index 4bae539..4cb029a 100644 --- a/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/StringFunctions.kt +++ b/plugin/src/main/kotlin/me/dkim19375/bedwars/plugin/util/StringFunctions.kt @@ -33,4 +33,17 @@ fun String.toComponent(): TextComponent = LegacyComponentSerializer.legacySectio fun List.toComponents(): List = map(String::toComponent) -fun Array.toComponents(): Array = map(String::toComponent).toTypedArray() \ No newline at end of file +fun Array.toComponents(): Array = map(String::toComponent).toTypedArray() + +fun getProgressBar( + current: Int, + max: Int, + totalBars: Int, + symbol: Char, + completedColor: ChatColor, + notCompletedColor: ChatColor, +): String { + val percent = current.toDouble() / max + val progressBars = (totalBars * percent).toInt() + return "${("$completedColor$symbol").repeat(progressBars)}${("$notCompletedColor$symbol").repeat(totalBars - progressBars)}" +} \ No newline at end of file diff --git a/plugin/src/main/resources/shop.yml b/plugin/src/main/resources/shop.yml index bffd0c9..91e4951 100644 --- a/plugin/src/main/resources/shop.yml +++ b/plugin/src/main/resources/shop.yml @@ -1,26 +1,4 @@ -# EXAMPLE ITEM -# -# example-item: -# -# row: 1 -# column: 2 -# OR -# slot: 1 (starts at 0) -# -# material: 'POTION' -# amount: 2 -# potion-type: 'STRENGTH' (Only needed if "material" is POTION) -# potion-amplifier: 2 (Only needed if "material" is POTION) -# potion-duration: 600 (in TICKS (20 ticks per second, only needed if "material" is POTION) -# enchants: (Optional) -# - 'DAMAGE_ALL' -# - 'KNOCKBACK:2' (Knockback level 2) -# cost: 10 -# cost-item: 'IRON' (Item category: IRON, GOLD, EMERALD) -# display-name: 'Damage Potion' (Optional) -# permanent: false (Optional, if true, then you will keep it when you die) -# default-on-spawn: false (Optional, if true, then you will get it when you spawn) -# item-category: 'POTIONS' (Shop category: BLOCKS, MELEE, ARMOR, TOOLS, RANGED, POTIONS, UTILITY) +# Please view https://github.com/dkim19375/Bedwars/wiki/Configuration for how to configure this! wool: slot: 19 @@ -28,7 +6,7 @@ wool: amount: 16 cost: 4 cost-item: 'IRON' - display-name: 'Wool' + name: 'Wool' item-category: 'BLOCKS' hardened-clay: @@ -37,7 +15,7 @@ hardened-clay: amount: 16 cost: 12 cost-item: 'IRON' - display-name: 'Clay' + name: 'Clay' item-category: 'BLOCKS' blast-proof-glass: @@ -46,7 +24,7 @@ blast-proof-glass: amount: 4 cost: 12 cost-item: 'IRON' - display-name: 'Blast Proof Glass' + name: 'Blast Proof Glass' item-category: 'BLOCKS' end-stone: @@ -55,7 +33,7 @@ end-stone: amount: 12 cost: 24 cost-item: 'IRON' - display-name: 'Endstone' + name: 'Endstone' item-category: 'BLOCKS' ladder: @@ -64,7 +42,7 @@ ladder: amount: 16 cost: 12 cost-item: 'IRON' - display-name: 'Ladder' + name: 'Ladder' item-category: 'BLOCKS' wood: @@ -73,7 +51,7 @@ wood: amount: 16 cost: 4 cost-item: 'GOLD' - display-name: 'Wood' + name: 'Wood' item-category: 'BLOCKS' obsidian: @@ -82,7 +60,7 @@ obsidian: amount: 4 cost: 4 cost-item: 'EMERALD' - display-name: 'Obsidian' + name: 'Obsidian' item-category: 'BLOCKS' wood-sword: @@ -91,7 +69,7 @@ wood-sword: amount: 1 cost: 0 cost-item: 'IRON' - display-name: 'Wooden Sword' + name: 'Wooden Sword' permanent: true default-on-spawn: true item-category: 'MELEE' @@ -102,7 +80,7 @@ stone-sword: amount: 1 cost: 10 cost-item: 'IRON' - display-name: 'Stone Sword' + name: 'Stone Sword' item-category: 'MELEE' iron-sword: @@ -111,7 +89,7 @@ iron-sword: amount: 1 cost: 7 cost-item: 'GOLD' - display-name: 'Iron Sword' + name: 'Iron Sword' item-category: 'MELEE' diamond-sword: @@ -120,7 +98,7 @@ diamond-sword: amount: 1 cost: 4 cost-item: 'EMERALD' - display-name: 'Diamond Sword' + name: 'Diamond Sword' item-category: 'MELEE' knockback-stick: @@ -131,7 +109,7 @@ knockback-stick: - 'KNOCKBACK' cost: 5 cost-item: 'GOLD' - display-name: 'Stick (Knockback I)' + name: 'Stick (Knockback I)' item-category: 'MELEE' leather-armor: @@ -140,7 +118,7 @@ leather-armor: amount: 1 cost: 0 cost-item: 'IRON' - display-name: 'Leather Armor' + name: 'Leather Armor' permanent: true default-on-spawn: true item-category: 'ARMOR' @@ -151,7 +129,7 @@ chain-armor: amount: 1 cost: 40 cost-item: 'IRON' - display-name: 'Chainmail Armor' + name: 'Chainmail Armor' permanent: true item-category: 'ARMOR' @@ -161,7 +139,7 @@ iron-armor: amount: 1 cost: 12 cost-item: 'GOLD' - display-name: 'Iron Armor' + name: 'Iron Armor' permanent: true item-category: 'ARMOR' @@ -171,7 +149,7 @@ diamond-armor: amount: 1 cost: 6 cost-item: 'EMERALD' - display-name: 'Diamond Armor' + name: 'Diamond Armor' permanent: true item-category: 'ARMOR' @@ -181,7 +159,7 @@ shears: amount: 1 cost: 20 cost-item: 'IRON' - display-name: 'Shears' + name: 'Shears' permanent: true item-category: 'TOOLS' @@ -191,7 +169,7 @@ wooden-pickaxe: amount: 1 cost: 8 cost-item: 'IRON' - display-name: 'Wooden Pickaxe' + name: 'Wooden Pickaxe' permanent: true item-category: 'TOOLS' @@ -203,8 +181,9 @@ stone-pickaxe: - 'DIG_SPEED' cost: 15 cost-item: 'IRON' - display-name: 'Stone Pickaxe' + name: 'Stone Pickaxe' item-category: 'TOOLS' + downgrade: 'wooden-pickaxe' iron-pickaxe: slot: 22 @@ -214,8 +193,9 @@ iron-pickaxe: - 'DIG_SPEED:2' cost: 4 cost-item: 'GOLD' - display-name: 'Iron Pickaxe' + name: 'Iron Pickaxe' item-category: 'TOOLS' + downgrade: 'stone-pickaxe' gold-pickaxe: slot: 23 @@ -225,8 +205,9 @@ gold-pickaxe: - 'DIG_SPEED:3' cost: 3 cost-item: 'GOLD' - display-name: 'Gold Pickaxe' + name: 'Gold Pickaxe' item-category: 'TOOLS' + downgrade: 'iron-pickaxe' diamond-pickaxe: slot: 24 @@ -236,8 +217,9 @@ diamond-pickaxe: - 'DIG_SPEED:3' cost: 8 cost-item: 'GOLD' - display-name: 'Diamond Pickaxe' + name: 'Diamond Pickaxe' item-category: 'TOOLS' + downgrade: 'gold-pickaxe' wood-axe: slot: 25 @@ -245,7 +227,7 @@ wood-axe: amount: 1 cost: 8 cost-item: 'IRON' - display-name: 'Wooden Axe' + name: 'Wooden Axe' permanent: true item-category: 'TOOLS' @@ -257,8 +239,9 @@ stone-axe: - 'DIG_SPEED' cost: 15 cost-item: 'IRON' - display-name: 'Stone Axe' + name: 'Stone Axe' item-category: 'TOOLS' + downgrade: 'wood-axe' iron-axe: slot: 29 @@ -268,8 +251,9 @@ iron-axe: - 'DIG_SPEED:2' cost: 4 cost-item: 'GOLD' - display-name: 'Iron Axe' + name: 'Iron Axe' item-category: 'TOOLS' + downgrade: 'stone-axe' gold-axe: slot: 30 @@ -279,8 +263,9 @@ gold-axe: - 'DIG_SPEED:3' cost: 3 cost-item: 'GOLD' - display-name: 'Gold Axe' + name: 'Gold Axe' item-category: 'TOOLS' + downgrade: 'iron-axe' diamond-axe: slot: 31 @@ -290,8 +275,9 @@ diamond-axe: - 'DIG_SPEED:3' cost: 8 cost-item: 'GOLD' - display-name: 'Diamond Axe' + name: 'Diamond Axe' item-category: 'TOOLS' + downgrade: 'gold-axe' arrow: slot: 19 @@ -299,7 +285,7 @@ arrow: amount: 8 cost: 2 cost-item: 'GOLD' - display-name: 'Arrow' + name: 'Arrow' item-category: 'RANGED' bow: @@ -308,7 +294,7 @@ bow: amount: 1 cost: 12 cost-item: 'GOLD' - display-name: 'Bow' + name: 'Bow' item-category: 'RANGED' power-bow: @@ -319,7 +305,7 @@ power-bow: - 'ARROW_DAMAGE' cost: 24 cost-item: 'GOLD' - display-name: 'Bow (Power I)' + name: 'Bow (Power I)' item-category: 'RANGED' punch-bow: @@ -331,7 +317,7 @@ punch-bow: - 'ARROW_KNOCKBACK' cost: 6 cost-item: 'EMERALD' - display-name: 'Bow (Power I, Punch I)' + name: 'Bow (Power I, Punch I)' item-category: 'RANGED' speed: @@ -343,7 +329,7 @@ speed: potion-duration: 900 cost: 1 cost-item: 'EMERALD' - display-name: 'Speed II Potion' + name: 'Speed II Potion' item-category: 'POTIONS' jump: @@ -355,7 +341,7 @@ jump: potion-duration: 900 cost: 1 cost-item: 'EMERALD' - display-name: 'Jump V Potion' + name: 'Jump V Potion' item-category: 'POTIONS' invisibility: @@ -367,7 +353,7 @@ invisibility: potion-duration: 600 cost: 2 cost-item: 'EMERALD' - display-name: 'Invisibility Potion' + name: 'Invisibility Potion' item-category: 'POTIONS' golden-apple: @@ -376,41 +362,92 @@ golden-apple: amount: 1 cost: 3 cost-item: 'GOLD' - display-name: 'Golden Apple' + name: 'Golden Apple' item-category: 'UTILITY' -fireball: +bed-bugs: slot: 20 + material: 'SNOW_BALL' + amount: 1 + cost: 40 + cost-item: 'IRON' + name: 'Bed Bug' + item-category: 'UTILITY' + special-type: 'BED_BUGS' + mob-type: 'SILVERFISH' + +dream-defender: + slot: 21 + material: 'MONSTER_EGG' + amount: 1 + cost: 120 + cost-item: 'IRON' + name: 'Dream Defender' + item-category: 'UTILITY' + special-type: 'DREAM_DEFENDER' + mob-type: 'IRON_GOLEM' + +fireball: + slot: 22 material: 'FIREBALL' amount: 1 cost: 40 cost-item: 'IRON' - display-name: 'Fireball' + name: 'Fireball' item-category: 'UTILITY' TNT: - slot: 21 + slot: 23 material: 'TNT' amount: 1 cost: 4 cost-item: 'GOLD' - display-name: 'TNT' + name: 'TNT' item-category: 'UTILITY' pearl: - slot: 22 + slot: 24 material: 'ENDER_PEARL' amount: 1 cost: 4 cost-item: 'EMERALD' - display-name: 'Ender Pearl' + name: 'Ender Pearl' item-category: 'UTILITY' water-bucket: - slot: 23 + slot: 25 material: 'WATER_BUCKET' amount: 1 cost: 1 cost-item: 'EMERALD' - display-name: 'Water Bucket' + name: 'Water Bucket' + item-category: 'UTILITY' + +bridge-egg: + slot: 28 + material: 'EGG' + amount: 1 + cost: 1 + cost-item: 'EMERALD' + name: 'Bridge Egg' + item-category: 'UTILITY' + special-type: 'BRIDGE_EGGS' + +magic-milk: + slot: 29 + material: 'MILK_BUCKET' + amount: 1 + cost: 4 + cost-item: 'GOLD' + name: 'Magic Milk' + item-category: 'UTILITY' + special-type: 'MAGIC_MILK' + +sponge: + slot: 30 + mateiral: 'SPONGE' + amount: 4 + cost: 3 + cost-item: 'GOLD' + name: 'Sponge' item-category: 'UTILITY' \ No newline at end of file diff --git a/v1_16/src/main/kotlin/me/dkim19375/bedwars/v1_16/NBTUtilities.kt b/v1_16/src/main/kotlin/me/dkim19375/bedwars/v1_16/NBTUtilities.kt index 0a21cdc..ee5cbca 100644 --- a/v1_16/src/main/kotlin/me/dkim19375/bedwars/v1_16/NBTUtilities.kt +++ b/v1_16/src/main/kotlin/me/dkim19375/bedwars/v1_16/NBTUtilities.kt @@ -21,9 +21,11 @@ package me.dkim19375.bedwars.v1_16 import me.dkim19375.bedwars.compat.abstract.NBTUtilitiesAbstract import org.bukkit.NamespacedKey import org.bukkit.entity.ArmorStand +import org.bukkit.entity.Entity import org.bukkit.entity.Item import org.bukkit.entity.LivingEntity import org.bukkit.inventory.ItemStack +import org.bukkit.persistence.PersistentDataHolder import org.bukkit.persistence.PersistentDataType import org.bukkit.plugin.java.JavaPlugin @@ -32,13 +34,25 @@ class NBTUtilities(plugin: JavaPlugin) : NBTUtilitiesAbstract() { private val CONFIG_ITEM_NS_KEY = NamespacedKey(plugin, CONFIG_ITEM_KEY) private val HOLOGRAM_NS_KEY = NamespacedKey(plugin, HOLOGRAM_KEY) + private val MOB_DROP_NS_KEY = NamespacedKey(plugin, MOB_DROP_KEY) + private val GEN_DROP_NS_KEY = NamespacedKey(plugin, GEN_DROP_KEY) private val TRACKER_NS_KEY = NamespacedKey(plugin, TRACKER_KEY) - private val DROP_NS_KEY = NamespacedKey(plugin, DROP_KEY) private val PDT_STRING: PersistentDataType get() = PersistentDataType.STRING private val PDT_BYTE: PersistentDataType get() = PersistentDataType.BYTE + private fun T.modifyByte(key: NamespacedKey, add: Boolean = true): T = apply { + if (add) { + persistentDataContainer.set(key, PDT_BYTE, 0) + } else { + persistentDataContainer.remove(key) + } + } + + private fun T.hasKey(key: NamespacedKey): Pair = + persistentDataContainer.keys.contains(key) to this + override fun addAI(entity: T): Unit = entity.setAI(true) override fun removeAI(entity: T): Unit = entity.setAI(false) @@ -54,32 +68,19 @@ class NBTUtilities(plugin: JavaPlugin) : NBTUtilitiesAbstract() { override fun getConfigItem(item: ItemStack): String? = item.itemMeta?.persistentDataContainer?.get(CONFIG_ITEM_NS_KEY, PDT_STRING) - override fun isHologram(armorStand: ArmorStand): Boolean = - armorStand.persistentDataContainer.keys.contains(HOLOGRAM_NS_KEY) + override fun isHologram(armorStand: ArmorStand): Boolean = armorStand.hasKey(HOLOGRAM_NS_KEY).first - override fun setHologramNBT(armorStand: ArmorStand, holo: Boolean): ArmorStand { - if (holo) { - armorStand.persistentDataContainer.set(HOLOGRAM_NS_KEY, PDT_BYTE, 0) - } else { - armorStand.persistentDataContainer.remove(HOLOGRAM_NS_KEY) - } - return armorStand - } + override fun setHologramNBT(armorStand: ArmorStand, holo: Boolean): ArmorStand = armorStand.modifyByte(HOLOGRAM_NS_KEY, holo) override fun setUnbreakable(item: ItemStack, unbreakable: Boolean): ItemStack = item.apply { itemMeta = itemMeta?.apply { isUnbreakable = true } } - override fun setDrop(item: Item, drop: Boolean): Item { - if (drop) { - item.persistentDataContainer.set(HOLOGRAM_NS_KEY, PDT_BYTE, 0) - } else { - item.persistentDataContainer.remove(DROP_NS_KEY) - } - return item - } + override fun setDrop(item: Item, drop: Boolean): Item = item.modifyByte(GEN_DROP_NS_KEY, drop) - override fun isDrop(item: Item): Pair = item.let { - it.persistentDataContainer.keys.contains(DROP_NS_KEY) to it - } + override fun isDrop(item: Item): Pair = item.hasKey(GEN_DROP_NS_KEY) + + override fun disableDrops(entity: T): T = entity.modifyByte(MOB_DROP_NS_KEY) + + override fun isDropsDisabled(entity: T): Pair = entity.hasKey(MOB_DROP_NS_KEY) } \ No newline at end of file diff --git a/v1_8/src/main/kotlin/me/dkim19375/bedwars/v1_8/NBTUtilities.kt b/v1_8/src/main/kotlin/me/dkim19375/bedwars/v1_8/NBTUtilities.kt index 0aa0ef6..47c7127 100644 --- a/v1_8/src/main/kotlin/me/dkim19375/bedwars/v1_8/NBTUtilities.kt +++ b/v1_8/src/main/kotlin/me/dkim19375/bedwars/v1_8/NBTUtilities.kt @@ -38,6 +38,22 @@ class NBTUtilities : NBTUtilitiesAbstract() { return patched to NBTInjector.getNbtData(patched) } + private fun T.modifyByte(key: String, add: Boolean = true): T = if (add) { + getNBT().let { + it.second.setByte(key, 0) + it.first + } + } else { + getNBT().let { + it.second.removeKey(key) + it.first + } + } + + private fun T.hasByte(key: String): Pair = getNBT().let { + it.second.keys.contains(key) to it.first + } + private fun NBTCompound.getStringOrNull(key: String): String? = if (keys.contains(key)) getString(key) else null private fun T.getVanillaNBT(): NBTCompound = NBTEntity(this) @@ -55,36 +71,19 @@ class NBTUtilities : NBTUtilitiesAbstract() { override fun getConfigItem(item: ItemStack): String? = item.getNBT().getStringOrNull(CONFIG_ITEM_KEY) - override fun isHologram(armorStand: ArmorStand): Boolean = armorStand.getNBT().second.keys.contains(HOLOGRAM_KEY) + override fun isHologram(armorStand: ArmorStand): Boolean = armorStand.hasByte(HOLOGRAM_KEY).first - override fun setHologramNBT(armorStand: ArmorStand, holo: Boolean): ArmorStand = if (holo) { - armorStand.getNBT().let { - it.second.setByte(HOLOGRAM_KEY, 0) - it.first - } - } else { - armorStand.getNBT().let { - it.second.removeKey(HOLOGRAM_KEY) - it.first - } - } + override fun setHologramNBT(armorStand: ArmorStand, holo: Boolean): ArmorStand = + armorStand.modifyByte(HOLOGRAM_KEY, holo) override fun setUnbreakable(item: ItemStack, unbreakable: Boolean): ItemStack = item.getNBT().apply { setInteger("Unbreakable", if (unbreakable) 1 else 0) }.item - override fun setDrop(item: Item, drop: Boolean): Item = if (drop) { - item.getNBT().let { - it.second.setByte(DROP_KEY, 0) - it.first - } - } else { - item.getNBT().let { - it.second.removeKey(DROP_KEY) - it.first - } - } + override fun setDrop(item: Item, drop: Boolean): Item = item.modifyByte(GEN_DROP_KEY, drop) - override fun isDrop(item: Item): Pair = item.getNBT().let { - it.second.keys.contains(DROP_KEY) to it.first - } + override fun isDrop(item: Item): Pair = item.hasByte(GEN_DROP_KEY) + + override fun disableDrops(entity: T): T = entity.modifyByte(MOB_DROP_KEY) + + override fun isDropsDisabled(entity: T): Pair = entity.hasByte(MOB_DROP_KEY) } \ No newline at end of file