Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 60 additions & 167 deletions app/src/main/java/com/messark/hawkerrush/MainViewModel.kt

Large diffs are not rendered by default.

77 changes: 4 additions & 73 deletions app/src/main/java/com/messark/hawkerrush/model/GameModels.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.messark.hawkerrush.model

import androidx.compose.ui.graphics.Color
import com.messark.hawkerrush.registry.StallRegistry

data class AxialCoordinate(val q: Int, val r: Int)

Expand Down Expand Up @@ -98,80 +99,10 @@ data class Stall(
return Math.round(cost * (0.2f + nextUpgradeIndex * 0.1f)).toInt()
}

fun getUpgradeBenefit(category: String, level: Int, baseStall: Stall): String {
fun getUpgradeBenefit(category: String, level: Int): String {
if (level <= 0) return ""

return when (category) {
"Damage" -> {
var currentDamage = baseStall.damage
val increasePerLevel = if (stallType == StallType.CHICKEN_RICE) {
(baseStall.damage * 0.3f).toInt() + 2
} else {
(baseStall.damage * 0.2f).toInt() + 1
}
for (l in 1..level) {
currentDamage += increasePerLevel
if (l % 10 == 0) {
currentDamage = Math.round(currentDamage * 1.25f)
}
}
val percentage = Math.round(((currentDamage - baseStall.damage).toFloat() / baseStall.damage) * 100)
"+$percentage%"
}
"Rate" -> {
var currentRate = baseStall.fireRateMs
val rateReduction = (baseStall.fireRateMs * 0.1f).toLong()
for (l in 1..level) {
currentRate = Math.max(50L, currentRate - rateReduction)
if (l % 10 == 0) {
currentRate = Math.max(50L, Math.round(currentRate * 0.75))
}
}
val percentage = Math.round(((baseStall.fireRateMs - currentRate).toFloat() / baseStall.fireRateMs) * 100)
"+$percentage%"
}
"Range" -> {
var currentRange = baseStall.range
for (l in 1..level) {
currentRange += 0.5f
if (l % 10 == 0) {
currentRange *= 1.25f
}
}
"+${String.format("%.1f", currentRange - baseStall.range)}"
}
"Radius" -> {
var currentRadius = baseStall.aoeRadius
for (l in 1..level) {
currentRadius += 0.2f
if (l % 10 == 0) {
currentRadius *= 1.25f
}
}
"+${String.format("%.1f", currentRadius - baseStall.aoeRadius)}"
}
"Duration" -> {
var currentDuration = baseStall.effectDurationMs
for (l in 1..level) {
currentDuration += 500
if (l % 10 == 0) {
currentDuration = Math.round(currentDuration * 1.25f).toLong()
}
}
"+${currentDuration - baseStall.effectDurationMs}ms"
}
"Effect" -> {
var currentEffect = baseStall.freezeDurationMs
for (l in 1..level) {
currentEffect += 100
if (l % 10 == 0) {
currentEffect = Math.round(currentEffect * 1.25f).toLong()
}
}
"+${currentEffect - baseStall.freezeDurationMs}ms"
}
else -> ""
}
val stallDef = StallRegistry.get(stallType)
return stallDef.getUpgradeBenefit(category, level, stallDef)
}
}

Expand Down
76 changes: 0 additions & 76 deletions app/src/main/java/com/messark/hawkerrush/model/TutorialModels.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,79 +13,3 @@ data class TutorialData(
val enemyType: EnemyType? = null,
val stallType: StallType? = null
)

