This commit is contained in:
TomTom 2023-10-05 19:15:36 +02:00
parent 5495652ea9
commit b347e37f15
16 changed files with 155 additions and 19 deletions

View File

@ -23,6 +23,14 @@ class Messages(file: File, stream: InputStream) {
fun NO_WATER_NEARBY_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-water-nearby")
@JvmStatic
fun CONTAINER_FULL_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.container-full")
@JvmStatic
fun RELOAD_SUCCESS() = AxMinionsAPI.INSTANCE.getMessages().get<String>("reload")
@JvmStatic
fun PLACE_SUCCESS() = AxMinionsAPI.INSTANCE.getMessages().get<String>("place.success")
@JvmStatic
fun PLACE_LIMIT_REACHED() = AxMinionsAPI.INSTANCE.getMessages().get<String>("place.limit-reached")
@JvmStatic
fun PLACE_MINION_AT_LOCATION() = AxMinionsAPI.INSTANCE.getMessages().get<String>("place.minion-at-location")
}
private val config = Config(

View File

@ -2,6 +2,7 @@ package com.artillexstudios.axminions.api.data
import com.artillexstudios.axminions.api.minions.Minion
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import org.bukkit.Location
import java.util.UUID
interface DataHandler {
@ -18,5 +19,7 @@ interface DataHandler {
fun getMinionAmount(uuid: UUID): Int
fun isMinion(location: Location): Boolean
fun disable()
}

View File

@ -38,15 +38,16 @@ abstract class MinionType(private val name: String, private val defaults: InputS
run(minion)
}
fun getItem(): ItemStack {
fun updateArmor(minion: Minion) {
}
fun getItem(level: Int = 1): ItemStack {
val builder = ItemBuilder(config.getSection("item"))
val itemStack = builder.clonedGet()
val itemMeta = itemStack.itemMeta ?: return itemStack
builder.storePersistentData(MinionTypes.getMinionKey(), PersistentDataType.STRING, name)
builder.storePersistentData(MinionTypes.getLevelKey(), PersistentDataType.INTEGER, level)
itemMeta.persistentDataContainer.set(MinionTypes.getMinionKey(), PersistentDataType.STRING, name)
itemStack.setItemMeta(itemMeta)
return itemStack
return builder.clonedGet()
}
fun getConfig(): Config {

View File

@ -8,6 +8,7 @@ import java.util.Collections
object MinionTypes {
private val TYPES = hashMapOf<String, MinionType>()
private val MINION_KEY = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "minion_type")
private val LEVEL_KEY = NamespacedKey(AxMinionsAPI.INSTANCE.getAxMinionsInstance(), "level")
@JvmStatic
fun register(type: MinionType): MinionType {
@ -35,6 +36,11 @@ object MinionTypes {
return MINION_KEY
}
@JvmStatic
fun getLevelKey(): NamespacedKey {
return LEVEL_KEY
}
@JvmStatic
fun getMinionTypes(): Map<String, MinionType> {
return Collections.unmodifiableMap(TYPES)

View File

@ -32,6 +32,12 @@ allprojects {
jvmToolchain(17)
}
compileKotlin {
kotlinOptions {
javaParameters = true
}
}
repositories {
mavenCentral()
mavenLocal()

View File

@ -11,10 +11,13 @@ import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
import com.artillexstudios.axminions.commands.AxMinionsCommand
import com.artillexstudios.axminions.data.H2DataHandler
import com.artillexstudios.axminions.listeners.MinionPlaceListener
import com.artillexstudios.axminions.minions.MinionTicker
import com.artillexstudios.axminions.minions.miniontype.CollectorMinionType
import com.artillexstudios.axminions.minions.miniontype.FarmerMinionType
import net.byteflux.libby.BukkitLibraryManager
import net.byteflux.libby.Library
import org.bukkit.Bukkit
import revxrsal.commands.bukkit.BukkitCommandHandler
import java.io.File
@ -71,6 +74,10 @@ class AxMinionsPlugin : AxPlugin() {
handler.register(AxMinionsCommand())
handler.registerBrigadier()
Bukkit.getPluginManager().registerEvents(MinionPlaceListener(), this)
MinionTicker.startTicking()
}
private fun loadDataHandler() {

View File

@ -1,6 +1,11 @@
package com.artillexstudios.axminions.commands
import com.artillexstudios.axapi.utils.StringUtils
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
import revxrsal.commands.annotation.AutoComplete
@ -22,11 +27,18 @@ class AxMinionsCommand {
receiver.inventory.addItem(minionType.getItem())
}
@Subcommand("reload")
@CommandPermission("axminions.command.reload")
@Description("Reload the configurations of the plugin")
fun reload(sender: CommandSender) {
val start = System.currentTimeMillis()
AxMinionsPlugin.config.reload()
AxMinionsPlugin.messages.reload()
MinionTypes.getMinionTypes().forEach {
it.value.getConfig().reload()
}
sender.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.RELOAD_SUCCESS(), Placeholder.unparsed("time", (System.currentTimeMillis() - start).toString())))
}
}

View File

@ -115,6 +115,19 @@ class H2DataHandler : DataHandler {
return 0
}
override fun isMinion(location: Location): Boolean {
connection.prepareStatement("SELECT * FROM `axminions_data` WHERE `location` = ?;").use { preparedStatement ->
preparedStatement.setString(1, Serializers.LOCATION.serialize(location))
preparedStatement.executeQuery().use { resultSet ->
if (resultSet.next()) {
return true
}
}
}
return false
}
override fun disable() {
connection.close()
}

View File

@ -0,0 +1,56 @@
package com.artillexstudios.axminions.listeners
import com.artillexstudios.axapi.utils.StringUtils
import com.artillexstudios.axminions.AxMinionsPlugin
import com.artillexstudios.axminions.api.AxMinionsAPI
import com.artillexstudios.axminions.api.config.Messages
import com.artillexstudios.axminions.api.minions.Direction
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
import com.artillexstudios.axminions.minions.Minion
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder
import org.bukkit.Material
import org.bukkit.event.EventHandler
import org.bukkit.event.Listener
import org.bukkit.event.block.Action
import org.bukkit.event.player.PlayerInteractEvent
import org.bukkit.inventory.ItemStack
import org.bukkit.persistence.PersistentDataType
class MinionPlaceListener : Listener {
@EventHandler
fun onPlayerInteractEvent(event: PlayerInteractEvent) {
if (event.action != Action.RIGHT_CLICK_BLOCK && event.action != Action.RIGHT_CLICK_AIR) return
if (event.clickedBlock == null) return
if (event.item == null) return
if (!event.item!!.hasItemMeta()) return
val type = event.item!!.itemMeta!!.persistentDataContainer.get(MinionTypes.getMinionKey(), PersistentDataType.STRING) ?: return
val minionType = MinionTypes.valueOf(type) ?: return
event.isCancelled = true
val location = event.clickedBlock!!.getRelative(event.blockFace).location
location.add(0.5, 0.0, 0.5)
val maxMinions = AxMinionsAPI.INSTANCE.getMinionLimit(event.player)
AxMinionsPlugin.dataQueue.submit {
val placed = AxMinionsPlugin.dataHandler.getMinionAmount(event.player.uniqueId)
if (placed >= maxMinions && !event.player.hasPermission("axminions.limit.*")) {
event.player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.PLACE_LIMIT_REACHED(), Placeholder.unparsed("placed", placed.toString()), Placeholder.unparsed("max", maxMinions.toString())))
return@submit
}
if (AxMinionsPlugin.dataHandler.isMinion(location)) {
event.player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.PLACE_MINION_AT_LOCATION()))
return@submit
}
val minion = Minion(location, event.player.uniqueId, event.player, minionType, 1, ItemStack(Material.AIR), null, Direction.NORTH, "")
AxMinionsPlugin.dataHandler.saveMinion(minion)
event.player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.PLACE_SUCCESS()))
}
}
}

