aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/moe/nea/firmament/features/events
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2024-08-28 19:04:24 +0200
committerLinnea Gräf <nea@nea.moe>2024-08-28 19:04:24 +0200
commitd2f240ff0ca0d27f417f837e706c781a98c31311 (patch)
tree0db7aff6cc14deaf36eed83889d59fd6b3a6f599 /src/main/kotlin/moe/nea/firmament/features/events
parenta6906308163aa3b2d18fa1dc1aa71ac9bbcc83ab (diff)
downloadFirmament-d2f240ff0ca0d27f417f837e706c781a98c31311.tar.gz
Firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.tar.bz2
Firmament-d2f240ff0ca0d27f417f837e706c781a98c31311.zip
Refactor source layout
Introduce compat source sets and move all kotlin sources to the main directory [no changelog]
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/features/events')
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/events/anniversity/AnniversaryFeatures.kt224
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/events/carnival/CarnivalFeatures.kt17
-rw-r--r--src/main/kotlin/moe/nea/firmament/features/events/carnival/MinesweeperHelper.kt276
3 files changed, 0 insertions, 517 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/features/events/anniversity/AnniversaryFeatures.kt b/src/main/kotlin/moe/nea/firmament/features/events/anniversity/AnniversaryFeatures.kt
deleted file mode 100644
index 8926a95..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/events/anniversity/AnniversaryFeatures.kt
+++ /dev/null
@@ -1,224 +0,0 @@
-
-package moe.nea.firmament.features.events.anniversity
-
-import io.github.notenoughupdates.moulconfig.observer.ObservableList
-import io.github.notenoughupdates.moulconfig.xml.Bind
-import moe.nea.jarvis.api.Point
-import kotlin.time.Duration.Companion.seconds
-import net.minecraft.entity.passive.PigEntity
-import net.minecraft.util.math.BlockPos
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.events.EntityInteractionEvent
-import moe.nea.firmament.events.ProcessChatEvent
-import moe.nea.firmament.events.TickEvent
-import moe.nea.firmament.events.WorldReadyEvent
-import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
-import moe.nea.firmament.gui.hud.MoulConfigHud
-import moe.nea.firmament.rei.SBItemEntryDefinition
-import moe.nea.firmament.repo.ItemNameLookup
-import moe.nea.firmament.util.MC
-import moe.nea.firmament.util.SHORT_NUMBER_FORMAT
-import moe.nea.firmament.util.SkyblockId
-import moe.nea.firmament.util.TimeMark
-import moe.nea.firmament.util.parseShortNumber
-import moe.nea.firmament.util.useMatch
-
-object AnniversaryFeatures : FirmamentFeature {
- override val identifier: String
- get() = "anniversary"
-
- object TConfig : ManagedConfig(identifier) {
- val enableShinyPigTracker by toggle("shiny-pigs") {true}
- val trackPigCooldown by position("pig-hud", 200, 300) { Point(0.1, 0.2) }
- }
-
- override val config: ManagedConfig?
- get() = TConfig
-
- data class ClickedPig(
- val clickedAt: TimeMark,
- val startLocation: BlockPos,
- val pigEntity: PigEntity
- ) {
- @Bind("timeLeft")
- fun getTimeLeft(): Double = 1 - clickedAt.passedTime() / pigDuration
- }
-
- val clickedPigs = ObservableList<ClickedPig>(mutableListOf())
- var lastClickedPig: PigEntity? = null
-
- val pigDuration = 90.seconds
-
- @Subscribe
- fun onTick(event: TickEvent) {
- clickedPigs.removeIf { it.clickedAt.passedTime() > pigDuration }
- }
-
- val pattern = "SHINY! You extracted (?<reward>.*) from the piglet's orb!".toPattern()
-
- @Subscribe
- fun onChat(event: ProcessChatEvent) {
- if(!TConfig.enableShinyPigTracker)return
- if (event.unformattedString == "Oink! Bring the pig back to the Shiny Orb!") {
- val pig = lastClickedPig ?: return
- // TODO: store proper location based on the orb location, maybe
- val startLocation = pig.blockPos ?: return
- clickedPigs.add(ClickedPig(TimeMark.now(), startLocation, pig))
- lastClickedPig = null
- }
- if (event.unformattedString == "SHINY! The orb is charged! Click on it for loot!") {
- val player = MC.player ?: return
- val lowest =
- clickedPigs.minByOrNull { it.startLocation.getSquaredDistance(player.pos) } ?: return
- clickedPigs.remove(lowest)
- }
- pattern.useMatch(event.unformattedString) {
- val reward = group("reward")
- val parsedReward = parseReward(reward)
- addReward(parsedReward)
- PigCooldown.rewards.atOnce {
- PigCooldown.rewards.clear()
- rewards.mapTo(PigCooldown.rewards) { PigCooldown.DisplayReward(it) }
- }
- }
- }
-
- fun addReward(reward: Reward) {
- val it = rewards.listIterator()
- while (it.hasNext()) {
- val merged = reward.mergeWith(it.next()) ?: continue
- it.set(merged)
- return
- }
- rewards.add(reward)
- }
-
- val rewards = mutableListOf<Reward>()
-
- fun <T> ObservableList<T>.atOnce(block: () -> Unit) {
- val oldObserver = observer
- observer = null
- block()
- observer = oldObserver
- update()
- }
-
- sealed interface Reward {
- fun mergeWith(other: Reward): Reward?
- data class EXP(val amount: Double, val skill: String) : Reward {
- override fun mergeWith(other: Reward): Reward? {
- if (other is EXP && other.skill == skill)
- return EXP(amount + other.amount, skill)
- return null
- }
- }
-
- data class Coins(val amount: Double) : Reward {
- override fun mergeWith(other: Reward): Reward? {
- if (other is Coins)
- return Coins(other.amount + amount)
- return null
- }
- }
-
- data class Items(val amount: Int, val item: SkyblockId) : Reward {
- override fun mergeWith(other: Reward): Reward? {
- if (other is Items && other.item == item)
- return Items(amount + other.amount, item)
- return null
- }
- }
-
- data class Unknown(val text: String) : Reward {
- override fun mergeWith(other: Reward): Reward? {
- return null
- }
- }
- }
-
- val expReward = "\\+(?<exp>$SHORT_NUMBER_FORMAT) (?<kind>[^ ]+) XP".toPattern()
- val coinReward = "\\+(?<amount>$SHORT_NUMBER_FORMAT) coins".toPattern()
- val itemReward = "(?:(?<amount>[0-9]+)x )?(?<name>.*)".toPattern()
- fun parseReward(string: String): Reward {
- expReward.useMatch<Unit>(string) {
- val exp = parseShortNumber(group("exp"))
- val kind = group("kind")
- return Reward.EXP(exp, kind)
- }
- coinReward.useMatch<Unit>(string) {
- val coins = parseShortNumber(group("amount"))
- return Reward.Coins(coins)
- }
- itemReward.useMatch(string) {
- val amount = group("amount")?.toIntOrNull() ?: 1
- val name = group("name")
- val item = ItemNameLookup.guessItemByName(name, false) ?: return@useMatch
- return Reward.Items(amount, item)
- }
- return Reward.Unknown(string)
- }
-
- @Subscribe
- fun onWorldClear(event: WorldReadyEvent) {
- lastClickedPig = null
- clickedPigs.clear()
- }
-
- @Subscribe
- fun onEntityClick(event: EntityInteractionEvent) {
- if (event.entity is PigEntity) {
- lastClickedPig = event.entity
- }
- }
-
- @Subscribe
- fun init(event: WorldReadyEvent) {
- PigCooldown.forceInit()
- }
-
- object PigCooldown : MoulConfigHud("anniversary_pig", TConfig.trackPigCooldown) {
- override fun shouldRender(): Boolean {
- return clickedPigs.isNotEmpty() && TConfig.enableShinyPigTracker
- }
-
- @Bind("pigs")
- fun getPigs() = clickedPigs
-
- class DisplayReward(val backedBy: Reward) {
- @Bind
- fun count(): String {
- return when (backedBy) {
- is Reward.Coins -> backedBy.amount
- is Reward.EXP -> backedBy.amount
- is Reward.Items -> backedBy.amount
- is Reward.Unknown -> 0
- }.toString()
- }
-
- val itemStack = if (backedBy is Reward.Items) {
- SBItemEntryDefinition.getEntry(backedBy.item, backedBy.amount)
- } else {
- SBItemEntryDefinition.getEntry(SkyblockId.NULL)
- }
-
- @Bind
- fun name(): String {
- return when (backedBy) {
- is Reward.Coins -> "Coins"
- is Reward.EXP -> backedBy.skill
- is Reward.Items -> itemStack.value.asItemStack().name.string
- is Reward.Unknown -> backedBy.text
- }
- }
-
- @Bind
- fun isKnown() = backedBy !is Reward.Unknown
- }
-
- @get:Bind("rewards")
- val rewards = ObservableList<DisplayReward>(mutableListOf())
-
- }
-
-}
diff --git a/src/main/kotlin/moe/nea/firmament/features/events/carnival/CarnivalFeatures.kt b/src/main/kotlin/moe/nea/firmament/features/events/carnival/CarnivalFeatures.kt
deleted file mode 100644
index 1e6d97a..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/events/carnival/CarnivalFeatures.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-
-package moe.nea.firmament.features.events.carnival
-
-import moe.nea.firmament.features.FirmamentFeature
-import moe.nea.firmament.gui.config.ManagedConfig
-
-object CarnivalFeatures : FirmamentFeature {
- object TConfig : ManagedConfig(identifier) {
- val enableBombSolver by toggle("bombs-solver") { true }
- val displayTutorials by toggle("tutorials") { true }
- }
-
- override val config: ManagedConfig?
- get() = TConfig
- override val identifier: String
- get() = "carnival"
-}
diff --git a/src/main/kotlin/moe/nea/firmament/features/events/carnival/MinesweeperHelper.kt b/src/main/kotlin/moe/nea/firmament/features/events/carnival/MinesweeperHelper.kt
deleted file mode 100644
index 06caf86..0000000
--- a/src/main/kotlin/moe/nea/firmament/features/events/carnival/MinesweeperHelper.kt
+++ /dev/null
@@ -1,276 +0,0 @@
-
-package moe.nea.firmament.features.events.carnival
-
-import io.github.notenoughupdates.moulconfig.observer.ObservableList
-import io.github.notenoughupdates.moulconfig.platform.ModernItemStack
-import io.github.notenoughupdates.moulconfig.xml.Bind
-import java.util.UUID
-import net.minecraft.block.Blocks
-import net.minecraft.item.Item
-import net.minecraft.item.ItemStack
-import net.minecraft.item.Items
-import net.minecraft.text.ClickEvent
-import net.minecraft.text.Text
-import net.minecraft.util.math.BlockPos
-import net.minecraft.world.WorldAccess
-import moe.nea.firmament.annotations.Subscribe
-import moe.nea.firmament.commands.thenExecute
-import moe.nea.firmament.events.AttackBlockEvent
-import moe.nea.firmament.events.CommandEvent
-import moe.nea.firmament.events.EntityUpdateEvent
-import moe.nea.firmament.events.ProcessChatEvent
-import moe.nea.firmament.events.WorldReadyEvent
-import moe.nea.firmament.events.WorldRenderLastEvent
-import moe.nea.firmament.features.debug.DebugLogger
-import moe.nea.firmament.util.LegacyFormattingCode
-import moe.nea.firmament.util.MC
-import moe.nea.firmament.util.MoulConfigUtils
-import moe.nea.firmament.util.ScreenUtil
-import moe.nea.firmament.util.SkyblockId
-import moe.nea.firmament.util.item.createSkullItem
-import moe.nea.firmament.util.render.RenderInWorldContext
-import moe.nea.firmament.util.setSkyBlockFirmamentUiId
-import moe.nea.firmament.util.skyBlockId
-import moe.nea.firmament.util.useMatch
-
-object MinesweeperHelper {
- val sandBoxLow = BlockPos(-112, 72, -11)
- val sandBoxHigh = BlockPos(-106, 72, -5)
- val boardSize = Pair(sandBoxHigh.x - sandBoxLow.x, sandBoxHigh.z - sandBoxLow.z)
-
- val gameStartMessage = "[NPC] Carnival Pirateman: Good luck, matey!"
- val gameEndMessage = "Fruit Digging"
- val bombPattern = "MINES! There (are|is) (?<bombCount>[0-8]) bombs? hidden nearby\\.".toPattern()
- val startGameQuestion = "[NPC] Carnival Pirateman: Would ye like to do some Fruit Digging?"
-
-
- enum class Piece(
- @get:Bind("fruitName")
- val fruitName: String,
- val points: Int,
- val specialAbility: String,
- val totalPerBoard: Int,
- val textureHash: String,
- val fruitColor: LegacyFormattingCode,
- ) {
- COCONUT("Coconut",
- 200,
- "Prevents a bomb from exploding next turn",
- 3,
- "10ceb1455b471d016a9f06d25f6e468df9fcf223e2c1e4795b16e84fcca264ee",
- LegacyFormattingCode.DARK_PURPLE),
- APPLE("Apple",
- 100,
- "Gains 100 points for each apple dug up",
- 8,
- "17ea278d6225c447c5943d652798d0bbbd1418434ce8c54c54fdac79994ddd6c",
- LegacyFormattingCode.GREEN),
- WATERMELON("Watermelon",
- 100,
- "Blows up an adjacent fruit for half the points",
- 4,
- "efe4ef83baf105e8dee6cf03dfe7407f1911b3b9952c891ae34139560f2931d6",
- LegacyFormattingCode.DARK_BLUE),
- DURIAN("Durian",
- 800,
- "Halves the points earned in the next turn",
- 2,
- "ac268d36c2c6047ffeec00124096376b56dbb4d756a55329363a1b27fcd659cd",
- LegacyFormattingCode.DARK_PURPLE),
- MANGO("Mango",
- 300,
- "Just an ordinary fruit",
- 10,
- "f363a62126a35537f8189343a22660de75e810c6ac004a7d3da65f1c040a839",
- LegacyFormattingCode.GREEN),
- DRAGON_FRUIT("Dragonfruit",
- 1200,
- "Halves the points earned in the next turn",
- 1,
- "3cc761bcb0579763d9b8ab6b7b96fa77eb6d9605a804d838fec39e7b25f95591",
- LegacyFormattingCode.LIGHT_PURPLE),
- POMEGRANATE("Pomegranate",
- 200,
- "Grants an extra 50% more points in the next turn",
- 4,
- "40824d18079042d5769f264f44394b95b9b99ce689688cc10c9eec3f882ccc08",
- LegacyFormattingCode.DARK_BLUE),
- CHERRY("Cherry",
- 200,
- "The second cherry grants 300 bonus points",
- 2,
- "c92b099a62cd2fbf8ada09dec145c75d7fda4dc57b968bea3a8fa11e37aa48b2",
- LegacyFormattingCode.DARK_PURPLE),
- BOMB("Bomb",
- -1,
- "Destroys nearby fruit",
- 15,
- "a76a2811d1e176a07b6d0a657b910f134896ce30850f6e80c7c83732d85381ea",
- LegacyFormattingCode.DARK_RED),
- RUM("Rum",
- -1,
- "Stops your dowsing ability for one turn",
- 5,
- "407b275d28b927b1bf7f6dd9f45fbdad2af8571c54c8f027d1bff6956fbf3c16",
- LegacyFormattingCode.YELLOW),
- ;
-
- val textureUrl = "http://textures.minecraft.net/texture/$textureHash"
- val itemStack = createSkullItem(UUID.randomUUID(), textureUrl)
- .setSkyBlockFirmamentUiId("MINESWEEPER_$name")
-
- @Bind
- fun getIcon() = ModernItemStack.of(itemStack)
-
- @Bind
- fun pieceLabel() = fruitColor.formattingCode + fruitName
-
- @Bind
- fun boardLabel() = "§a$totalPerBoard§7/§rboard"
-
- @Bind("description")
- fun getDescription() = buildString {
- append(specialAbility)
- if (points >= 0) {
- append(" Default points: $points.")
- }
- }
- }
-
- object TutorialScreen {
- @get:Bind("pieces")
- val pieces = ObservableList(Piece.entries.toList().reversed())
-
- @get:Bind("modes")
- val modes = ObservableList(DowsingMode.entries.toList())
- }
-
- enum class DowsingMode(
- val itemType: Item,
- @get:Bind("feature")
- val feature: String,
- @get:Bind("description")
- val description: String,
- ) {
- MINES(Items.IRON_SHOVEL, "Bomb detection", "Tells you how many bombs are near the block"),
- ANCHOR(Items.DIAMOND_SHOVEL, "Lowest fruit", "Shows you which block nearby contains the lowest scoring fruit"),
- TREASURE(Items.GOLDEN_SHOVEL, "Highest fruit", "Tells you which kind of fruit is the highest scoring nearby"),
- ;
-
- @Bind("itemType")
- fun getItemStack() = ModernItemStack.of(ItemStack(itemType))
-
- companion object {
- val id = SkyblockId("CARNIVAL_SHOVEL")
- fun fromItem(itemStack: ItemStack): DowsingMode? {
- if (itemStack.skyBlockId != id) return null
- return DowsingMode.entries.find { it.itemType == itemStack.item }
- }
- }
- }
-
- data class BoardPosition(
- val x: Int,
- val y: Int
- ) {
- fun toBlockPos() = BlockPos(sandBoxLow.x + x, sandBoxLow.y, sandBoxLow.z + y)
-
- fun getBlock(world: WorldAccess) = world.getBlockState(toBlockPos()).block
- fun isUnopened(world: WorldAccess) = getBlock(world) == Blocks.SAND
- fun isOpened(world: WorldAccess) = getBlock(world) == Blocks.SANDSTONE
- fun isScorched(world: WorldAccess) = getBlock(world) == Blocks.SANDSTONE_STAIRS
-
- companion object {
- fun fromBlockPos(blockPos: BlockPos): BoardPosition? {
- if (blockPos.y != sandBoxLow.y) return null
- val x = blockPos.x - sandBoxLow.x
- val y = blockPos.z - sandBoxLow.z
- if (x < 0 || x >= boardSize.first) return null
- if (y < 0 || y >= boardSize.second) return null
- return BoardPosition(x, y)
- }
- }
- }
-
- data class GameState(
- val nearbyBombs: MutableMap<BoardPosition, Int> = mutableMapOf(),
- val knownBombPositions: MutableSet<BoardPosition> = mutableSetOf(),
- var lastClickedPosition: BoardPosition? = null,
- var lastDowsingMode: DowsingMode? = null,
- )
-
- var gameState: GameState? = null
- val log = DebugLogger("minesweeper")
-
- @Subscribe
- fun onCommand(event: CommandEvent.SubCommand) {
- event.subcommand("minesweepertutorial") {
- thenExecute {
- ScreenUtil.setScreenLater(MoulConfigUtils.loadScreen("carnival/minesweeper_tutorial",
- TutorialScreen,
- null))
- }
- }
- }
-
- @Subscribe
- fun onWorldChange(event: WorldReadyEvent) {
- gameState = null
- }
-
- @Subscribe
- fun onChat(event: ProcessChatEvent) {
- if (CarnivalFeatures.TConfig.displayTutorials && event.unformattedString == startGameQuestion) {
- MC.sendChat(Text.translatable("firmament.carnival.tutorial.minesweeper").styled {
- it.withClickEvent(ClickEvent(ClickEvent.Action.RUN_COMMAND, "/firm minesweepertutorial"))
- })
- }
- if (!CarnivalFeatures.TConfig.enableBombSolver) {
- gameState = null // TODO: replace this which a watchable property
- return
- }
- if (event.unformattedString == gameStartMessage) {
- gameState = GameState()
- log.log { "Game started" }
- }
- if (event.unformattedString.trim() == gameEndMessage) {
- gameState = null // TODO: add a loot tracker maybe? probably not, i dont think people care
- log.log { "Finished game" }
- }
- val gs = gameState ?: return
- bombPattern.useMatch(event.unformattedString) {
- val bombCount = group("bombCount").toInt()
- log.log { "Marking ${gs.lastClickedPosition} as having $bombCount nearby" }
- val pos = gs.lastClickedPosition ?: return
- gs.nearbyBombs[pos] = bombCount
- }
- }
-
- @Subscribe
- fun onMobChange(event: EntityUpdateEvent) {
- val gs = gameState ?: return
- if (event !is EntityUpdateEvent.TrackedDataUpdate) return
- // TODO: listen to state
- }
-
- @Subscribe
- fun onBlockClick(event: AttackBlockEvent) {
- val gs = gameState ?: return
- val boardPosition = BoardPosition.fromBlockPos(event.blockPos)
- log.log { "Breaking block at ${event.blockPos} ($boardPosition)" }
- gs.lastClickedPosition = boardPosition
- gs.lastDowsingMode = DowsingMode.fromItem(event.player.inventory.mainHandStack)
- }
-
- @Subscribe
- fun onRender(event: WorldRenderLastEvent) {
- val gs = gameState ?: return
- RenderInWorldContext.renderInWorld(event) {
- for ((pos, bombCount) in gs.nearbyBombs) {
- this.text(pos.toBlockPos().up().toCenterPos(), Text.literal("§a$bombCount \uD83D\uDCA3"))
- }
- }
- }
-
-
-}