small update
boss prototype, auto planter, visual reworks, bug fixes
This commit is contained in:
+38
-13
@@ -3,18 +3,19 @@ from __future__ import annotations
|
||||
import random
|
||||
|
||||
# Rune kinds (gems). Each rune is an item equipped into a plant's slots.
|
||||
RUNE_COLORS = ("sapphire", "ruby", "amethyst", "jade", "brown")
|
||||
RUNE_COLORS = ("sapphire", "ruby", "amethyst", "jade", "brown", "pearl")
|
||||
RUNE_NAMES = {
|
||||
"sapphire": "Sapphire Rune",
|
||||
"ruby": "Ruby Rune",
|
||||
"amethyst": "Amethyst Rune",
|
||||
"jade": "Jade Rune",
|
||||
"brown": "Brown Rune",
|
||||
"pearl": "Pearl Rune",
|
||||
}
|
||||
|
||||
# Tier classification: sapphire/ruby/amethyst/jade are Tier 1, brown is Tier 2.
|
||||
# Tier classification: sapphire/ruby/amethyst/jade are Tier 1, brown & pearl Tier 2.
|
||||
TIER1_COLORS = ("sapphire", "ruby", "amethyst", "jade")
|
||||
TIER2_COLORS = ("brown",)
|
||||
TIER2_COLORS = ("brown", "pearl")
|
||||
RUNE_TIERS = {c: 1 for c in TIER1_COLORS}
|
||||
RUNE_TIERS.update({c: 2 for c in TIER2_COLORS})
|
||||
|
||||
@@ -25,6 +26,7 @@ RUNE_ICON_FILES = {
|
||||
"jade": "jade_rune",
|
||||
"amethyst": "amethyst_rune",
|
||||
"brown": "rune_brown",
|
||||
"pearl": "pearl_rune",
|
||||
}
|
||||
|
||||
# Old color names kept in earlier saves, mapped to the current gem names.
|
||||
@@ -43,31 +45,39 @@ def canonical_color(color: str) -> str:
|
||||
|
||||
# Primitive effects: each rune rolls its own stat and stacks additively with
|
||||
# other equipped runes of the same effect. Brown is rarer and rolls lower, but
|
||||
# turns part of the damage this plant deals into a Wilt.
|
||||
# turns part of the damage this plant deals into a Wilt. Pearl rolls a chunk of
|
||||
# critical hit chance.
|
||||
RUNE_EFFECTS = {
|
||||
"ruby": "damage", # +damage dealt
|
||||
"sapphire": "shield", # +shielding
|
||||
"jade": "healing", # +healing received
|
||||
"amethyst": "damage_taken", # -damage taken
|
||||
"brown": "wilt", # damage dealt also Wils the target
|
||||
"pearl": "crit", # +critical hit chance
|
||||
}
|
||||
PCT_MIN = 25
|
||||
PCT_MAX = 35
|
||||
BROWN_PCT_MIN = 5
|
||||
BROWN_PCT_MAX = 15
|
||||
PEARL_PCT_MIN = 20
|
||||
PEARL_PCT_MAX = 40
|
||||
# a plant can't stack more than this many runes of the same type
|
||||
MAX_RUNES_PER_TYPE = 2
|
||||
# runes sacrificed to reroll one rune to a higher stat
|
||||
RUNE_SACRIFICE_COST = 3
|
||||
# coin costs to buy a random rune of a tier in the runes shop
|
||||
T1_RUNE_COST = 100
|
||||
T2_RUNE_COST = 150
|
||||
# brown drops less often than the other runes (relative weights)
|
||||
RUNE_WEIGHTS = {"sapphire": 1.0, "ruby": 1.0, "amethyst": 1.0, "jade": 1.0, "brown": 0.75}
|
||||
# brown & pearl drop less often than the other runes (relative weights)
|
||||
RUNE_WEIGHTS = {"sapphire": 1.0, "ruby": 1.0, "amethyst": 1.0, "jade": 1.0,
|
||||
"brown": 0.75, "pearl": 0.75}
|
||||
_EFFECT_TEXTS = {
|
||||
"ruby": "+{pct}% damage dealt",
|
||||
"sapphire": "+{pct}% shielding",
|
||||
"jade": "+{pct}% healing",
|
||||
"amethyst": "-{pct}% damage taken",
|
||||
"brown": "deals {pct}% of damage as Wilt",
|
||||
"pearl": "+{pct}% critical chance",
|
||||
}
|
||||
RUNE_SUMMARIES = {
|
||||
"ruby": "Increases damage dealt",
|
||||
@@ -75,6 +85,7 @@ RUNE_SUMMARIES = {
|
||||
"jade": "Increases healing received",
|
||||
"amethyst": "Reduces damage taken",
|
||||
"brown": "Deals a portion of damage as Wilt",
|
||||
"pearl": "Increases critical hit chance",
|
||||
}
|
||||
|
||||
MAX_RUNE_SLOTS = 3
|
||||
@@ -91,12 +102,23 @@ def random_color() -> str:
|
||||
|
||||
|
||||
def roll_pct(color: str = None) -> int:
|
||||
"""Roll a rune's stat percentage. Brown rolls 5-15; the rest 25-35."""
|
||||
"""Roll a rune's stat percentage. Brown rolls 5-15, pearl 20-40, the rest 25-35."""
|
||||
if color == "brown":
|
||||
return random.randint(BROWN_PCT_MIN, BROWN_PCT_MAX)
|
||||
if color == "pearl":
|
||||
return random.randint(PEARL_PCT_MIN, PEARL_PCT_MAX)
|
||||
return random.randint(PCT_MIN, PCT_MAX)
|
||||
|
||||
|
||||
def max_pct(color: str) -> int:
|
||||
"""The highest stat a rune of `color` can roll (brown/pearl have their own caps)."""
|
||||
if color == "brown":
|
||||
return BROWN_PCT_MAX
|
||||
if color == "pearl":
|
||||
return PEARL_PCT_MAX
|
||||
return PCT_MAX
|
||||
|
||||
|
||||
def name(color: str) -> str:
|
||||
return RUNE_NAMES.get(color, "Rune")
|
||||
|
||||
@@ -106,11 +128,11 @@ def tier(color: str) -> int:
|
||||
|
||||
|
||||
def roll_ratio(rune) -> float:
|
||||
"""How close a rune's roll is to its own maximum (0..1). Brown's 5-15 range
|
||||
is compared to its 15 cap, so a maxed brown ranks equally with a maxed
|
||||
yellow even though 15 < 35."""
|
||||
max_pct = BROWN_PCT_MAX if rune.get("color") == "brown" else PCT_MAX
|
||||
return rune.get("pct", 0) / max_pct
|
||||
"""How close a rune's roll is to its own maximum (0..1). Each color is
|
||||
compared to its own cap, so a maxed brown or pearl ranks equally with a
|
||||
maxed ruby even though 15 < 35."""
|
||||
cap = max_pct(rune.get("color"))
|
||||
return rune.get("pct", 0) / cap
|
||||
|
||||
|
||||
def effect_text(color: str, pct: int) -> str:
|
||||
@@ -124,6 +146,7 @@ _CARD_TEXTS = {
|
||||
"jade": "+{pct}% heal",
|
||||
"amethyst": "-{pct}% taken",
|
||||
"brown": "Wilt {pct}%",
|
||||
"pearl": "+{pct}% crit",
|
||||
}
|
||||
|
||||
|
||||
@@ -149,9 +172,11 @@ def summary(color: str) -> str:
|
||||
|
||||
|
||||
def roll_range(color: str) -> str:
|
||||
"""The stat range a rune of `color` rolls between (brown is lower)."""
|
||||
"""The stat range a rune of `color` rolls between (brown/pearl are lower)."""
|
||||
if color == "brown":
|
||||
return f"{BROWN_PCT_MIN}–{BROWN_PCT_MAX}%"
|
||||
if color == "pearl":
|
||||
return f"{PEARL_PCT_MIN}–{PEARL_PCT_MAX}%"
|
||||
return f"{PCT_MIN}–{PCT_MAX}%"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user