mirror of
https://github.com/Artillex-Studios/AxMinions.git
synced 2024-11-22 11:35:19 +01:00
Add charge feature
This commit is contained in:
parent
61532f1087
commit
41506f281a
@ -40,6 +40,16 @@ class Config(file: File, stream: InputStream) {
|
||||
@JvmStatic
|
||||
fun PRICES_HOOK() = AxMinionsAPI.INSTANCE.getConfig().get("hooks.prices", "ShopGUIPlus")
|
||||
@JvmStatic
|
||||
fun CHARGE_ENABLED() = AxMinionsAPI.INSTANCE.getConfig().get("charge.enabled", false)
|
||||
@JvmStatic
|
||||
fun CHARGE_AMOUNT() = AxMinionsAPI.INSTANCE.getConfig().get("charge.amount", 1800)
|
||||
@JvmStatic
|
||||
fun MAX_CHARGE() = AxMinionsAPI.INSTANCE.getConfig().get("charge.max-charge", 1440)
|
||||
@JvmStatic
|
||||
fun CHARGE_PRICE() = AxMinionsAPI.INSTANCE.getConfig().get("charge.price", 10000.0)
|
||||
@JvmStatic
|
||||
fun TIMER_FORMAT() = AxMinionsAPI.INSTANCE.getConfig().get("timer-format", 1)
|
||||
@JvmStatic
|
||||
fun GUI_SIZE() = AxMinionsAPI.INSTANCE.getConfig().get<Int>("gui.size")
|
||||
@JvmStatic
|
||||
fun PULL_FROM_CHEST() = AxMinionsAPI.INSTANCE.getConfig().get("pull-tools-from-chest", false)
|
||||
|
@ -27,6 +27,16 @@ class Messages(file: File, stream: InputStream) {
|
||||
@JvmStatic
|
||||
fun CONTAINER_FULL_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.container-full")
|
||||
@JvmStatic
|
||||
fun TIME_DAY() = AxMinionsAPI.INSTANCE.getMessages().get<Long>("time.day")
|
||||
@JvmStatic
|
||||
fun TIME_HOUR() = AxMinionsAPI.INSTANCE.getMessages().get<Long>("time.hour")
|
||||
@JvmStatic
|
||||
fun TIME_MINUTE() = AxMinionsAPI.INSTANCE.getMessages().get<Long>("time.minute")
|
||||
@JvmStatic
|
||||
fun TIME_SECOND() = AxMinionsAPI.INSTANCE.getMessages().get<Long>("time.second")
|
||||
@JvmStatic
|
||||
fun NO_CHARGE_WARNING() = AxMinionsAPI.INSTANCE.getMessages().get<String>("warnings.no-charge")
|
||||
@JvmStatic
|
||||
fun RELOAD_SUCCESS() = AxMinionsAPI.INSTANCE.getMessages().get<String>("reload")
|
||||
@JvmStatic
|
||||
fun PLACE_SUCCESS() = AxMinionsAPI.INSTANCE.getMessages().get<String>("place.success")
|
||||
@ -46,6 +56,10 @@ class Messages(file: File, stream: InputStream) {
|
||||
fun ROTATION_NAME(direction: Direction) = AxMinionsAPI.INSTANCE.getMessages().get("directions.${direction.name.lowercase(
|
||||
Locale.ENGLISH)}", direction.name)
|
||||
@JvmStatic
|
||||
fun CHARGE() = AxMinionsAPI.INSTANCE.getMessages().get<String>("charge.charge")
|
||||
@JvmStatic
|
||||
fun CHARGE_FAIL() = AxMinionsAPI.INSTANCE.getMessages().get<String>("charge.not-enough-money")
|
||||
@JvmStatic
|
||||
fun WRONG_TOOL() = AxMinionsAPI.INSTANCE.getMessages().get<String>("tools.wrong-tool")
|
||||
@JvmStatic
|
||||
fun ERROR_INVENTORY_FULL() = AxMinionsAPI.INSTANCE.getMessages().get<String>("errors.inventory-full")
|
||||
|
@ -113,4 +113,8 @@ interface Minion : InventoryHolder {
|
||||
fun isOwnerOnline(): Boolean
|
||||
|
||||
fun setOwnerOnline(online: Boolean)
|
||||
|
||||
fun getCharge(): Long
|
||||
|
||||
fun setCharge(charge: Long)
|
||||
}
|
@ -73,11 +73,11 @@ abstract class MinionType(private val name: String, private val defaults: InputS
|
||||
}
|
||||
|
||||
fun getDouble(key: String, level: Int): Double {
|
||||
return get(key, level, -1.0, Double::class.java)!!
|
||||
return get(key, level, 0.0, Double::class.java)!!
|
||||
}
|
||||
|
||||
fun getLong(key: String, level: Int): Long {
|
||||
return get(key, level, -1, Long::class.java)!!
|
||||
return get(key, level, 0, Long::class.java)!!
|
||||
}
|
||||
|
||||
fun getSection(key: String, level: Int): Section? {
|
||||
|
@ -0,0 +1,55 @@
|
||||
package com.artillexstudios.axminions.api.utils
|
||||
|
||||
import com.artillexstudios.axminions.api.config.Config
|
||||
import com.artillexstudios.axminions.api.config.Messages
|
||||
import java.time.Duration
|
||||
|
||||
object TimeUtils {
|
||||
|
||||
fun format(time: Long): String {
|
||||
if (time < 0) return "---"
|
||||
|
||||
val remainingTime: Duration = Duration.ofMillis(time)
|
||||
val total: Long = remainingTime.seconds
|
||||
val days = total / 86400
|
||||
val hours = (total % 86400) / 3600
|
||||
val minutes = (total % 3600) / 60
|
||||
val seconds = total % 60
|
||||
|
||||
when (Config.TIMER_FORMAT()) {
|
||||
1 -> {
|
||||
if (days > 0) return String.format("%02d:%02d:%02d:%02d", days, hours, minutes, seconds)
|
||||
if (hours > 0) return String.format("%02d:%02d:%02d", hours, minutes, seconds)
|
||||
return String.format("%02d:%02d", minutes, seconds)
|
||||
}
|
||||
|
||||
2 -> {
|
||||
if (days > 0) return days.toString() + Messages.TIME_DAY()
|
||||
if (hours > 0) return hours.toString() + Messages.TIME_HOUR()
|
||||
if (minutes > 0) return minutes.toString() + Messages.TIME_MINUTE()
|
||||
return seconds.toString() + Messages.TIME_SECOND()
|
||||
}
|
||||
|
||||
else -> {
|
||||
if (days > 0) return java.lang.String.format(
|
||||
((("%02d" + Messages.TIME_DAY()) + " %02d" + Messages.TIME_HOUR()) + " %02d" + Messages.TIME_MINUTE()) + " %02d" + Messages.TIME_SECOND(),
|
||||
days,
|
||||
hours,
|
||||
minutes,
|
||||
seconds
|
||||
)
|
||||
if (hours > 0) return java.lang.String.format(
|
||||
(("%02d" + Messages.TIME_HOUR()) + " %02d" + Messages.TIME_MINUTE()) + " %02d" + Messages.TIME_SECOND(),
|
||||
hours,
|
||||
minutes,
|
||||
seconds
|
||||
)
|
||||
return java.lang.String.format(
|
||||
("%02d" + Messages.TIME_MINUTE()) + " %02d" + Messages.TIME_SECOND(),
|
||||
minutes,
|
||||
seconds
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ package com.artillexstudios.axminions.api.warnings
|
||||
|
||||
import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.warnings.impl.WarningContainerFull
|
||||
import com.artillexstudios.axminions.api.warnings.impl.WarningNoCharge
|
||||
import com.artillexstudios.axminions.api.warnings.impl.WarningNoContainer
|
||||
import com.artillexstudios.axminions.api.warnings.impl.WarningNoTool
|
||||
import com.artillexstudios.axminions.api.warnings.impl.WarningNoWaterNearby
|
||||
@ -21,6 +22,9 @@ object Warnings {
|
||||
@JvmField
|
||||
val NO_WATER_NEARBY = register(WarningNoWaterNearby())
|
||||
|
||||
@JvmField
|
||||
val NO_CHARGE = register(WarningNoCharge())
|
||||
|
||||
@JvmStatic
|
||||
fun register(warning: Warning): Warning {
|
||||
WARNINGS[warning.getName()] = warning
|
||||
|
@ -0,0 +1,13 @@
|
||||
package com.artillexstudios.axminions.api.warnings.impl
|
||||
|
||||
import com.artillexstudios.axapi.utils.StringUtils
|
||||
import com.artillexstudios.axminions.api.config.Messages
|
||||
import com.artillexstudios.axminions.api.warnings.Warning
|
||||
import net.kyori.adventure.text.Component
|
||||
|
||||
class WarningNoCharge : Warning("no_charge") {
|
||||
|
||||
override fun getContent(): Component {
|
||||
return StringUtils.format(Messages.NO_CHARGE_WARNING())
|
||||
}
|
||||
}
|
@ -67,6 +67,12 @@ class H2DataHandler : DataHandler {
|
||||
it.executeUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
dataSource.connection.use { connection ->
|
||||
connection.prepareStatement("ALTER TABLE `axminions_minions` ADD COLUMN IF NOT EXISTS `charge` BIGINT DEFAULT(0);").use {
|
||||
it.executeUpdate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun insertType(minionType: MinionType) {
|
||||
@ -105,6 +111,7 @@ class H2DataHandler : DataHandler {
|
||||
val storage = resultSet.getDouble("storage")
|
||||
val actions = resultSet.getLong("actions")
|
||||
val tool = resultSet.getString("tool")
|
||||
val charge = resultSet.getLong("charge")
|
||||
|
||||
val location = getLocation(locationId)
|
||||
var chestLocation: Location? = null
|
||||
@ -129,7 +136,8 @@ class H2DataHandler : DataHandler {
|
||||
actions,
|
||||
storage,
|
||||
locationId,
|
||||
chestLocationId
|
||||
chestLocationId,
|
||||
charge
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -255,7 +263,7 @@ class H2DataHandler : DataHandler {
|
||||
}
|
||||
|
||||
dataSource.connection.use { connection ->
|
||||
connection.prepareStatement("MERGE INTO `axminions_minions`(`location_id`, `chest_location_id`, `owner_id`, `type_id`, `direction`, `level`, `storage`, `actions`, `tool`) KEY(`location_id`) VALUES(?,?,?,?,?,?,?,?,?)")
|
||||
connection.prepareStatement("MERGE INTO `axminions_minions`(`location_id`, `chest_location_id`, `owner_id`, `type_id`, `direction`, `level`, `storage`, `actions`, `tool`, `charge`) KEY(`location_id`) VALUES(?,?,?,?,?,?,?,?,?,?)")
|
||||
.use { statement ->
|
||||
statement.setInt(1, locationId)
|
||||
if (linkedChestId == null) {
|
||||
@ -274,6 +282,7 @@ class H2DataHandler : DataHandler {
|
||||
} else {
|
||||
statement.setString(9, Serializers.ITEM_STACK.serialize(minion.getTool()))
|
||||
}
|
||||
statement.setLong(10, minion.getCharge())
|
||||
statement.executeUpdate()
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
|
||||
import com.artillexstudios.axminions.api.utils.CoolDown
|
||||
import com.artillexstudios.axminions.api.utils.Keys
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import java.util.Locale
|
||||
import net.md_5.bungee.api.ChatMessageType
|
||||
import net.md_5.bungee.api.chat.TextComponent
|
||||
import org.bukkit.Material
|
||||
@ -146,7 +147,7 @@ class MinionInventoryListener : Listener {
|
||||
}
|
||||
|
||||
if (Config.UPGRADE_SOUND().isNotBlank()) {
|
||||
player.playSound(player, Config.UPGRADE_SOUND(), 1.0f, 1.0f)
|
||||
player.playSound(player, Sound.valueOf(Config.UPGRADE_SOUND().uppercase(Locale.ENGLISH)), 1.0f, 1.0f)
|
||||
}
|
||||
|
||||
minion.setLevel(minion.getLevel() + 1)
|
||||
@ -171,6 +172,38 @@ class MinionInventoryListener : Listener {
|
||||
minion.setStorage(0.0)
|
||||
}
|
||||
}
|
||||
|
||||
"charge" -> {
|
||||
if ((AxMinionsPlugin.integrations.getEconomyIntegration()?.getBalance(player)
|
||||
?: return) < Config.CHARGE_PRICE()
|
||||
) {
|
||||
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE_FAIL()))
|
||||
return
|
||||
}
|
||||
|
||||
AxMinionsPlugin.integrations.getEconomyIntegration()?.let {
|
||||
minion.getOwner()?.let { player ->
|
||||
it.takeBalance(player, Config.CHARGE_PRICE())
|
||||
}
|
||||
}
|
||||
|
||||
val chargeSeconds = (minion.getCharge() - System.currentTimeMillis()) / 1000
|
||||
|
||||
if (chargeSeconds + Config.CHARGE_AMOUNT() > Config.MAX_CHARGE() * 60L) {
|
||||
minion.setCharge(System.currentTimeMillis() + Config.MAX_CHARGE() * 60L * 1000L)
|
||||
return
|
||||
}
|
||||
|
||||
if (minion.getCharge() < System.currentTimeMillis()) {
|
||||
minion.setCharge(System.currentTimeMillis() + Config.CHARGE_AMOUNT() * 1000)
|
||||
} else {
|
||||
minion.setCharge(minion.getCharge() + Config.CHARGE_AMOUNT() * 1000)
|
||||
}
|
||||
|
||||
if (Messages.CHARGE().isNotBlank()) {
|
||||
player.sendMessage(StringUtils.formatToString(Messages.PREFIX() + Messages.CHARGE()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
minion.updateInventories()
|
||||
|
@ -21,6 +21,7 @@ import com.artillexstudios.axminions.api.minions.Minion
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionType
|
||||
import com.artillexstudios.axminions.api.minions.miniontype.MinionTypes
|
||||
import com.artillexstudios.axminions.api.utils.Keys
|
||||
import com.artillexstudios.axminions.api.utils.TimeUtils
|
||||
import com.artillexstudios.axminions.api.utils.fastFor
|
||||
import com.artillexstudios.axminions.api.warnings.Warning
|
||||
import com.artillexstudios.axminions.api.warnings.Warnings
|
||||
@ -40,6 +41,7 @@ import org.bukkit.entity.Player
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import org.bukkit.inventory.meta.Damageable
|
||||
import org.bukkit.inventory.meta.ItemMeta
|
||||
import org.bukkit.persistence.PersistentDataType
|
||||
import org.bukkit.util.EulerAngle
|
||||
|
||||
@ -55,7 +57,8 @@ class Minion(
|
||||
private var actions: Long,
|
||||
private var storage: Double,
|
||||
private val locationID: Int,
|
||||
private var chestLocationId: Int
|
||||
private var chestLocationId: Int,
|
||||
private var charge: Long
|
||||
) : Minion {
|
||||
companion object {
|
||||
private val numberFormat = NumberFormat.getCompactNumberInstance(Locale.ENGLISH, NumberFormat.Style.SHORT)
|
||||
@ -72,6 +75,7 @@ class Minion(
|
||||
private val extraData = hashMapOf<String, String>()
|
||||
private var linkedInventory: Inventory? = null
|
||||
internal val openInventories = mutableListOf<Inventory>()
|
||||
private var toolMeta: ItemMeta? = null
|
||||
|
||||
@Volatile
|
||||
private var ticking = false
|
||||
@ -188,6 +192,13 @@ class Minion(
|
||||
debugHologram?.setLine(0, StringUtils.format("Ticking: $ticking"))
|
||||
}
|
||||
|
||||
if (Config.CHARGE_ENABLED() && getCharge() < System.currentTimeMillis()) {
|
||||
Warnings.NO_CHARGE.display(this)
|
||||
return
|
||||
}
|
||||
|
||||
Warnings.remove(this, Warnings.NO_CHARGE)
|
||||
|
||||
Scheduler.get().executeAt(location) {
|
||||
type.tick(this)
|
||||
}
|
||||
@ -207,7 +218,7 @@ class Minion(
|
||||
private fun updateInventory(inventory: Inventory) {
|
||||
AxMinionsAPI.INSTANCE.getConfig().getConfig().getSection("gui.items").getRoutesAsStrings(false).forEach {
|
||||
if (it.equals("filler")) return@forEach
|
||||
val item: ItemStack
|
||||
val item: ItemStack?
|
||||
if (it.equals("upgrade", true) || it.equals("statistics", true)) {
|
||||
val level = Placeholder.parsed("level", level.toString())
|
||||
val nextLevel = Placeholder.parsed(
|
||||
@ -287,6 +298,15 @@ class Minion(
|
||||
).get()
|
||||
} else if (it.equals("item")) {
|
||||
item = tool?.clone() ?: ItemStack(Material.AIR)
|
||||
} else if (it.equals("charge")) {
|
||||
if (Config.CHARGE_ENABLED()) {
|
||||
val charge = Placeholder.parsed("charge", TimeUtils.format(charge - System.currentTimeMillis()))
|
||||
item = ItemBuilder(type.getConfig().getSection("gui.$it"), charge).storePersistentData(
|
||||
Keys.GUI, PersistentDataType.STRING, it
|
||||
).get()
|
||||
} else {
|
||||
item = null
|
||||
}
|
||||
} else {
|
||||
val rotation = Placeholder.unparsed("direction", Messages.ROTATION_NAME(direction))
|
||||
val linked = Placeholder.unparsed(
|
||||
@ -304,7 +324,9 @@ class Minion(
|
||||
).get()
|
||||
}
|
||||
|
||||
inventory.setItem(AxMinionsAPI.INSTANCE.getConfig().get("gui.items.$it.slot"), item)
|
||||
if (item != null) {
|
||||
inventory.setItem(AxMinionsAPI.INSTANCE.getConfig().get("gui.items.$it.slot"), item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -373,6 +395,12 @@ class Minion(
|
||||
|
||||
override fun setTool(tool: ItemStack, save: Boolean) {
|
||||
this.tool = tool.clone()
|
||||
toolMeta = if (!tool.type.isAir) {
|
||||
tool.itemMeta
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
||||
dirty = true
|
||||
|
||||
if (this.tool?.type == Material.AIR) {
|
||||
@ -456,6 +484,8 @@ class Minion(
|
||||
|
||||
updateInventories()
|
||||
}
|
||||
} else {
|
||||
linkedInventory = null
|
||||
}
|
||||
|
||||
AxMinionsPlugin.dataQueue.submit {
|
||||
@ -595,7 +625,7 @@ class Minion(
|
||||
override fun damageTool(amount: Int) {
|
||||
if (!Config.USE_DURABILITY()) return
|
||||
|
||||
val meta = this.tool?.itemMeta as? Damageable ?: return
|
||||
val meta = toolMeta as? Damageable ?: return
|
||||
|
||||
if (Math.random() > 1f / (meta.getEnchantLevel(Enchantment.DURABILITY) + 1)) return
|
||||
|
||||
@ -641,7 +671,7 @@ class Minion(
|
||||
}
|
||||
|
||||
override fun canUseTool(): Boolean {
|
||||
val meta = this.tool?.itemMeta ?: return false
|
||||
val meta = toolMeta ?: return false
|
||||
|
||||
if (!Config.USE_DURABILITY() && meta is Damageable) {
|
||||
return true
|
||||
@ -688,7 +718,7 @@ class Minion(
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun isOwnerOnline(): Boolean {
|
||||
@ -699,6 +729,18 @@ class Minion(
|
||||
ownerOnline = online
|
||||
}
|
||||
|
||||
override fun getCharge(): Long {
|
||||
return charge
|
||||
}
|
||||
|
||||
override fun setCharge(charge: Long) {
|
||||
this.charge = charge
|
||||
|
||||
AxMinionsPlugin.dataQueue.submit {
|
||||
AxMinionsPlugin.dataHandler.saveMinion(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getInventory(): Inventory {
|
||||
return Bukkit.createInventory(this, 9)
|
||||
}
|
||||
|
@ -67,6 +67,17 @@ hooks:
|
||||
# Supported prices providers: ShopGUIPlus, Essentials, EconomyShopGUI, CMI, custom
|
||||
prices: "ShopGUIPlus"
|
||||
|
||||
charge:
|
||||
enabled: false
|
||||
amount: 1800 # in seconds
|
||||
max-charge: 1440 # in minutes
|
||||
price: 10000
|
||||
|
||||
# 1 - HH:MM:SS, for example 01:25:35
|
||||
# 2 - short format, for example 20m
|
||||
# 3 - text format, for example 01h 25m 35s
|
||||
timer-format: 1
|
||||
|
||||
gui:
|
||||
size: 27
|
||||
items:
|
||||
@ -100,10 +111,19 @@ gui:
|
||||
slot: 15
|
||||
statistics:
|
||||
slot: 16
|
||||
charge:
|
||||
type: "lava_bucket"
|
||||
name: "<#FB8E08><b>Charge"
|
||||
lore:
|
||||
- ""
|
||||
- " <gray>- <white>Current charge: <#FFCC00><charge>"
|
||||
- ""
|
||||
- "<#FB8E08><b>(!)</b> Click here to charge your minion for <white>10 minutes</white> for <white>$10,000</white>!"
|
||||
slot: 9
|
||||
|
||||
# Only change this, if you are asked to! This will make your performance worse, and will spam messages in your console!
|
||||
# Requires restart!
|
||||
debug: false
|
||||
|
||||
# Do not change!
|
||||
config-version: 6
|
||||
config-version: 7
|
@ -23,6 +23,13 @@ warnings:
|
||||
no-tool: "<#FF3333>⚠ <#FFAAAA>The minion needs a tool </#FFAAAA>⚠"
|
||||
no-water-nearby: "<#FF3333>⚠ <#FFAAAA>The minion needs water nearby </#FFAAAA>⚠"
|
||||
container-full: "<#FF3333>⚠ <#FFAAAA>The container of this minion is full </#FFAAAA>⚠"
|
||||
no-charge: "<#FF3333>⚠ <#FFAAAA>The minion ran out of charge! Refuel it!</#FFAAAA>⚠"
|
||||
|
||||
time:
|
||||
day: "d"
|
||||
hour: "h"
|
||||
minute: "m"
|
||||
second: "s"
|
||||
|
||||
statistics: |
|
||||
<white>Ticking minions: <gradient:#00aaff:#00ccff><ticking></gradient>
|
||||
@ -58,8 +65,12 @@ directions:
|
||||
south: "South"
|
||||
west: "West"
|
||||
|
||||
charge:
|
||||
charge: "<green>You have added <white>30 minutes</white> of charge to your minion!"
|
||||
not-enough-money: "<red>You don't have enough money to charge this minion!"
|
||||
|
||||
tools:
|
||||
wrong-tool: "<red>You can't place this item as the tool if this minion!"
|
||||
|
||||
# Do not change!
|
||||
config-version: 2
|
||||
config-version: 3
|
@ -63,7 +63,7 @@ object DamageHandler {
|
||||
|
||||
DUMMY_ENTITY?.setItemSlot(EquipmentSlot.MAINHAND, nmsItem)
|
||||
|
||||
if (!nmsEntity.isAttackable) return
|
||||
if (!nmsEntity.isAttackable || entity is Player) return
|
||||
val f2 = 1.0f
|
||||
|
||||
var f1 = if (nmsEntity is LivingEntity) {
|
||||
|
Loading…
Reference in New Issue
Block a user