Skip to content

Commit

Permalink
feat: implement furniture interactionHitbx outline
Browse files Browse the repository at this point in the history
  • Loading branch information
Boy0000 committed Jan 20, 2024
1 parent 4baa501 commit e18860d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.mineinabyss.blocky.components.core

import com.mineinabyss.blocky.serializers.BrightnessSerializer
import com.mineinabyss.idofront.serialization.SerializableItemStack
import com.mineinabyss.idofront.serialization.Vector3fSerializer
import com.mineinabyss.idofront.serialization.toSerializable
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import org.bukkit.Location
Expand All @@ -10,6 +12,8 @@ import org.bukkit.block.data.type.Slab
import org.bukkit.entity.Display.Billboard
import org.bukkit.entity.Display.Brightness
import org.bukkit.entity.ItemDisplay.ItemDisplayTransform
import org.bukkit.inventory.ItemStack
import org.bukkit.util.BoundingBox
import org.joml.Vector3f
import kotlin.math.cos
import kotlin.math.sin
Expand All @@ -24,7 +28,9 @@ data class BlockyFurniture(
) {
@Serializable
@SerialName("blocky:interaction_hitbox")
data class InteractionHitbox(val width: Float, val height: Float)
data class InteractionHitbox(val width: Float, val height: Float, val outline: SerializableItemStack = ItemStack(Material.GLASS).toSerializable()) {
fun toBoundingBox(location: Location) = BoundingBox.of(location, width.times(0.7), height.times(0.7), width.times(0.7))
}

@Serializable
@SerialName("blocky:collision_hitbox")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ object FurniturePacketHelpers {
val outlinePlayerMap = mutableMapOf<UUID, UUID>()
fun sendHitboxOutlinePacket(furniture: ItemDisplay, player: Player) {
if (outlinePlayerMap[player.uniqueId] == furniture.uniqueId) return
removeHitboxOutlinePacket(player)
outlinePlayerMap[player.uniqueId] = furniture.uniqueId
val entityId = hitboxOutlineIdMap.computeIfAbsent(furniture) { Entity.nextEntityId() }
val hitbox = furniture.toGeary().get<BlockyFurniture>()?.interactionHitbox ?: return
Expand All @@ -193,7 +194,7 @@ object FurniturePacketHelpers {
val metadataPacket = ClientboundSetEntityDataPacket(
entityId, listOf(
SynchedEntityData.DataValue(12, EntityDataSerializers.VECTOR3, Vector3f(hitbox.width, hitbox.height, hitbox.width)),
SynchedEntityData.DataValue(23, EntityDataSerializers.ITEM_STACK, CraftItemStack.asNMSCopy(org.bukkit.inventory.ItemStack(Material.GLASS))),
SynchedEntityData.DataValue(23, EntityDataSerializers.ITEM_STACK, CraftItemStack.asNMSCopy(hitbox.outline.toItemStack())),
SynchedEntityData.DataValue(24, EntityDataSerializers.INT, furniture.itemDisplayTransform.ordinal)
)
)
Expand All @@ -214,6 +215,13 @@ object FurniturePacketHelpers {
outlinePlayerMap.remove(player.uniqueId)
}

fun removeHitboxOutlinePacket(player: Player) {
val furniture = outlinePlayerMap[player.uniqueId]?.toEntity() ?: return
val displayEntityPacket = ClientboundRemoveEntitiesPacket(hitboxOutlineIdMap[furniture] ?: return)
PacketContainer.fromPacket(displayEntityPacket).sendTo(player)
outlinePlayerMap.remove(player.uniqueId)
}

/**
* Sends a packet to show the collision hitbox of the given furniture to all players in the world.
* @param baseEntity The furniture to show the collision hitbox of.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,37 @@ package com.mineinabyss.blocky.systems

import com.mineinabyss.blocky.components.core.BlockyFurniture
import com.mineinabyss.blocky.helpers.FurniturePacketHelpers
import com.mineinabyss.blocky.helpers.GenericHelpers.toBlockCenterLocation
import com.mineinabyss.geary.papermc.tracking.entities.toGearyOrNull
import com.mineinabyss.geary.systems.RepeatingSystem
import com.mineinabyss.geary.systems.accessors.Pointer
import com.mineinabyss.idofront.time.ticks
import org.bukkit.entity.ItemDisplay
import org.bukkit.entity.Player
import org.bukkit.util.BoundingBox
import org.bukkit.util.Vector


class FurnitureOutlineSystem : RepeatingSystem(1.ticks) {
val Pointer.player by get<Player>()

override fun Pointer.tick() {
if (!player.isConnected) return
val entities = player.getNearbyEntities(8.0, 8.0, 8.0).filterIsInstance<ItemDisplay>().toList()
val playerDirection: Vector = player.location.getDirection().normalize()
val boundingEntities = entities.map {
val hitbox = it.toGearyOrNull()?.get<BlockyFurniture>()?.interactionHitbox ?: return
val loc = it.location.toBlockCenterLocation().apply { y += hitbox.height / 2 }
it to BoundingBox.of(
loc,
(hitbox.width / 2).toDouble(),
(hitbox.height / 2).toDouble(),
(hitbox.width / 2).toDouble()
)
}

var distance = 0.0
while (distance <= 5.0) {
val point = player.eyeLocation.clone().add(player.location.getDirection().clone().multiply(distance))
boundingEntities.forEach {
if (point.toVector() !in it.second) return@forEach FurniturePacketHelpers.removeHitboxOutlinePacket(it.first, player)
FurniturePacketHelpers.sendHitboxOutlinePacket(it.first, player)
distance = 5.0
}
val location = player.eyeLocation
val direction = location.direction.clone().multiply(0.1)
val result = player.rayTraceBlocks(5.0)
val distanceEyeToRaycastBlock = result?.hitBlock?.let { location.distance(it.location) } ?: (5.0 * 5.0)

distance += 0.2
while (location.toBlockLocation().distanceSquared(player.eyeLocation) < distanceEyeToRaycastBlock) {
location.getNearbyEntities(5.0, 5.0, 5.0).filterIsInstance<ItemDisplay>().firstOrNull {
it.toGearyOrNull()?.get<BlockyFurniture>()?.interactionHitbox?.let { i ->
it.boundingBox.overlaps(i.toBoundingBox(location))
} == true
}?.let {
FurniturePacketHelpers.sendHitboxOutlinePacket(it, player)
return
}
location.add(direction)
}

// player.getLineOfSight(null, 5).filter { it.type.isAir }.toList().forEach entity@{ block ->
// entities.forEach { itemDisplay ->
// if (itemDisplay.location.distance(player.eyeLocation) > 10.0) return@entity FurniturePacketHelpers.removeHitboxOutlinePacket(itemDisplay, player)
// if (!itemDisplay.boundingBox.overlaps(BoundingBox.of(block, block.getRelative(BlockFace.UP)))) return@entity FurniturePacketHelpers.removeHitboxOutlinePacket(itemDisplay, player)
//
// FurniturePacketHelpers.sendHitboxOutlinePacket(itemDisplay, player)
// }
// }
FurniturePacketHelpers.removeHitboxOutlinePacket(player)
}
}

0 comments on commit e18860d

Please sign in to comment.