diff --git a/src/main/kotlin/com/pobnellion/pobutils/Pobutils.kt b/src/main/kotlin/com/pobnellion/pobutils/Pobutils.kt index 2bf1062..d413c5e 100644 --- a/src/main/kotlin/com/pobnellion/pobutils/Pobutils.kt +++ b/src/main/kotlin/com/pobnellion/pobutils/Pobutils.kt @@ -9,6 +9,7 @@ import com.pobnellion.pobutils.modules.hub.Hub import com.pobnellion.pobutils.modules.noJoinMessage.NoJoinMessage import com.pobnellion.pobutils.modules.portals.Portals import com.pobnellion.pobutils.modules.sit.Sit +import com.pobnellion.pobutils.modules.snowballDamage.SnowballDamage import com.pobnellion.pobutils.modules.spawn.Spawn import com.pobnellion.pobutils.modules.warp.Warp import org.bukkit.plugin.java.JavaPlugin @@ -30,9 +31,9 @@ class Pobutils : JavaPlugin() { registerModule(NoJoinMessage(this)) registerModule(Portals(this)) registerModule(Sit(this)) // TODO: maybe sit when right click stairs? + registerModule(SnowballDamage(this)) registerModule(Spawn(this)) registerModule(Warp(this)) - //snowballDamage config.options().copyDefaults(true) saveConfig() diff --git a/src/main/kotlin/com/pobnellion/pobutils/modules/formatChat/CmdFormatChatConfig.kt b/src/main/kotlin/com/pobnellion/pobutils/modules/formatChat/CmdFormatChatConfig.kt index 7f848ae..02c9df5 100644 --- a/src/main/kotlin/com/pobnellion/pobutils/modules/formatChat/CmdFormatChatConfig.kt +++ b/src/main/kotlin/com/pobnellion/pobutils/modules/formatChat/CmdFormatChatConfig.kt @@ -24,7 +24,7 @@ object CmdFormatChatConfig { ctx.source.sender.sendMessage(Component.text("serverAlias set to: $alias", NamedTextColor.YELLOW)) return@executes Command.SINGLE_SUCCESS })) - .then(Commands.literal("messageFormat")) + .then(Commands.literal("messageFormat") .then(Commands.argument("format", StringArgumentType.greedyString()) .executes { ctx -> val format = StringArgumentType.getString(ctx, "format") @@ -33,7 +33,7 @@ object CmdFormatChatConfig { plugin.saveConfig() ctx.source.sender.sendMessage(Component.text("messageFormat set to: $format", NamedTextColor.YELLOW)) return@executes Command.SINGLE_SUCCESS - }) + })) .then(Commands.literal("formatMessageText") .then(Commands.argument("shouldFormat", BoolArgumentType.bool()) .executes { ctx -> diff --git a/src/main/kotlin/com/pobnellion/pobutils/modules/snowballDamage/CmdSnowballDamageConfig.kt b/src/main/kotlin/com/pobnellion/pobutils/modules/snowballDamage/CmdSnowballDamageConfig.kt new file mode 100644 index 0000000..5ca5677 --- /dev/null +++ b/src/main/kotlin/com/pobnellion/pobutils/modules/snowballDamage/CmdSnowballDamageConfig.kt @@ -0,0 +1,133 @@ +package com.pobnellion.pobutils.modules.snowballDamage + +import com.mojang.brigadier.Command +import com.mojang.brigadier.arguments.BoolArgumentType +import com.mojang.brigadier.arguments.StringArgumentType +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import io.papermc.paper.command.brigadier.CommandSourceStack +import io.papermc.paper.command.brigadier.Commands +import io.papermc.paper.command.brigadier.argument.ArgumentTypes +import io.papermc.paper.registry.RegistryKey +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.format.NamedTextColor +import org.bukkit.NamespacedKey +import org.bukkit.entity.EntityType +import org.bukkit.plugin.java.JavaPlugin + +@Suppress("UnstableApiUsage") +object CmdSnowballDamageConfig { + fun configCmd(plugin: JavaPlugin, snowballDamage: SnowballDamage) : LiteralArgumentBuilder { + return Commands.literal(snowballDamage.name) + .then(entityListEdit(plugin, snowballDamage,"noClipList")) + .then(entityListEdit(plugin, snowballDamage,"damageList")) + .then(Commands.literal("invertDamageList") + .then(Commands.argument("invert", BoolArgumentType.bool()) + .executes { ctx -> + val invert = BoolArgumentType.getBool(ctx, "invert") + + plugin.config.set("data.snowballDamage.invertDamageList", invert) + plugin.saveConfig() + snowballDamage.invertDamageList = invert + + ctx.source.sender.sendMessage(Component.text("invertDamageList set to ", NamedTextColor.YELLOW) + .append(Component.text(invert.toString(), NamedTextColor.WHITE))) + + return@executes Command.SINGLE_SUCCESS + })) + .executes { ctx -> + ctx.source.sender.sendMessage("SnowballDamage config:") + + ctx.source.sender.sendMessage(Component.text("noClipList: ", NamedTextColor.YELLOW) + .append(Component.text(snowballDamage.noClipList.joinToString(", ") { entityType -> entityType.key.toString() }, NamedTextColor.WHITE))) + + ctx.source.sender.sendMessage(Component.text("damageList: ", NamedTextColor.YELLOW) + .append(Component.text(snowballDamage.damageList.joinToString(", ") { entityType -> entityType.key.toString() }, NamedTextColor.WHITE))) + + ctx.source.sender.sendMessage(Component.text("invertDamageList: ", NamedTextColor.YELLOW) + .append(Component.text(snowballDamage.invertDamageList.toString(), NamedTextColor.WHITE))) + + return@executes Command.SINGLE_SUCCESS + } + } + + fun entityListEdit(plugin: JavaPlugin, snowballDamage: SnowballDamage, listName: String) : LiteralArgumentBuilder { + return Commands.literal(listName) + .then(Commands.literal("add") + .then(Commands.argument("entityType", ArgumentTypes.resource(RegistryKey.ENTITY_TYPE)) + .executes { ctx -> + val entityType = ctx.getArgument("entityType", EntityType::class.java) + + val list = when (listName) { + "noClipList" -> snowballDamage.noClipList + "damageList" -> snowballDamage.damageList + else -> { return@executes Command.SINGLE_SUCCESS } // Will never happen + } + + if (list.contains(entityType)) { + ctx.source.sender.sendMessage(Component.text("$listName already contains ${entityType.key}", NamedTextColor.RED)) + return@executes Command.SINGLE_SUCCESS + } + + list.add(entityType) + plugin.config.set("data.snowballDamage.$listName", list.map { type -> type.key.toString() }) + plugin.saveConfig() + ctx.source.sender.sendMessage(Component.text("${entityType.key} added to $listName", NamedTextColor.YELLOW)) + + return@executes Command.SINGLE_SUCCESS + })) + .then(Commands.literal("remove") + .then(Commands.argument("entityType", StringArgumentType.greedyString()) + .suggests { ctx, builder -> + val list = when (listName) { + "noClipList" -> snowballDamage.noClipList + "damageList" -> snowballDamage.damageList + else -> { return@suggests builder.buildFuture() } + } + + for (entityType in list) + builder.suggest(entityType.key.toString()) + + return@suggests builder.buildFuture() + }.executes { ctx -> + val entityTypeName = StringArgumentType.getString(ctx, "entityType") + val key = NamespacedKey.fromString(entityTypeName) + val entityType = EntityType.fromName(key?.key) + + if (entityType == null) { + ctx.source.sender.sendMessage(Component.text("Unknown entity type: $entityTypeName", NamedTextColor.RED)) + return@executes Command.SINGLE_SUCCESS + } + + val list = when (listName) { + "noClipList" -> snowballDamage.noClipList + "damageList" -> snowballDamage.damageList + else -> { return@executes Command.SINGLE_SUCCESS } // Will never happen + } + + if (!list.contains(entityType)) { + ctx.source.sender.sendMessage(Component.text("$listName does not contain ${entityType.key}", NamedTextColor.RED)) + return@executes Command.SINGLE_SUCCESS + } + + list.remove(entityType) + plugin.config.set("data.snowballDamage.$listName", list.map { type -> type.key.toString() }) + plugin.saveConfig() + ctx.source.sender.sendMessage(Component.text("${entityType.key} removed from $listName", NamedTextColor.YELLOW)) + + return@executes Command.SINGLE_SUCCESS + })) + .then(Commands.literal("clear") + .executes { ctx -> + plugin.config.set("data.snowballDamage.$listName", null) + plugin.saveConfig() + + when (listName) { + "noClipList" -> snowballDamage.noClipList.clear() + "damageList" -> snowballDamage.damageList.clear() + } + + ctx.source.sender.sendMessage(Component.text("Cleared $listName", NamedTextColor.YELLOW)) + return@executes Command.SINGLE_SUCCESS + }) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/pobutils/modules/snowballDamage/SnowballDamage.kt b/src/main/kotlin/com/pobnellion/pobutils/modules/snowballDamage/SnowballDamage.kt new file mode 100644 index 0000000..22109ac --- /dev/null +++ b/src/main/kotlin/com/pobnellion/pobutils/modules/snowballDamage/SnowballDamage.kt @@ -0,0 +1,83 @@ +package com.pobnellion.pobutils.modules.snowballDamage + +import com.mojang.brigadier.builder.LiteralArgumentBuilder +import com.pobnellion.pobutils.modules.ModuleBase +import io.papermc.paper.command.brigadier.CommandSourceStack +import org.bukkit.NamespacedKey +import org.bukkit.entity.EntityType +import org.bukkit.entity.LivingEntity +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.entity.EntityDamageByEntityEvent +import org.bukkit.event.entity.ProjectileHitEvent +import org.bukkit.plugin.java.JavaPlugin + +@Suppress("UnstableApiUsage") +class SnowballDamage(plugin: JavaPlugin) : ModuleBase(plugin), Listener { + override val name: String = "snowballDamage" + var noClipList: MutableSet = mutableSetOf() + var damageList : MutableSet = mutableSetOf() + var invertDamageList: Boolean = false + + override fun register() { + plugin.server.pluginManager.registerEvents(this, plugin) + } + + override fun reload() { + noClipList.clear() + damageList.clear() + onEnable() + } + + override fun onDisable() { } + + override fun onEnable() { + val configNoClipList = plugin.config.getStringList("data.snowballDamage.noClipList") + val configNoDamageList = plugin.config.getStringList("data.snowballDamage.damageList") + invertDamageList = plugin.config.getBoolean("data.snowballDamage.invertDamageList") + + for (entityTypeName in configNoClipList) { + val key = NamespacedKey.fromString(entityTypeName) + val entityType = EntityType.fromName(key?.key) + + if (entityType == null) + plugin.logger.warning("Could not parse EntityType '$entityTypeName'") + else + noClipList.add(entityType) + } + + for (entityTypeName in configNoDamageList) { + val key = NamespacedKey.fromString(entityTypeName) + val entityType = EntityType.fromName(key?.key) + + if (entityType == null) + plugin.logger.warning("Could not parse EntityType '$entityTypeName'") + else + damageList.add(entityType) + } + } + + override fun configCmd(): LiteralArgumentBuilder? { + return CmdSnowballDamageConfig.configCmd(plugin, this) + } + + @EventHandler + fun onSnowballHit(event: ProjectileHitEvent) { + if (event.entityType != EntityType.SNOWBALL || event.hitEntity == null) + return + + if (noClipList.contains(event.hitEntity!!.type)) + event.isCancelled = true + } + + @EventHandler + fun onSnowballDamage(event: EntityDamageByEntityEvent) { + if (event.damager.type != EntityType.SNOWBALL || event.getEntity() !is LivingEntity) + return + + if (!invertDamageList && damageList.contains(event.entityType)) + event.setDamage(1.0) + else if (invertDamageList && !damageList.contains(event.entityType)) + event.setDamage(1.0) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/pobutils/modules/spawn/CmdSpawnConfig.kt b/src/main/kotlin/com/pobnellion/pobutils/modules/spawn/CmdSpawnConfig.kt index cb8e55f..438a203 100644 --- a/src/main/kotlin/com/pobnellion/pobutils/modules/spawn/CmdSpawnConfig.kt +++ b/src/main/kotlin/com/pobnellion/pobutils/modules/spawn/CmdSpawnConfig.kt @@ -8,6 +8,7 @@ import io.papermc.paper.command.brigadier.CommandSourceStack import io.papermc.paper.command.brigadier.Commands import io.papermc.paper.command.brigadier.argument.ArgumentTypes import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver +import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.NamedTextColor import org.bukkit.entity.Player @@ -39,7 +40,7 @@ object CmdSpawnConfig { private fun setLocation(plugin: JavaPlugin, spawn: Spawn) : LiteralArgumentBuilder { return Commands.literal("location") - .then(Commands.argument("position", ArgumentTypes.blockPosition()) + .then(Commands.argument("position", ArgumentTypes.finePosition(true)) .then(Commands.argument("direction", StringArgumentType.word()) .suggests { ctx, builder -> builder.suggest("north") @@ -49,7 +50,7 @@ object CmdSpawnConfig { return@suggests builder.buildFuture() }.executes { ctx -> - val position = ctx.getArgument("position", BlockPositionResolver::class.java).resolve(ctx.source) + val position = ctx.getArgument("position", FinePositionResolver::class.java).resolve(ctx.source) val direction = StringArgumentType.getString(ctx, "direction") val location = position.toLocation((ctx.source.sender as Player).world) diff --git a/src/main/kotlin/com/pobnellion/pobutils/modules/warp/CmdWarpConfig.kt b/src/main/kotlin/com/pobnellion/pobutils/modules/warp/CmdWarpConfig.kt index 84882e3..75b5a93 100644 --- a/src/main/kotlin/com/pobnellion/pobutils/modules/warp/CmdWarpConfig.kt +++ b/src/main/kotlin/com/pobnellion/pobutils/modules/warp/CmdWarpConfig.kt @@ -7,6 +7,7 @@ import io.papermc.paper.command.brigadier.CommandSourceStack import io.papermc.paper.command.brigadier.Commands import io.papermc.paper.command.brigadier.argument.ArgumentTypes import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver +import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver import net.kyori.adventure.text.Component import net.kyori.adventure.text.format.NamedTextColor import org.bukkit.entity.Player @@ -42,10 +43,10 @@ object CmdWarpConfig { private fun add(plugin: JavaPlugin, warp: Warp) : LiteralArgumentBuilder { return Commands.literal("add") .then(Commands.argument("name", StringArgumentType.word()) - .then(Commands.argument("location", ArgumentTypes.blockPosition()) + .then(Commands.argument("location", ArgumentTypes.finePosition(true)) .executes { ctx -> val name = StringArgumentType.getString(ctx, "name") - val position = ctx.getArgument("location", BlockPositionResolver::class.java).resolve(ctx.source) + val position = ctx.getArgument("location", FinePositionResolver::class.java).resolve(ctx.source) val location = position.toLocation((ctx.source.sender as Player).world) if (plugin.config.get("data.warps.$name") != null) { @@ -72,10 +73,10 @@ object CmdWarpConfig { warpNames?.forEach { name -> builder.suggest(name) } return@suggests builder.buildFuture() } - .then(Commands.argument("location", ArgumentTypes.blockPosition()) + .then(Commands.argument("location", ArgumentTypes.finePosition(true)) .executes { ctx -> val name = StringArgumentType.getString(ctx, "name") - val position = ctx.getArgument("location", BlockPositionResolver::class.java).resolve(ctx.source) + val position = ctx.getArgument("location", FinePositionResolver::class.java).resolve(ctx.source) val location = position.toLocation((ctx.source.sender as Player).world) if (plugin.config.get("data.warps.$name") == null) {