Skip to content

Commit

Permalink
Merge pull request #92 from DockyardMC/feature/guardian-beams
Browse files Browse the repository at this point in the history
Feature/guardian beams
  • Loading branch information
LukynkaCZE authored Jan 3, 2025
2 parents 866fa96 + fe8a2d4 commit 9d7a38a
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 11 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
dockyard.version=0.7.15
dockyard.version=0.7.16
kotlin.code.style=official
36 changes: 28 additions & 8 deletions src/main/kotlin/io/github/dockyardmc/Main.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
package io.github.dockyardmc

import io.github.dockyardmc.apis.GuardianBeam
import io.github.dockyardmc.commands.Commands
import io.github.dockyardmc.commands.IntArgument
import io.github.dockyardmc.commands.PlayerArgument
import io.github.dockyardmc.commands.simpleSuggestion
import io.github.dockyardmc.datagen.EventsDocumentationGenerator
import io.github.dockyardmc.entity.Guardian
import io.github.dockyardmc.events.*
import io.github.dockyardmc.extentions.broadcastMessage
import io.github.dockyardmc.inventory.give
import io.github.dockyardmc.item.ItemRarity
import io.github.dockyardmc.item.ItemStack
import io.github.dockyardmc.location.Location
import io.github.dockyardmc.player.Player
import io.github.dockyardmc.player.systems.GameMode
import io.github.dockyardmc.registry.Blocks
import io.github.dockyardmc.registry.Items
import io.github.dockyardmc.registry.PotionEffects
import io.github.dockyardmc.ui.examples.ExampleCookieClickerScreen
import io.github.dockyardmc.ui.examples.ExampleMinesweeperScreen
import io.github.dockyardmc.runnables.ticks
import io.github.dockyardmc.utils.DebugSidebar
import io.github.dockyardmc.world.WorldManager
import kotlin.time.Duration.Companion.seconds

// This is just testing/development environment.
// To properly use dockyard, visit https://dockyardmc.github.io/Wiki/wiki/quick-start.html
Expand Down Expand Up @@ -64,18 +66,36 @@ fun main(args: Array<String>) {
player.give(item)
}