View File

@ -38,7 +38,7 @@ class Minion(
private lateinit var entity: PacketArmorStand
private var nextAction = 0
private var range = 0.0
private var dirty = false
private var dirty = true
private var armTick = 2.0
private var warning: Warning? = null
private var hologram: Hologram? = null
@ -233,7 +233,7 @@ class Minion(
}
private fun loadExtraData(data: String) {
data.split("|").fastFor { split ->
data.split("|").forEach { split ->
val secondSplit = split.split("=")
if (secondSplit.isNotEmpty()) {
extraData[secondSplit[0]] = secondSplit[1]

View File

@ -1,19 +1,21 @@
package com.artillexstudios.axminions.minions
import com.artillexstudios.axapi.scheduler.Scheduler
import com.artillexstudios.axminions.utils.fastFor
object MinionTicker {
private var tick = 0L
fun tickAll() {
// Code to tick all
private inline fun tickAll() {
Minions.getMinions().fastFor { minion ->
minion.tick()
}
tick++
}
fun startTicking() {
Scheduler.get().runTimer({ task ->
Scheduler.get().runTimer({ _ ->
tickAll()
}, 0, 0)
}

View File

@ -2,9 +2,10 @@ package com.artillexstudios.axminions.minions
import com.artillexstudios.axminions.api.minions.Minion
import java.util.Collections
import java.util.concurrent.ConcurrentLinkedQueue
object Minions {
private val entities = mutableListOf<Minion>()
private val entities = ConcurrentLinkedQueue<Minion>()
fun load(minion: Minion) {
entities.add(minion)
@ -15,6 +16,6 @@ object Minions {
}
fun getMinions(): List<Minion> {
return Collections.unmodifiableList(entities)
return Collections.unmodifiableList(entities.toList())
}
}

View File

@ -1,5 +1,20 @@
prefix: "<gradient:#00aaff:#00ccff>AxMinions</gradient> <gray>»</gray> "
reload: "<green>Plugin successfully reloaded in <white><time></white>ms!"
place:
success: "<green>Successfully placed a new <type> minion! <gray>(<placed>/<max>)"
limit-reached: "<red>Could not place minion! You have reached the limit! <gray>(<placed>/<max>)"
minion-at-location: "<red>Could not place minion! There already is a minion at that location!"
pickup:
success: "<green>Successfully picked up a minion! <gray>(<placed>/<max>)"
inventory-full: "<red>Could not pick up minion! Make some space in your inventory!"
convert:
start: "<green>Starting data conversion... "
finish: "<green>Successfully finished data conversion!"
warnings:
no-container: "<#FF3333>⚠ <#FFAAAA>You must link the minion to a container </#FFAAAA>⚠"
no-tool: "<#FF3333>⚠ <#FFAAAA>The minion needs a tool </#FFAAAA>⚠"

View File

@ -1,4 +1,7 @@
name: "<level_color>[<level>] <#FFEE00>Collector <white>Minion <gray>[<owner>]"
name: "<#FFEE00>Collector <white>Minion"
entity:
name: "<level_color>[<level>] <#FFEE00>Collector <white>Minion <gray>[<owner>]"
tool:
material:

View File

@ -1,4 +1,7 @@
name: "<level_color>[<level>] <#33FF33>Farmer <white>Minion <gray>[<owner>]"
name: "<#33FF33>Farmer <white>Minion"
entity:
name: "<level_color>[<level>] <#33FF33>Farmer <white>Minion <gray>[<owner>]"
tool:
material:

Binary file not shown.