Skip to content

Commit

Permalink
Furniture and Directional additions (#69)
Browse files Browse the repository at this point in the history
* add 4 and 6 sided directional

* add strict rotation option

* fix furniture seats

* minor cleanup

* add strict, very strict rotation limits
  • Loading branch information
Boy0000 authored Nov 24, 2022
1 parent 21aa447 commit 3f0f2ec
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 145 deletions.
53 changes: 34 additions & 19 deletions src/main/kotlin/com/mineinabyss/blocky/ResourcepackGeneration.kt
Original file line number Diff line number Diff line change
Expand Up @@ -155,32 +155,47 @@ class ResourcepackGeneration {

private fun PrefabKey.directionalJsonProperties(parent: GearyEntity): JsonObject? {
return JsonObject().apply {

this.addProperty(
"model", parent.get<BlockyBlock>()?.blockModel
?: this@directionalJsonProperties.toEntityOrNull()?.get<BlockyBlock>()?.blockModel
?: return null
)
parent.get<BlockyDirectional>()?.let { p ->
when {
this@directionalJsonProperties == p.xBlock -> {
this.addProperty("x", 90)
this.addProperty("z", 90)
}

this@directionalJsonProperties == p.zBlock -> {
this.addProperty("x", 90)
this.addProperty("y", 90)
val childModel = this@directionalJsonProperties.toEntityOrNull()?.get<BlockyBlock>()?.blockModel
val parentModel = parent.get<BlockyBlock>()?.blockModel
this.addProperty("model", childModel ?: parentModel ?: return null)

// If using the parent model, we need to add the rotation depending on the childDirection
if (childModel == null || childModel == parentModel) {
parent.get<BlockyDirectional>()?.let { p ->
when {
this@directionalJsonProperties == p.xBlock -> {
this.addProperty("x", 90)
this.addProperty("z", 90)
}

this@directionalJsonProperties == p.zBlock || this@directionalJsonProperties == p.eastBlock -> {
this.addProperty("x", 90)
this.addProperty("y", 90)
}

this@directionalJsonProperties == p.southBlock ->
this.addProperty("y", 180)

this@directionalJsonProperties == p.westBlock -> {
this.addProperty("z", 90)
this.addProperty("y", 270)
}

this@directionalJsonProperties == p.upBlock ->
this.addProperty("y", 270)

this@directionalJsonProperties == p.downBlock ->
this.addProperty("x", 180)
}
}
}
}
}

private fun String.getModelJson(): JsonObject {
val content = JsonObject()
content.addProperty("model", this)
return content
return JsonObject().apply {
addProperty("model", this@getModelJson)
}
}

private fun getInstrument(id: Instrument): String {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.mineinabyss.blocky.api.events.furniture

import com.mineinabyss.blocky.components.core.BlockyFurniture
import com.mineinabyss.geary.papermc.access.toGeary
import org.bukkit.entity.Entity
import org.bukkit.entity.Player
import org.bukkit.event.Cancellable
Expand All @@ -10,6 +12,8 @@ class BlockyFurnitureBreakEvent(
val player: Player?
) : BlockyFurnitureEvent(entity), Cancellable {

override val furniture get() = entity.toGeary().get<BlockyFurniture>()!!

private var cancelled = false

override fun isCancelled() = cancelled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class WorldEditListener : Listener {
if (gearyEntity.has<BlockyLight>())
handleLight.createBlockLight(loc, gearyEntity.get<BlockyLight>()?.lightLevel!!)
if (gearyEntity.has<BlockySeat>()) // This is probably never called until we go insane and support furniture in WorldEdit
spawnFurnitureSeat(loc, ((actor as? Player)?.location?.yaw?.minus(180) ?: 0f), gearyEntity.get<BlockySeat>()?.heightOffset ?: 0.0)
spawnFurnitureSeat(loc, ((actor as? Player)?.location?.yaw?.minus(180) ?: 0f))

return extent.setBlock(pos.blockX, pos.blockY, pos.blockZ, block)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,26 @@ class WorldEditSupport {
return BukkitAdapter.adapt(Bukkit.createBlockData(Material.TRIPWIRE)).toBaseBlock()
}

val gearyEntity = PrefabKey.ofOrNull(input.replace("[direction=up]", "")
val gearyEntity = PrefabKey.ofOrNull(input.replaceDirectionText())?.toEntityOrNull() ?: return null
val type = gearyEntity.get<BlockyBlock>()?.blockType ?: return null
val blockData =
if (type == BlockType.WIRE) gearyEntity.get<BlockyBlock>()!!.getBlockyTripWire()
else gearyEntity.getBlockyNoteBlock(
BlockFace.valueOf(
input.substringAfter("[direction=", "up]").substringBefore("]", "UP").uppercase()
), null
)

return BukkitAdapter.adapt(blockData).toBaseBlock()
}

private fun String.replaceDirectionText(): String {
return this.replace("[direction=up]", "")
.replace("[direction=down]", "")
.replace("[direction=north]", "")
.replace("[direction=south]", "")
.replace("[direction=west]", "")
.replace("[direction=east]", ""))?.toEntityOrNull() ?: return null
val type = gearyEntity.get<BlockyBlock>()?.blockType ?: return null

val blockData = when {
type == BlockType.WIRE -> gearyEntity.get<BlockyBlock>()!!.getBlockyTripWire()
input.endsWith("[direction=up]") -> {
gearyEntity.getBlockyNoteBlock(BlockFace.UP)
}
input.endsWith("[direction=north]") -> {
gearyEntity.getBlockyNoteBlock(BlockFace.NORTH)
}
input.endsWith("[direction=south]") -> {
gearyEntity.getBlockyNoteBlock(BlockFace.SOUTH)
}
input.endsWith("[direction=west]") -> {
gearyEntity.getBlockyNoteBlock(BlockFace.WEST)
}
input.endsWith("[direction=east]") -> {
gearyEntity.getBlockyNoteBlock(BlockFace.EAST)
}
else -> {
gearyEntity.getBlockyNoteBlock(BlockFace.UP)
}
}

return BukkitAdapter.adapt(blockData).toBaseBlock()
.replace("[direction=east]", "")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import kotlinx.serialization.Serializable
data class BlockyBlock (
val blockType: BlockType,
val blockId: Int,
val blockModel: String,
val blockModel: String? = null,
) {
enum class BlockType {
NOTEBLOCK, WIRE, LEAF, CAVEVINE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@ import kotlinx.serialization.Serializable
@SerialName("blocky:furniture")
data class BlockyFurniture(
val furnitureType: FurnitureType,
val strictRotation: Boolean = true,
val collisionHitbox: List<BlockLocation> = listOf(),
val rotationType: RotationType = RotationType.VERY_STRICT,
val collisionHitbox: List<BlockLocation> = emptyList(),
val originOffset: BlockLocation = BlockLocation(0, 0, 0),
) {
enum class FurnitureType {
ARMOR_STAND, ITEM_FRAME, GLOW_ITEM_FRAME
}

enum class RotationType {
NONE, STRICT, VERY_STRICT
}

val hasStrictRotation get() = rotationType != RotationType.NONE
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,17 @@ data class BlockyDirectional(
val yBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val xBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val zBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val northBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val southBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val westBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val eastBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val upBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val downBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null,
val parentBlock: @Serializable(with = PrefabKeySerializer::class) PrefabKey? = null
) {
val isLogType get() = yBlock != null && xBlock != null && zBlock != null
val isFurnaceType get() = northBlock != null && southBlock != null && westBlock != null && eastBlock != null
val isDropperType get() = isFurnaceType && upBlock != null && downBlock != null
val isParentBlock: Boolean
get() = parentBlock == null

Expand Down
70 changes: 31 additions & 39 deletions src/main/kotlin/com/mineinabyss/blocky/helpers/FurnitureHelpers.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,19 @@ fun getTargetBlock(placedAgainst: Block, blockFace: BlockFace): Block? {
}
}

fun getLocations(rotation: Float, center: Location, relativeCoordinates: List<BlockLocation>): List<Location> {
val output: MutableList<Location> = ArrayList()
for (modifier in relativeCoordinates) output.add(modifier.groundRotate(rotation).add(center))
return output
fun getLocations(rotation: Float, center: Location, relativeCoordinates: List<BlockLocation>): MutableList<Location> {
return mutableListOf<Location>().apply {
relativeCoordinates.forEach {blockLoc ->
this.add(blockLoc.groundRotate(rotation).add(center))
}
}
}

fun getRotation(yaw: Float, restricted: Boolean): Rotation {
var id = ((Location.normalizeYaw(yaw) + 180) * 8 / 360 + 0.5).toInt() % 8
if (restricted && id % 2 != 0) id -= 1
fun BlockyFurniture.getRotation(yaw: Float): Rotation {
val rotationDegree = if (this.rotationType == BlockyFurniture.RotationType.STRICT) 0 else 1
val id = (((Location.normalizeYaw(yaw) + 180) * 8 / 360 + 0.5).toInt() % 8).apply {
if (this@getRotation.hasStrictRotation && this % 2 != 0) this - rotationDegree
}
return Rotation.values()[id]
}

Expand Down Expand Up @@ -77,12 +81,8 @@ fun GearyEntity.placeBlockyFurniture(
val modelengine = get<BlockyModelEngine>()
val blockPlaceEvent = BlockPlaceEvent(loc.block, loc.block.state, loc.block, item, player, true, EquipmentSlot.HAND)

val rotation =
getRotation(
player.location.yaw,
furniture?.collisionHitbox?.isNotEmpty() == true || furniture?.strictRotation == true
)
val yaw = if (furniture?.furnitureType != BlockyFurniture.FurnitureType.ARMOR_STAND || furniture.strictRotation)
val rotation = furniture?.getRotation(player.location.yaw) ?: Rotation.NONE
val yaw = if (furniture?.furnitureType != BlockyFurniture.FurnitureType.ARMOR_STAND || furniture.hasStrictRotation)
getYaw(rotation) else player.location.yaw - 180

when {
Expand Down Expand Up @@ -169,18 +169,17 @@ fun GearyEntity.placeBlockyFurniture(

private fun GearyEntity.placeBarrierHitbox(yaw: Float, loc: Location, player: Player) {
val furniture = get<BlockyFurniture>() ?: return
val locations = getLocations(yaw, loc, furniture.collisionHitbox).toMutableList()
locations.forEach { adjacentLoc ->
adjacentLoc.block.setType(Material.BARRIER, false)
val locations = getLocations(yaw, loc, furniture.collisionHitbox)
locations.forEach { l ->
val location = l.toBlockCenterLocation()
location.yaw = yaw
location.block.setType(Material.BARRIER, false)

if (has<BlockyLight>()) {
handleLight.createBlockLight(adjacentLoc, get<BlockyLight>()!!.lightLevel)
}

if (has<BlockySeat>()) {
spawnFurnitureSeat(adjacentLoc, (player.location.yaw - 180), get<BlockySeat>()?.heightOffset ?: 0.0)
}
adjacentLoc.block.persistentDataContainer.set(FURNITURE_ORIGIN, DataType.LOCATION, loc)
this.get<BlockyLight>()?.let { handleLight.createBlockLight(location, it.lightLevel) }
this.get<BlockySeat>()?.let { spawnFurnitureSeat(location.apply { y += max(0.0, it.heightOffset) }, player.location.yaw - 180) }

location.block.persistentDataContainer.set(FURNITURE_ORIGIN, DataType.LOCATION, loc)
}

if (locations.isNotEmpty()) {
Expand Down Expand Up @@ -225,44 +224,37 @@ val Block.blockyFurniture
}
}

private fun Entity.checkFurnitureHitbox(): Boolean {
toGearyOrNull()?.get<BlockyBarrierHitbox>()?.barriers?.forEach { barrierLoc ->
if (barrierLoc.toBlockLocation() == this.location.toBlockLocation()) return true
}
return false
}

//TODO Fix seat breaking below 0.0 offset and remove max() check here
fun spawnFurnitureSeat(loc: Location, yaw: Float, heightOffset: Double) {
val location = loc.add(0.0, max(0.0, heightOffset), 0.0).toCenterLocation()
fun spawnFurnitureSeat(location: Location, yaw: Float) {
location.yaw = yaw
location.spawn<ArmorStand>()?.apply {
isVisible = false
isMarker = true
isSilent = true
isSmall = true
setGravity(false)
toGeary().setPersisting(BlockySeat(heightOffset))
toGeary().setPersisting(BlockySeat(location.y - location.toBlockCenterLocation().y))
persistentDataContainer.set(FURNITURE_ORIGIN, DataType.LOCATION, location)
} ?: return
}

fun Player.sitOnBlockySeat(block: Block) {
val stand = block.blockySeat ?: return
if (stand.passengers.isEmpty()) stand.addPassenger(this)
block.blockySeat?.let {
if (this.passengers.isEmpty()) it.addPassenger(this)
}
}

fun Entity.removeAssosiatedSeats() {
this.toGearyOrNull()?.get<BlockySeatLocations>()?.seats?.forEach seatLoc@{ seatLoc ->
this.toGearyOrNull()?.get<BlockySeatLocations>()?.seats?.forEach { seatLoc ->
seatLoc.block.blockySeat?.remove()
}
}

val Block.blockySeat
get(): Entity? {
val seatLoc = this.persistentDataContainer.get(FURNITURE_ORIGIN, DataType.LOCATION) ?: return null
return this.world.getNearbyEntities(this.boundingBox.expand(1.0)).firstOrNull {
it.toGearyOrNull() != null && it.toGeary().has<BlockySeat>() && !it.toGeary().has<BlockyFurniture>() &&
it.persistentDataContainer.get(FURNITURE_ORIGIN, DataType.LOCATION) == seatLoc
it.toGearyOrNull()?.let { g ->
g.has<BlockySeat>() && !g.has<BlockyFurniture>()
} ?: false
}
}
Loading

0 comments on commit 3f0f2ec

Please sign in to comment.