basic noita parsing
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
"""
|
||||
Decode a polylan_mod_log.txt.
|
||||
|
||||
Hash format: sha1(seed|timestamp|id) — timestamp is bound into the hash so
|
||||
it cannot be altered without breaking the signature.
|
||||
|
||||
Seed-less entries (INIT, DEBUG, mod checks) use sha1(id) with no seed or
|
||||
timestamp — those are resolved via a static lookup.
|
||||
|
||||
Usage:
|
||||
python decode_log.py [path/to/polylan_mod_log.txt]
|
||||
|
||||
Default path: ~/.local/share/Steam/steamapps/common/Noita/polylan_mod_log.txt
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import re
|
||||
from functools import cache
|
||||
from noita.services.spells import ALL_SPELLS, ALL_PERKS
|
||||
|
||||
|
||||
SEED_POOL = [
|
||||
# General good seeds
|
||||
3154823,
|
||||
3718311,
|
||||
10064758,
|
||||
123156801,
|
||||
1024089369,
|
||||
1026967166,
|
||||
# Pacifist seeds
|
||||
177795258,
|
||||
520542929,
|
||||
10600249,
|
||||
25300740,
|
||||
21875589,
|
||||
24085389,
|
||||
59775105,
|
||||
44190726,
|
||||
1039649471,
|
||||
1072607354,
|
||||
# Perk combo seeds
|
||||
839747651,
|
||||
839844768,
|
||||
840909713,
|
||||
839959129,
|
||||
840016192,
|
||||
840039886,
|
||||
840398606,
|
||||
840439045,
|
||||
840457463,
|
||||
840492754,
|
||||
840507802,
|
||||
840513742,
|
||||
840542079,
|
||||
840574169,
|
||||
840610974,
|
||||
840626894,
|
||||
840872436,
|
||||
840894605,
|
||||
841221188,
|
||||
]
|
||||
|
||||
DEATH_PENALTY = 1
|
||||
|
||||
# All scoreable events: base 1 pt for every spell and perk, overrides below.
|
||||
POINTS = {
|
||||
# ── Spells ───────────────────────────────────────────────────────────────
|
||||
**{sid: 1 for sid in ALL_SPELLS},
|
||||
"ADD_TRIGGER": 10,
|
||||
"NOLLA": 10,
|
||||
"CHAOTIC_TRANSMUTATION": 10,
|
||||
"DUPLICATE": 5,
|
||||
"OMEGA": 10,
|
||||
"HEALING_BOLT": 5,
|
||||
# ── Perks ─────────────────────────────────────────────────────────────────
|
||||
**{pid: 1 for pid in ALL_PERKS},
|
||||
"EDIT_WANDS_EVERYWHERE": 10,
|
||||
# ── Spell combos ─────────────────────────────────────────────────────────
|
||||
"PING_PONG_DRILL": 10,
|
||||
"HEAVY_SHOT_DISC": 10,
|
||||
"TOUCH_OF_ANY": 5,
|
||||
"TWO_ARC_MODIFIERS": 10,
|
||||
"TWO_TRAIL_MODIFIERS": 10,
|
||||
# ── Perk combos ──────────────────────────────────────────────────────────
|
||||
"CRIMSON_ALCHEMIST": 15,
|
||||
"GREEDY_GOBLIN_KING": 15,
|
||||
"STORM_TOUCHED_ASCENDANT": 15,
|
||||
"ARCHMAGE_OF_CONTROL": 15,
|
||||
"HAUNTED_MAGE": 15,
|
||||
"GLASS_CANNON_MESSIAH": 15,
|
||||
"INFINITE_ENGINE": 15,
|
||||
"PERFECT_ACCURACY_LOOP": 15,
|
||||
"HOMING_DEATH_SWARM": 15,
|
||||
"UNTOUCHABLE_FIELD": 15,
|
||||
"ELECTRIC_SUSTAIN_LOOP": 15,
|
||||
"IMMORTAL_LEECH_CORE": 15,
|
||||
"PROJECTILE_OVERLOAD": 15,
|
||||
"CLOSE_RANGE_DEATH_MACHINE": 15,
|
||||
"CRITICAL_MASS": 15,
|
||||
"HOLY_MOUNTAIN_ABUSER": 15,
|
||||
"DEFLECTOR_MATRIX": 15,
|
||||
"STORMBORNE_LEVITATOR": 15,
|
||||
# ── Objectives ───────────────────────────────────────────────────────────
|
||||
"HP_200": 5,
|
||||
"HP_500": 5,
|
||||
"HP_2000": 5,
|
||||
"HP_5000": 5,
|
||||
"GOLD_1000": 5,
|
||||
"GOLD_10000": 5,
|
||||
"GOLD_100000": 5,
|
||||
"GOLD_1000000": 5,
|
||||
**{f"ORB_{i}": 5 for i in range(34)},
|
||||
"FIND_AMBROSIA": 10,
|
||||
"WAND_MANA_500": 10,
|
||||
"WAND_MANA_1000": 10,
|
||||
"WAND_MANA_1500": 10,
|
||||
"WAND_CAPACITY_10": 10,
|
||||
"WAND_CAPACITY_20": 10,
|
||||
"BOSS_KILL": 100,
|
||||
"CRIMSON_ALCHEMIST-BOSS_KILL": 100,
|
||||
"GREEDY_GOBLIN_KING-BOSS_KILL": 100,
|
||||
"STORM_TOUCHED_ASCENDANT-BOSS_KILL": 100,
|
||||
"ARCHMAGE_OF_CONTROL-BOSS_KILL": 100,
|
||||
"HAUNTED_MAGE-BOSS_KILL": 100,
|
||||
"GLASS_CANNON_MESSIAH-BOSS_KILL": 100,
|
||||
"INFINITE_ENGINE-BOSS_KILL": 100,
|
||||
"PERFECT_ACCURACY_LOOP-BOSS_KILL": 100,
|
||||
"HOMING_DEATH_SWARM-BOSS_KILL": 100,
|
||||
"UNTOUCHABLE_FIELD-BOSS_KILL": 100,
|
||||
"ELECTRIC_SUSTAIN_LOOP-BOSS_KILL": 100,
|
||||
"IMMORTAL_LEECH_CORE-BOSS_KILL": 100,
|
||||
"PROJECTILE_OVERLOAD-BOSS_KILL": 100,
|
||||
"CLOSE_RANGE_DEATH_MACHINE-BOSS_KILL": 100,
|
||||
"CRITICAL_MASS-BOSS_KILL": 100,
|
||||
"HOLY_MOUNTAIN_ABUSER-BOSS_KILL": 100,
|
||||
"DEFLECTOR_MATRIX-BOSS_KILL": 100,
|
||||
"STORMBORNE_LEVITATOR-BOSS_KILL": 100,
|
||||
}
|
||||
|
||||
# Perk-combo IDs — used to award a per-combo boss-kill bonus.
|
||||
PERK_COMBO_IDS = {
|
||||
"CRIMSON_ALCHEMIST",
|
||||
"GREEDY_GOBLIN_KING",
|
||||
"STORM_TOUCHED_ASCENDANT",
|
||||
"ARCHMAGE_OF_CONTROL",
|
||||
"HAUNTED_MAGE",
|
||||
"GLASS_CANNON_MESSIAH",
|
||||
"INFINITE_ENGINE",
|
||||
"PERFECT_ACCURACY_LOOP",
|
||||
"HOMING_DEATH_SWARM",
|
||||
"UNTOUCHABLE_FIELD",
|
||||
"ELECTRIC_SUSTAIN_LOOP",
|
||||
"IMMORTAL_LEECH_CORE",
|
||||
"PROJECTILE_OVERLOAD",
|
||||
"CLOSE_RANGE_DEATH_MACHINE",
|
||||
"CRITICAL_MASS",
|
||||
"HOLY_MOUNTAIN_ABUSER",
|
||||
"DEFLECTOR_MATRIX",
|
||||
"STORMBORNE_LEVITATOR",
|
||||
}
|
||||
|
||||
BOSS_KILL_COMBO_BONUS = 100 # default bonus per active perk combo on boss kill
|
||||
|
||||
# IDs tried with the seed+timestamp scheme.
|
||||
_ALL_IDS = list(POINTS.keys()) + ["DEATH"]
|
||||
|
||||
# Seed-less hashes (sha1(id) only, no seed, no timestamp).
|
||||
_STATIC_LOOKUP = {
|
||||
hashlib.sha1(k.encode()).hexdigest(): k
|
||||
for k in ["-", "DEBUG", "polylan-mod", "cheatgui", "alchemy_recipes_display"]
|
||||
}
|
||||
|
||||
|
||||
def _sha1(text: str) -> str:
|
||||
return hashlib.sha1(text.encode("utf-8")).hexdigest()
|
||||
|
||||
|
||||
@cache
|
||||
def resolve(
|
||||
hash_val: str, ts: str, preferred_seed: int | None = None
|
||||
) -> tuple[str | None, int | None]:
|
||||
"""Return (name, seed) or (None, None). preferred_seed is tried first."""
|
||||
if hash_val in _STATIC_LOOKUP:
|
||||
return _STATIC_LOOKUP[hash_val], None
|
||||
|
||||
seeds = (
|
||||
[preferred_seed] + [s for s in SEED_POOL if s != preferred_seed]
|
||||
if preferred_seed is not None
|
||||
else SEED_POOL
|
||||
)
|
||||
|
||||
for seed in seeds:
|
||||
prefix = f"{seed}|{ts}|"
|
||||
for name in _ALL_IDS:
|
||||
if _sha1(prefix + name) == hash_val:
|
||||
return name, seed
|
||||
|
||||
return None, None
|
||||
|
||||
|
||||
def parse_log(file) -> list:
|
||||
entries = []
|
||||
for il, line in enumerate(file.split("\n")):
|
||||
m = re.match(r"\[(.+?)\] ([0-9a-f]{40})", line.rstrip())
|
||||
if m:
|
||||
entries.append({"ts": m.group(1), "hash": m.group(2)})
|
||||
continue
|
||||
|
||||
print(f"Unable to parse line number {il:>4}: {line.strip()}??")
|
||||
|
||||
return entries
|
||||
|
||||
|
||||
def decode(file) -> None:
|
||||
entries = parse_log(file)
|
||||
|
||||
if not entries:
|
||||
print("No entries found in log.")
|
||||
return
|
||||
|
||||
seen = set()
|
||||
total = 0
|
||||
deaths = 0
|
||||
have_init = False
|
||||
have_debug = False
|
||||
known_seed = None # cached once first seeded entry is resolved
|
||||
current_run_perk_combos = set() # perk combos seen since the last "-" entry
|
||||
|
||||
for entry in entries:
|
||||
name, seed = resolve(entry["hash"], entry["ts"], known_seed)
|
||||
|
||||
if name is None:
|
||||
print(f" ???? (unresolved) {entry['hash']} ts: {entry['ts']}")
|
||||
continue
|
||||
|
||||
if seed is not None and known_seed is None:
|
||||
known_seed = seed
|
||||
|
||||
if name == "-":
|
||||
have_init = True
|
||||
current_run_perk_combos = set()
|
||||
continue
|
||||
|
||||
if name == "DEBUG":
|
||||
have_debug = True
|
||||
continue
|
||||
|
||||
if name == "DEATH":
|
||||
deaths += 1
|
||||
continue
|
||||
|
||||
# skip mod-presence entries
|
||||
if name not in POINTS:
|
||||
continue
|
||||
|
||||
if name in seen:
|
||||
continue
|
||||
|
||||
if name not in {"BOSS_KILL"}:
|
||||
seen.add(name)
|
||||
|
||||
if name in PERK_COMBO_IDS:
|
||||
current_run_perk_combos.add(name)
|
||||
|
||||
pts = POINTS.get(name, 0)
|
||||
if pts:
|
||||
print(f" +{pts:>4} {name:<40} first seen: {entry['ts']}")
|
||||
total += pts
|
||||
|
||||
if name == "BOSS_KILL":
|
||||
for combo_id in sorted(current_run_perk_combos):
|
||||
bonus_key = f"{combo_id}-BOSS_KILL"
|
||||
if bonus_key not in seen:
|
||||
seen.add(bonus_key)
|
||||
bonus_pts = POINTS.get(bonus_key, BOSS_KILL_COMBO_BONUS)
|
||||
print(f" +{bonus_pts:>4} {bonus_key:<40} combo bonus")
|
||||
total += bonus_pts
|
||||
|
||||
death_deduction = deaths * DEATH_PENALTY
|
||||
if deaths:
|
||||
print(
|
||||
f" -{death_deduction:>4} ({deaths} death{'s' if deaths > 1 else ''} × {DEATH_PENALTY} pts)"
|
||||
)
|
||||
|
||||
if have_init:
|
||||
print(
|
||||
f"\nTotal: {total - death_deduction} pts ({total} earned − {death_deduction} penalty)"
|
||||
)
|
||||
|
||||
if have_debug:
|
||||
print("Note: DEBUG mode was active during at least one session.")
|
||||
@@ -0,0 +1,40 @@
|
||||
from noita.models import LogfileSubmission, Objectiv
|
||||
from noita.services.decode import parse_log, resolve
|
||||
|
||||
|
||||
from collections import Counter
|
||||
|
||||
|
||||
def parse_objectives_from_logfile(logfile: LogfileSubmission) -> Counter:
|
||||
"""Parse a log file, and output a count for each ID."""
|
||||
file_data = logfile.file.read().decode()
|
||||
|
||||
ids = []
|
||||
for entry in parse_log(file_data):
|
||||
idx, _seed = resolve(entry["hash"], entry["ts"])
|
||||
|
||||
if idx:
|
||||
ids.append(idx)
|
||||
|
||||
return Counter(ids)
|
||||
|
||||
|
||||
def parse_objectives_and_store(logfile: LogfileSubmission) -> None:
|
||||
"""Parse a logfile and store output."""
|
||||
|
||||
if not logfile.user:
|
||||
return
|
||||
|
||||
counter = parse_objectives_from_logfile(logfile)
|
||||
|
||||
for idx, count in counter.items():
|
||||
if idx in {"-", "DEBUG"}:
|
||||
continue
|
||||
|
||||
obj, created = Objectiv.objects.get_or_create(
|
||||
objectiv_id=idx,
|
||||
user=logfile.user,
|
||||
)
|
||||
|
||||
obj.count += count
|
||||
obj.save(update_fields=["count"])
|
||||
@@ -0,0 +1,535 @@
|
||||
ALL_SPELLS = [
|
||||
"FUNKY_SPELL",
|
||||
"ACIDSHOT",
|
||||
"BLACK_HOLE",
|
||||
"BLACK_HOLE_DEATH_TRIGGER",
|
||||
"BOMB",
|
||||
"BOMB_CART",
|
||||
"BUBBLESHOT",
|
||||
"BUBBLESHOT_TRIGGER",
|
||||
"AIR_BULLET",
|
||||
"CHAIN_BOLT",
|
||||
"CHAINSAW",
|
||||
"CURSED_ORB",
|
||||
"ANTIHEAL",
|
||||
"DEATH_CROSS",
|
||||
"DEATH_CROSS_BIG",
|
||||
"LASER_EMITTER_FOUR",
|
||||
"POWERDIGGER",
|
||||
"DIGGER",
|
||||
"PIPE_BOMB",
|
||||
"PIPE_BOMB_DEATH_TRIGGER",
|
||||
"GRENADE_LARGE",
|
||||
"DYNAMITE",
|
||||
"CRUMBLING_EARTH",
|
||||
"TENTACLE_PORTAL",
|
||||
"SLOW_BULLET",
|
||||
"SLOW_BULLET_TRIGGER",
|
||||
"SLOW_BULLET_TIMER",
|
||||
"EXPANDING_ORB",
|
||||
"FIREBALL",
|
||||
"GRENADE",
|
||||
"GRENADE_TRIGGER",
|
||||
"GRENADE_TIER_2",
|
||||
"GRENADE_TIER_3",
|
||||
"GRENADE_ANTI",
|
||||
"FIREBOMB",
|
||||
"FIREWORK",
|
||||
"FLAMETHROWER",
|
||||
"GLITTER_BOMB",
|
||||
"LANCE",
|
||||
"GLUE_SHOT",
|
||||
"HEAL_BULLET",
|
||||
"LANCE_HOLY",
|
||||
"BOMB_HOLY",
|
||||
"BOMB_HOLY_GIGA",
|
||||
"HOOK",
|
||||
"ICEBALL",
|
||||
"LASER",
|
||||
"LIGHTNING",
|
||||
"THUNDERBALL",
|
||||
"BALL_LIGHTNING",
|
||||
"LUMINOUS_DRILL",
|
||||
"LASER_LUMINOUS_DRILL",
|
||||
"BULLET",
|
||||
"BULLET_TRIGGER",
|
||||
"BULLET_TIMER",
|
||||
"HEAVY_BULLET",
|
||||
"HEAVY_BULLET_TRIGGER",
|
||||
"HEAVY_BULLET_TIMER",
|
||||
"MAGIC_SHIELD",
|
||||
"BIG_MAGIC_SHIELD",
|
||||
"ROCKET",
|
||||
"ROCKET_TIER_2",
|
||||
"ROCKET_TIER_3",
|
||||
"METEOR",
|
||||
"MIST_BLOOD",
|
||||
"MIST_ALCOHOL",
|
||||
"MIST_SLIME",
|
||||
"MIST_RADIOACTIVE",
|
||||
"BUCKSHOT",
|
||||
"MEGALASER",
|
||||
"EXPLODING_DUCKS",
|
||||
"FREEZING_GAZE",
|
||||
"INFESTATION",
|
||||
"NUKE",
|
||||
"NUKE_GIGA",
|
||||
"DARKFLAME",
|
||||
"GLOWING_BOLT",
|
||||
"LASER_EMITTER",
|
||||
"LASER_EMITTER_CUTTER",
|
||||
"POLLEN",
|
||||
"SPORE_POD",
|
||||
"PROPANE_TANK",
|
||||
"RANDOM_PROJECTILE",
|
||||
"SUMMON_ROCK",
|
||||
"DISC_BULLET",
|
||||
"DISC_BULLET_BIG",
|
||||
"DISC_BULLET_BIGGER",
|
||||
"SLIMEBALL",
|
||||
"LIGHT_BULLET",
|
||||
"LIGHT_BULLET_TRIGGER",
|
||||
"LIGHT_BULLET_TRIGGER_2",
|
||||
"LIGHT_BULLET_TIMER",
|
||||
"RUBBER_BALL",
|
||||
"ARROW",
|
||||
"BOUNCY_ORB",
|
||||
"BOUNCY_ORB_TIMER",
|
||||
"SPIRAL_SHOT",
|
||||
"SPITTER",
|
||||
"SPITTER_TIMER",
|
||||
"SPITTER_TIER_2",
|
||||
"SPITTER_TIER_2_TIMER",
|
||||
"SPITTER_TIER_3",
|
||||
"SPITTER_TIER_3_TIMER",
|
||||
"EXPLODING_DEER",
|
||||
"SUMMON_EGG",
|
||||
"TNTBOX",
|
||||
"TNTBOX_BIG",
|
||||
"FISH",
|
||||
"SUMMON_HOLLOW_EGG",
|
||||
"MISSILE",
|
||||
"PEBBLE",
|
||||
"TENTACLE",
|
||||
"TENTACLE_TIMER",
|
||||
"TELEPORT_PROJECTILE_CLOSER",
|
||||
"TELEPORT_PROJECTILE_STATIC",
|
||||
"SWAPPER_PROJECTILE",
|
||||
"TELEPORT_PROJECTILE",
|
||||
"TELEPORT_PROJECTILE_SHORT",
|
||||
"MINE",
|
||||
"MINE_DEATH_TRIGGER",
|
||||
"WHITE_HOLE",
|
||||
"WORM_SHOT",
|
||||
"WALL_HORIZONTAL",
|
||||
"WALL_VERTICAL",
|
||||
"WALL_SQUARE",
|
||||
"REGENERATION_FIELD",
|
||||
"FREEZE_FIELD",
|
||||
"LEVITATION_FIELD",
|
||||
"TELEPORTATION_FIELD",
|
||||
"BERSERK_FIELD",
|
||||
"SHIELD_FIELD",
|
||||
"ELECTROCUTION_FIELD",
|
||||
"POLYMORPH_FIELD",
|
||||
"CHAOS_POLYMORPH_FIELD",
|
||||
"CLOUD_WATER",
|
||||
"CLOUD_OIL",
|
||||
"CLOUD_BLOOD",
|
||||
"CLOUD_ACID",
|
||||
"CLOUD_THUNDER",
|
||||
"DESTRUCTION",
|
||||
"BOMB_DETONATOR",
|
||||
"PURPLE_EXPLOSION_FIELD",
|
||||
"WORM_RAIN",
|
||||
"METEOR_RAIN",
|
||||
"SWARM_FLY",
|
||||
"SWARM_FIREBUG",
|
||||
"SWARM_WASP",
|
||||
"DELAYED_SPELL",
|
||||
"MASS_POLYMORPH",
|
||||
"PROJECTILE_THUNDER_FIELD",
|
||||
"PROJECTILE_GRAVITY_FIELD",
|
||||
"PROJECTILE_TRANSMUTATION_FIELD",
|
||||
"RANDOM_STATIC_PROJECTILE",
|
||||
"WHITE_HOLE_BIG",
|
||||
"BLACK_HOLE_BIG",
|
||||
"BLACK_HOLE_GIGA",
|
||||
"THUNDER_BLAST",
|
||||
"FIRE_BLAST",
|
||||
"EXPLOSION_LIGHT",
|
||||
"POISON_BLAST",
|
||||
"EXPLOSION",
|
||||
"ALCOHOL_BLAST",
|
||||
"WHITE_HOLE_GIGA",
|
||||
"FRIEND_FLY",
|
||||
"VACUUM_POWDER",
|
||||
"VACUUM_LIQUID",
|
||||
"VACUUM_ENTITIES",
|
||||
"CLUSTERMOD",
|
||||
"MANA_REDUCE",
|
||||
"ARC_POISON",
|
||||
"ARC_FIRE",
|
||||
"ARC_GUNPOWDER",
|
||||
"ARC_ELECTRIC",
|
||||
"ROCKET_DOWNWARDS",
|
||||
"ROCKET_OCTAGON",
|
||||
"BOUNCE",
|
||||
"BOUNCE_SPARK",
|
||||
"BOUNCE_LASER",
|
||||
"REMOVE_BOUNCE",
|
||||
"BOUNCE_SMALL_EXPLOSION",
|
||||
"BOUNCE_HOLE",
|
||||
"BOUNCE_EXPLOSION",
|
||||
"BOUNCE_LARPA",
|
||||
"BOUNCE_LIGHTNING",
|
||||
"BOUNCE_LASER_EMITTER",
|
||||
"EXPLOSION_TINY",
|
||||
"HITFX_CRITICAL_BLOOD",
|
||||
"HITFX_CRITICAL_OIL",
|
||||
"HITFX_CRITICAL_WATER",
|
||||
"HITFX_BURNING_CRITICAL_HIT",
|
||||
"CRITICAL_HIT",
|
||||
"AREA_DAMAGE",
|
||||
"BLOODLUST",
|
||||
"DAMAGE",
|
||||
"DAMAGE_RANDOM",
|
||||
"DAMAGE_FOREVER",
|
||||
"ZERO_DAMAGE",
|
||||
"HEAVY_SHOT",
|
||||
"LIGHT_SHOT",
|
||||
"CRUMBLING_EARTH_PROJECTILE",
|
||||
"FREEZE",
|
||||
"ELECTRIC_CHARGE",
|
||||
"HITFX_EXPLOSION_ALCOHOL",
|
||||
"HITFX_EXPLOSION_ALCOHOL_GIGA",
|
||||
"HITFX_EXPLOSION_SLIME",
|
||||
"HITFX_EXPLOSION_SLIME_GIGA",
|
||||
"HITFX_TOXIC_CHARM",
|
||||
"COLOUR_RED",
|
||||
"COLOUR_ORANGE",
|
||||
"COLOUR_YELLOW",
|
||||
"COLOUR_GREEN",
|
||||
"COLOUR_BLUE",
|
||||
"COLOUR_PURPLE",
|
||||
"COLOUR_RAINBOW",
|
||||
"COLOUR_INVIS",
|
||||
"HEAVY_SPREAD",
|
||||
"KNOCKBACK",
|
||||
"LARPA_CHAOS_2",
|
||||
"LARPA_CHAOS",
|
||||
"LARPA_DOWNWARDS",
|
||||
"LARPA_DEATH",
|
||||
"LARPA_UPWARDS",
|
||||
"LIFETIME_DOWN",
|
||||
"LIFETIME",
|
||||
"CHAIN_SHOT",
|
||||
"NOLLA",
|
||||
"LIGHT",
|
||||
"NECROMANCY",
|
||||
"ORBIT_DISCS",
|
||||
"ORBIT_NUKES",
|
||||
"ORBIT_FIREBALLS",
|
||||
"ORBIT_LARPA",
|
||||
"ORBIT_LASERS",
|
||||
"LINE_ARC",
|
||||
"HORIZONTAL_ARC",
|
||||
"GRAVITY",
|
||||
"GRAVITY_ANTI",
|
||||
"FLY_UPWARDS",
|
||||
"FLY_DOWNWARDS",
|
||||
"ORBIT_SHOT",
|
||||
"TRUE_ORBIT",
|
||||
"SPIRALING_SHOT",
|
||||
"PINGPONG_PATH",
|
||||
"PHASING_ARC",
|
||||
"CHAOTIC_ARC",
|
||||
"SINEWAVE",
|
||||
"HOMING_WAND",
|
||||
"HOMING_CURSOR",
|
||||
"HOMING_SHORT",
|
||||
"AUTOAIM",
|
||||
"HOMING",
|
||||
"HOMING_ROTATE",
|
||||
"HOMING_SHOOTER",
|
||||
"ANTI_HOMING",
|
||||
"HOMING_ACCELERATING",
|
||||
"HOMING_AREA",
|
||||
"FIREBALL_RAY_ENEMY",
|
||||
"GRAVITY_FIELD_ENEMY",
|
||||
"TENTACLE_RAY_ENEMY",
|
||||
"LIGHTNING_RAY_ENEMY",
|
||||
"HITFX_PETRIFY",
|
||||
"PIERCING_SHOT",
|
||||
"LASER_EMITTER_WIDER",
|
||||
"QUANTUM_SPLIT",
|
||||
"RANDOM_EXPLOSION",
|
||||
"RANDOM_MODIFIER",
|
||||
"RECOIL",
|
||||
"RECOIL_DAMPER",
|
||||
"RECHARGE",
|
||||
"SPREAD_REDUCE",
|
||||
"EXPLOSION_REMOVE",
|
||||
"SLOW_BUT_STEADY",
|
||||
"ENERGY_SHIELD_SHOT",
|
||||
"SPEED",
|
||||
"DECELERATING_SHOT",
|
||||
"ACCELERATING_SHOT",
|
||||
"FIZZLE",
|
||||
"FLOATING_ARC",
|
||||
"AVOIDING_ARC",
|
||||
"CLIPPING_SHOT",
|
||||
"UNSTABLE_GUNPOWDER",
|
||||
"MATTER_EATER",
|
||||
"EXPLOSIVE_PROJECTILE",
|
||||
"FIREBALL_RAY_LINE",
|
||||
"FIREBALL_RAY",
|
||||
"LIGHTNING_RAY",
|
||||
"TENTACLE_RAY",
|
||||
"LASER_EMITTER_RAY",
|
||||
"SPELLS_TO_POWER",
|
||||
"ESSENCE_TO_POWER",
|
||||
"ACID_TRAIL",
|
||||
"FIRE_TRAIL",
|
||||
"GUNPOWDER_TRAIL",
|
||||
"OIL_TRAIL",
|
||||
"POISON_TRAIL",
|
||||
"RAINBOW_TRAIL",
|
||||
"WATER_TRAIL",
|
||||
"BURN_TRAIL",
|
||||
"WATER_TO_POISON",
|
||||
"BLOOD_TO_ACID",
|
||||
"LAVA_TO_BLOOD",
|
||||
"LIQUID_TO_EXPLOSION",
|
||||
"TOXIC_TO_ACID",
|
||||
"STATIC_TO_SAND",
|
||||
"TRANSMUTATION",
|
||||
"CURSE_WITHER_ELECTRICITY",
|
||||
"CURSE_WITHER_EXPLOSION",
|
||||
"CURSE_WITHER_MELEE",
|
||||
"CURSE_WITHER_PROJECTILE",
|
||||
"CURSE",
|
||||
"BURST_2",
|
||||
"BURST_3",
|
||||
"BURST_4",
|
||||
"BURST_8",
|
||||
"BURST_X",
|
||||
"SCATTER_2",
|
||||
"SCATTER_3",
|
||||
"SCATTER_4",
|
||||
"I_SHAPE",
|
||||
"T_SHAPE",
|
||||
"PENTAGRAM_SHAPE",
|
||||
"CIRCLE_SHAPE",
|
||||
"Y_SHAPE",
|
||||
"W_SHAPE",
|
||||
"TOUCH_PISS",
|
||||
"TOUCH_GRASS",
|
||||
"SOILBALL",
|
||||
"CIRCLE_FIRE",
|
||||
"CIRCLE_ACID",
|
||||
"CIRCLE_OIL",
|
||||
"CIRCLE_WATER",
|
||||
"MATERIAL_BLOOD",
|
||||
"MATERIAL_CEMENT",
|
||||
"MATERIAL_OIL",
|
||||
"MATERIAL_ACID",
|
||||
"MATERIAL_WATER",
|
||||
"SEA_LAVA",
|
||||
"SEA_ALCOHOL",
|
||||
"SEA_OIL",
|
||||
"SEA_WATER",
|
||||
"SEA_ACID",
|
||||
"SEA_ACID_GAS",
|
||||
"SEA_SWAMP",
|
||||
"SEA_MIMIC",
|
||||
"TOUCH_BLOOD",
|
||||
"TOUCH_GOLD",
|
||||
"TOUCH_OIL",
|
||||
"TOUCH_SMOKE",
|
||||
"TOUCH_ALCOHOL",
|
||||
"TOUCH_WATER",
|
||||
"X_RAY",
|
||||
"BLOOD_MAGIC",
|
||||
"CASTER_CAST",
|
||||
"I_SHOT",
|
||||
"Y_SHOT",
|
||||
"T_SHOT",
|
||||
"W_SHOT",
|
||||
"QUAD_SHOT",
|
||||
"PENTA_SHOT",
|
||||
"HEXA_SHOT",
|
||||
"SUPER_TELEPORT_CAST",
|
||||
"TELEPORT_CAST",
|
||||
"LONG_DISTANCE_CAST",
|
||||
"ALL_ACID",
|
||||
"ALL_BLACKHOLES",
|
||||
"ALL_DEATHCROSSES",
|
||||
"ALL_ROCKETS",
|
||||
"ALL_NUKES",
|
||||
"ALL_DISCS",
|
||||
"SUMMON_WANDGHOST",
|
||||
"TEMPORARY_PLATFORM",
|
||||
"TEMPORARY_WALL",
|
||||
"MONEY_MAGIC",
|
||||
"BLOOD_TO_POWER",
|
||||
"RESET",
|
||||
"ENERGY_SHIELD",
|
||||
"ENERGY_SHIELD_SECTOR",
|
||||
"TINY_GHOST",
|
||||
"TORCH",
|
||||
"TORCH_ELECTRIC",
|
||||
"ADD_TRIGGER",
|
||||
"ADD_TIMER",
|
||||
"ADD_DEATH_TRIGGER",
|
||||
"CESSATION",
|
||||
"DIVIDE_2",
|
||||
"DIVIDE_3",
|
||||
"DIVIDE_4",
|
||||
"DIVIDE_10",
|
||||
"OMEGA",
|
||||
"ZETA",
|
||||
"TAU",
|
||||
"SIGMA",
|
||||
"PHI",
|
||||
"MU",
|
||||
"ALPHA",
|
||||
"GAMMA",
|
||||
"KANTELE_A",
|
||||
"KANTELE_D",
|
||||
"KANTELE_DIS",
|
||||
"KANTELE_E",
|
||||
"KANTELE_G",
|
||||
"OCARINA_A",
|
||||
"OCARINA_B",
|
||||
"OCARINA_C",
|
||||
"OCARINA_D",
|
||||
"OCARINA_E",
|
||||
"OCARINA_F",
|
||||
"OCARINA_GSHARP",
|
||||
"OCARINA_A2",
|
||||
"RANDOM_SPELL",
|
||||
"DRAW_RANDOM",
|
||||
"DRAW_RANDOM_X3",
|
||||
"DRAW_3_RANDOM",
|
||||
"IF_PROJECTILE",
|
||||
"IF_HP",
|
||||
"IF_ENEMY",
|
||||
"IF_HALF",
|
||||
"IF_ELSE",
|
||||
"IF_END",
|
||||
"DUPLICATE",
|
||||
"SUMMON_PORTAL",
|
||||
"ALL_SPELLS",
|
||||
]
|
||||
|
||||
ALL_PERKS = [
|
||||
"CRITICAL_HIT",
|
||||
"BREATH_UNDERWATER",
|
||||
"EXTRA_MONEY",
|
||||
"EXTRA_MONEY_TRICK_KILL",
|
||||
"GOLD_IS_FOREVER",
|
||||
"TRICK_BLOOD_MONEY",
|
||||
"EXPLODING_GOLD",
|
||||
"HOVER_BOOST",
|
||||
"FASTER_LEVITATION",
|
||||
"MOVEMENT_FASTER",
|
||||
"LOW_GRAVITY",
|
||||
"HIGH_GRAVITY",
|
||||
"SPEED_DIVER",
|
||||
"STRONG_KICK",
|
||||
"TELEKINESIS",
|
||||
"REPELLING_CAPE",
|
||||
"EXPLODING_CORPSES",
|
||||
"SAVING_GRACE",
|
||||
"INVISIBILITY",
|
||||
"GLOBAL_GORE",
|
||||
"REMOVE_FOG_OF_WAR",
|
||||
"LEVITATION_TRAIL",
|
||||
"VAMPIRISM",
|
||||
"EXTRA_HP",
|
||||
"HEARTS_MORE_EXTRA_HP",
|
||||
"GLASS_CANNON",
|
||||
"LOW_HP_DAMAGE_BOOST",
|
||||
"RESPAWN",
|
||||
"WORM_ATTRACTOR",
|
||||
"WORM_DETRACTOR",
|
||||
"RADAR_ENEMY",
|
||||
"FOOD_CLOCK",
|
||||
"WAND_RADAR",
|
||||
"ITEM_RADAR",
|
||||
"MOON_RADAR",
|
||||
"PROTECTION_FIRE",
|
||||
"PROTECTION_RADIOACTIVITY",
|
||||
"PROTECTION_EXPLOSION",
|
||||
"PROTECTION_MELEE",
|
||||
"PROTECTION_ELECTRICITY",
|
||||
"TELEPORTITIS",
|
||||
"TELEPORTITIS_DODGE",
|
||||
"STAINLESS_ARMOUR",
|
||||
"EDIT_WANDS_EVERYWHERE",
|
||||
"NO_WAND_EDITING",
|
||||
"WAND_EXPERIMENTER",
|
||||
"ADVENTURER",
|
||||
"ABILITY_ACTIONS_MATERIALIZED",
|
||||
"PROJECTILE_HOMING",
|
||||
"PROJECTILE_HOMING_SHOOTER",
|
||||
"UNLIMITED_SPELLS",
|
||||
"FREEZE_FIELD",
|
||||
"FIRE_GAS",
|
||||
"DISSOLVE_POWDERS",
|
||||
"BLEED_SLIME",
|
||||
"BLEED_OIL",
|
||||
"BLEED_GAS",
|
||||
"SHIELD",
|
||||
"REVENGE_EXPLOSION",
|
||||
"REVENGE_TENTACLE",
|
||||
"REVENGE_RATS",
|
||||
"REVENGE_BULLET",
|
||||
"ATTACK_FOOT",
|
||||
"LEGGY_FEET",
|
||||
"PLAGUE_RATS",
|
||||
"VOMIT_RATS",
|
||||
"CORDYCEPS",
|
||||
"MOLD",
|
||||
"WORM_SMALLER_HOLES",
|
||||
"PROJECTILE_REPULSION",
|
||||
"RISKY_CRITICAL",
|
||||
"FUNGAL_DISEASE",
|
||||
"PROJECTILE_SLOW_FIELD",
|
||||
"PROJECTILE_REPULSION_SECTOR",
|
||||
"PROJECTILE_EATER_SECTOR",
|
||||
"ORBIT",
|
||||
"ANGRY_GHOST",
|
||||
"HUNGRY_GHOST",
|
||||
"DEATH_GHOST",
|
||||
"HOMUNCULUS",
|
||||
"ELECTRICITY",
|
||||
"ATTRACT_ITEMS",
|
||||
"EXTRA_KNOCKBACK",
|
||||
"LOWER_SPREAD",
|
||||
"LOW_RECOIL",
|
||||
"BOUNCE",
|
||||
"FAST_PROJECTILES",
|
||||
"ALWAYS_CAST",
|
||||
"EXTRA_MANA",
|
||||
"NO_MORE_SHUFFLE",
|
||||
"NO_MORE_KNOCKBACK",
|
||||
"DUPLICATE_PROJECTILE",
|
||||
"FASTER_WANDS",
|
||||
"EXTRA_SLOTS",
|
||||
"CONTACT_DAMAGE",
|
||||
"EXTRA_PERK",
|
||||
"PERKS_LOTTERY",
|
||||
"GAMBLE",
|
||||
"EXTRA_SHOP_ITEM",
|
||||
"GENOME_MORE_HATRED",
|
||||
"GENOME_MORE_LOVE",
|
||||
"PEACE_WITH_GODS",
|
||||
"MANA_FROM_KILLS",
|
||||
"ANGRY_LEVITATION",
|
||||
"LASER_AIM",
|
||||
"PERSONAL_LASER",
|
||||
"MEGA_BEAM_STONE",
|
||||
"IRON_STOMACH",
|
||||
]
|
||||
Reference in New Issue
Block a user