From eccd0dd5a32e955628785fb123b4279258de637b Mon Sep 17 00:00:00 2001 From: minemobs Date: Tue, 2 Apr 2024 20:55:08 +0000 Subject: [PATCH] Partially implemented the Boxing Glove --- .../java/fr/sunderia/bomberman/Powerup.java | 3 + .../sunderia/bomberman/PrimedTntEntity.java | 5 +- .../kotlin/fr/sunderia/bomberman/Bomberman.kt | 71 +++++++++++++++---- .../fr/sunderia/bomberman/party/Game.kt | 5 +- .../fr/sunderia/bomberman/utils/Axis.kt | 6 ++ .../sunderia/bomberman/utils/PositionUtils.kt | 19 +++++ .../sunderia/bomberman/utils/PowerupTags.kt | 13 ++++ 7 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 src/main/kotlin/fr/sunderia/bomberman/utils/Axis.kt create mode 100644 src/main/kotlin/fr/sunderia/bomberman/utils/PositionUtils.kt create mode 100644 src/main/kotlin/fr/sunderia/bomberman/utils/PowerupTags.kt diff --git a/src/main/java/fr/sunderia/bomberman/Powerup.java b/src/main/java/fr/sunderia/bomberman/Powerup.java index a56ad4f..8844d1a 100644 --- a/src/main/java/fr/sunderia/bomberman/Powerup.java +++ b/src/main/java/fr/sunderia/bomberman/Powerup.java @@ -1,10 +1,12 @@ package fr.sunderia.bomberman; +import fr.sunderia.bomberman.utils.PowerupTags; import net.minestom.server.attribute.Attribute; import net.minestom.server.attribute.AttributeInstance; import net.minestom.server.attribute.AttributeModifier; import net.minestom.server.attribute.AttributeOperation; import net.minestom.server.entity.Player; +import net.minestom.server.tag.Tag; import java.util.function.Consumer; @@ -16,6 +18,7 @@ enum Powerup { SPEED_UP(p -> incrementSpeed(p, 0.1f / 8)), //MIN SPEED -0.025 SPEED_DOWN(p -> incrementSpeed(p, -0.025f / 4)), + BOXING_GLOVE(p -> p.setTag(PowerupTags.BOXING_GLOVE.getTag(Boolean.class), true)) ; private final Consumer effect; diff --git a/src/main/java/fr/sunderia/bomberman/PrimedTntEntity.java b/src/main/java/fr/sunderia/bomberman/PrimedTntEntity.java index 7cef046..05ef72c 100644 --- a/src/main/java/fr/sunderia/bomberman/PrimedTntEntity.java +++ b/src/main/java/fr/sunderia/bomberman/PrimedTntEntity.java @@ -83,6 +83,9 @@ private void dropPowerup(Pos pos) { return; int index = Random.Default.nextInt(Powerup.values().length); Powerup powerup = Powerup.values()[index]; + if(powerup == Powerup.BOXING_GLOVE) { + Bomberman.Companion.getLogger().info("Spawned boxing glove"); + } ItemStack is = ItemStack.of(Material.NAUTILUS_SHELL).withMeta(meta -> meta.customModelData(index + 1) .displayName(Component.text(powerup.name().replace("_", " ").toLowerCase()))); ItemEntity item = new ItemEntity(is); @@ -114,7 +117,7 @@ public void update(long time) { if (--fuseTime != 0) return; explode(); - getInstance().setBlock(this.spawnPos, Block.AIR); + getInstance().setBlock(this.position, Block.AIR); remove(); } } diff --git a/src/main/kotlin/fr/sunderia/bomberman/Bomberman.kt b/src/main/kotlin/fr/sunderia/bomberman/Bomberman.kt index 49eedf1..ec33c01 100644 --- a/src/main/kotlin/fr/sunderia/bomberman/Bomberman.kt +++ b/src/main/kotlin/fr/sunderia/bomberman/Bomberman.kt @@ -3,8 +3,16 @@ package fr.sunderia.bomberman import com.google.gson.Gson import com.google.gson.GsonBuilder import fr.sunderia.bomberman.InstanceCreator.Companion.createInstanceContainer -import fr.sunderia.bomberman.party.* +import fr.sunderia.bomberman.party.Game +import fr.sunderia.bomberman.party.GameCommand +import fr.sunderia.bomberman.party.Party +import fr.sunderia.bomberman.party.PartyCommand +import fr.sunderia.bomberman.utils.Axis import fr.sunderia.bomberman.utils.Cooldown +import fr.sunderia.bomberman.utils.PositionUtils +import fr.sunderia.bomberman.utils.PositionUtils.Companion.removeBlockAt +import fr.sunderia.bomberman.utils.PositionUtils.Companion.setBlockAt +import fr.sunderia.bomberman.utils.PowerupTags import net.kyori.adventure.key.Key import net.kyori.adventure.resource.ResourcePackInfo import net.kyori.adventure.resource.ResourcePackRequest @@ -13,11 +21,7 @@ import net.kyori.adventure.text.JoinConfiguration import net.kyori.adventure.text.format.NamedTextColor import net.kyori.adventure.title.TitlePart import net.minestom.server.MinecraftServer -import net.minestom.server.attribute.Attribute -import net.minestom.server.attribute.AttributeModifier import net.minestom.server.coordinate.Pos -import net.minestom.server.entity.Entity -import net.minestom.server.entity.EntityType import net.minestom.server.entity.GameMode import net.minestom.server.entity.Player import net.minestom.server.event.EventNode @@ -27,9 +31,12 @@ import net.minestom.server.extras.lan.OpenToLAN import net.minestom.server.instance.Instance import net.minestom.server.instance.InstanceContainer import net.minestom.server.instance.block.Block +import net.minestom.server.instance.block.BlockFace import net.minestom.server.item.ItemStack import net.minestom.server.item.Material +import net.minestom.server.listener.PlayerDiggingListener import net.minestom.server.network.NetworkBuffer +import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket import net.minestom.server.network.packet.server.play.ChangeGameStatePacket import net.minestom.server.network.packet.server.play.SetCooldownPacket import net.minestom.server.tag.Tag @@ -42,7 +49,6 @@ import java.io.ByteArrayOutputStream import java.io.IOException import java.net.URI import java.util.* -import java.util.function.Consumer import java.util.logging.Level import java.util.logging.Logger @@ -101,11 +107,11 @@ class Bomberman { extensionNode.addListener(AsyncPlayerConfigurationEvent::class.java) { it.spawningInstance = container } //extensionNode.addListener(PlayerSkinInitEvent::class.java) { it.skin = PlayerSkin.fromUuid(it.player.uuid.toString()) } - extensionNode.addListener(PlayerChatEvent::class.java) { + /*extensionNode.addListener(PlayerChatEvent::class.java) { val gameMode = GameMode.entries.find { gm -> it.message.uppercase().contains(gm.name) } ?: return@addListener it.isCancelled = true it.player.gameMode = gameMode - } + }*/ extensionNode.addListener(PlayerDisconnectEvent::class.java) { Party.removePlayerFromParty(it.player) @@ -118,10 +124,38 @@ class Bomberman { Game.playerLeft(instance) } } + + MinecraftServer.getPacketListenerManager().setPlayListener(ClientPlayerDiggingPacket::class.java) { packet: ClientPlayerDiggingPacket, player: Player -> + val instance = player.instance + if(player.gameMode != GameMode.ADVENTURE || packet.status != ClientPlayerDiggingPacket.Status.STARTED_DIGGING) return@setPlayListener PlayerDiggingListener.playerDiggingListener(packet, player) + if(!player.hasTag(PowerupTags.BOXING_GLOVE.tag)) return@setPlayListener + if(!instance.getBlock(packet.blockPosition).compare(Block.BARRIER)) return@setPlayListener + if(packet.blockFace == BlockFace.TOP || packet.blockFace == BlockFace.BOTTOM) return@setPlayListener + val tnt = instance.entities + .filterIsInstance() + .firstOrNull { it.position.sameBlock(packet.blockPosition) } ?: return@setPlayListener + val lastPos = when (packet.blockFace) { + BlockFace.NORTH -> { + getFurthestAirBlock(Axis.Z, 1.0, tnt.position, tnt.instance) + } + BlockFace.WEST -> { + getFurthestAirBlock(Axis.X, 1.0, tnt.position, tnt.instance) + } + BlockFace.SOUTH -> { + getFurthestAirBlock(Axis.Z, -1.0, tnt.position, tnt.instance) + } + else -> { + getFurthestAirBlock(Axis.X, -1.0, tnt.position, tnt.instance) + } + } + removeBlockAt(tnt.position, tnt.instance) + tnt.teleport(lastPos) + setBlockAt(tnt.position, Block.BARRIER, tnt.instance) + } gameNode.addListener(PickupItemEvent::class.java) { if(!it.instance.hasTag(Tag.Boolean("game"))) return@addListener - if (it.livingEntity !is Player || it.itemStack.material().id() != Material.NAUTILUS_SHELL.id()) return@addListener + if(it.livingEntity !is Player || it.itemStack.material().id() != Material.NAUTILUS_SHELL.id()) return@addListener val player = it.entity as Player if (player.gameMode != GameMode.ADVENTURE) { it.isCancelled = true @@ -144,7 +178,7 @@ class Bomberman { PacketUtils.sendPacket(player, packet) } if(!it.spawnInstance.hasTag(Tag.Boolean("game"))) return@addListener - player.inventory.addItemStack(ItemStack.of(Material.TNT).withMeta { it.canPlaceOn(Block.STONE, Block.BRICKS).build() } ) + player.inventory.addItemStack(ItemStack.of(Material.TNT).withMeta { it.canPlaceOn(Block.STONE, Block.BRICKS).canDestroy(Block.BARRIER).build() } ) powerMap[player.uuid] = 2 player.scheduler().scheduleTask({ @@ -155,10 +189,10 @@ class Bomberman { Component.text(": ${powerMap[player.uuid]}") ).style { it.font(Key.key("default")) }) }, TaskSchedule.immediate(), TaskSchedule.tick(10)) - player.sendResourcePacks(ResourcePackRequest.resourcePackRequest().packs(ResourcePackInfo.resourcePackInfo() + /*player.sendResourcePacks(ResourcePackRequest.resourcePackRequest().packs(ResourcePackInfo.resourcePackInfo() .hash(resourcePackSha1!!) .uri(URI.create("https://raw.githubusercontent.com/Sunderia/Bomberman/main/bomberman.zip")) - )) + ))*/ } @@ -217,7 +251,16 @@ class Bomberman { extensionNode.addChild(gameNode) } - fun terminate() { - + private fun getFurthestAirBlock(axis: Axis, add: Double, pos: Pos, instance: Instance): Pos { + var lastPos: Pos = pos + var iter = 0 + val addPos = Pos(if(axis == Axis.X) add else .0, .0, if(axis == Axis.Z) add else .0) + while(instance.getBlock(lastPos.add(addPos)).isAirOrBarrier() && iter < 10) { + lastPos = lastPos.add(addPos) + iter++ + } + return lastPos } + + private fun Block.isAirOrBarrier() = this.isAir || this.compare(Block.BARRIER) } \ No newline at end of file diff --git a/src/main/kotlin/fr/sunderia/bomberman/party/Game.kt b/src/main/kotlin/fr/sunderia/bomberman/party/Game.kt index f6c039a..48a0a3d 100644 --- a/src/main/kotlin/fr/sunderia/bomberman/party/Game.kt +++ b/src/main/kotlin/fr/sunderia/bomberman/party/Game.kt @@ -4,6 +4,7 @@ import fr.sunderia.bomberman.Bomberman import fr.sunderia.bomberman.Bomberman.Companion.powerMap import fr.sunderia.bomberman.InstanceCreator.Companion.createInstanceContainer import fr.sunderia.bomberman.InstanceCreator.Companion.generateStructure +import fr.sunderia.bomberman.utils.PowerupTags import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component.text import net.kyori.adventure.text.format.NamedTextColor @@ -70,13 +71,13 @@ data class Game(val instance: InstanceContainer, val scheduler: SchedulerManager powerMap.replaceAll { _: UUID, _: Int -> 2 } instance.players.forEach { p: Player -> p.clearEffects() - val uuids = - p.getAttribute(Attribute.MOVEMENT_SPEED).modifiers.stream() + val uuids = p.getAttribute(Attribute.MOVEMENT_SPEED).modifiers.stream() .map { obj: AttributeModifier -> obj.id } .toList().toTypedArray() for (uuid in uuids) { p.getAttribute(Attribute.MOVEMENT_SPEED).removeModifier(uuid!!) } + p.removeTag(PowerupTags.BOXING_GLOVE.tag) } instance.entities.stream() .filter { e: Entity -> diff --git a/src/main/kotlin/fr/sunderia/bomberman/utils/Axis.kt b/src/main/kotlin/fr/sunderia/bomberman/utils/Axis.kt new file mode 100644 index 0000000..6b68832 --- /dev/null +++ b/src/main/kotlin/fr/sunderia/bomberman/utils/Axis.kt @@ -0,0 +1,6 @@ +package fr.sunderia.bomberman.utils + +enum class Axis { + X, + Z +} \ No newline at end of file diff --git a/src/main/kotlin/fr/sunderia/bomberman/utils/PositionUtils.kt b/src/main/kotlin/fr/sunderia/bomberman/utils/PositionUtils.kt new file mode 100644 index 0000000..4a4a826 --- /dev/null +++ b/src/main/kotlin/fr/sunderia/bomberman/utils/PositionUtils.kt @@ -0,0 +1,19 @@ +package fr.sunderia.bomberman.utils + +import net.minestom.server.coordinate.Pos +import net.minestom.server.instance.Instance +import net.minestom.server.instance.block.Block + +class PositionUtils { + companion object { + fun removeBlockAt(pos: Pos, instance: Instance) { + instance.setBlock(pos, Block.AIR) + } + + fun setBlockAt(pos: Pos, block: Block, instance: Instance) { + instance.setBlock(pos, block) + } + + fun toBlockPos(pos: Pos) = Pos(pos.blockX() + .0, pos.blockY() + .0, pos.blockZ() +.0) + } +} \ No newline at end of file diff --git a/src/main/kotlin/fr/sunderia/bomberman/utils/PowerupTags.kt b/src/main/kotlin/fr/sunderia/bomberman/utils/PowerupTags.kt new file mode 100644 index 0000000..7a1b5d9 --- /dev/null +++ b/src/main/kotlin/fr/sunderia/bomberman/utils/PowerupTags.kt @@ -0,0 +1,13 @@ +package fr.sunderia.bomberman.utils + +import net.minestom.server.tag.Tag + +enum class PowerupTags(val tag: Tag<*>) { + BOXING_GLOVE(Tag.Boolean("boxing_glove")), + ; + + @Suppress("UNCHECKED_CAST") + fun getTag(clazz: Class): Tag { + return this.tag as Tag + } +} \ No newline at end of file