Commands.add("/minesweeper") {
addArgument("mines", IntArgument())
var laser: GuardianBeam? = null
Commands.add("/laser") {
execute {
val player = it.getPlayerOrThrow()
player.openInventory(ExampleMinesweeperScreen(player, getArgument("mines")))
laser = GuardianBeam(Location(0, 10, 0, player.world), player.location)
}
}

Commands.add("/cookie") {
Commands.add("/move") {
execute {
val player = it.getPlayerOrThrow()
player.openInventory(ExampleCookieClickerScreen(player))
laser?.moveEnd(player.location, 1.seconds)
}
}

Events.on<WorldTickEvent> { event ->
val player = event.world.players.firstOrNull() ?: return@on
if (laser?.end?.value == player.location) return@on
laser?.moveEnd(player.location, 2.ticks)
}

Commands.add("/cleartarget") {
execute {
val player = it.getPlayerOrThrow()
player.world.entities.forEach { entity ->
if (entity is Guardian) {
entity.target.value = null
entity.isRetractingSpikes.value = true
}
}
}
}

Expand Down
121 changes: 121 additions & 0 deletions src/main/kotlin/io/github/dockyardmc/apis/GuardianBeam.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package io.github.dockyardmc.apis

import cz.lukynka.Bindable
import cz.lukynka.BindablePool
import io.github.dockyardmc.entity.EntityManager.despawnEntity
import io.github.dockyardmc.entity.EntityManager.spawnEntity
import io.github.dockyardmc.entity.Guardian
import io.github.dockyardmc.entity.Squid
import io.github.dockyardmc.location.Location
import io.github.dockyardmc.player.Player
import io.github.dockyardmc.runnables.ticks
import io.github.dockyardmc.scheduler.SchedulerTask
import io.github.dockyardmc.scroll.LegacyTextColor
import io.github.dockyardmc.team.TeamCollisionRule
import io.github.dockyardmc.team.TeamManager
import io.github.dockyardmc.utils.Disposable
import io.github.dockyardmc.utils.Viewable
import io.github.dockyardmc.utils.locationLerp
import io.github.dockyardmc.utils.percent
import java.util.UUID
import kotlin.math.round
import kotlin.time.Duration

class GuardianBeam(start: Location, end: Location): Viewable(), Disposable {

private companion object {
val NO_COLLISION_TEAM = TeamManager.create("beam_no_collision_${UUID.randomUUID()}", LegacyTextColor.WHITE)

init {
NO_COLLISION_TEAM.teamCollisionRule.value = TeamCollisionRule.NEVER
}
}

private val bindablePool = BindablePool()

val start: Bindable<Location> = bindablePool.provideBindable(start)
val end: Bindable<Location> = bindablePool.provideBindable(end)

private val guardianEntity: Guardian = start.world.spawnEntity(Guardian(start)) as Guardian
private val targetEntity: Squid = start.world.spawnEntity(Squid(end)) as Squid

private var currentStartMoveTask: SchedulerTask? = null
private var currentEndMoveTask: SchedulerTask? = null

override var autoViewable: Boolean = false // doesnt even work

init {
targetEntity.isInvisible.value = true
guardianEntity.isInvisible.value = true

targetEntity.team.value = NO_COLLISION_TEAM
guardianEntity.team.value = NO_COLLISION_TEAM

guardianEntity.target.value = targetEntity

this.start.valueChanged { change ->
guardianEntity.teleport(change.newValue)
}

this.end.valueChanged { change ->
targetEntity.teleport(change.newValue)
}
}

override fun addViewer(player: Player) {
targetEntity.addViewer(player)
guardianEntity.addViewer(player)
}

override fun removeViewer(player: Player) {
targetEntity.removeViewer(player)
guardianEntity.removeViewer(player)
}

override fun dispose() {
start.value.world.despawnEntity(targetEntity)
start.value.world.despawnEntity(guardianEntity)
bindablePool.dispose()
}

fun moveEnd(newLocation: Location, interpolation: Duration = 0.ticks) {
val scheduler = start.value.world.scheduler
val totalTicks = round(interpolation.inWholeMilliseconds / 50f).toInt()

currentEndMoveTask?.cancel()

var currentTick = 0
currentEndMoveTask = scheduler.runRepeating(1.ticks) {
currentTick++
if(currentTick == totalTicks) currentEndMoveTask?.cancel()

val time = percent(totalTicks, currentTick) / 100f
val loc = locationLerp(targetEntity.location, newLocation, time)
end.value = loc
}
}

fun moveStart(newLocation: Location, interpolation: Duration = 0.ticks) {
val scheduler = start.value.world.scheduler
val totalTicks = round(interpolation.inWholeMilliseconds / 50f).toInt()

currentStartMoveTask?.cancel()

var currentTick = 0
currentStartMoveTask = scheduler.runRepeating(1.ticks) {
currentTick++
if(currentTick == totalTicks) currentStartMoveTask?.cancel()

val time = percent(totalTicks, currentTick) / 100f
val loc = locationLerp(guardianEntity.location, newLocation, time)
start.value = loc
}
}

fun cancelMovement() {
currentStartMoveTask?.cancel()
currentEndMoveTask?.cancel()
currentStartMoveTask = null
currentEndMoveTask = null
}
}
12 changes: 12 additions & 0 deletions src/main/kotlin/io/github/dockyardmc/entity/ElderGuardian.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.github.dockyardmc.entity

import cz.lukynka.Bindable
import io.github.dockyardmc.location.Location
import io.github.dockyardmc.registry.EntityTypes
import io.github.dockyardmc.registry.registries.EntityType

class ElderGuardian(location: Location): Guardian(location) {

override var health: Bindable<Float> = bindablePool.provideBindable(80f)
override var type: EntityType = EntityTypes.ELDER_GUARDIAN
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@ enum class EntityMetadataType(var index: Int) {
TEXT_DISPLAY_FORMATTING(27),
ITEM_DISPLAY_ITEM(23),
ITEM_DISPLAY_RENDER_TYPE(24),
BLOCK_DISPLAY_BLOCK(23)
BLOCK_DISPLAY_BLOCK(23),
GUARDIAN_RETRACTING_SPIKES(16),
GUARDIAN_TARGET_ENTITY_ID(17),
}


Expand Down
31 changes: 31 additions & 0 deletions src/main/kotlin/io/github/dockyardmc/entity/Guardian.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.github.dockyardmc.entity

import cz.lukynka.Bindable
import io.github.dockyardmc.location.Location
import io.github.dockyardmc.registry.EntityTypes
import io.github.dockyardmc.registry.registries.EntityType

open class Guardian(location: Location): Entity(location) {

companion object {
val RETRACTING_SPIKES_METADATA = EntityMetadataType.GUARDIAN_RETRACTING_SPIKES
val TARGET_ENTITY_ID = EntityMetadataType.GUARDIAN_TARGET_ENTITY_ID
}

override var type: EntityType = EntityTypes.GUARDIAN
override var health: Bindable<Float> = bindablePool.provideBindable(30f)
override var inventorySize: Int = 0

val isRetractingSpikes: Bindable<Boolean> = bindablePool.provideBindable(false)
val target: Bindable<Entity?> = bindablePool.provideBindable(null)

init {
isRetractingSpikes.valueChanged { change ->
metadata[RETRACTING_SPIKES_METADATA] = EntityMetadata(RETRACTING_SPIKES_METADATA, EntityMetaValue.BOOLEAN, change.newValue)
}

target.valueChanged { change ->
metadata[TARGET_ENTITY_ID] = EntityMetadata(TARGET_ENTITY_ID, EntityMetaValue.VAR_INT, change.newValue?.entityId ?: 0)
}
}
}
12 changes: 12 additions & 0 deletions src/main/kotlin/io/github/dockyardmc/entity/Squid.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.github.dockyardmc.entity

import cz.lukynka.Bindable
import io.github.dockyardmc.location.Location
import io.github.dockyardmc.registry.EntityTypes
import io.github.dockyardmc.registry.registries.EntityType

class Squid(location: Location): Entity(location) {
override var type: EntityType = EntityTypes.SQUID
override var health: Bindable<Float> = bindablePool.provideBindable(10f)
override var inventorySize: Int = 0
}
6 changes: 5 additions & 1 deletion src/main/kotlin/io/github/dockyardmc/utils/MathUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import java.io.File
import java.security.MessageDigest
import java.util.Random
import kotlin.math.*
import kotlin.time.times

fun multiplyQuaternions(q1: Quaternion, q2: Quaternion): Quaternion {
val x = q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y
Expand Down Expand Up @@ -59,7 +60,10 @@ fun getRelativeLocation(current: Location, previous: Location): Location {
return Location(x, y, z, current.world)
}

fun percent(max: Double, part: Double): Double = (part / max) * 100
fun percent(max: Double, part: Double): Double = (part / max) * 100.0
fun percent(max: Int, part: Int): Float = (part.toFloat() / max.toFloat()) * 100
fun percent(max: Float, part: Float): Float = (part / max) * 100f
fun percent(max: Long, part: Long): Float = (part.toFloat() / max.toFloat()) * 100L

// percent is float 0f - 1f.
fun percentOf(percent: Float, max: Double): Double = percent * max
Expand Down

0 comments on commit 9d7a38a

Please sign in to comment.