From bc75f0bf45592c72374b181679c5f591b42c838e Mon Sep 17 00:00:00 2001 From: Demur Rumed Date: Sun, 12 May 2024 20:45:35 +0000 Subject: [PATCH] Introduce 12 new weapons, along with a rare Earth spell Imbue --- src/cards.csv | 144 +++++++------ src/rs/fuzz/Cargo.toml | 2 +- src/rs/src/aieval.rs | 13 +- src/rs/src/aisearch.rs | 3 +- src/rs/src/card.rs | 13 +- src/rs/src/game.rs | 62 ++++-- src/rs/src/lib.rs | 14 +- src/rs/src/skill.rs | 444 +++++++++++++++++++++++++++++++++++++---- src/rs/src/text.rs | 67 +++++-- src/ui/art.js | 17 +- 10 files changed, 614 insertions(+), 165 deletions(-) diff --git a/src/cards.csv b/src/cards.csv index 28408faa..252b2185 100644 --- a/src/cards.csv +++ b/src/cards.csv @@ -12,8 +12,8 @@ 7007|War Axe|0|0|1|3|4|2|buff=axe+draw=axedraw| 5008|Quantum Locket|0|2|1|1|||1=locketshift+locket| 7008|Quantum Locket|0|2|1|0|||1=locketshift+locket| -5009|Chromatic Butterfly|0|4|2|1|1|1|hit=chromastat|airborne -7009|Chromatic Butterfly|0|4|2|1|1|2|hit=chromastat|airborne +5009|Chromatic Butterfly|0|4|2|1|1|1|hit=chromastat|airborne+bug +7009|Chromatic Butterfly|0|4|2|1|1|2|hit=chromastat|airborne+bug 5010|Mark of Chroma|0|2|-1|0|||pillar|pillar+stackable+additive+charges=1 7010|Mark of Chroma|0|2|-1|0|||pillar+play=pillar1|pillar+stackable+additive+charges=1 5011|Mark of Entropy|1|2|-1|0|||pillar|pillar+stackable+additive+charges=1 @@ -92,8 +92,8 @@ 7114|Schrödinger's Cat|1|4|1|1|1|3|1=deadalive|nocturnal 5115|Singularity|1|4|1|10|-1|3|singularity|token 7115|Singularity|1|4|1|10|-7|5|singularity|token -5116|Spider Cow|1|4|1|4|3|3|ownplay=mutant|aquatic -7116|Micro Spider Cow|1|4|1|1|1|2|ownplay=mutant|aquatic +5116|Spider Cow|1|4|1|4|3|3|ownplay=mutant|aquatic+bug +7116|Micro Spider Cow|1|4|1|1|1|2|ownplay=mutant|aquatic+bug 5117|Ricochet|1|2|2|3|||spell=ricochet| 7117|Ricochet|1|2|2|2|||spell=ricochet| 5118|Golden Goose|1|4|2|4|2|6|1:10=summon 6002|airborne @@ -116,6 +116,8 @@ 7126|Pink Jelly|1|3|1|4|||jelly| 5127|Chaos Seed 2.0|1|3|2|1|||cseed2| 7127|Pandemonium 3.0|1|3|2|4|||pandemonium3| +5128|Magic Wand|1|0|3|3|2|7|1=shazam|psionic +7128|Magic Wand|1|0|3|2|2|7|1=shazam|psionic 5130|Shard of Serendipity|1|3|3|2|||serendipity| 7130|Shard of Serendipity|1|3|3|3|||serendipity| 5150|Entropy Pendulum|1|2|0|0|||pend|pillar+stackable+additive+charges=1 @@ -126,8 +128,8 @@ 7201|Ivory Dragon|2|4|2|10|11|5||airborne+nocturnal 5202|Virus|2|4|1|1|1|1|0=virusinfect+owndeath=poisonfoe 1|airborne+poisonous+nocturnal+aquatic 7202|Retrovirus|2|4|1|2|1|1|0=virusplague|airborne+poisonous+nocturnal+aquatic -5203|Flesh Spider|2|4|1|3|3|3|1:9=web|nocturnal -7203|Flesh Recluse|2|4|1|3|6|3|1:9=web|nocturnal +5203|Flesh Spider|2|4|1|3|3|3|1:9=web|nocturnal+bug +7203|Flesh Recluse|2|4|1|3|6|3|1:9=web|nocturnal+bug 5204|Vulture|2|4|1|2|1|2|death=growth 1 1|airborne+nocturnal 7204|Condor|2|4|1|2|2|3|death=growth 1 1|airborne+nocturnal 5205|Skull Shield|2|1|2|3||1|shield=skull| @@ -148,8 +150,8 @@ 7212|Aflatoxin|2|3|2|4|||aflatoxin| 5213|Mummy|2|4|1|4|5|3|prespell=mummy|nocturnal 7213|Mummy|2|4|1|3|5|4|prespell=mummy|nocturnal -5214|Deathstalker|2|4|1|2||1|hit=poison 2|poisonous+nocturnal -7214|Deathstalker|2|4|1|2||3|hit=poison 2|poisonous+nocturnal +5214|Deathstalker|2|4|1|2||1|hit=poison 2|poisonous+nocturnal+bug +7214|Deathstalker|2|4|1|2||3|hit=poison 2|poisonous+nocturnal+bug 5215|Soul Catcher|2|2|1|1:0|||death=soulcatch| 7215|Soul Catcher|2|2|1|0|||death=soulcatch| 5216|Ouija Essence|2|2|2|3|||death=ouija+owndiscard=hasten+upkeep+owndestroy=ouijadestroy+1:5=ouijagrowth| @@ -174,10 +176,12 @@ 7225|Envenom|2|3|1|2|||envenom| 5226|Reaper|2|4|3|7|7|4|2:8=reap+prespell=evadecrea|nocturnal 7226|Reaper|2|4|3|7|8|4|1:8=reap+prespell=evadecrea|nocturnal -5227|Plague Mask|2|1|2|2||1|buff=poisondr+1:7=doctor| -7227|Plague Mask|2|1|2|3||2|buff=poisondr+1:7=doctor| +5227|Plague Mask|2|1|2|2||1|hp=poisondr+1:7=doctor| +7227|Plague Mask|2|1|2|3||2|hp=poisondr+1:7=doctor| 5228|Frailty|2|3|1|1|||frail| 7228|Frailty|2|3|1|1|||frail2| +5229|Skeleton Axe|2|0|3|3|2|4|1=bonesharpen+buff=skeletoncount|nocturnal +7229|Skeleton Axe|2|0|3|4|0|4|1=bonesharpen+buff=skeletoncount|nocturnal 5230|Shard of Sacrifice|2|3|3|2|||sosa| 7230|Shard of Sacrifice|2|3|3|2|||sosa| 5250|Death Pendulum|2|2|0|0|||pend|pillar+stackable+additive+charges=1 @@ -214,8 +218,8 @@ 7314|Overdrive|3|3|1|4|||acceleration| 5315|Graviton Salvager|3|4|1|1|1|5|destroy=salvage| 7315|Graviton Salvager|3|4|1|1|2|5|destroy=salvage| -5316|Repulsor|3|1|2|1|||buff=accumulation|stackable+additive+charges=1 -7316|Repulsors|3|1|2|6|||buff=accumulation|stackable+additive+charges=2 +5316|Repulsor|3|1|2|1|||hp=accumulation|stackable+additive+charges=1 +7316|Repulsors|3|1|2|6|||hp=accumulation|stackable+additive+charges=2 5317|Graviton Defender|3|4|1|5|3|10|shield=counter+2=gpull| 7317|Graviton Defender|3|4|1|5|4|12|shield=counter+2=gpull| 5318|Graviton Deployer|3|4|2|7|4|6|2=deployblobs| @@ -238,6 +242,8 @@ 7326|Brawl|3|3|3|13|||brawl| 5327|Boar|3|4|1|3|2|1|growth 1 0| 7327|Boar|3|4|1|3|3|1|growth 1 1| +5328|Scepter of Ruling|3|0|3|5|4|8|3:12=beguile| +7328|Scepter of Ruling|3|0|3|5|4|8|2:12=beguile| 5330|Shard of Focus|3|4|3|6||1|1=accretion| 7330|Shard of Focus|3|4|3|4||1|1=accretion| 5331|Stasis|3|3|2|1|||stasisdraw+owndraw=sanctify+owndiscard=sanctify| @@ -246,8 +252,8 @@ 7350|Gravity Pendulum|3|2|0|0|||pend+ownplay=pillar1|pillar+stackable+additive+charges=1 5400|Stone Pillar|4|2|0|0|||pillar|pillar+stackable+additive+charges=1 7400|Stone Tower|4|2|0|0|||pillar+ownplay=pillar1|pillar+stackable+additive+charges=1 -5401|Antlion|4|4|1|2|3|2|1=burrow| -7401|Antlion|4|4|1|2|4|4|1=burrow| +5401|Antlion|4|4|1|2|3|2|1=burrow|bug +7401|Antlion|4|4|1|2|4|4|1=burrow|bug 5402|Hematite Golem|4|4|1|4|4|6||golem 7402|Steel Golem|4|4|1|4|6|9||golem 5403|Stone Dragon|4|4|2|10|9|9||golem+airborne @@ -260,10 +266,10 @@ 7406|Gnome Gemfinder|4|4|1|0|1|3|quanta 4| 5407|Pulverizer|4|0|3|4|5|12|3:3=destroy| 7407|Pulverizer|4|0|3|4|5|12|2:3=destroy| -5408|Graboid|4|4|2|3|1|1|1:10=evolve|burrowed -7408|Graboid|4|4|2|3|1|1|1:10=evolve|burrowed -5409|Shrieker|4|4|1|8|8|3|1=burrow| -7409|Shrieker|4|4|1|8|10|4|1=burrow| +5408|Graboid|4|4|2|3|1|1|1:10=evolve|burrowed+bug +7408|Graboid|4|4|2|3|1|1|1:10=evolve|burrowed+bug +5409|Shrieker|4|4|1|8|8|3|1=burrow|bug +7409|Shrieker|4|4|1|8|10|4|1=burrow|bug 5410|Protect Artifact|4|3|1|2|||enchant| 7410|Protect Artifact|4|3|1|1|||enchant| 5411|Earthquake|4|3|2|3|||earthquake 4| @@ -294,16 +300,20 @@ 7423|Boomstick|4|0|3|4|6|9|2=golemhit| 5424|Golem Defender|4|1|2|3||1|0=turngolem+shield=absorbdmg|golem 7424|Golem Defender|4|1|2|5||2|0=turngolem+shield=absorbdmg|golem +5425|Imbue|4|3|3|4|||imbue| +7425|Imbue|4|3|3|3|||imbue| 5426|Minotaur|4|4|2|5|4|5|ownattack=predator| 7426|Minotaur|4|4|2|6|6|4|ownattack=predator| 5427|Gaian Enchantress|4|4|2|6|3|7|2:12=enchant+buff=countimmbur| 7427|Gaian Enchantress|4|4|2|5|3|7|2:12=enchant+buff=countimmbur| 5428|Ironclad Blacksmith|4|4|1|4|3|6|1:6=tempering 3| 7428|Ironclad Blacksmith|4|4|1|4|3|7|2:6=tempering 5| -5429|Stonewall|4|1|2|9|||buff=stonewall| -7429|Stonewall|4|1|2|9||1|buff=stonewall| +5429|Stonewall|4|1|2|9|||hp=stonewall| +7429|Stonewall|4|1|2|9||1|hp=stonewall| 5430|Shard of Integrity|4|3|3|2|||integrity| 7430|Shard of Integrity|4|3|3|1|||integrity| +5431|Great Maul|4|0|3|7|7|60|0=grab2h+attack=maul+buff=novaval+turnstart=nova0+destroy=attack| +7431|Great Maul|4|0|3|7|8|70|0=grab2h+attack=maul+buff=novaval+turnstart=nova0+destroy=attack| 5450|Earth Pendulum|4|2|0|0|||pend|pillar+stackable+additive+charges=1 7450|Earth Pendulum|4|2|0|0|||pend+ownplay=pillar1|pillar+stackable+additive+charges=1 5500|Emerald Pillar|5|2|0|0|||pillar|pillar+stackable+additive+charges=1 @@ -330,12 +340,12 @@ 7510|Empathic Bond|5|2|1|4|||empathy| 5511|Adrenaline|5|3|2|4|||adrenaline| 7511|Adrenaline|5|3|2|3|||adrenaline| -5512|Scorpion|5|4|1|3|1|2|hit=poison 1|poisonous -7512|Scorpion|5|4|1|3|2|2|hit=poison 1|poisonous +5512|Scorpion|5|4|1|3|1|2|hit=poison 1|poisonous+bug +7512|Scorpion|5|4|1|3|2|2|hit=poison 1|poisonous+bug 5513|Mitosis|5|3|2|5|||mitosisspell| 7513|Mitosis|5|3|2|4|||mitosisspell| -5514|Giant Spider|5|4|1|5|5|6|1:9=web| -7514|Giant Recluse|5|4|1|5|7|6|1:9=web| +5514|Giant Spider|5|4|1|5|5|6|1:9=web|bug +7514|Giant Recluse|5|4|1|5|7|6|1:9=web|bug 5515|Cell|5|4|2|3|1|1|2=mitosis+ownpoison=cell| 7515|Cell|5|4|2|2|1|1|2=mitosis+ownpoison=cell| 5516|Elf|5|4|2|5|3|4|2:9=snipe+prespell=elf|ranged @@ -352,8 +362,10 @@ 7521|Equalize|5|3|1|1|||equalize| 5522|Rejuvenation|5|3|3|4|||regeneratespell| 7522|Rejuvenation|5|3|3|3|||regeneratespell| -5523|Scorpion Claws|5|0|3|4|1|3|beginattack=nothrottle|adrenaline=1 -7523|Scorpion Claws|5|0|3|4|2|3|beginattack=nothrottle|adrenaline=1 +5523|Scorpion Claws|5|0|3|4|1|3|beginattack=nothrottle|adrenaline=1+bug +7523|Scorpion Claws|5|0|3|4|2|3|beginattack=nothrottle|adrenaline=1+bug +5524|Infested Log|5|0|3|3|3|2|1:2=poison 2+play=bugpoison|poisonous +7524|Infested Log|5|0|3|2|3|2|1:2=poison 2+play=bugpoison|poisonous 5530|Shard of Gratitude|5|2|3|3|||regenerate 4| 7530|Shard of Gratitude|5|2|3|2|||regenerate 4| 5531|Alpha Wolf|5|4|2|5|2|2|ownplay=alphawolf|nocturnal @@ -370,8 +382,8 @@ 7550|Life Pendulum|5|2|0|0|||pend+ownplay=pillar1|pillar+stackable+additive+charges=1 5600|Burning Pillar|6|2|0|0|||pillar|pillar+stackable+additive+charges=1 7600|Burning Tower|6|2|0|0|||pillar+ownplay=pillar1|pillar+stackable+additive+charges=1 -5601|Ash Eater|6|4|1|1|2|1|quanta 6| -7601|Brimstone Eater|6|4|1|1|3|1|quanta 6| +5601|Ash Eater|6|4|1|1|2|1|quanta 6|bug +7601|Brimstone Eater|6|4|1|1|3|1|quanta 6|bug 5602|Crimson Dragon|6|4|2|10|12|3||airborne 7602|Ruby Dragon|6|4|2|12|15|3||airborne 5603|Fire Spirit|6|4|1|1||2|1=growth 2 0|airborne @@ -410,8 +422,8 @@ 7619|Heat Mirror|6|2|2|3|||play=heatmirror+4=summon 8201| 5620|Red Nymph|6|4|4|8|1|11|3=rage| 7620|Fire Nymph|6|4|4|8|1|13|4=rage| -5621|Firebrand|6|0|3|2|8|9|losecharge+prespell=firebrand|charges=2 -7621|Firebrand|6|0|3|3|12|9|losecharge+prespell=firebrand|charges=1 +5621|Firebrand|6|0|3|2|8|9|1:8=reveal+losecharge+prespell=firebrand|charges=2 +7621|Firebrand|6|0|3|3|12|9|1:8=reveal+losecharge+prespell=firebrand|charges=1 5622|Salamander|6|4|1|4|5|2||aquatic 7622|Salamander|6|4|1|4|7|2||aquatic 5623|Thermal Recoil|6|1|2|0||-1|shield=absorber| @@ -422,6 +434,10 @@ 7625|Ferro Golem|6|4|2|6|7|4|1:10=drawequip|golem 5626|Wicked Shield|6|1|2|2||4|1:11=wicked+turnstart=resetdr| 7626|Wicked Shield|6|1|2|3||4|1:11=wicked+turnstart=halvedr| +5627|Sun Blade|6|0|3|3|5|3|1:10=heatstroke+hit=heatstroke+death=miragemill| +7627|Sun Blade|6|0|3|3|8|4|1:10=heatstroke+hit=heatstroke+death=miragemill| +5628|Mirage|6|4|3|0|3|6|blocked=healblocked|token +7628|Mirage|6|4|3|0|3|6|blocked=healblocked|token 5630|Shard of Bravery|6|3|3|2|||bravery| 7630|Shard of Bravery|6|3|3|1|||bravery| 5650|Fire Pendulum|6|2|0|0|||pend|pillar+stackable+additive+charges=1 @@ -478,10 +494,12 @@ 7724|Siren|7|4|2|4|4|5|1:11=sing|aquatic 5725|Atlantis's Protection|7|3|2|3|||protectall| 7725|Atlantis's Protection|7|3|2|2|||protectall| -5727|Diving Bell Spider|7|4|1|2|2|5|1:9=bellweb|aquatic -7727|Diving Bell Spider|7|4|1|2|4|4|1:9=bellweb|aquatic -5728|Bobbit Worm|7|4|2|5|3|4|1:4=detain|aquatic+burrowed -7728|Bobbit Worm|7|4|2|5|5|5|1:4=detain|aquatic+burrowed +5726|Fishing Rod|7|0|3|3|3|3|2:10=fish|aquatic +7726|Fishing Rod|7|0|3|3|3|3|1:10=fish|aquatic +5727|Diving Bell Spider|7|4|1|2|2|5|1:9=bellweb|aquatic+bug +7727|Diving Bell Spider|7|4|1|2|4|4|1:9=bellweb|aquatic+bug +5728|Bobbit Worm|7|4|2|5|3|4|1:4=detain|aquatic+burrowed+bug +7728|Bobbit Worm|7|4|2|5|5|5|1:4=detain|aquatic+burrowed+bug 5729|Arctic Dolphin|7|4|2|6|6|4|2=deepdive|aquatic 7729|Arctic Dolphin|7|4|2|6|7|4|2=deepdive|aquatic 5730|Shard of Patience|7|2|3|4|||0=die+attack=patience|frozen=2 @@ -514,8 +532,8 @@ 7810|Miracle|8|3|3|12|||miracle| 5811|Luciferin|8|3|2|2:0|||luciferin| 7811|Luciferin|8|3|2|0|||luciferin| -5812|Hope|8|1|2|7|||buff=hope|immaterial -7812|Hope|8|1|2|7||1|buff=hope|immaterial +5812|Hope|8|1|2|7|||hp=hope|immaterial +7812|Hope|8|1|2|7||1|hp=hope|immaterial 5813|Crusader|8|4|1|5|2|4|2=endow| 7813|Crusader|8|4|1|5|3|5|2=endow| 5814|Sanctuary|8|2|1|4|||regenerate 4,sanctify+owndraw=sanctify| @@ -534,28 +552,30 @@ 7820|Light Nymph|8|4|4|9|6|9|3=luciferin| 5821|Pacify|8|3|1|3|||pacify| 7821|Pacify|8|3|1|2|||pacify| -5822|Prismatic Gladius|8|0|3|1|3|5|1:7=growth 2 2+ownfreeze=icegrowth 1 1| -7822|Prismatic Gladius|8|0|3|1|5|5|1:7=growth 2 2+ownfreeze=icegrowth 1 1| +5822|Prismatic Gladius|8|0|3|1|3|5|1:7=growth 2 2+ownfreeze=icegrowth| +7822|Prismatic Gladius|8|0|3|1|5|5|1:7=growth 2 2+ownfreeze=icegrowth| 5823|Reinforce|8|3|2|4|||bolsterintodeck| 7823|Reinforce|8|3|2|3|||bolsterintodeck| 5824|Writ of Vindication|8|2|2|3|||death=vindicate+turnstart=unvindicate| 7824|Writ of Vindication|8|2|2|2|||death=vindicate+turnstart=unvindicate| 5825|Writ of Vengeance|8|2|2|4|||death=vengeance|stackable+additive+charges=108 7825|Writ of Vengeance|8|2|2|3|||death=vengeance|stackable+additive+charges=108 -5826|Null Mantis|8|4|1|7|7|4|1:12=nullspell+prespell=evadespell| -7826|Minor Null Mantis|8|4|1|2|4|2|2:12=nullspell+prespell=evadespell| +5826|Null Mantis|8|4|1|7|7|4|1:12=nullspell+prespell=evadespell|bug +7826|Minor Null Mantis|8|4|1|2|4|2|2:12=nullspell+prespell=evadespell|bug 5827|Byakko|8|4|3|6|7|2|blocked=virtue| 7827|Byakko|8|4|3|7|9|3|blocked=virtue| 5828|Dispersion|8|3|3|7|||dispersion| 7828|Dispersion|8|3|3|5|||dispersion| +5829|Bo Staff|8|0|3|3|5|5|2=hero+buff=buffdr+hit=boreset| +7829|Bo Staff|8|0|3|3|5|5|1=hero+buff=buffdr+hit=boreset| 5830|Shard of Divinity|8|3|3|3|||divinity| 7830|Shard of Divinity|8|3|3|2|||divinity| 5850|Light Pendulum|8|2|0|0|||pend|pillar+stackable+additive+charges=1 7850|Light Pendulum|8|2|0|0|||pend+ownplay=pillar1|pillar+stackable+additive+charges=1 5900|Wind Pillar|9|2|0|0|||pillar|pillar+stackable+additive+charges=1 7900|Wind Tower|9|2|0|0|||pillar+ownplay=pillar1|pillar+stackable+additive+charges=1 -5901|Dragonfly|9|4|1|1|2|1|quanta 9|airborne -7901|Damselfly|9|4|1|0|2|1|quanta 9|airborne +5901|Dragonfly|9|4|1|1|2|1|quanta 9|airborne+bug +7901|Damselfly|9|4|1|0|2|1|quanta 9|airborne+bug 5902|Wyrm|9|4|1|4|3|4|1=dive|airborne 7902|Wyrm|9|4|1|4|5|3|2=dive|airborne 5903|Azure Dragon|9|4|2|9|9|6||airborne @@ -566,10 +586,10 @@ 7905|Thunderstorm|9|3|2|2|||storm 2| 5906|Flying Weapon|9|3|1|1|||flyingweapon| 7906|Flying Weapon|9|3|1|1:0|||flyingweapon| -5907|Firefly Queen|9|4|2|6|3|7|2:5=summon 5908|airborne+nocturnal -7907|Firefly Queen|9|4|2|6|3|7|2:5=summon 7908|airborne+nocturnal -5908|Firefly|9|4|1|2|3|2|quanta 8|airborne+nocturnal -7908|Firefly|9|4|1|2|4|3|quanta 6|airborne+nocturnal +5907|Firefly Queen|9|4|2|6|3|7|2:5=summon 5908|airborne+nocturnal+bug +7907|Firefly Queen|9|4|2|6|3|7|2:5=summon 7908|airborne+nocturnal+bug +5908|Firefly|9|4|1|2|3|2|quanta 8|airborne+nocturnal+bug +7908|Firefly|9|4|1|2|4|3|quanta 6|airborne+nocturnal+bug 5909|Owl's Eye|9|0|3|5|5|7|2=snipe|ranged 7909|Owl's Eye|9|0|3|5|7|7|2=snipe|ranged 5910|Unstable Gas|9|2|2|4|||1:6=ignite+owndiscard=ignitediscard| @@ -606,6 +626,8 @@ 7925|Thunderbird|9|4|1|3|4|4|ownplay=drawpillar+1:10=millpillar|airborne 5926|Stormshield|9|1|2|6|||shield=deckblock+2:11=tutordraw| 7926|Stormshield|9|1|2|4|||shield=deckblock+2:11=tutordraw| +5927|Snowflake|9|0|3|3|2|2|2=coldsnap+death=snowflake+destroy=snowflake+hit=rngfreeze+ownfreeze=icecharge| +7927|Snowflake|9|0|3|2|3|2|2=coldsnap+death=snowflake+destroy=snowflake+hit=rngfreeze+ownfreeze=icecharge| 5930|Shard of Freedom|9|2|3|2|||prespell=freeevade+attack=freedom| 7930|Shard of Freedom|9|2|3|1|||prespell=freeevade+attack=freedom| 5950|Air Pendulum|9|2|0|0|||pend|pillar+stackable+additive+charges=1 @@ -630,22 +652,24 @@ 8008|Eternity|10|0|3|5|4|8|3=rewind| 6009|Sundial|10|2|1|3|||3:8=hasten+losecharge+attack=stasis|charges=1 8009|Sundial|10|2|1|2|||3:8=hasten+losecharge+attack=stasis|charges=1 -6010|Scarab|10|4|1|2|2||1:3=devour+hp=swarm|airborne -8010|Scarab|10|4|1|2|3||1:3=devour+hp=swarm|airborne +6010|Scarab|10|4|1|2|2||1:3=devour+hp=swarm|airborne+bug +8010|Scarab|10|4|1|2|3||1:3=devour+hp=swarm|airborne+bug 6011|Precognition|10|3|2|1|||precognition| 8011|Precognition|10|3|2|2:0|||precognition| 6012|Pharaoh|10|4|3|9|4|9|2=summon 6010| 8012|Pharaoh|10|4|3|9|4|9|2=summon 8010| -6013|Dune Scorpion|10|4|1|2||1|hit=neuro|poisonous -8013|Dune Scorpion|10|4|1|2||3|hit=neuro|poisonous +6013|Dune Scorpion|10|4|1|2||1|hit=neuro|poisonous+bug +8013|Dune Scorpion|10|4|1|2||3|hit=neuro|poisonous+bug 6014|Ghost of the Past|10|4|1|6|7|4|owndiscard=obsession| 8014|Ghost of the Past|10|4|1|7|9|4|owndiscard=obsession| 6015|Neurotoxin|10|3|2|4|||neuroify| 8015|Neurotoxin|10|3|2|3|||neuroify| 6016|Time Barrier|10|1|2|7|||shield=blockwithcharge+draw=gaintimecharge|charges=5+stackable 8016|Time Barrier|10|1|2|5|||shield=blockwithcharge+draw=gaintimecharge|charges=5+stackable -6017|Innovation|10|3|3|4|||innovation| -8017|Innovation|10|3|3|3|||innovation| +6017|Innovation|10|3|3|4|||innovate 3| +8017|Innovation|10|3|3|3|||innovate 3| +6018|Dull Khopesh|10|0|3|4|0|2|2=innovate 2+hit=mill| +8018|Dull Khopesh|10|0|3|5|1|4|1=innovate 2+hit=mill| 6020|Golden Nymph|10|4|4|8|6|4|2=precognition| 8020|Time Nymph|10|4|4|8|7|5|2=precognition| 6021|Time Bomb|10|4|2|1||2|0=tick| @@ -676,10 +700,10 @@ 8100|Obsidian Tower|11|2|0|0|||pillar+ownplay=pillar1|pillar+stackable+additive+charges=1 6101|Black Dragon|11|4|2|10|10|5||airborne+nocturnal 8101|Obsidian Dragon|11|4|2|12|12|7||airborne+nocturnal -6102|Devourer|11|4|2|2||2|1:4=burrow+siphon|nocturnal -8102|Pest|11|4|2|2||4|1:4=burrow+siphon|nocturnal -6103|Parasite|11|4|1|2|2|1|1:2=poison 1|poisonous+nocturnal+aquatic -8103|Bloodsucker|11|4|1|2|3|1|1:2=poison 1|poisonous+nocturnal+aquatic +6102|Devourer|11|4|2|2||2|1:4=burrow+siphon|nocturnal+bug +8102|Pest|11|4|2|2||4|1:4=burrow+siphon|nocturnal+bug +6103|Parasite|11|4|1|2|2|1|1:2=poison 1|poisonous+nocturnal+aquatic+bug +8103|Bloodsucker|11|4|1|2|3|1|1:2=poison 1|poisonous+nocturnal+aquatic+bug 6104|Dusk Mantle|11|1|2|5|||shield=evade 50| 8104|Dusk Mantle|11|1|2|4|||shield=evade 50| 6105|Steal|11|3|2|4|||steal| @@ -704,6 +728,8 @@ 8114|Cloak|11|2|1|2|||losecharge|cloak+charges=4 6115|Shadling|11|4|2|1||2|2=siphonstrength|nocturnal 8115|Shadling|11|4|2|1|2|3|2=siphonstrength|nocturnal +6116|Scythe|11|0|3|3|6|6|1=haunt|nocturnal +8116|Scythe|11|0|3|2|6|6|1=haunt|nocturnal 6120|Black Nymph|11|4|4|8|6|6|1=liquid|nocturnal 8120|Dark Nymph|11|4|4|8|7|7|1=liquid|nocturnal 6122|Despair|11|1|2|6|||shield=despair| @@ -750,8 +776,8 @@ 8206|Lobotomizer|12|0|3|3|5|4|1=lobotomize| 6207|Phase Dragon|12|4|2|12|8|6||immaterial+airborne 8207|Phase Dragon|12|4|2|13|10|6||immaterial+airborne -6208|Phase Spider|12|4|1|3|4|2|1:9=web| -8208|Phase Recluse|12|4|1|4|7|2|1:9=web| +6208|Phase Spider|12|4|1|3|4|2|1:9=web|bug +8208|Phase Recluse|12|4|1|4|7|2|1:9=web|bug 6209|Quintessence|12|3|2|4|||quint| 8209|Quintessence|12|3|2|3|||quint| 6210|Fractal|12|3|3|12|||fractal| @@ -790,6 +816,8 @@ 8226|Space Whale|12|4|1|6|10|10||aquatic+frozen=2 6227|Hush|12|1|2|2|||shield=hush| 8227|Hush|12|1|2|4|||shield=hush|immaterial +6228|Cyberweapon|12|0|3|3|4|2|1:9=datashrink+hit=databloat| +8228|Cyberweapon|12|0|3|3|6|2|1:9=datashrink+hit=databloat| 6230|Shard of Wisdom|12|3|3|3|||wisdom| 8230|Shard of Wisdom|12|3|3|2|||wisdom| 6250|Aether Pendulum|12|2|0|0|||pend|pillar+stackable+additive+charges=1 diff --git a/src/rs/fuzz/Cargo.toml b/src/rs/fuzz/Cargo.toml index 00eaccbd..024ad372 100644 --- a/src/rs/fuzz/Cargo.toml +++ b/src/rs/fuzz/Cargo.toml @@ -14,4 +14,4 @@ opt-level = 1 etg = { version = "0.1", path = "../" } rand = { version = "0.8", default-features = false } rand_pcg = { version = "0.3", default-features = false } -rayon = "1.5" \ No newline at end of file +rayon = "1" diff --git a/src/rs/src/aieval.rs b/src/rs/src/aieval.rs index ab8cdee0..3e450fb3 100644 --- a/src/rs/src/aieval.rs +++ b/src/rs/src/aieval.rs @@ -444,11 +444,11 @@ fn eval_skill( Skill::hush => 3 * PREC, Skill::icebolt | Skill::v_icebolt(_) => 10 * PREC, Skill::ignite => 10 * PREC, - Skill::immolate(_) => 5 * PREC, + Skill::immolate(x) => x as i32 * (PREC / 2), Skill::improve | Skill::v_improve => 6 * PREC, Skill::inertia => 2 * PREC, Skill::ink => 3 * PREC, - Skill::innovation => 3 * PREC, + Skill::innovate(x) => x as i32 * PREC, Skill::integrity | Skill::v_integrity => 4 * PREC, Skill::jelly => 5 * PREC, Skill::jetstream => 5 * (PREC / 2), @@ -870,7 +870,8 @@ fn estimate_damage(ctx: &Game, id: i16, freedom: i32, wall: &mut Wall) -> i32 { (momatk * 3 + 1) / 2 } else { momatk - } * freedom >> PRECBITS; + } * freedom + >> PRECBITS; } for &skill in ctx.getSkill(id, Event::Hit) { if skill == Skill::vampire { @@ -949,7 +950,8 @@ fn evalthing( let mut hp = 0; if iscrea { if inhand - || !flooded || thing.flag.get(Flag::aquatic) + || !flooded + || thing.flag.get(Flag::aquatic) || !ctx.material(id, None) || ctx.getIndex(id) <= 4 { @@ -1165,7 +1167,8 @@ pub fn eval(ctx: &Game) -> i32 { .filter(|&pr| pr != 0 && ctx.hasskill(pr, Event::Attack, Skill::v_freedom)) .map(|pr| ctx.get(pr, Stat::charges)) .sum::() - .min(4) as i32 * (PREC / 4) + .min(4) as i32 + * (PREC / 4) }; if !stasis && !patience { for cr in player.creatures { diff --git a/src/rs/src/aisearch.rs b/src/rs/src/aisearch.rs index 57f185cd..2ba4ba2f 100644 --- a/src/rs/src/aisearch.rs +++ b/src/rs/src/aisearch.rs @@ -150,7 +150,8 @@ fn lethal(ctx: &Game) -> Option { .into_iter() .filter(|&id| id != 0) .map(|id| gclone.trueatk(id)) - .sum::() > 0 + .sum::() + > 0 { proc_sopa(&mut gclone, turn); } diff --git a/src/rs/src/card.rs b/src/rs/src/card.rs index 2351974d..7dc7917f 100644 --- a/src/rs/src/card.rs +++ b/src/rs/src/card.rs @@ -100,15 +100,22 @@ impl Card { } pub fn status(&self) -> &'static [(Stat, i16)] { - unsafe { StatTable.get_unchecked(self.statidx as usize..self.statidx as usize + self.statlen as usize) } + unsafe { + StatTable.get_unchecked(self.statidx as usize..self.statidx as usize + self.statlen as usize) + } } pub fn skill(&self) -> &'static [(Event, &'static [Skill])] { - unsafe { SkillTable.get_unchecked(self.skillidx as usize..self.skillidx as usize + self.skilllen as usize) } + unsafe { + SkillTable + .get_unchecked(self.skillidx as usize..self.skillidx as usize + self.skilllen as usize) + } } pub fn name(&self) -> &'static str { - unsafe { NameTable.get_unchecked(self.nameidx as usize..self.nameidx as usize + self.namelen as usize) } + unsafe { + NameTable.get_unchecked(self.nameidx as usize..self.nameidx as usize + self.namelen as usize) + } } } diff --git a/src/rs/src/game.rs b/src/rs/src/game.rs index 471d0497..9e1deef8 100644 --- a/src/rs/src/game.rs +++ b/src/rs/src/game.rs @@ -107,14 +107,14 @@ impl PlayerData { self.hand_iter().count() } - pub fn hand_last(&self) -> Option { + pub fn hand_last(&self) -> i16 { if self.hand[0] == 0 { - None + return 0; } else { let mut idx = 7; loop { if self.hand[idx] != 0 { - return Some(self.hand[idx]); + return self.hand[idx]; } idx -= 1; } @@ -453,6 +453,7 @@ impl Flag { pub const vindicated: u64 = 1 << 32; pub const voodoo: u64 = 1 << 33; pub const whetstone: u64 = 1 << 34; + pub const bug: u64 = 1 << 35; pub fn get(self, key: u64) -> bool { self.0 & key != 0 @@ -853,14 +854,16 @@ impl Game { format!( "{}", 3 + (self.get_quanta(self.get_owner(c), etg::Fire) as i16 - - self.get(c, Stat::cost)) / 4 + - self.get(c, Stat::cost)) + / 4 ) } Skill::drainlife => { format!( "{}", 2 + (self.get_quanta(self.get_owner(c), etg::Darkness) as i16 - - self.get(c, Stat::cost)) / 5 + - self.get(c, Stat::cost)) + / 5 ) } Skill::icebolt => { @@ -1354,6 +1357,10 @@ impl Game { self.rng.choose(slice) } + pub fn choose_iter<'a, 'b, T>(&'a self, a: impl IntoIterator) -> Option<&'b T> { + self.rng.choose_iter(a) + } + pub fn upto(&mut self, n: u32) -> u32 { self.rng.upto(n) } @@ -1604,7 +1611,7 @@ impl Game { } pub fn truedr(&self, id: i16, t: i16) -> i16 { - self.get(id, Stat::hp) + self.trigger_pure(Event::Buff, id, t) + self.get(id, Stat::hp) + self.trigger_pure(Event::Hp, id, t) } pub fn truehp(&self, id: i16) -> i16 { @@ -1646,8 +1653,8 @@ impl Game { if dmg != 0 { let mut data = ProcData::default(); data.dmg = dmg; - self.trigger_data(Event::Hit, c, t, &mut data); self.trigger_data(Event::Shield, t, c, &mut data); + self.trigger_data(Event::Hit, c, t, &mut data); } } } @@ -1964,15 +1971,20 @@ impl Game { thing.status.insert(Stat::atk, card.attack as i16); thing.status.insert(Stat::cost, card.cost as i16); thing.status.insert(Stat::costele, card.costele as i16); - thing.flag.0 &= - !(Flag::additive - | Flag::airborne | Flag::aquatic - | Flag::golem | Flag::nightfall - | Flag::nocturnal - | Flag::pillar | Flag::poisonous - | Flag::ranged | Flag::stackable - | Flag::token | Flag::tunnel - | Flag::voodoo | Flag::whetstone); + thing.flag.0 &= !(Flag::additive + | Flag::airborne + | Flag::aquatic + | Flag::golem + | Flag::nightfall + | Flag::nocturnal + | Flag::pillar + | Flag::poisonous + | Flag::ranged + | Flag::stackable + | Flag::token + | Flag::tunnel + | Flag::voodoo + | Flag::whetstone); thing.flag.0 |= card.flag(); for &(k, v) in card.status() { thing.status.insert(k, v); @@ -2180,7 +2192,7 @@ impl Game { pub fn trigger_data(&mut self, k: Event, c: i16, t: i16, data: &mut ProcData) { if let Some(ss) = self.get_thing(c).skill.get(k) { - for &s in ss.clone().iter() { + for s in ss.clone().into_iter() { s.proc(self, c, t, data); } } @@ -2305,6 +2317,11 @@ impl Game { } } + pub fn shatter(&mut self, id: i16) { + self.fx(id, Fx::Shatter); + self.die(id); + } + pub fn die(&mut self, id: i16) { let idx = self.remove(id); if idx == -1 { @@ -2448,11 +2465,12 @@ impl Game { pub fn clearStatus(&mut self, id: i16) { let thing = self.get_thing_mut(id); - thing.flag.0 &= - !(Flag::additive - | Flag::cloak | Flag::nightfall - | Flag::stackable - | Flag::tunnel | Flag::whetstone); + thing.flag.0 &= !(Flag::additive + | Flag::cloak + | Flag::nightfall + | Flag::stackable + | Flag::tunnel + | Flag::whetstone); for (st, ref mut val) in thing.status.iter_mut() { if matches!(st, Stat::charges | Stat::flooding) { *val = 0; diff --git a/src/rs/src/lib.rs b/src/rs/src/lib.rs index e53f0695..a2ebf5d7 100644 --- a/src/rs/src/lib.rs +++ b/src/rs/src/lib.rs @@ -199,7 +199,7 @@ mod test { ctx.set_quanta(p2, etg::Light, 2); attack_foe(&mut ctx, dev); attack_foe(&mut ctx, dev); - assert_eq!(ctx.get_player(p1).hand_last(), Some(dev)); + assert_eq!(ctx.get_player(p1).hand_last(), dev); assert_eq!(ctx.get(dev, Stat::atk), 4); assert_eq!(ctx.get(dev, Stat::hp), 2); assert_eq!(ctx.get(dev, Stat::maxhp), 2); @@ -208,7 +208,7 @@ mod test { Skill::ren.proc(&mut ctx, dev, dev, &mut ProcData::default()); Skill::pacify.proc(&mut ctx, dev, dev, &mut ProcData::default()); Skill::equalize.proc(&mut ctx, dev, dev, &mut ProcData::default()); - assert_eq!(ctx.get_player(p1).hand_last(), Some(dev)); + assert_eq!(ctx.get_player(p1).hand_last(), dev); assert_eq!(ctx.get(dev, Stat::atk), 0); assert_eq!(ctx.get(dev, Stat::hp), 0); assert_eq!(ctx.get(dev, Stat::maxhp), 0); @@ -286,7 +286,7 @@ mod test { ctx.setWeapon(p2, dagger); ctx.r#move(GameMove::End(0)); assert_eq!(ctx.get_weapon(p2), 0); - assert_eq!(ctx.get_player(p2).hand_last(), Some(dagger)); + assert_eq!(ctx.get_player(p2).hand_last(), dagger); } #[test] @@ -466,7 +466,7 @@ mod test { let tgting = Skill::regrade.targeting(CardSet::Open).unwrap(); let (mut ctx, p1, p2) = setup(CardSet::Open); assert!(!tgting.check(&ctx, p1, p2)); - let pillar = ctx.get_player(p1).hand_last().unwrap(); + let pillar = ctx.get_player(p1).hand_last(); assert!(!tgting.check(&ctx, pillar, pillar)); assert!(tgting.check(&ctx, p1, pillar)); ctx.play(pillar, 0, true); @@ -597,14 +597,14 @@ mod test { ctx.set(whim, Stat::casts, 1); ctx.useactive(whim, tstorm); assert_eq!(ctx.get_player(p1).deck.first(), Some(&tstorm)); - assert_eq!(ctx.get_player(p1).hand_last(), Some(dfly)); + assert_eq!(ctx.get_player(p1).hand_last(), dfly); } #[test] fn yoink_targeting() { let tgting = Skill::yoink.targeting(CardSet::Open).unwrap(); let (ctx, p1, p2) = setup(CardSet::Open); - assert!(tgting.check(&ctx, p1, ctx.get_player(p2).hand_last().unwrap())); - assert!(!tgting.check(&ctx, p1, ctx.get_player(p1).hand_last().unwrap())); + assert!(tgting.check(&ctx, p1, ctx.get_player(p2).hand_last())); + assert!(!tgting.check(&ctx, p1, ctx.get_player(p1).hand_last())); } } diff --git a/src/rs/src/skill.rs b/src/rs/src/skill.rs index 8a8dd7b1..32c0361b 100644 --- a/src/rs/src/skill.rs +++ b/src/rs/src/skill.rs @@ -203,6 +203,10 @@ impl Skills { } } + pub fn into_iter(self) -> impl Iterator)> { + self.0.into_iter() + } + pub fn iter(&self) -> impl Iterator { self.0.iter().map(|&(k, ref v)| (k, v.as_ref())) } @@ -251,6 +255,7 @@ pub enum Skill { alphawolf, antimatter, appease, + attack, autoburrow, autoburrowoff, autoburrowproc, @@ -267,7 +272,9 @@ pub enum Skill { blockhp, bloodmoon, bolsterintodeck, + bonesharpen, boneyard, + boreset, bounce, bow, bravery, @@ -275,6 +282,8 @@ pub enum Skill { brew, brokenmirror, bubbleclear, + buffdr, + bugpoison, burrow, butterfly, catapult, @@ -285,6 +294,7 @@ pub enum Skill { chromastat, clear, cold, + coldsnap, corpseexplosion, counter, countimmbur, @@ -293,6 +303,8 @@ pub enum Skill { cseed, cseed2, dagger, + databloat, + datashrink, deadalive, deathwish, deckblast, @@ -353,6 +365,7 @@ pub enum Skill { firebrand, firestorm(i16), firewall, + fish, flood, flooddeath, flyingweapon, @@ -364,6 +377,7 @@ pub enum Skill { frail, frail2, freedom, + freedomoff, freeevade, freeze(u8), freezeperm, @@ -375,6 +389,7 @@ pub enum Skill { golemhit, gpull, gpullspell, + grab2h, grave, growth(i8, i8), guard, @@ -383,22 +398,29 @@ pub enum Skill { hammer, hasten, hatch, + haunt, + haunted(i16), heal, + healblocked, heatmirror, + heatstroke, + hero, hitownertwice, holylight, hope, hush, icebolt, - icegrowth(i8, i8), + icecharge, + icegrowth, ignite, ignitediscard, + imbue, immolate(i16), improve, inertia, inflation, ink, - innovation, + innovate(u8), integrity, jelly, jetstream, @@ -413,6 +435,7 @@ pub enum Skill { luciferin, lycanthropy, martyr, + maul, mend, metamorph, midas, @@ -420,6 +443,7 @@ pub enum Skill { millpillar, mimic, miracle, + miragemill, mist, mitosis, mitosisspell, @@ -434,7 +458,9 @@ pub enum Skill { noeatspell, nothrottle, nova, + nova0, nova2, + novaval, nullspell, nymph, obsession, @@ -492,6 +518,7 @@ pub enum Skill { reveal, rewind, ricochet, + rngfreeze, sabbath, sadism, salvage, @@ -502,6 +529,7 @@ pub enum Skill { scramblespam, serendipity, shardgolem, + shazam, shtriga, shuffle3, silence, @@ -512,11 +540,13 @@ pub enum Skill { siphonactive, siphonstrength, skeleton, + skeletoncount, skull, skyblitz, slime, slow, snipe, + snowflake, solar, sosa, soulcatch, @@ -652,7 +682,7 @@ impl Tgt { deftgt!(butterfly, _butterfly, 15); deftgt!(devour, _devour, 16); deftgt!(paradox, _paradox, 17); - deftgt!(notskele, _notskele, 18); + deftgt!(skele, _skele, 18); deftgt!(forceplay, _forceplay, 19); deftgt!(airbornecrea, _airbornecrea, 20); deftgt!(golem, _golem, 21); @@ -663,6 +693,7 @@ impl Tgt { deftgt!(poisoned, _poisoned, 26); deftgt!(permcharge, _permcharge, 27); deftgt!(target, _target, 28); + deftgt!(equipcard, _equipcard, 29); pub fn full_check(self, ctx: &Game, c: i16, t: i16) -> bool { let kind = ctx.get_kind(t); @@ -697,9 +728,7 @@ impl Tgt { Tgt::_own => ctx.get_owner(c) == ctx.get_owner(t), Tgt::_notself => c != t, Tgt::_card => c != t && ctx.get_kind(t) == Kind::Spell, - Tgt::_pill => { - ctx.material(t, Some(Kind::Permanent)) && ctx.get(t, Flag::pillar) - } + Tgt::_pill => ctx.get(t, Flag::pillar), Tgt::_weap => { let tkind = ctx.get_kind(t); ctx.material(t, None) @@ -750,10 +779,7 @@ impl Tgt { Tgt::_paradox => { ctx.material(t, Some(Kind::Creature)) && ctx.truehp(t) < ctx.trueatk(t) } - Tgt::_notskele => { - ctx.material(t, Some(Kind::Creature)) - && !card::IsOf(ctx.get(t, Stat::card), card::Skeleton) - } + Tgt::_skele => card::IsOf(ctx.get(t, Stat::card), card::Skeleton), Tgt::_forceplay => { ctx.get_kind(t) == Kind::Spell || (ctx.material(t, None) @@ -801,6 +827,10 @@ impl Tgt { .and_then(|&sk| sk.targeting(ctx.cardset())) .is_some() } + Tgt::_equipcard => { + let card = ctx.get(t, Stat::card); + card != 0 && matches!(ctx.get_card(card).kind, Kind::Shield | Kind::Weapon) + } _ => unsafe { core::hint::unreachable_unchecked() }, }) as u32; } else { @@ -913,6 +943,7 @@ impl<'a> Display for SkillName<'a> { Skill::alphawolf => Ok(()), Skill::antimatter => f.write_str("antimatter"), Skill::appease => f.write_str("appease"), + Skill::attack => f.write_str("attack"), Skill::autoburrow => f.write_str("autoburrow"), Skill::autoburrowoff => Ok(()), Skill::autoburrowproc => Ok(()), @@ -929,7 +960,9 @@ impl<'a> Display for SkillName<'a> { Skill::blockwithcharge => f.write_str("blockwithcharge"), Skill::bloodmoon => Ok(()), Skill::bolsterintodeck => f.write_str("bolsterintodeck"), + Skill::bonesharpen => f.write_str("bonesharpen"), Skill::boneyard => f.write_str("boneyard"), + Skill::boreset => Ok(()), Skill::bounce => f.write_str("bounce"), Skill::bow => f.write_str("bow"), Skill::bravery => Ok(()), @@ -937,6 +970,8 @@ impl<'a> Display for SkillName<'a> { Skill::brew => f.write_str("brew"), Skill::brokenmirror => Ok(()), Skill::bubbleclear => f.write_str("bubbleclear"), + Skill::buffdr => Ok(()), + Skill::bugpoison => Ok(()), Skill::burrow => f.write_str(if ctx.get(id, Flag::burrowed) { "unburrow" } else { "burrow" }), Skill::butterfly => f.write_str("butterfly"), Skill::catapult => f.write_str("catapult"), @@ -947,6 +982,7 @@ impl<'a> Display for SkillName<'a> { Skill::chromastat => f.write_str("chromastat"), Skill::clear => f.write_str("clear"), Skill::cold => f.write_str("cold"), + Skill::coldsnap => f.write_str("snowclone"), Skill::corpseexplosion => Ok(()), Skill::counter => f.write_str("counter"), Skill::countimmbur => f.write_str("countimmbur"), @@ -955,6 +991,8 @@ impl<'a> Display for SkillName<'a> { Skill::cseed => f.write_str("cseed"), Skill::cseed2 => Ok(()), Skill::dagger => f.write_str("dagger"), + Skill::databloat => f.write_str("databloat"), + Skill::datashrink => f.write_str("datashrink"), Skill::deadalive => f.write_str("deadalive"), Skill::deathwish => f.write_str("deathwish"), Skill::deckblast => Ok(()), @@ -1015,6 +1053,7 @@ impl<'a> Display for SkillName<'a> { Skill::firebrand => f.write_str("firebrand"), Skill::firestorm(_) => Ok(()), Skill::firewall => f.write_str("firewall"), + Skill::fish => f.write_str("fish"), Skill::flood => f.write_str("flood"), Skill::flooddeath => Ok(()), Skill::flyingweapon => f.write_str("flyingweapon"), @@ -1026,6 +1065,7 @@ impl<'a> Display for SkillName<'a> { Skill::frail => Ok(()), Skill::frail2 => Ok(()), Skill::freedom => f.write_str("freedom"), + Skill::freedomoff => Ok(()), Skill::freeevade => Ok(()), Skill::freeze(x) => write!(f, "freeze{x}"), Skill::freezeperm => f.write_str("freezeperm"), @@ -1037,30 +1077,38 @@ impl<'a> Display for SkillName<'a> { Skill::golemhit => f.write_str("golemhit"), Skill::gpull => f.write_str("gpull"), Skill::gpullspell => Ok(()), + Skill::grab2h => f.write_str("grab2h"), Skill::grave => f.write_str("grave"), Skill::growth(atk, hp) => write!(f, "growth{atk:+}{hp:+}"), Skill::guard => f.write_str("guard"), Skill::halveatk => Ok(()), Skill::halvedr => Ok(()), + Skill::haunt => f.write_str("haunt"), + Skill::haunted(..) => f.write_str("haunted"), Skill::hammer => f.write_str("hammer"), Skill::hasten => f.write_str("hasten"), Skill::hatch => f.write_str("hatch"), Skill::heal => f.write_str("heal"), + Skill::healblocked => Ok(()), Skill::heatmirror => Ok(()), + Skill::heatstroke => f.write_str("heatstroke"), + Skill::hero => f.write_str("hero"), Skill::hitownertwice => f.write_str("hitownertwice"), Skill::holylight => f.write_str("holylight"), Skill::hope => f.write_str("hope"), Skill::hush => f.write_str("hush"), Skill::icebolt => f.write_str("icebolt"), - Skill::icegrowth(atk, hp) => write!(f, "icegrowth{atk:+}{hp:+}"), + Skill::icecharge => Ok(()), + Skill::icegrowth => Ok(()), Skill::ignite => f.write_str("ignite"), Skill::ignitediscard => Ok(()), + Skill::imbue => Ok(()), Skill::immolate(x) => write!(f, "immolate{x}"), Skill::improve => f.write_str("improve"), Skill::inertia => f.write_str("inertia"), Skill::inflation => f.write_str("inflation"), Skill::ink => f.write_str("ink"), - Skill::innovation => f.write_str("innovation"), + Skill::innovate(x) => write!(f, "innovate{x}"), Skill::integrity => f.write_str("integrity"), Skill::jelly => f.write_str("jelly"), Skill::jetstream => f.write_str("jetstream"), @@ -1075,6 +1123,7 @@ impl<'a> Display for SkillName<'a> { Skill::luciferin => f.write_str("luciferin"), Skill::lycanthropy => f.write_str("lycanthropy"), Skill::martyr => f.write_str("martyr"), + Skill::maul => Ok(()), Skill::mend => f.write_str("mend"), Skill::metamorph => f.write_str("metamorph"), Skill::midas => f.write_str("midas"), @@ -1082,6 +1131,7 @@ impl<'a> Display for SkillName<'a> { Skill::millpillar => f.write_str("millpillar"), Skill::mimic => f.write_str("mimic"), Skill::miracle => Ok(()), + Skill::miragemill => Ok(()), Skill::mist => f.write_str("mist"), Skill::mitosis => f.write_str("mitosis"), Skill::mitosisspell => Ok(()), @@ -1096,7 +1146,9 @@ impl<'a> Display for SkillName<'a> { Skill::noeatspell => Ok(()), Skill::nothrottle => Ok(()), Skill::nova => Ok(()), + Skill::nova0 => Ok(()), Skill::nova2 => Ok(()), + Skill::novaval => Ok(()), Skill::nullspell => f.write_str("nullspell"), Skill::nymph => f.write_str("nymph"), Skill::obsession => Ok(()), @@ -1169,6 +1221,7 @@ impl<'a> Display for SkillName<'a> { Skill::reveal => f.write_str("reveal"), Skill::rewind => f.write_str("rewind"), Skill::ricochet => Ok(()), + Skill::rngfreeze => Ok(()), Skill::sabbath => Ok(()), Skill::sadism => f.write_str("sadism"), Skill::salvage => f.write_str("salvage"), @@ -1179,6 +1232,7 @@ impl<'a> Display for SkillName<'a> { Skill::scramblespam => f.write_str("scramblespam"), Skill::serendipity => f.write_str("serendipity"), Skill::shardgolem => f.write_str("shardgolem"), + Skill::shazam => f.write_str("shazam"), Skill::shtriga => f.write_str("shtriga"), Skill::shuffle3 => f.write_str("shuffle3"), Skill::silence => Ok(()), @@ -1189,11 +1243,13 @@ impl<'a> Display for SkillName<'a> { Skill::siphonactive => f.write_str("siphonactive"), Skill::siphonstrength => f.write_str("siphonstrength"), Skill::skeleton => Ok(()), + Skill::skeletoncount => Ok(()), Skill::skull => f.write_str("skull"), Skill::skyblitz => f.write_str("skyblitz"), Skill::slime => f.write_str("slime"), Skill::slow => f.write_str("slow"), Skill::snipe => f.write_str("snipe"), + Skill::snowflake => Ok(()), Skill::solar => f.write_str("solar"), Skill::sosa => f.write_str("sosa"), Skill::soulcatch => f.write_str("soulcatch"), @@ -1298,21 +1354,27 @@ impl Skill { Self::abomination | Self::becomearctic | Self::beguilestop - | Self::bounce | Self::catlife + | Self::bounce + | Self::catlife | Self::cell | Self::chromastat - | Self::counter | Self::decrsteam + | Self::counter + | Self::decrsteam | Self::deepdiveproc | Self::deepdiveproc2 | Self::dshieldoff | Self::elf | Self::firebrand - | Self::martyr | Self::mummy + | Self::martyr + | Self::mummy | Self::obsession | Self::predatoroff | Self::protectonce | Self::protectoncedmg - | Self::salvage | Self::siphon - | Self::skeleton | Self::swarm - | Self::virtue | Self::v_obsession + | Self::salvage + | Self::siphon + | Self::skeleton + | Self::swarm + | Self::virtue + | Self::v_obsession | Self::v_singularity | Self::v_swarm ) @@ -1357,6 +1419,7 @@ impl Skill { } } Self::bolsterintodeck => Tgt::crea, + Self::bonesharpen => tgt!(and own crea), Self::bubbleclear => tgt!(or crea perm), Self::butterfly => Tgt::butterfly, Self::catapult => tgt!(and crea own), @@ -1369,8 +1432,9 @@ impl Skill { Tgt::crea } } - Self::cseed => Tgt::crea, + Self::cseed | Self::v_cseed => Tgt::crea, Self::cseed2 => Tgt::notself, + Self::datashrink => tgt!(and card not pill), Self::destroy => Tgt::perm, Self::destroycard => tgt!(or card play), Self::detain => Tgt::devour, @@ -1385,7 +1449,7 @@ impl Skill { if set == CardSet::Open { Tgt::permstack } else { - Tgt::pill + tgt!(and perm pill) } } Self::embezzle => Tgt::crea, @@ -1397,6 +1461,7 @@ impl Skill { Self::fickle => Tgt::card, Self::firebolt => tgt!(or crea play), Self::firestorm(_) => Tgt::play, + Self::fish => Tgt::play, Self::flyingweapon => Tgt::playerweap, Self::forceplay => Tgt::forceplay, Self::fractal => Tgt::crea, @@ -1420,12 +1485,14 @@ impl Skill { } } Self::guard => Tgt::crea, + Self::haunt => Tgt::crea, Self::heal => tgt!(or crea play), Self::holylight => tgt!(or crea play), Self::icebolt => tgt!(or crea play), + Self::imbue => tgt!(and own and card equipcard), Self::immolate(_) => tgt!(and crea own), Self::improve => Tgt::crea, - Self::innovation => Tgt::card, + Self::innovate(_) => Tgt::card, Self::jelly => Tgt::crea, Self::jetstream => Tgt::crea, Self::lightning => tgt!(or crea play), @@ -1456,7 +1523,7 @@ impl Skill { Self::neuroify => tgt!(or crea play), Self::nightmare => Tgt::crea, Self::nightshade => Tgt::crea, - Self::nymph => Tgt::pill, + Self::nymph | Self::v_nymph => tgt!(and perm pill), Self::pacify => tgt!(or crea weap), Self::pandemonium2 => Tgt::play, Self::paradox => Tgt::paradox, @@ -1476,7 +1543,7 @@ impl Skill { Self::quinttog => Tgt::quinttog, Self::rage => Tgt::crea, Self::readiness | Self::v_readiness => Tgt::crea, - Self::reap => Tgt::notskele, + Self::reap => tgt!(and crea not skele), Self::regeneratespell => tgt!(or crea and perm nonstack), Self::regrade => tgt!(and not or play permstack notself), Self::reinforce => Tgt::crea, @@ -1487,6 +1554,7 @@ impl Skill { Self::scatter => tgt!(or card play), Self::scramble => Tgt::play, Self::scramblespam => Tgt::play, + Self::shazam => tgt!(or card and own crea), Self::shuffle3 => Tgt::crea, Self::silence => tgt!(or crea play), Self::silence => tgt!(or crea perm), @@ -1495,6 +1563,7 @@ impl Skill { Self::siphonactive => tgt!(and or crea weap notself), Self::siphonstrength => tgt!(and crea notself), Self::snipe => Tgt::crea, + Self::coldsnap => Tgt::card, Self::stasisdraw => Tgt::play, Self::steal | Self::v_steal => tgt!(and perm not own), Self::storm(_) => Tgt::play, @@ -1524,7 +1593,6 @@ impl Skill { } Self::yoink => tgt!(and or card play not own), Self::v_bblood => Tgt::crea, - Self::v_cseed => Tgt::crea, Self::v_drainlife(_) => tgt!(or crea play), Self::v_endow => Tgt::weap, Self::v_firebolt(_) => tgt!(or crea play), @@ -1532,7 +1600,6 @@ impl Skill { Self::v_icebolt(_) => tgt!(or crea play), Self::v_improve => Tgt::crea, Self::v_mutation => Tgt::crea, - Self::v_nymph => Tgt::pill, _ => return None, }) } @@ -1557,14 +1624,14 @@ impl Skill { | Skill::v_drainlife(x) | Skill::v_firebolt(x) | Skill::v_icebolt(x) => x as i32, - Skill::growth(x, _) | Skill::icegrowth(x, _) => x as i32, + Skill::growth(x, _) => x as i32, _ => 0, } } pub const fn param2(self) -> i32 { match self { - Skill::growth(_, x) | Skill::icegrowth(_, x) => x as i32, + Skill::growth(_, x) => x as i32, _ => 0, } } @@ -1660,6 +1727,11 @@ impl Skill { ctx.fx(c, Fx::Appeased); Skill::devour.proc(ctx, c, t, data); } + Self::attack => { + ctx.queue_attack(c, 0); + let nova = ctx.get_mut(c, Stat::nova); + *nova = nova.saturating_sub(1); + } Self::equalize => { if ctx.get_kind(t) == Kind::Creature { let ttrueatk = ctx.trueatk(t); @@ -1736,8 +1808,7 @@ impl Skill { ctx.buffhp(t, 3); } Self::blockhp => { - let owner = ctx.get_owner(c); - let maxhp = ctx.get_mut(owner, Stat::maxhp); + let maxhp = ctx.get_mut(ctx.get_owner(c), Stat::maxhp); *maxhp = (*maxhp + data.blocked).min(500); } Self::blockwithcharge => { @@ -1771,6 +1842,13 @@ impl Skill { &[ctx.new_thing(card, owner), ctx.new_thing(card, owner), ctx.new_thing(card, owner)]; ctx.get_player_mut(owner).deck_mut().extend(cards); } + Skill::bonesharpen => { + ctx.setSkill(t, Event::Cast, &[Skill::reinforce]); + ctx.set(t, Stat::cast, 0); + if card::IsOf(ctx.get(t, Stat::card), card::Skeleton) { + ctx.set(c, Stat::casts, 1); + } + } Self::boneyard => { let skele = if ctx.cardset() == CardSet::Open { card::Skeleton } else { card::v_Skeleton }; if !card::IsOf(ctx.get(t, Stat::card), skele) { @@ -1779,6 +1857,20 @@ impl Skill { ctx.addCrea(owner, skele); } } + Self::boreset => { + let shield = ctx.get_shield(ctx.get_owner(c)); + if shield != 0 { + if let Some(stored) = ctx.get_thing_mut(c).status.get_mut(Stat::swarmhp) { + let limit = core::mem::replace(stored, 0); + let sswarm = ctx.get(shield, Stat::swarmhp); + if limit >= sswarm { + ctx.set(shield, Stat::swarmhp, 0); + } else { + ctx.set(shield, Stat::swarmhp, sswarm - limit); + } + } + } + } Self::bounce => { ctx.set(c, Stat::hp, ctx.get(c, Stat::maxhp)); ctx.rmskill(c, Event::Predeath, Skill::bounce); @@ -1845,6 +1937,12 @@ impl Skill { ctx.addskills(t, Event::Prespell, &[Skill::protectonce]); ctx.addskills(t, Event::Spelldmg, &[Skill::protectoncedmg]); } + Skill::bugpoison => { + let owner = ctx.get_owner(c); + if c != t && ctx.get(t, Flag::bug) && owner == ctx.get_owner(t) { + ctx.poison(ctx.get_foe(owner), 1) + } + } Self::burrow => { if ctx.get(c, Flag::burrowed) { ctx.set(c, Flag::burrowed, false); @@ -1969,6 +2067,20 @@ impl Skill { ctx.freeze(t, 3); } } + Self::coldsnap => { + let charges = ctx.get_mut(c, Stat::charges); + let count = (core::mem::replace(charges, 0) + 1) as u32; + let owner = ctx.get_owner(t); + if !ctx.sanctified(owner) { + ctx.remove(t); + let decklen = ctx.get_player(owner).deck.len() as u32; + for n in 1..=count { + let idx = ctx.upto(decklen + n) as usize; + let inst = if n == count { t } else { ctx.cloneinst(t) }; + ctx.get_player_mut(owner).deck_mut().insert(idx, inst); + } + } + } Self::corpseexplosion => { let dmg = 1 + ctx.truehp(t) / 5; ctx.die(t); @@ -2043,6 +2155,24 @@ impl Skill { ); } } + Self::databloat => { + if ctx.get_kind(t) == Kind::Player && !ctx.sanctified(t) { + for id in ctx.get_player(t).hand_iter() { + if !ctx.get(id, Flag::pillar) { + ctx.incrStatus(id, Stat::cost, 1) + } + } + } + } + Self::datashrink => { + let thing = ctx.get_thing_mut(t); + if let Some(cost) = thing.status.get_mut(Stat::cost) { + *cost -= 2; + if *cost < 0 { + *cost = 0; + } + } + } Self::deadalive => { let index = ctx.getIndex(c); ctx.fx(c, Fx::Death); @@ -2448,8 +2578,6 @@ impl Skill { ctx.fx(t, Fx::Endow); ctx.incrAtk(c, ctx.trueatk(t) - ctx.trigger_pure(Event::Buff, t, 0)); ctx.buffhp(c, 2); - ctx.set(c, Stat::cast, ctx.get(t, Stat::cast)); - ctx.set(c, Stat::castele, ctx.get(t, Stat::castele)); let tgt = ctx.get_thing(t); let tstatus = tgt.status.clone(); { @@ -2472,7 +2600,7 @@ impl Skill { | Stat::cast | Stat::costele | Stat::cost => (), - Stat::adrenaline => ctx.set(c, k, v), + Stat::adrenaline | Stat::cast | Stat::castele | Stat::swarmhp => ctx.set(c, k, v), _ => ctx.incrStatus(c, k, v), } } @@ -2588,6 +2716,41 @@ impl Skill { ctx.spelldmg(t, 1); } } + Self::fish => { + let owner = ctx.get_owner(c); + if !ctx.get_player(owner).hand_full() { + if !ctx.get(t, Flag::protectdeck) { + let deck = ctx.get_player(t).deck.as_ref(); + let mut foundidx = usize::MAX; + for (idx, card) in deck.iter().cloned().enumerate() { + if ctx.get(card, Flag::aquatic) { + foundidx = idx; + break; + } + } + if foundidx != usize::MAX { + let lastidx = deck.len() - 1; + ctx.get_player_mut(t).deck_mut().swap(foundidx, lastidx); + let id = ctx.draw(t); + if id != 0 && ctx.addCard(owner, id) != -1 { + ctx.fx(id, Fx::StartPos(-t)); + ctx.proc(Event::Draw, owner); + return; + } + } + } + let upped = card::Upped(ctx.get(c, Stat::card)); + if let Some(card) = ctx.choose_iter( + ctx.get_cards() + .filter(upped) + .iter() + .filter(|card| (card.flag() & Flag::token) != 0), + ) { + let id = ctx.new_thing(card.code, owner); + ctx.addCard(owner, id); + } + } + } Self::flood => { data.flags |= ProcData::flood; } @@ -2722,6 +2885,9 @@ impl Skill { data.flags |= ProcData::freedom; } } + Self::freedomoff => { + ctx.rmskill(c, Event::Attack, Skill::freedom); + } Self::freeevade => { if !data.get(ProcData::evade) { let tgt = data.tgt; @@ -2796,6 +2962,12 @@ impl Skill { ctx.set(t, Stat::gpull, 0); } } + Self::grab2h => { + let shield = ctx.get_shield(ctx.get_owner(c)); + if shield != 0 { + Skill::destroy.proc(ctx, c, shield, data); + } + } Self::grave => { ctx.set(c, Flag::burrowed, false); ctx.transform(c, ctx.get(t, Stat::card)); @@ -2841,9 +3013,34 @@ impl Skill { ctx.set(c, Stat::casts, 1); } } + Self::haunt => { + let own = ctx.get_owner(c); + let thing = ctx.get_thing_mut(t); + if let Some(smap) = thing.skill.get_mut(Event::OwnDeath) { + smap.extend(&[Skill::haunted(own)]); + } else { + thing.skill.insert(Event::OwnDeath, Cow::from(Vec::from(&[Skill::haunted(own)]))); + } + } + Self::haunted(own) => { + ctx.rmskill(c, Event::OwnDeath, Skill::haunted(own)); + let atk = ctx.get(t, Stat::atk); + let hp = ctx.get(t, Stat::maxhp); + let card = ctx.get(t, Stat::card); + let skele = ctx.new_thing(card::As(card, card::Skeleton), own); + ctx.set(skele, Stat::atk, atk); + ctx.set(skele, Stat::maxhp, hp); + ctx.set(skele, Stat::hp, hp); + ctx.addCrea(own, skele); + } Self::heal => { ctx.dmg(t, -20); } + Self::healblocked => { + if data.blocked > 0 { + ctx.dmg(ctx.get_owner(c), -data.blocked); + } + } Self::heatmirror => { let owner = ctx.get_owner(c); if data.get(ProcData::fromhand) @@ -2855,6 +3052,22 @@ impl Skill { ctx.addCrea(owner, spark); } } + Self::heatstroke => { + let foe = ctx.get_foe(ctx.get_owner(c)); + let mirage = ctx.new_thing(card::As(ctx.get(c, Stat::card), card::Mirage), foe); + ctx.addCrea(foe, mirage); + } + Self::hero => { + ctx.delay(c, 1); + let shield = ctx.get_player(ctx.get_owner(c)).shield; + if shield != 0 { + if !ctx.hasskill(shield, Event::Hp, Skill::v_swarmhp) { + ctx.addskills(shield, Event::Hp, &[Skill::v_swarmhp]); + } + ctx.incrStatus(shield, Stat::swarmhp, 1); + ctx.incrStatus(c, Stat::swarmhp, 1); + } + } Self::hitownertwice => { if !ctx.hasskill(c, Event::Turnstart, Skill::predatoroff) { ctx.addskills(c, Event::Turnstart, &[Skill::predatoroff]); @@ -2891,9 +3104,14 @@ impl Skill { } ctx.spelldmg(t, 2 + bonus); } - Self::icegrowth(atk, hp) => { + Self::icecharge => { + ctx.incrStatus(c, Stat::charges, data.amt); + data.amt = 0; + } + Self::icegrowth => { + let amt = data.amt as i8; data.amt = 0; - Skill::growth(atk, hp).proc(ctx, c, t, data); + Skill::growth(amt, 0).proc(ctx, c, t, data); } Self::ignite => { ctx.die(c); @@ -2909,6 +3127,55 @@ impl Skill { let foe = ctx.get_foe(owner); ctx.spelldmg(foe, 5); } + Self::imbue => { + let isweap = ctx.get_card(ctx.get(t, Stat::card)).kind == Kind::Weapon; + let pl = ctx.get_player(ctx.get_owner(t)); + let equip = if isweap { pl.weapon } else { pl.shield }; + ctx.die(t); + if equip == 0 { + return; + } + ctx.unsummon(equip); + ctx.fx(t, Fx::Endow); + let tgt = ctx.get_thing(t); + let tstatus = tgt.status.clone(); + let mut setcast = false; + { + let newskill = tgt.skill.clone(); + let tflag = tgt.flag.0; + let mut sader = ctx.get_thing_mut(equip); + for (nk, nv) in newskill.into_iter() { + match sader.skill.entry(nk) { + SkillsEntry::Occupied(sk) => { + if nk == Event::Cast { + continue; + } + sk.into_mut().extend(nv.as_ref()); + } + SkillsEntry::Vacant(sk) => { + if nk == Event::Cast { + setcast = true; + } + sk.insert(nv); + } + } + } + sader.flag.0 |= tflag; + sader.flag.0 &= !Flag::additive; + } + for &(k, v) in tstatus.iter() { + match k { + Stat::hp | Stat::maxhp | Stat::atk | Stat::card | Stat::costele => (), + Stat::castele | Stat::cast => { + if setcast { + ctx.set(equip, k, v) + } + } + Stat::adrenaline => ctx.set(equip, k, v), + _ => ctx.incrStatus(equip, k, v), + } + } + } Self::immolate(x) => { ctx.die(t); if !ctx.hasskill(t, Event::OwnAttack, Skill::singularity) @@ -2958,6 +3225,7 @@ impl Skill { ctx.set(id, Stat::castele, etg::Chroma); } } + ctx.set(c, Stat::casts, 1); } Self::ink => { let owner = ctx.get_owner(c); @@ -2965,11 +3233,11 @@ impl Skill { ctx.set(p, Stat::charges, 1); ctx.addPerm(owner, p); } - Self::innovation => { + Self::innovate(x) => { let town = ctx.get_owner(t); if !ctx.sanctified(town) { ctx.die(t); - for _ in 0..3 { + for _ in 0..x { ctx.drawcard(town); } } @@ -3331,7 +3599,8 @@ impl Skill { let thing = ctx.get_thing(cr); if thing.skill.iter().all(|(k, v)| { k == Event::OwnPlay - || k == Event::OwnDiscard || v.iter().all(|&sk| sk.passive()) + || k == Event::OwnDiscard + || v.iter().all(|&sk| sk.passive()) }) { ctx.addskills(cr, Event::OwnAttack, &[Skill::quanta(etg::Light as i8)]); } @@ -3354,6 +3623,15 @@ impl Skill { ctx.dmg(owner, data.amt); } } + Self::maul => { + if (data.flags & ProcData::attackphase) != 0 + && ctx.get_player(ctx.get_owner(c)).shield != 0 + && ctx.get_kind(c) == ctx.get_kind(t) + && ctx.getIndex(c) == ctx.getIndex(t) + { + data.flags |= ProcData::stasis; + } + } Self::mend => { ctx.dmg(t, if ctx.cardset() == CardSet::Open { -10 } else { -5 }); } @@ -3385,7 +3663,9 @@ impl Skill { } } Self::mill => { - ctx.mill(t, 1); + if throttle(ctx, data, c) && ctx.get_kind(t) == Kind::Player { + ctx.mill(t, 1); + } } Self::millpillar => { if let Some(&card) = ctx.get_player(t).deck.last() { @@ -3409,6 +3689,11 @@ impl Skill { ctx.set(owner, Stat::hp, 1); } } + Self::miragemill => { + if card::IsOf(ctx.get(t, Stat::card), card::Mirage) { + ctx.mill(ctx.get_owner(t), 1) + } + } Self::mist => { for _ in 0..ctx.get(c, Stat::charges) { if ctx.upto(20) == 0 { @@ -3534,6 +3819,9 @@ impl Skill { ctx.addCrea(owner, c); } } + Self::nova0 => { + ctx.set(c, Stat::nova, 0); + } Self::nova2 => { let owner = ctx.get_owner(c); for i in 1..13 { @@ -3811,7 +4099,8 @@ impl Skill { ctx.addskills(c, Event::Turnstart, &[Skill::predatoroff]); ctx.queue_attack(c, 0); if !ctx.sanctified(foe) { - if let Some(card) = ctx.get_player(foe).hand_last() { + let card = ctx.get_player(foe).hand_last(); + if card != 0 { ctx.die(card); } } @@ -3977,8 +4266,10 @@ impl Skill { ctx.fx(c, Fx::EndPos(t)); let hp = ctx.truehp(c); let atk = ctx.trueatk(c); + let psn = ctx.get(c, Stat::poison); ctx.buffhp(t, hp); ctx.incrAtk(t, atk); + ctx.poison(t, psn); ctx.remove(c); } Self::ren => { @@ -4042,6 +4333,20 @@ impl Skill { } } } + Self::rngfreeze => { + if ctx.get_kind(t) == Kind::Player { + let mut ids = Vec::with_capacity(18); + let pl = ctx.get_player(t); + for id in pl.permanents.into_iter().chain(once(pl.weapon)).chain(once(pl.shield)) { + if id != 0 && ctx.material(id, None) && !ctx.get(id, Flag::stackable) { + ids.push(id); + } + } + if let Some(id) = ctx.choose(&ids) { + ctx.freeze(*id, 2); + } + } + } Self::sabbath => { if !ctx.sanctified(t) { ctx.set(t, Flag::sabbath, true); @@ -4163,6 +4468,23 @@ impl Skill { } } } + Self::shazam => { + let code = ctx.get(t, Stat::card); + let uncode = card::AsUpped(code, false); + let element = ctx.get_card(code).element; + let newcard = if ctx.get_kind(t) == Kind::Spell { + ctx.random_card(false, |ctx, card| card.element == element && card.code != uncode) + } else { + ctx.random_card(false, |ctx, card| { + card.element == element + && card.rarity == 1 && card.kind == Kind::Creature + && card.code != uncode + }) + }; + if let Some(newcard) = newcard { + ctx.transform(t, card::As(code, newcard.code)); + } + } Self::shtriga => { if ctx.get_owner(c) == t { ctx.set(c, Flag::immaterial, true); @@ -4311,13 +4633,19 @@ impl Skill { ctx.delay(t, 2); } } + Self::snowflake => { + let charges = ctx.get(t, Stat::frozen); + if charges > 0 { + ctx.incrStatus(c, Stat::charges, charges); + } + } Self::snipe => { ctx.dmg(t, 3); } Self::solar => { let owner = ctx.get_owner(c); if ctx.cardset() == CardSet::Open || !ctx.get(owner, Flag::sanctuary) { - ctx.spend(owner, etg::Light, -1); + ctx.spend(owner, etg::Light, -data.blocked); } } Self::sosa => { @@ -4429,14 +4757,12 @@ impl Skill { } Self::swave => { if ctx.get(t, Stat::frozen) != 0 { - ctx.fx(t, Fx::Shatter); - ctx.die(t); + ctx.shatter(t); } else { if ctx.get_kind(t) == Kind::Player { let weapon = ctx.get_weapon(t); if weapon != 0 && ctx.get(weapon, Stat::frozen) != 0 { - ctx.fx(weapon, Fx::Shatter); - ctx.die(weapon); + ctx.shatter(weapon); } } ctx.spelldmg(t, 4); @@ -4535,6 +4861,11 @@ impl Skill { .chain(plpl.permanents.into_iter()) .filter(|&pr| pr != 0 && ctx.material(pr, None)), ); + for id in perms.iter().cloned() { + if ctx.get(id, Stat::frozen) > 0 { + ctx.shatter(id); + } + } if let Some(&pr) = ctx.choose(&perms) { ctx.fx(pr, Fx::Shuffled); let newowner = if ctx.next32() & 1 == 0 { pl } else { ctx.get_foe(pl) }; @@ -5343,6 +5674,7 @@ impl Skill { } Self::accumulation | Self::axe + | Self::buffdr | Self::bow | Self::countimmbur | Self::dagger @@ -5350,7 +5682,9 @@ impl Skill { | Self::fiery | Self::hammer | Self::hope + | Self::novaval | Self::poisondr + | Self::skeletoncount | Self::staff | Self::stonewall | Self::swarm @@ -5366,6 +5700,14 @@ impl Skill { let mark = ctx.get_player(ctx.get_owner(c)).mark as i16; (mark == etg::Fire || mark == etg::Time) as i16 } + Self::buffdr => { + let shield = ctx.get_player(ctx.get_owner(c)).shield as i16; + if shield == 0 { + 0 + } else { + ctx.truedr(shield, 0) + } + } Self::bow => { let mark = ctx.get_player(ctx.get_owner(c)).mark as i16; (mark == etg::Air || ctx.cardset() == CardSet::Open && mark == etg::Light) as i16 @@ -5419,6 +5761,7 @@ impl Skill { cr != 0 && ctx.hasskill(cr, Event::OwnAttack, Skill::quanta(etg::Light as i8)) }) .count() as i16, + Self::novaval => ctx.get(c, Stat::nova), Self::poisondr => { if t == 0 { 0 @@ -5432,6 +5775,19 @@ impl Skill { } } } + Self::skeletoncount => { + let upped = card::Upped(ctx.get(c, Stat::card)); + let mut dmg = 0; + for cr in ctx.get_player(ctx.get_owner(c)).creatures { + if cr != 0 { + let crcard = ctx.get(cr, Stat::card); + if card::IsOf(crcard, card::Skeleton) { + dmg += if upped { ctx.get(cr, Stat::atk) } else { 1 }; + } + } + } + dmg + } Self::staff => { let mark = ctx.get_player(ctx.get_owner(c)).mark as i16; (mark == etg::Life || mark == etg::Water) as i16 diff --git a/src/rs/src/text.rs b/src/rs/src/text.rs index 4d4b4cbd..4721e166 100644 --- a/src/rs/src/text.rs +++ b/src/rs/src/text.rs @@ -170,6 +170,7 @@ impl<'a> SkillThing<'a> { Cow::from("If target creature or weapon's attack is positive, it becomes negative. Otherwise, it becomes positive"), Skill::appease => Cow::from("Sacrifice target creature you own & gain 1|1. If this ability isn't used, this creature will attack its owner. This creature attacks normally the turn it's played or if it loses this ability"), + Skill::attack => Cow::from("Whenever a permanent is destroyed, decrease strength by 1 for rest of turn & attack"), Skill::autoburrow => Cow::from("Until end of turn, your creatures with burrow enter play burrowed"), Skill::axedraw => @@ -194,6 +195,7 @@ impl<'a> SkillThing<'a> { } Skill::bloodmoon => Cow::from("Aquatic creatures gain \"Gain 1:8 when it attacks.\"\nGolems gain \"Damage dealt by this card also reduces the defender's maxHP.\"\nNocturnal creatures gain \"Heal yourself equal to the damage dealt by this card.\""), Skill::bolsterintodeck => Cow::from("Add 3 copies of target creature on top of your deck"), + Skill::bonesharpen => Cow::from("Replace your own target creature's skills with \"0: Combine with target creature, giving strength, HP, & poison counters\"\nIf target is skeleton, reactivated"), Skill::boneyard => { Cow::from(format!("Whenever a creature which isn't a Skeleton dies, summon a {} Skeleton", if self.upped() { "2|2" } else { "1|1" })) } @@ -215,16 +217,18 @@ impl<'a> SkillThing<'a> { Cow::from(s) } Skill::bubbleclear => Cow::from("Remove all statuses from target creature or permanent. If target is a creature, heal it by 1HP.\nTarget gains Bubble, protecting it the next time it's targeted by opponent, or receives spell damage"), - Skill::butterfly => Cow::from(if self.set() == CardSet::Open { - "Target creature or weapon with strength or HP less than 3 has its skills replaced with \"3:1 Destroy target permanent.\"" - } else { - "Target creature with less attack than 3 has its skills replaced with \"3:1 Destroy target permanent\"" - }), + Skill::buffdr => Cow::from("Increase attack by shield's damage reduction"), + Skill::bugpoison => Cow::from("Poison opponent when another bug enters play"), Skill::burrow => Cow::from(if self.get_flag(Flag::burrowed) { "Unburrow" } else { "Burrow. Strength is halved while burrowed" }), + Skill::butterfly => Cow::from(if self.set() == CardSet::Open { + "Target creature or weapon with strength or HP less than 3 has its skills replaced with \"3:1 Destroy target permanent.\"" + } else { + "Target creature with less attack than 3 has its skills replaced with \"3:1 Destroy target permanent\"" + }), Skill::catapult => Cow::from("Sacrifice your own creature. Damage opponent based on target creature's HP†. Frozen creatures deal 50% more damage. Poisoned creatures transfer poisons to opponent.\n\n† (100 * HP) / (100 + HP), rounding up"), Skill::catlife => { let card = self.card(); @@ -240,6 +244,7 @@ impl<'a> SkillThing<'a> { Skill::clear => Cow::from("Remove statuses (positive & negative) from target creature or permanent, & heal target creature 1"), Skill::cold => Cow::from("\u{2153} chance to freeze non-ranged attackers for 3 turns"), + Skill::coldsnap => Cow::from("Shuffle target card into owner's deck. Expend charges to shuffle that many more copies"), Skill::corpseexplosion => Cow::from(if self.upped() { "Sacrifice one of your creatures to deal 1 spell damage to all enemy creatures. Increase damage by 1 for every 5HP of the sacrifice. Poisonous sacrifices poison. Poisoned sacrifices poison. Also affect opponent" } else { @@ -255,6 +260,8 @@ impl<'a> SkillThing<'a> { Cow::from("Inflict a random effect on target creature. Possible effects include damage, lobotomize, parallel universe, gravity pull, rewind, & freeze 6"), Skill::cseed2 => Cow::from("Inflict a random effect on target card. All existing effects are possible"), + Skill::databloat => Cow::from("On hit, increase target player's hand's non-pillar card's costs by one"), + Skill::datashrink => Cow::from("Decrease target non-pillar card's cost by two. Cannot reduce below 0"), Skill::deadalive if ev == Event::Hit => Cow::from("When this card deals damage, trigger all effects that occur when a creature dies"), Skill::deadalive if ev == Event::Cast => Cow::from("Trigger all effects that occur when a creature dies"), Skill::deathwish => Cow::from("Whenever opponent casts a spell or ability on an allied creature, if this creature is a valid target, that spell or ability targets this creature instead"), @@ -354,6 +361,7 @@ impl<'a> SkillThing<'a> { Skill::firebrand => Cow::from("Last an additional turn when targeted with Tempering"), Skill::firestorm(x) => Cow::from(format!("Deal {} spell damage to all of target player's creatures. Remove frozen status from damaged creatures. Removes cloak", x)), Skill::firewall => Cow::from("Deals 1 damage to each non-ranged attacking creature"), + Skill::fish => Cow::from("Draw aquatic card from target player's deck. Draw random token if not able to draw an aquatic card"), Skill::flooddeath => Cow::from("Each player's non-aquatic creatures past their first five creature slots die at the end of that player's turn"), Skill::flyself => @@ -385,6 +393,7 @@ impl<'a> SkillThing<'a> { Skill::gaintimecharge => Cow::from("Gain one stack for every card you draw. Does not gain a stack from your draw at the start of your turn"), Skill::gas => Cow::from("Summon an Unstable Gas"), + Skill::grab2h => Cow::from("Destroy your shield"), Skill::grave => Cow::from("When another creature dies, unburrow & transform this creature into a fresh copy of the dying creature. This creature retains nocturnal"), Skill::give => @@ -396,7 +405,7 @@ impl<'a> SkillThing<'a> { Skill::growth(atk, hp) if ev == Event::Death => Cow::from(format!("When any creature dies, gain {atk}|{hp}")), Skill::growth(atk, hp) if ev == Event::Cast => Cow::from(format!("Gain {atk}|{hp}")), Skill::growth(atk, hp) if ev == Event::OwnAttack => Cow::from(format!("This creature gains {}|{} when it attacks", atk, hp)), - Skill::icegrowth(atk, hp) => Cow::from(format!("When this card would be frozen, instead gain {atk}|{hp}")), + Skill::icegrowth => Cow::from(format!("When this card would be frozen, instead gain attack for how much it would be frozen")), Skill::guard => Cow::from("Delay target creature & this creature. If target creature isn't airborne or this creature is airborne, this creature deals damage equal to its strength to target creature"), Skill::halveatk => Cow::from("This creature's strength is halved after it attacks"), @@ -404,13 +413,19 @@ impl<'a> SkillThing<'a> { Skill::hasten if ev == Event::Cast => Cow::from("Draw a card"), Skill::hasten if ev == Event::OwnDiscard => Cow::from("When discarded, you draw a card"), Skill::hatch => - Cow::from("Transform this creature into a random creature. Caster can be reactivated"), + Cow::from("Transform this creature into a random creature. Caster reactivated"), + Skill::haunt => Cow::from("When target creature dies, summon a full health Skeleton with the same stats"), + Skill::haunted(own) => Cow::from(format!("When this dies, summon a full health Skeleton with the same stats for player {}", own)), Skill::heal => Cow::from("Target creature or player heals 20HP"), + Skill::healblocked => Cow::from("When this creature attacks, if any damage is blocked by opponent's shield, heal yourself for the amount this creature's damage was blocked"), Skill::heatmirror => Cow::from(if self.upped() { "When your opponent plays a creature from their hand, summon a Ball Lightning" } else { "When your opponent plays a creature from their hand, summon a Spark" }), + Skill::heatstroke if ev == Event::Hit => Cow::from("Opponent summons mirage on hit"), + Skill::heatstroke => Cow::from("Opponent summons mirage"), + Skill::hero => Cow::from("Increase your shield's damage reduction by 1, delaying this card. Increment stored counter. Remove bonus damage reduction by stored when this attacks, resetting stored value"), Skill::hitownertwice => Cow::from("When this creature attacks, it also attacks its owner twice"), Skill::holylight => Cow::from(if self.upped() { "Remove all statuses from target creature or permanent. Heal target creature or player 10. If target creature is nocturnal, instead deal 10 spell damage to target creature.\nGain 1:8 when played" @@ -424,15 +439,16 @@ impl<'a> SkillThing<'a> { Skill::ignite => Cow::from("Deal 20 spell damage to opponent. Deal 1 spell damage to each creature"), Skill::ignitediscard => Cow::from("When discarded, deal 5 spell damage to opponent"), + Skill::imbue => Cow::from("Discard target equipment card, combining its skills & statuses on corresponding equipped equipment. Return that equipment to hand. Imbued equipment cannot be `additive`"), Skill::immolate(x) => Cow::from(format!("Sacrifice creature you control. Gain {}:6 plus 1 quanta of each other element", x+1)), Skill::improve => Cow::from("Transform a target creature into a random mutant creature. Mutant creatures gain a random ability; & randomly gains between 1 to 5 strength & hp"), Skill::inertia => Cow::from("When any card you own is targeted by either player, gain 2:3"), - Skill::inflation => Cow::from("Increase the cost of all active skills by 1"), + Skill::inflation => Cow::from("Increase the cost of all active skills by 1, caster reactivated"), Skill::ink => Cow::from("Summon a Cloak that lasts 1 turn"), - Skill::innovation => - Cow::from("Discard target card in either player's hand. The owner of target card draws three cards. Destroy top card of your deck"), + Skill::innovate(x) => + Cow::from(format!("Discard target card in either player's hand. The owner of target card draws {} cards. Destroy top card of your deck", x)), Skill::integrity => Cow::from("Destroy all shards in your hand to play a Shard Golem with stats & skills based on the shards destroyed"), Skill::jelly => @@ -470,6 +486,7 @@ impl<'a> SkillThing<'a> { }), Skill::martyr => Cow::from("Gains 1|0 for every point of damage this card receives. Heals its owner when healed"), + Skill::maul => Cow::from("While shield equipped prevent attacking during attack phase, & block card in opposing slot"), Skill::mend => Cow::from(if self.set() == CardSet::Open { "Heal target creature 10HP" } else { @@ -479,11 +496,15 @@ impl<'a> SkillThing<'a> { Cow::from("Change your mark to target's element.\nIncrease your mark power by 1"), Skill::midas => Cow::from("Target permanent becomes a Golden Relic with \"2:0: Sacrifice this card & draw a card.\" If target is a weapon, its strength is 1. If target is a shield, its damage reduction is 1"), - Skill::mill => Cow::from("Destroy top card of target player's deck"), + Skill::mill => Cow::from(match ev { + Event::Hit => "Destroy top card of player's deck on hit. Throttled (only triggers twice from Adrenaline)", + _ => "Destroy top card of target player's deck", + }), Skill::millpillar => Cow::from("If top card of target player's deck is a pillar, pendulum, or tower, destroy that card"), Skill::mimic => - Cow::from("Whenever another creature enters play, transform this card into a fresh copy of that creature. This creature retains this ability"), + Cow::from("When another creature enters play, transform this card into a fresh copy of that creature. This creature retains this ability"), + Skill::miragemill => Cow::from("When a mirage dies, their owner destroys top card of their deck"), Skill::mist => Cow::from("Each stack has a 5% chance to evade attacks"), Skill::miracle => Cow::from("Heal yourself to one below your maxHP. Consumes all 1:8"), @@ -544,7 +565,7 @@ impl<'a> SkillThing<'a> { "When this creature dies, transform it into an Ash" }), Skill::photosynthesis => - Cow::from("Gain 2:5. Unless cost was 0 or 1:0, caster can be reactivated"), + Cow::from("Gain 2:5. Unless cost was 0 or 1:0, caster reactivated"), Skill::pillar => Cow::from(format!("Gain {}:{} every turn", if self.card().element == 0 { '3' } else { '1' }, self.card().element)), Skill::pillar1 => Cow::from(format!("Gain {}:{} when played", if self.card().element == 0 { '3' } else { '1' }, self.card().element)), Skill::pend => @@ -634,15 +655,17 @@ impl<'a> SkillThing<'a> { Skill::regrade => Cow::from("If target card is upgraded, it becomes unupgraded. If target card is unupgraded, it becomes upgraded. Gain 1 quanta of target card's element. Cannot target stacks"), Skill::reinforce => - Cow::from("Combine with target creature, causing it to gain strength & HP equal to this creature's strength & HP"), + Cow::from("Combine with target creature, giving strength, HP, & poison counters"), Skill::ren => Cow::from("Target creature gains: \"When dying instead return to owner's hand. Modified state besides this effect remains when played again.\""), Skill::resetdr => Cow::from("Zero damage reduction at start of your turn"), Skill::resummon => Cow::from("Target creature is summoned again, as is"), Skill::rewind => Cow::from("Put target creature on top of its owner's deck. Removes all bonuses & modifiers on target creature"), Skill::reveal if ev == Event::OwnPlay => Cow::from("Reveal opponent's hand when played & on attack"), + Skill::reveal if ev == Event::Cast => Cow::from("Reveal opponent's hand for this turn"), Skill::ricochet => Cow::from("Any targeted spells cast by either player are copied when played. The copy has a random caster & a random non-player target"), + Skill::rngfreeze => Cow::from("Randomly freeze one of opponent's non-stacking permanents for two turns on hit"), Skill::sabbath => Cow::from("Target cannot gain quanta until their turn ends. Their deck is protected until start of their next turn.\nSilence all your opponent's creatures & heal all your creatures by 8"), Skill::sadism => Cow::from("Whenever any creatures are damaged, heal yourself an equal amount"), @@ -666,9 +689,10 @@ impl<'a> SkillThing<'a> { } else { "Add 3 random non-pillar cards to your hand. At least one will be 1:1" }), + Skill::shazam => Cow::from("Transform creature you control into a random common creature of the same element, or transform target card into a random card of the same element"), Skill::shtriga => Cow::from("Gain immaterial when your next turn starts"), Skill::shuffle3 => - Cow::from("Shuffle 3 copies of target creature into your deck & expend a charge. Destroyed when all charges expended"), + Cow::from("Shuffle 3 copies of target creature into your deck & expend charge. Destroyed when all charges expended"), Skill::silence => Cow::from("Silence target player or creature. Silenced players cannot play cards until the end of their next turn, while silenced creatures cannot use active skills until the end of their next turn"), Skill::sing => Cow::from("Target creature without this ability attacks its owner"), @@ -681,10 +705,11 @@ impl<'a> SkillThing<'a> { Skill::siphon => Cow::from("Remove 1:0 randomly from opponent's quanta pool when this creature attacks. Gain 1:11 for each quanta removed. Throttled (only triggers twice from Adrenaline)"), Skill::siphonactive => - Cow::from("Copy target creature or weapon's skills. Remove skills from target. Caster can be reactivated"), + Cow::from("Copy target creature or weapon's skills. Remove skills from target. Caster reactivated"), Skill::siphonstrength => Cow::from("Target creature loses 1|0. Gain 1|0"), Skill::skeleton => Cow::from("If this creature is targeted by Rewind, it becomes a random creature"), + Skill::skeletoncount => Cow::from(if self.upped() { "Increase attack by sum of base attack of your skeletons" } else { "Increase attack by number of skeletons you own" }), Skill::skull => Cow::from(if self.set() == CardSet::Open { "Attacking non-ranged creatures may randomly die (1 in HP chance) & are replaced by Skeletons" } else { @@ -695,7 +720,8 @@ impl<'a> SkillThing<'a> { Skill::slime => Cow::from("Increase damage reduction by 1 when damage reduction does not prevent all damage from non-ranged attacker"), Skill::slow => Cow::from("Non-ranged attackers are delayed for one turn after their attack. Delayed creatures may not attack or use active skills"), Skill::snipe => Cow::from("Deal 3 damage to target creature"), - Skill::solar => Cow::from("Gain 1:8 for each attacker"), + Skill::snowflake if ev == Event::Death => Cow::from("Whenever card dies or is destroyed, gain charge per frozen counter"), + Skill::solar => Cow::from("Gain 1:8 equal to amount of damage blocked"), Skill::sosa => Cow::from(if self.upped() { "Sacrifice 40HP. Consume all non-1:2 quanta. For two turns, damage heals you & healing damages you" @@ -755,9 +781,9 @@ impl<'a> SkillThing<'a> { Skill::tidalhealing => Cow::from("Remove frozen status & poison from all your creatures. Your aquatic creatures gain \"Give 1 purify counter to this card's owner on hit. Throttled (only triggers twice from Adrenaline)\". This ability does not stack"), Skill::tornado => Cow::from(if self.upped() { - "Randomly choose two of opponent's permanents. Each selected permanent is shuffled into a random player's deck" + "Shatter all frozen permanents. Randomly choose two of opponent's permanents. Each selected permanent is shuffled into a random player's deck" } else { - "Randomly choose two of opponent's permanents & one of your permanents. Each selected permanent is shuffled into a random player's deck" + "Shatter all frozen permanents. Randomly choose two of opponent's permanents & one of your permanents. Each selected permanent is shuffled into a random player's deck" }), Skill::trick => Cow::from("If target creature's owner has creatures in their deck, put target creature into their deck & summon a random different creature from their deck"), @@ -847,7 +873,7 @@ impl<'a> SkillThing<'a> { }), Skill::v_plague => Cow::from("Poison foe's creatures. Removes cloak"), Skill::v_readiness => - Cow::from("Target creature's active becomes costless. Skill can be reactivated"), + Cow::from("Target creature's active becomes costless & reactivated"), Skill::v_relic => Cow::from("Worthless"), Skill::v_rewind => Cow::from("Remove target creature to top of owner's deck. If target is a Skeleton, transform it into a random creature. If target is a Mummy, transform it into a Pharaoh"), @@ -976,6 +1002,7 @@ impl<'a> SkillThing<'a> { Flag::airborne => ret.push_str("airborne, "), Flag::appeased => ret.push_str("appeased, "), Flag::aquatic => ret.push_str("aquatic, "), + Flag::bug => ret.push_str("bug, "), Flag::burrowed => ret.push_str("burrowed, "), Flag::golem => ret.push_str("golem, "), Flag::immaterial => ret.push_str("immaterial, "), diff --git a/src/ui/art.js b/src/ui/art.js index 8f7c49ce..75f7745e 100644 --- a/src/ui/art.js +++ b/src/ui/art.js @@ -1,6 +1,6 @@ import { card_index, card_name, CardSet } from '../rs/pkg/etg.js'; -function trMouseOver(e) { +function trMouseOver() { let i = 1; for (; i < this.children.length; i++) { const child = this.children[i].children[0]; @@ -46,16 +46,20 @@ for (const credit of [ [['moomoose', 'http://elementscommunity.org/forum/profile/?u=40'], ['5i6']], [ ['Niharia', 'https://etg.dek.im/forum/index.php?action=profile;u=522'], - '5fq5j35p6', + '53d5ck5fq5j35p662k', ], [ ['OdinVanguard', 'http://elementscommunity.org/forum/profile/?u=232'], '4se4sf4t44t54td4tf4tg4vf4vk4vo52i52m52o52p52s53053855m55t56156556956a56c56e59459659k5c55cr5cs5f45f65f75ff5fg5fj5fn5i85ii5ir5lq5lu5lv5m25oi5on5or5ri5ru5s15s65s95un5ur5us5v05v15vc5ve5vk61u62362862962d7167e7', ], [['pepokish', 'http://theowlettenest.com'], '52g58o5bv5f05i45ie5l85lb5oj'], + [ + ['pimpollo', 'https://etg.dek.im/forum/index.php?action=profile;u=525'], + '508', + ], [ ['Ravizant', 'http://elementscommunity.org/forum/profile/?u=8037'], - '4sc4tb4vp4vi4vj4vm4vq4vt4vu4vv50050350a50u52h52j52k52n52r52u52v53153353453753e54255n55q55v56456856f56i57658p58q58r58u58v59559959a59f59g59i59m5bt5c35c85ca5cb5cc5cd5ce5cf5cg5ch5ci5cq5de5f35f85f95fd5fi5fu5gi5ia5ih5ik5im5in5ip5is5j25jm5l95la5lc5lf5lh5li5lk5ln5lo5lp5m65mq5oh5ou5p15p35pa5pu5rh5rm5rn5rq5rv5se5t25uq5uu5vd5vg5vh5vi61p61q61v62062762c62g62m6rr6u377a77p7au7av7dj7e27jq7k17qa7ta80980a', + '4sc4tb4vp4vi4vj4vm4vq4vt4vu4vv50050350a50u52h52j52k52n52r52u52v53153353453753e54255n55q55v56456856f56i57658p58q58r58u58v59559959a59f59g59i59m5bt5c35c85ca5cb5cc5cd5ce5cf5cg5ch5ci5cq5de5f35f85f95fd5fi5fu5gi5ia5ih5ik5im5in5ip5is5j25jm5l95la5lc5lf5lh5li5lk5ln5lo5lp5m65mq5oh5ou5p15p35pa5pu5rh5rm5rn5rq5rv5se5t25uq5uu5v45vd5vg5vh5vi61p61q61v62062762c62g62m6rr6u377a77p7au7av7dj7e27jq7k17qa7ta80980a', ], [ ['sael', 'mailto:animaetmateria@gmail.com'], @@ -67,7 +71,7 @@ for (const credit of [ ], [ ['serprex', 'https://serprex.github.io'], - '50453a53bl8t5cj5ctlfp5iv5j05p4lrl5rolrp5s0lsb5sc5sd5sf5valvh5vl62262a62h62j', + '50453a53b56gl8t5cj5ctlfp5iv5j05p4lrl5rolrp5s05s2lsb5sc5sd5sf5valvh5vl62262a62h62j', ], [ ['Sovereign', 'https://soundcloud.com/the_sovereign'], @@ -94,6 +98,11 @@ for (const credit of [ '5i95if7dl', ], [['TheManuz', 'http://elementscommunity.org/forum/profile/?u=75'], '5025ot'], + [['Treldon', 'http://elemetscommunity.org/forum/profile/?u=8771'], '5iu'], + [ + ['Turlututu', 'https://etg.dek.im/forum/index.php?action=profile;u=430'], + '59n5fr5m55p7', + ], [ ['vrt', 'http://elementscommunity.org/forum/profile/?u=16'], '4sb4vc4ve4vh52t55l55o55r5605625635915c05c15c95f15f25fa5fc5i55i75id5ij5ll5oc5of5rk5rs5rt5uk5ul5um5ut5uv5v361o61t62462562674a80g590',