From 074840b0118bd939eabd4c8b267e52ad0aca43f3 Mon Sep 17 00:00:00 2001 From: Syntax <79747812+Zag-bop@users.noreply.github.com> Date: Wed, 28 Feb 2024 19:32:43 +0000 Subject: [PATCH] Shooting Star Distractions and Diversion (#458) * Add Crashed star objects to objects.yml * Add xp value & mining chance to stardust in item.yml * Add various locations for Crashed Stars in StarLocationData class * Add star_sprite to npcs yml. * Add examine text to crashed_star objects in objects yml. * Add Prospecting crashed stars that will display progress to the next layer. * Add rewards when the star is completed, converting stardust to coins, astral runes, cosmic runes and gold ore. inline with runescape * Add dialog to star sprite after star completion * Add check to mining to make sure that a player doesn't exceed 200 stardust in inventory and bank (a player will still gain experience) * Add shooting_star_shadow to npcs yml * Change some star `collect_for_next_layer` values, forgot to change them from testing * Add Star shadow moving to crashing tile before star spawning (missing crashing animation) * Add check to `mining.kts` if the player is the first to mine the star they will be granted `(miningLevel * 75)` inline with runescape. * Add Fall in star object to `objects.yml` * Add replacing falling star object with crashed star object * Add player animation when moved due to being under a crashing star * Change code formatting Intelij plugin formats code that doesn't follow Voids code format * Add "step_back_startled" animation to `animation.yml` * Add various sounds for `Star Falling`, `Star despawning`, `Star changing tier`, `Star Sprite spawning` * Fix force movement --------- Co-authored-by: GregHib --- data/definitions/animations.yml | 2 + data/definitions/items.yml | 3 + data/definitions/npcs.yml | 6 + data/definitions/objects.yml | 76 +++++++ data/definitions/sounds.yml | 11 + .../client/instruction/handle/WalkHandler.kt | 1 - .../voidps/engine/entity/character/Visuals.kt | 27 +-- .../dnd/shootingstar/ShootingStar.kts | 190 ++++++++++++++++++ .../dnd/shootingstar/ShootingStarHandler.kt | 47 +++++ .../dnd/shootingstar/StarLocationData.kt | 22 ++ .../world/activity/skill/mining/Mining.kts | 17 +- 11 files changed, 383 insertions(+), 19 deletions(-) create mode 100644 game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStar.kts create mode 100644 game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStarHandler.kt create mode 100644 game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/StarLocationData.kt diff --git a/data/definitions/animations.yml b/data/definitions/animations.yml index bff5a04d90..66b92fb6d3 100644 --- a/data/definitions/animations.yml +++ b/data/definitions/animations.yml @@ -1370,6 +1370,8 @@ ice_cleave: 7070 sweep: 1203 powerstab: 7078 shove: 1064 +fall_back_on_butt: 4172 +step_back_startled: 4835 quick_smash: 1667 clobber: 2876 disrupt: 14788 diff --git a/data/definitions/items.yml b/data/definitions/items.yml index 7fb204a33b..762aa151be 100644 --- a/data/definitions/items.yml +++ b/data/definitions/items.yml @@ -58302,6 +58302,9 @@ elemental_spell: stardust: id: 13727 tradeable: false + mining: + xp: 80.0 + chance: 10-75 destroy: "You can mine more if you find another crashed star." examine: "Small, shiny bits of rock." kept: "Wilderness" diff --git a/data/definitions/npcs.yml b/data/definitions/npcs.yml index 47ab3f2505..89d9ece58e 100644 --- a/data/definitions/npcs.yml +++ b/data/definitions/npcs.yml @@ -196,6 +196,12 @@ cook_lumbridge: race: human wander_radius: 4 examine: "Lumbridge Castle's head cook." +star_sprite: + id: 8091 + examine: "A shiny, happy star sprite." +shooting_star_shadow: + id: 8092 + examine: "The shadow of a shooting star" doric: id: 284 race: dwarf diff --git a/data/definitions/objects.yml b/data/definitions/objects.yml index 7fc41d919a..9a548ce3cd 100644 --- a/data/definitions/objects.yml +++ b/data/definitions/objects.yml @@ -3969,8 +3969,84 @@ fire_green: fire_blue: id: 11406 examine: "Hot!" +crashed_star_falling_object: + id: 38659 + examine: "It's a crashed star." +crashed_star_tier_9: + id: 38660 + collect_for_next_layer: 15 + mining: + level: 90 + ores: [ stardust ] + gems: true + examine: "This is a size-9 star." +crashed_star_tier_8: + id: 38661 + collect_for_next_layer: 40 + mining: + level: 80 + ores: [ stardust ] + gems: true + examine: "This is a size-8 star." +crashed_star_tier_7: + id: 38662 + collect_for_next_layer: 40 + mining: + level: 70 + ores: [ stardust ] + gems: true + examine: "This is a size-7 star." +crashed_star_tier_6: + id: 38663 + collect_for_next_layer: 80 + mining: + level: 60 + ores: [ stardust ] + gems: true + examine: "This is a size-6 star." +crashed_star_tier_5: + id: 38664 + collect_for_next_layer: 175 + mining: + level: 50 + ores: [ stardust ] + gems: true + examine: "This is a size-5 star." +crashed_star_tier_4: + id: 38665 + collect_for_next_layer: 250 + mining: + level: 40 + ores: [ stardust ] + gems: true + examine: "This is a size-4 star." +crashed_star_tier_3: + id: 38666 + collect_for_next_layer: 450 + mining: + level: 30 + ores: [ stardust ] + gems: true + examine: "This is a size-3 star." +crashed_star_tier_2: + id: 38667 + collect_for_next_layer: 700 + mining: + level: 20 + ores: [ stardust ] + gems: true + examine: "This is a size-2 star." +crashed_star_tier_1: + id: 38668 + collect_for_next_layer: 1200 + mining: + level: 10 + ores: [ stardust ] + gems: true + examine: "This is a size-1 star." evil_tree: id: 11434 + upgrade_time: 50 examine: "This looks like a challenge anyone can deal with." evil_tree_stump: id: 11435 diff --git a/data/definitions/sounds.yml b/data/definitions/sounds.yml index 48a00157ad..b6ae594525 100644 --- a/data/definitions/sounds.yml +++ b/data/definitions/sounds.yml @@ -5,6 +5,17 @@ chest_open: 52 casket_open: 50 cupboard_close: 57 cupboard_open: 58 +star_meteor_falling: 5206 +star_meteor_landing: 5188 +star_meteor_change: 5189 +star_sprite_shake: 5193 +star_sprite_appear: 5195 +star_sprite_twinkle: 5197 +star_sprite_yawn: 5200 +star_sprite_wipe: 5201 +star_sprite_yawn_end1: 5202 +star_sprite_blink: 5205 +star_meteor_despawn: 5207 destroy_object: 2381 coffin_open: 54 demon_slayer_crystal_ball_anim: 2971 diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/client/instruction/handle/WalkHandler.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/client/instruction/handle/WalkHandler.kt index 0d51f65535..e1f337e750 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/client/instruction/handle/WalkHandler.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/client/instruction/handle/WalkHandler.kt @@ -12,7 +12,6 @@ class WalkHandler : InstructionHandler() { override fun validate(player: Player, instruction: Walk) { if (player.hasClock("delay") || player.hasClock("input_delay")) { - println("Ignored") return } player.closeInterfaces() diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/Visuals.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/Visuals.kt index acb957550c..a2bb7e45ff 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/Visuals.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/entity/character/Visuals.kt @@ -9,6 +9,7 @@ import world.gregs.voidps.engine.entity.character.move.tele import world.gregs.voidps.engine.entity.character.npc.NPC import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.character.player.appearance +import world.gregs.voidps.engine.entity.character.player.movementType import world.gregs.voidps.engine.entity.character.player.skill.Skill import world.gregs.voidps.engine.entity.obj.GameObject import world.gregs.voidps.engine.entity.obj.ObjectShape @@ -18,6 +19,8 @@ import world.gregs.voidps.network.visual.VisualMask import world.gregs.voidps.network.visual.Visuals import world.gregs.voidps.network.visual.update.Hitsplat import world.gregs.voidps.network.visual.update.Turn +import world.gregs.voidps.network.visual.update.player.MoveType +import world.gregs.voidps.network.visual.update.player.TemporaryMoveType import world.gregs.voidps.type.Delta import world.gregs.voidps.type.Direction import world.gregs.voidps.type.Distance @@ -192,24 +195,16 @@ fun Character.setForceMovement( flagForceMovement() } -fun Character.forceWalk(delta: Delta, delay: Int = 0, direction: Direction = Direction.NONE, block: () -> Unit = {}) { - setForceMovement(delta, delay, direction = direction) - this["force_walk"] = block - if (this is Player) { - strongQueue("force_walk", delay / 30) { - tele(delta) - clearAnimation() - } - } else if (this is NPC) { - strongQueue("force_walk", delay / 30) { - tele(delta) - clearAnimation() - } - } +fun Character.forceWalk(delta: Delta, delay: Int = tile.distanceTo(tile.add(delta)) * 30, direction: Direction = Direction.NONE) { + val start = tile + tele(delta) + setForceMovement(Delta.EMPTY, delay, start.delta(tile), direction = direction) } -fun Character.forceWalk(target: Tile, delay: Int = tile.distanceTo(target) * 30, direction: Direction = Direction.NONE, block: () -> Unit = {}) { - forceWalk(target.delta(tile), delay, direction, block) +fun Character.forceWalk(target: Tile, delay: Int = tile.distanceTo(target) * 30, direction: Direction = Direction.NONE) { + val start = tile + tele(target) + setForceMovement(Delta.EMPTY, delay, start.delta(tile), direction = direction) } val Character.turn: Delta diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStar.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStar.kts new file mode 100644 index 0000000000..8bbb2bb17e --- /dev/null +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStar.kts @@ -0,0 +1,190 @@ +package world.gregs.voidps.world.activity.dnd.shootingstar + +import com.github.michaelbull.logging.InlineLogger +import world.gregs.voidps.engine.client.message +import world.gregs.voidps.engine.client.ui.chat.plural +import world.gregs.voidps.engine.client.variable.start +import world.gregs.voidps.engine.data.definition.data.Rock +import world.gregs.voidps.engine.entity.World +import world.gregs.voidps.engine.entity.character.forceWalk +import world.gregs.voidps.engine.entity.character.mode.interact.Interact +import world.gregs.voidps.engine.entity.character.move.walkTo +import world.gregs.voidps.engine.entity.character.npc.NPC +import world.gregs.voidps.engine.entity.character.npc.NPCs +import world.gregs.voidps.engine.entity.character.npc.npcOperate +import world.gregs.voidps.engine.entity.character.player.Player +import world.gregs.voidps.engine.entity.character.player.Players +import world.gregs.voidps.engine.entity.character.player.chat.ChatType +import world.gregs.voidps.engine.entity.character.player.skill.Skill +import world.gregs.voidps.engine.entity.character.setAnimation +import world.gregs.voidps.engine.entity.obj.* +import world.gregs.voidps.engine.entity.objectDespawn +import world.gregs.voidps.engine.entity.worldSpawn +import world.gregs.voidps.engine.inject +import world.gregs.voidps.engine.inv.add +import world.gregs.voidps.engine.inv.inventory +import world.gregs.voidps.engine.inv.remove +import world.gregs.voidps.engine.map.collision.blocked +import world.gregs.voidps.engine.queue.softQueue +import world.gregs.voidps.engine.timer.timerStart +import world.gregs.voidps.engine.timer.toTicks +import world.gregs.voidps.type.Direction +import world.gregs.voidps.type.Tile +import world.gregs.voidps.type.random +import world.gregs.voidps.world.activity.dnd.shootingstar.ShootingStarHandler.currentActiveObject +import world.gregs.voidps.world.activity.dnd.shootingstar.ShootingStarHandler.currentStarTile +import world.gregs.voidps.world.activity.dnd.shootingstar.ShootingStarHandler.startEvent +import world.gregs.voidps.world.activity.dnd.shootingstar.ShootingStarHandler.totalCollected +import world.gregs.voidps.world.interact.dialogue.Cheerful +import world.gregs.voidps.world.interact.dialogue.Sad +import world.gregs.voidps.world.interact.dialogue.type.npc +import world.gregs.voidps.world.interact.entity.combat.hit.damage +import world.gregs.voidps.world.interact.entity.sound.areaSound +import java.util.concurrent.TimeUnit +import kotlin.math.roundToInt + +val objects: GameObjects by inject() +val npcs: NPCs by inject() +val players: Players by inject() +val logger = InlineLogger() + +worldSpawn { eventUpdate() } + +fun eventUpdate() { + World.queue("shooting_star_event_timer", startEvent) { + if (currentStarTile != Tile.EMPTY) { + cleanseEvent(true) + logger.info { "There was already an active star, deleted it and started a new event" } + } + startCrashedStarEvent() + eventUpdate() + } +} + +fun startCrashedStarEvent() { + val location = StarLocationData.entries.random() + currentStarTile = location.tile + val tier = random.nextInt(1, 9) + logger.info { "Crashed star event has started at: $location (${currentStarTile.x}, ${currentStarTile.y}) tier ${tier}." } + val shootingStarShadow: NPC? = npcs.add("shooting_star_shadow", Tile(currentStarTile.x, currentStarTile.y + 6), Direction.NONE) + shootingStarShadow?.walkTo(currentStarTile, noCollision = true, noRun = true) + areaSound("star_meteor_falling", currentStarTile, radius = 15, delay = 20) + World.queue("awaiting_shadow_walk", 6) { + val shootingStarObjectFalling: GameObject = objects.add("crashed_star_falling_object", currentStarTile) + val under = mutableListOf() + for (tile in currentStarTile.toCuboid(2, 2)) { + for (player in players[tile]) { + under.add(player) + } + } + for (player in under) { + player.damage(random.nextInt(10, 50)) + val direction = Direction.all.first { !player.blocked(it) } + player.forceWalk(direction.delta, 1, direction = direction.inverse()) + player.setAnimation("step_back_startled") + } + World.queue("falling_star_object_removal", 1) { + currentActiveObject = shootingStarObjectFalling.replace("crashed_star_tier_${tier}") + npcs.remove(shootingStarShadow) + } + } +} + +fun cleanseEvent(forceStopped: Boolean) { + currentActiveObject?.let { current -> objects[currentStarTile, current.id] }?.remove() + if (!forceStopped) { + areaSound("star_sprite_appear", currentStarTile, radius = 10) + val starSprite = npcs.add("star_sprite", currentStarTile, Direction.NONE, 0) + World.queue("start_sprite_despawn_timer", TimeUnit.MINUTES.toTicks(10)) { + npcs.remove(starSprite) + } + } + totalCollected = 0 + currentStarTile = Tile.EMPTY + currentActiveObject = null + ShootingStarHandler.earlyBird = false +} + +fun getLayerPercentage(totalCollected: Int, totalNeeded: Int): String { + val remaining = totalNeeded - totalCollected + val percentageRemaining = (remaining.toDouble() / totalNeeded.toDouble()) * 100 + return String.format("%.2f", percentageRemaining) +} + +fun calculateRewards(stardust: Int): Map { + val coinsPerStardust = 50002.0 / 200 + val astralRunesPerStardust = 52.0 / 200 + val cosmicRunesPerStardust = 152.0 / 200 + val goldOresPerStardust = 20.0 / 200 + + val coins = (coinsPerStardust * stardust).toInt() + val astralRunes = (astralRunesPerStardust * stardust).roundToInt() + val cosmicRunes = (cosmicRunesPerStardust * stardust).roundToInt() + val goldOres = (goldOresPerStardust * stardust).roundToInt() + + return mapOf( + "coins" to coins, + "astral_rune" to astralRunes, + "cosmic_rune" to cosmicRunes, + "gold_ore_noted" to goldOres + ) +} + +objectDespawn("shooting_star_tier_1") { + areaSound("star_meteor_despawn", it.tile, radius = 15) + cleanseEvent(false) +} + +timerStart("mining") { player -> + val target = (player.mode as? Interact)?.target as GameObject + val isStar = target.id.startsWith("crashed_star") + if (isStar) { + val isEarlyBird = ShootingStarHandler.isEarlyBird() + if (isEarlyBird) { + player.message("Congratulations!, You were the first person to find this star!") + val xpToAdd: Double = player.levels.get(Skill.Mining) * 75.0 + player.experience.add(Skill.Mining, xpToAdd) + } + } +} + +objectApproach("Prospect", "crashed_star_tier_#") { + if (player.queue.contains("prospect")) { + return@objectApproach + } + val starPayout = target.def["collect_for_next_layer", -1] + player.message("You examine the crashed star...") + player.start("movement_delay", 4) + player.softQueue("prospect", 4) { + val star = def.getOrNull("mining")?.ores?.firstOrNull() + if (star == null) { + player.message("Star has been mined...") + } else if (starPayout != -1) { + val percentageCollected = getLayerPercentage(totalCollected, starPayout) + player.message("There is $percentageCollected% left of this layer.") + } + } +} + +npcOperate("Talk-to", "star_sprite") { + npc("Thank you for helping me out of here") + val starDustCount = player.inventory.count("stardust") + if (player.inventory.isFull()) { + player.message("Inventory full. To make more room, sell, drop or bank something.", ChatType.Game) + } else if (starDustCount == 0) { + npc("You don't seem to have any stardust that I can exchange for a reward") + } else if (starDustCount > 0) { + val rewards = calculateRewards(starDustCount) + player.inventory.remove("stardust", starDustCount) + val messageBuilder = StringBuilder("Also, ") + rewards.entries.forEachIndexed { index, (reward, amount) -> + player.inventory.add(reward, amount) + if (index == 0) { + messageBuilder.append("have $amount $reward") + } else { + messageBuilder.append(", $amount ${reward.replace("_", " ").replace("noted", "").plural(amount)}") + } + } + npc("I have rewarded you by making it so you can mine extra ore for the next 15 minutes, ${messageBuilder}.") + } +} \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStarHandler.kt b/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStarHandler.kt new file mode 100644 index 0000000000..88eb9d5d83 --- /dev/null +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStarHandler.kt @@ -0,0 +1,47 @@ +package world.gregs.voidps.world.activity.dnd.shootingstar + +import world.gregs.voidps.engine.entity.obj.GameObject +import world.gregs.voidps.engine.entity.obj.remove +import world.gregs.voidps.engine.entity.obj.replace +import world.gregs.voidps.engine.timer.toTicks +import world.gregs.voidps.type.Tile +import world.gregs.voidps.type.random +import world.gregs.voidps.world.interact.entity.sound.areaSound +import java.util.concurrent.TimeUnit + +object ShootingStarHandler { + + var earlyBird: Boolean = false + var totalCollected: Int = 0 + var currentStarTile = Tile.EMPTY + var currentActiveObject: GameObject? = null + val startEvent = TimeUnit.HOURS.toTicks(random.nextInt(1, 2)) + + fun addStarDustCollected() { + totalCollected++ + } + + fun handleMinedStarDust(currentMinedStar: GameObject) { + val starPayout = currentMinedStar.def["collect_for_next_layer", -1] + if (totalCollected >= starPayout) { + val stage = currentMinedStar.id.takeLast(1) + if (stage == "1") { + currentMinedStar.remove() + return + } + val nextStage = currentMinedStar.id.replace(stage, (stage.toInt() - 1).toString()) + val nextStar = currentMinedStar.replace(nextStage) + totalCollected = 0 + currentActiveObject = nextStar + areaSound("star_meteor_change", currentStarTile, radius = 10) + } + } + + fun isEarlyBird(): Boolean { + if (!earlyBird) { + earlyBird = true + return true + } + return false + } +} diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/StarLocationData.kt b/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/StarLocationData.kt new file mode 100644 index 0000000000..6a90d19e38 --- /dev/null +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/StarLocationData.kt @@ -0,0 +1,22 @@ +package world.gregs.voidps.world.activity.dnd.shootingstar + +import world.gregs.voidps.type.Tile + +enum class StarLocationData(val description: String, val tile: Tile) { + AL_KHARID_BANK("the north west edge of the Al Kharid Bank.", Tile(3276, 3174)), + AL_KHARID_MINE("the north of the scorpion mine.", Tile(3299, 3308)), + MAGE_TRAINING_ARENA("the south of the entrance to the Mage Training Arena.", Tile(3348, 3284)), + CRAFTING_GUILD("the Crafting Guild by the gold rocks.", Tile(2940, 3281)), + RIMMINGTON_MINING_SITE("the centre of the big mine north of Rimmington.", Tile(2974, 3240)), + FALADOR_WEST_MINE("the mine east of the dark wizard tower.", Tile(2927, 3336)), + SOUTHERN_CRANDOR_MINE("the beach beneath the south-western mining area on Crandor.", Tile(2823, 3237)), + KELDAGRIM_ENTRANCE("the mine located south of cave entrance to Keldagrim.", Tile(2726, 3678)), + JATIZO_MINE("the right of the mine's entrance on north-west Jatizso.", Tile(2391, 3813)), + LUNAR_ISLE_MINE("the ladder to the Rune essence mines on Lunar Isle.", Tile(2146, 3942)), + MISCELLANIA_MINE_SITE("south of coal mine on Miscellania.", Tile(2531, 3887)), + CENTRAL_FREMENNIK_MINING("the central Fremennik Isles mining site (Neitiznot Drakolith mine).", Tile(2375, 3833)), + RELLEKKA_MINING_SITE("the mining site in the fenced off area inside the town of Rellekka. ", Tile(2676, 3698)), + ARDOUGNE_MINING_SITE("the iron rocks north of the monastery, south of East Ardougne.", Tile(2701, 3333)), + COAL_TRUCK_MINING("the middle of the coal rocks that supply the Coal trucks.", Tile(2586, 3477)), + FIGHT_ARENA_MINING("the mining spot north-east of Yanille, south-west of Port Khazard.", Tile(2634, 3133)) +} \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/mining/Mining.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/mining/Mining.kts index fc5c5a05c0..862063bf31 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/mining/Mining.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/skill/mining/Mining.kts @@ -33,6 +33,8 @@ import world.gregs.voidps.engine.queue.softQueue import world.gregs.voidps.engine.suspend.pause import world.gregs.voidps.network.visual.update.player.EquipSlot import world.gregs.voidps.type.random +import world.gregs.voidps.world.activity.bank.bank +import world.gregs.voidps.world.activity.dnd.shootingstar.ShootingStarHandler val objects: GameObjects by inject() val itemDefinitions: ItemDefinitions by inject() @@ -142,9 +144,16 @@ fun hasRequirements(player: Player, pickaxe: Item?, message: Boolean = false): B } fun addOre(player: Player, ore: String): Boolean { + if (ore == "stardust") { + ShootingStarHandler.addStarDustCollected() + val totalStarDust = player.inventory.count(ore) + player.bank.count(ore) + if (totalStarDust >= 200) { + player.message("You have the maximum amount of stardust but was still rewarded experience.") + return true + } + } val added = player.inventory.add(ore) - if (added) { - player.message("You manage to mine some ${ore.toLowerSpaceCase()}.") + if (added) { player.message("You manage to mine some ${ore.toLowerSpaceCase()}.") } else { player.inventoryFull() } @@ -152,6 +161,10 @@ fun addOre(player: Player, ore: String): Boolean { } fun deplete(rock: Rock, obj: GameObject): Boolean { + if (obj.id.startsWith("crashed_star_tier_")) { + ShootingStarHandler.handleMinedStarDust(obj) + return false + } if (rock.life >= 0) { objects.replace(obj, "depleted${obj.id.dropWhile { it != '_' }}", ticks = rock.life) return true