diff options
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/features/events')
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")) - } - } - } - - -} |