Skip to content
Closed
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ kotlin-coroutine = "1.10.2"
kotlin-runtime = "4.3.1"
kotlinx-serialization = "1.9.0"
java = "17"
mindustry = "152"
mindustry = "153"

# libraries
distributor = "4.2.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ data class MindustryConfig(
val tipsDelay: Duration = 5.minutes,
val afkDelay: Duration = 10.minutes,
val afkKickDelay: Duration = 15.minutes,
// val reviveCore: TODO FINISHME
) {
init {
if (afkDelay >= afkKickDelay) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import com.xpdustry.imperium.mindustry.world.ItemCommand
import com.xpdustry.imperium.mindustry.world.KillAllCommand
import com.xpdustry.imperium.mindustry.world.MapListener
import com.xpdustry.imperium.mindustry.world.ResourceHudListener
import com.xpdustry.imperium.mindustry.world.ReviveCoreCommand
import com.xpdustry.imperium.mindustry.world.RockTheVoteCommand
import com.xpdustry.imperium.mindustry.world.SaveCommand
import com.xpdustry.imperium.mindustry.world.SpawnCommand
Expand Down Expand Up @@ -193,6 +194,7 @@ class ImperiumPlugin : AbstractMindustryPlugin() {
DayNightCycleListener::class,
ImperiumPermissionListener::class,
ItemCommand::class,
ReviveCoreCommand::class,
)
.forEach(application::register)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* Imperium, the software collection powering the Chaotic Neutral network.
* Copyright (C) 2024 Xpdustry
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.xpdustry.imperium.mindustry.world

import com.xpdustry.distributor.api.annotation.EventHandler
import com.xpdustry.distributor.api.command.CommandSender
import com.xpdustry.distributor.api.component.Component
import com.xpdustry.distributor.api.component.ListComponent.components
import com.xpdustry.distributor.api.component.TranslatableComponent.translatable
import com.xpdustry.distributor.api.component.style.ComponentColor.*
import com.xpdustry.distributor.api.translation.TranslationArguments
import com.xpdustry.imperium.common.application.ImperiumApplication
import com.xpdustry.imperium.common.command.ImperiumCommand
import com.xpdustry.imperium.common.config.ImperiumConfig
import com.xpdustry.imperium.common.inject.InstanceManager
import com.xpdustry.imperium.common.inject.get
import com.xpdustry.imperium.mindustry.command.annotation.ClientSide
import com.xpdustry.imperium.mindustry.command.annotation.ServerSide
import com.xpdustry.imperium.mindustry.game.MenuToPlayEvent
import com.xpdustry.imperium.mindustry.misc.asAudience
import mindustry.Vars
import mindustry.content.Items
import mindustry.content.Planets
import mindustry.game.EventType
import mindustry.type.ItemStack
import mindustry.world.Block
import mindustry.world.blocks.storage.CoreBlock
import org.incendo.cloud.annotation.specifier.Range

// This code makes me cry
class ReviveCoreCommand(instances: InstanceManager) : ImperiumApplication.Listener {
val config = instances.get<ImperiumConfig>()
val coreList = mutableSetOf<CoreTile>()

@EventHandler
fun onBlockDestroy(event: EventType.BlockDestroyEvent) {
if (event.tile.block() !is CoreBlock) return
val block = event.tile.build
coreList.add(CoreTile(block.tileX(), block.tileY(), block.block as CoreBlock))
}

@EventHandler
fun onGameOver(event: MenuToPlayEvent) {
coreList.clear()
}

@ImperiumCommand(["revivecore|rc"])
@ClientSide
@ServerSide
fun onReviveCommand(sender: CommandSender, core: Int) {
val cores = coreList.toList()
val revive =
cores.getOrNull(core)
?: return sender.player.asAudience.sendMessage(translatable("imperium.revivecore.invalidcore", SCARLET))
if (!canReviveCore(revive, sender)) return
Vars.world.tile(revive.tileX, revive.tileY).setNet(revive.core as Block, sender.player.team(), 0)
coreList.remove(revive)
}

@ImperiumCommand(["revivecore|rc", "list"])
@ClientSide
@ServerSide
// TODO: better name?
fun onReviveCommandPage(sender: CommandSender) {
onReviveCommandList(sender, 1)
}

@ImperiumCommand(["revivecore|rc", "list"])
@ClientSide
@ServerSide
fun onReviveCommandList(sender: CommandSender, @Range(min = "1") page: Int) {
val cores = coreList.toList()
val entries = cores.chunked(5)
val pages = StringBuilder()
val pageEntry =
entries.getOrNull(page - 1) ?: return sender.player.asAudience.sendMessage(invalid_revivecore_page())
var counter: Int = (page - 1) * 5
for (entry in pageEntry) {
pages.append(
"[${counter}] ${entry.core.localizedName} (${entry.tileX}, ${entry.tileY}) - ${cost(entry.core)}\n"
)
counter++
}
sender.player.asAudience.sendMessage(corepage(pages.toString(), page, entries.size))
}

fun invalid_revivecore_page(): Component = components(SCARLET, translatable("imperium.revivecore.invalidpage"))

fun corepage(page: String, pageNumber: Int, pageCount: Int): Component =
components(
WHITE,
translatable("imperium.revivecore.pages", TranslationArguments.array(page, pageNumber, pageCount)),
)

// FINISHME: configable items... this doesnt work in erekir
fun canReviveCore(core: CoreTile, sender: CommandSender): Boolean {
val team = sender.player.team()
var canAfford: Boolean = false
if (Vars.state.rules.planet == Planets.serpulo) {
val surge = team.data().core().items.get(Items.surgeAlloy) >= 10000
val blast = team.data().core().items.get(Items.blastCompound) >= 8000
canAfford = surge && blast
}

return canAfford
}

// FINISHME: tell the players the required items, not this filler
fun cost(core: CoreBlock): String {
val items = ItemStack()
items.set(Items.copper, 1)
return items.toString() // outputs: "copper: 1"
}
}

data class CoreTile(val tileX: Int, val tileY: Int, val core: CoreBlock)
Original file line number Diff line number Diff line change
Expand Up @@ -293,4 +293,8 @@ imperium.killall.force.success.type=of type {0}
imperium.killall.force.success.team=from the {0} team.
imperium.player.afk.enabled=You have been marked as AFK
imperium.player.afk.disabled=You are no longer marked as AFK
imperium.player.afk.kicked=You have been kicked for being AFK for too long.
imperium.player.afk.kicked=You have been kicked for being AFK for too long.
# AHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
imperium.revivecore.pages = List of Revivable Cores\n------------------------------\n{0}\nPage {1} of {2}
imperium.revivecore.invalidpage = Invalid revive core page! Use a valid core page
imperium.revivecore.invalidcore = Invalid core number used! Use /rc list to view the revive-able cores
Loading