object TutorialContent {
val ENEMY_TUTORIALS = mapOf(
EnemyType.SALARYMAN to TutorialData(
id = "enemy_salaryman",
type = TutorialType.ENEMY,
title = "Salaryman",
description = "The fast-paced office worker. They move quickly across the grid, eager to reach their destination. Their high speed makes them difficult to hit, but they don't have much health.",
enemyType = EnemyType.SALARYMAN
),
EnemyType.TOURIST to TutorialData(
id = "enemy_tourist",
type = TutorialType.ENEMY,
title = "Tourist",
description = "A curious visitor who frequently stops to take pictures of the local sights. While stationary, they are easy targets for your stalls, but they have more health than a Salaryman.",
enemyType = EnemyType.TOURIST
),
EnemyType.AUNTIE to TutorialData(
id = "enemy_auntie",
type = TutorialType.ENEMY,
title = "Auntie",
description = "A veteran of the hawker scene. She moves slowly and deliberately, but possesses high health. It takes sustained fire from multiple stalls to stop her progress.",
enemyType = EnemyType.AUNTIE
),
EnemyType.DELIVERY_RIDER to TutorialData(
id = "enemy_delivery_rider",
type = TutorialType.ENEMY,
title = "Delivery Rider",
description = "A formidable boss on two wheels. He has massive health and moves at a significant speed. He is particularly cautious on wet surfaces, slowing down considerably when passing through sticky puddles.",
enemyType = EnemyType.DELIVERY_RIDER
)
)

val STALL_TUTORIALS = mapOf(
StallType.SATAY to TutorialData(
id = "stall_satay",
type = TutorialType.STALL,
title = "Uncle's Satay Stall (AoE Damage)",
signatureMove = "The Chili Conflagration",
description = "Wah, smells so shiok! Behind this unassuming grill, the Satay Uncle is fanning a fiery revolution. Watch out for his signature Chili Conflagration—the chili isn't just spicy; it's explosive. He loads up a massive spoon and, with a precision usually reserved for satay-counting, launches a gigantic splash of his secret, explosive chili sauce. When it hits, it covers a wide circle, dousing groups of enemies in a sticky, burning chili storm that eats away at their health (and their willpower). If you need a crowd-control burn, this Uncle is the OG.",
stallType = StallType.SATAY
),
StallType.CHICKEN_RICE to TutorialData(
id = "stall_chicken_rice",
type = TutorialType.STALL,
title = "Ah Hock’s Chicken Rice Stand (Single-Target DPS)",
signatureMove = "The Garlic-Ginger Gatling Gun",
description = "Ah Hock’s Chicken Rice is famous for two things: the tenderest steamed chicken and the single-minded focus of his attacks. Don’t be fooled by the simple setup; this stand is your base single-target workhorse. When an enemy is targeted, Ah Hock deploys his Garlic-Ginger Gatling Gun. Instead of bullets, he’s launching high-velocity, precision-aimed balls of marinated meat, dousing targets in flavor-infused damage. It’s consistent, it’s powerful, and it never runs out of stock. A classic choice that never fails.",
stallType = StallType.CHICKEN_RICE
),
StallType.ICE_KACHANG to TutorialData(
id = "stall_ice_kachang",
type = TutorialType.STALL,
title = "Auntie's Ice Kachang Cart (Stun/Freezer)",
signatureMove = "The Absolute Zero Brain Freeze",
description = "Want something to really chill out the enemies? Then you need the Auntie at the Ice Kachang Cart! She’s taken traditional dessert techniques to the cryo-level. Her specialized ice shaver can launch a massive, compacted ball of shaved ice, syrup, and cold, cold, red beans, aimed precisely at the lead enemy. Upon impact, it doesn't just damage; it delivers an Absolute Zero Brain Freeze. The target is frozen solid, encased in a giant colorful ice cube, completely immobilized for several precious seconds. A perfect stall for controlling boss units.",
stallType = StallType.ICE_KACHANG
),
StallType.TEH_TARIK to TutorialData(
id = "stall_teh_tarik",
type = TutorialType.STALL,
title = "Teh Tarik Maestro (Movement Slow)",
signatureMove = "The Perpetual Tarik Puddle",
description = "Welcome to the Teh Tarik Maestro, where the art of 'pulling' tea is a high-level tactical maneuver. This Maestro doesn't just make your enemies slower; he makes the very ground they walk on sticky. Utilizing a massive pair of custom cups, he performs a continuous, mesmerizing 'tarik' high in the air. Each 'pull' perfectly places a wide, frothy Perpetual Tarik Puddle of viscous, sweet milk tea. The tea is so thick and syrupy that enemies stepping into it are immediately bogged down, their speed cut in half as they struggle through the delicious, sticky mess. A crowd favorite for slowing the rush.",
stallType = StallType.TEH_TARIK
),
StallType.DURIAN to TutorialData(
id = "stall_durian",
type = TutorialType.STALL,
title = "The King Durian Bunker (High Damage/Slight AoE)",
signatureMove = "The Spiky Cataclysm",
description = "They call the Durian the King of Fruits, and this stall is the King of Damage. The King Durian Bunker is fortified with armor-plating and smells… well, like a durian. When the King’s crew makes a sale, they aren't selling just fruit; they are deploying a localized explosive. Using a heavy-duty pneumatic launcher, they fire an overripe, spikey Durian bomb into the largest cluster of enemies. Upon impact, it delivers a high-damage, single-target blow, followed immediately by a Spiky Cataclysm AoE explosion as the potent, heavy aroma bursts outward. It’s high-cost and slow-reloading, but the raw damage (and the scent) is devastating.",
stallType = StallType.DURIAN
)
)
}
Loading
Loading