diff --git a/src/Cards.json b/src/Cards.json index 907bbb6d..0e2d3b43 100644 --- a/src/Cards.json +++ b/src/Cards.json @@ -32,7 +32,7 @@ [["Mark of Entropy",5011,0,-1,"pillar","pillar+stackable+additive+charges=1"],["Mark of Entropy",7011,0,-1,"pillar+ownplay=pillar1","pillar+stackable+additive+charges=1"],["Amethyst Pillar",5100,0,0,"pillar","pillar+stackable+additive+charges=1"],["Amethyst Tower",7100,0,0,"pillar+ownplay=pillar1","pillar+stackable+additive+charges=1"],["Entropy Pendulum",5150,0,0,"pend","pillar+stackable+additive+charges=1"],["Entropy Pendulum",7150,0,0,"pend+ownplay=pillar1","pillar+stackable+additive+charges=1"], ["Ricochet",5117,3,2,"spell=ricochet",""],["Ricochet",7117,2,2,"spell=ricochet",""]], [["Mark of Death",5012,0,-1,"pillar","pillar+stackable+additive+charges=1"],["Mark of Death",7012,0,-1,"pillar+ownplay=pillar1","pillar+stackable+additive+charges=1"],["Bone Pillar",5200,0,0,"pillar","pillar+stackable+additive+charges=1"],["Bone Tower",7200,0,0,"pillar+ownplay=pillar1","pillar+stackable+additive+charges=1"],["Death Pendulum",5250,0,0,"pend","pillar+stackable+additive+charges=1"],["Death Pendulum",7250,0,0,"pend+ownplay=pillar1","pillar+stackable+additive+charges=1"], - ["Boneyard",5207,3,1,"death=boneyard",""],["Graveyard",7207,4,1,"death=boneyard",""],["Soul Catcher",5215,"1:0",1,"death=soulcatch",""],["Soul Catcher",7215,0,1,"death=soulcatch",""],["Ouija Essence",5216,3,2,"death=ouija+upkeep+owndiscard=hasten+2:5=ouijagrowth",""],["Ouija Source",7216,2,2,"death=ouija+upkeep+owndiscard=hasten+2:5=ouijagrowth",""],["Epidemic",5219,5,1,"death=epidemic",""],["Epidemic",7219,4,1,"death=epidemic",""]], + ["Boneyard",5207,3,1,"death=boneyard",""],["Graveyard",7207,4,1,"death=boneyard",""],["Soul Catcher",5215,"1:0",1,"death=soulcatch",""],["Soul Catcher",7215,0,1,"death=soulcatch",""],["Ouija Essence",5216,3,2,"death=ouija+owndiscard=hasten+upkeep+owndestroy=ouijadestroy+1:5=ouijagrowth",""],["Ouija Source",7216,2,2,"death=ouija+owndiscard=hasten+upkeep+owndestroy=ouijadestroy+1:5=ouijagrowth",""],["Epidemic",5219,5,1,"death=epidemic",""],["Epidemic",7219,4,1,"death=epidemic",""]], [["Mark of Gravity",5013,0,-1,"pillar","pillar+stackable+additive+charges=1"],["Mark of Gravity",7013,0,-1,"pillar+ownplay=pillar1","pillar+stackable+additive+charges=1"],["Gravity Pillar",5300,0,0,"pillar","pillar+stackable+additive+charges=1"],["Gravity Tower",7300,0,0,"pillar+ownplay=pillar1","pillar+stackable+additive+charges=1"],["Gravity Pendulum",5350,0,0,"pend","pillar+stackable+additive+charges=1"],["Gravity Pendulum",7350,0,0,"pend+ownplay=pillar1","pillar+stackable+additive+charges=1"], ["Catapult",5313,3,2,"2=catapult",""],["Catapult",7313,3,2,"1=catapult",""],["Inertia",5322,1,1,"spell=inertia",""],["Inertia",7322,"1:0",1,"spell=inertia",""]], [["Mark of Earth",5014,0,-1,"pillar","pillar+stackable+additive+charges=1"],["Mark of Earth",7014,0,-1,"pillar+ownplay=pillar1","pillar+stackable+additive+charges=1"],["Stone Pillar",5400,0,0,"pillar","pillar+stackable+additive+charges=1"],["Stone Tower",7400,0,0,"pillar+ownplay=pillar1","pillar+stackable+additive+charges=1"],["Earth Pendulum",5450,0,0,"pend","pillar+stackable+additive+charges=1"],["Earth Pendulum",7450,0,0,"pend+ownplay=pillar1","pillar+stackable+additive+charges=1"], diff --git a/src/Game.js b/src/Game.js index 9ae42366..b1d0e0cd 100644 --- a/src/Game.js +++ b/src/Game.js @@ -184,6 +184,18 @@ export default class Game { canTarget(c, t) { return this.game.can_target(c, t); } + replayJson() { + return ( + this.replay && + JSON.stringify({ + date: this.time, + seed: this.data.seed, + set: this.data.set, + players: this.data.players, + moves: this.replay, + }) + ); + } } function defineProp(key) { diff --git a/src/rs/src/aieval.rs b/src/rs/src/aieval.rs index 211b7b54..449109f1 100644 --- a/src/rs/src/aieval.rs +++ b/src/rs/src/aieval.rs @@ -178,6 +178,10 @@ fn eval_skill( const SparkUp: u16 = card::Upped(card::Spark) as u16; const Phantom: u16 = card::Phantom as u16; const PhantomUp: u16 = card::Upped(card::Phantom) as u16; + const FireflyV: u16 = card::v_Firefly as u16; + const FireflyUpV: u16 = card::Upped(card::v_Firefly) as u16; + const ScarabV: u16 = card::v_Scarab as u16; + const ScarabUpV: u16 = card::Upped(card::v_Scarab) as u16; skills .iter() .map(|&sk| match sk { @@ -369,7 +373,7 @@ fn eval_skill( Skill::freeze(x) | Skill::v_freeze(x) => x as f32, Skill::freezeperm => 4.0, Skill::fungusrebirth => 1.0, - Skill::gas | Skill::v_gas => 5.0, + Skill::gas => 5.0, Skill::give => 1.0, Skill::golemhit => { let mut dmg = 0.0; @@ -581,7 +585,7 @@ fn eval_skill( Skill::siphonactive => 3.0, Skill::siphonstrength => 4.0, Skill::skyblitz => 10.0, - Skill::snipe => 7.0, + Skill::snipe => 3.0, Skill::sosa | Skill::v_sosa => 6.0, Skill::soulcatch => 2.0, Skill::spores => 4.0, @@ -593,10 +597,10 @@ fn eval_skill( Skill::storm(x) | Skill::v_storm(x) | Skill::firestorm(x) => (x * 4) as f32, Skill::summon(FateEgg) => 3.0, Skill::summon(FateEggUp) => 4.0, - Skill::summon(Firefly) => 4.0, - Skill::summon(FireflyUp) => 5.0, - Skill::summon(Scarab) => 4.0, - Skill::summon(ScarabUp) => 4.5, + Skill::summon(Firefly) | Skill::summon(FireflyV) => 4.0, + Skill::summon(FireflyUp) | Skill::summon(FireflyUpV) => 5.0, + Skill::summon(Scarab) | Skill::summon(ScarabV) => 4.0, + Skill::summon(ScarabUp) | Skill::summon(ScarabUpV) => 4.5, Skill::summon(Shadow) => 3.0, Skill::summon(ShadowUp) => 4.0, Skill::summon(Spark) => 2.0, @@ -967,7 +971,7 @@ fn evalthing( let mut poison = ctx.get(id, Stat::poison); for &sk in ctx.getSkill(id, Event::OwnAttack).iter() { match sk { - Skill::growth(gatk, ghp) => poison = poison.saturating_sub(ghp as i32), + Skill::growth(_, ghp) => poison = poison.saturating_sub(ghp as i32), _ => (), } } @@ -1080,7 +1084,7 @@ fn evalthing( } } let flag = ctx.get_thing(id).flag; - if flag.get(Flag::airborne | Flag::ranged) { + if flag.get(Flag::airborne | Flag::ranged | Flag::whetstone) { score += 0.2; } else if flag.get(Flag::nightfall) { score += 0.5; @@ -1090,12 +1094,12 @@ fn evalthing( score += 1.0; } if iscrea { + let hpf32 = hp as f32; let voodoo = ctx.get(id, Flag::voodoo); if voodoo && ctx.material(id, None) { - score += hp as f32 / 10.0; + score += hpf32 / 10.0; } if hp != 0 && ctx.get(owner, Stat::gpull) == id { - let hpf32 = hp as f32; if voodoo { score += hpf32; } @@ -1113,9 +1117,9 @@ fn evalthing( } else { score *= if hp != 0 { if ctx.material(id, None) { - 1.0 + (cmp::min(hp, 33) as f32).ln() / 7.0 + 1.0 + hpf32.sqrt() / (hpf32.sqrt() * 2.0 + 4.0) } else { - 1.3 + 1.5 } } else if inhand { 0.9 @@ -1124,11 +1128,7 @@ fn evalthing( } } } else { - score *= if ctx.get(id, Flag::immaterial) { - 1.4 - } else { - 1.25 - }; + score *= if ctx.material(id, None) { 1.25 } else { 1.4 }; } if inhand { score * 0.9 @@ -1315,8 +1315,7 @@ pub fn eval(ctx: &Game) -> f32 { if patience { pscore += (ctx.count_creatures(pl) * 3) as f32; } - pscore += (quantamap.get(pl, etg::Chroma) as f32) / 1188.0; - pscore += (player.quanta.iter().map(|q| *q as u32).sum::() as f32) / 1188.0; + pscore += (quantamap.get(pl, etg::Chroma) as u32 + player.quanta.iter().map(|q| *q as u32).sum::()) as f32 / 14256.0; pscore += evalthing( ctx, &damage, diff --git a/src/rs/src/aisearch.rs b/src/rs/src/aisearch.rs index 5ec4322e..68521d17 100644 --- a/src/rs/src/aisearch.rs +++ b/src/rs/src/aisearch.rs @@ -27,30 +27,21 @@ struct Candidate { pub score: f32, } -fn get_worst_card(ctx: &Game) -> Candidate { +fn get_worst_card(ctx: &Game) -> (i32, f32) { if ctx.full_hand(ctx.turn) { ctx.get_player(ctx.turn) .hand .iter() + .filter(|&&card| card != 0) .map(|&card| { - let card = ctx.get_player(ctx.turn).hand[0]; let mut clone = ctx.clonegame(); clone.die(card); - let score = eval(&clone); - Candidate { - cmd: GameMove::End(card), - depth: 0, - score, - } + (card, eval(&clone)) }) - .max_by(|a, b| a.score.partial_cmp(&b.score).unwrap_or(Ordering::Equal)) + .max_by(|a, b| a.1.partial_cmp(&b.1).unwrap_or(Ordering::Equal)) .unwrap() } else { - Candidate { - cmd: GameMove::End(0), - depth: 0, - score: eval(ctx), - } + (0, eval(ctx)) } } @@ -226,6 +217,7 @@ fn scancore(ctx: &Game, depth: i32, candy: &mut Candidate, limit: &mut u32, cmd: | &[Skill::cseed2] | &[Skill::mutation] | &[Skill::improve] + | &[Skill::hatch] ) || ctx.hasskill(id, Event::Shield, Skill::randomdr) || ctx.hasskill(id, Event::OwnPlay, Skill::mutant) { @@ -242,7 +234,7 @@ fn scancore(ctx: &Game, depth: i32, candy: &mut Candidate, limit: &mut u32, cmd: }) { gclone.r#move(cmd); } - let score = eval(&gclone); + let score = get_worst_card(&gclone).1; if score > candy.score || (score == candy.score && depth < candy.depth) { if depth == 0 { *candy = Candidate { cmd, depth, score }; @@ -320,9 +312,13 @@ pub fn search(ctx: &Game) -> GameMove { }; } lethal(ctx).unwrap_or_else(|| { - let mut candy = get_worst_card(ctx); - let mut limit = 864; - scan(ctx, 0, &mut candy, &mut limit); + let (discard, score) = get_worst_card(ctx); + let mut candy = Candidate { + cmd: GameMove::End(discard), + depth: 0, + score, + }; + scan(ctx, 0, &mut candy, &mut 1260); candy.cmd }) } diff --git a/src/rs/src/game.rs b/src/rs/src/game.rs index e9ba4738..3191fb40 100644 --- a/src/rs/src/game.rs +++ b/src/rs/src/game.rs @@ -1761,6 +1761,7 @@ impl Game { } let mut dmgdata = ProcData::default(); dmgdata.dmg = dmg; + dmgdata.amt = capdmg; self.proc_data(Event::Dmg, id, &mut dmgdata); if realdmg > 0 { if (!dontdie || kind == Kind::Player) && self.truehp(id) <= 0 { diff --git a/src/rs/src/skill.rs b/src/rs/src/skill.rs index eee4fced..773ea748 100644 --- a/src/rs/src/skill.rs +++ b/src/rs/src/skill.rs @@ -423,6 +423,7 @@ pub enum Skill { nymph, obsession, ouija, + ouijadestroy, ouijagrowth, pacify, pairproduce, @@ -578,7 +579,6 @@ pub enum Skill { v_freeevade, v_freeze(u8), v_gaincharge2, - v_gas, v_gpullspell, v_gratitude, v_guard, @@ -1079,7 +1079,11 @@ impl Skill { | Skill::v_storm(x) => x as i32, Skill::summon(x) => x as i32, Skill::quanta(x) => x as i32, - Skill::freeze(x) | Skill::v_drainlife(x) | Skill::v_firebolt(x) | Skill::v_freeze(x) | Skill::v_icebolt(x) => x as i32, + Skill::freeze(x) + | Skill::v_drainlife(x) + | Skill::v_firebolt(x) + | Skill::v_freeze(x) + | Skill::v_icebolt(x) => x as i32, Skill::growth(x, _) | Skill::icegrowth(x, _) => x as i32, _ => 0, } @@ -1512,8 +1516,10 @@ impl Skill { owner }, |ctx, cr| { - ctx.spelldmg(cr, dmg); - ctx.poison(cr, poison); + if cr != t { + ctx.spelldmg(cr, dmg); + ctx.poison(cr, poison); + } }, ); ctx.spelldmg(foe, dmg); @@ -2191,7 +2197,12 @@ impl Skill { } Self::gas => { let owner = ctx.get_owner(c); - let gas = ctx.new_thing(card::As(ctx.get(c, Stat::card), card::UnstableGas), owner); + let gas = if ctx.cardset() == CardSet::Open { + card::UnstableGas + } else { + card::v_UnstableGas + }; + let gas = ctx.new_thing(card::As(ctx.get(c, Stat::card), gas), owner); ctx.addPerm(owner, gas); } Self::give => { @@ -2698,7 +2709,7 @@ impl Skill { Self::jetstream => { if ctx.get(t, Flag::airborne) { ctx.dmg(t, 1); - ctx.incrAtk(t, 4); + ctx.incrAtk(t, 3); } else { ctx.set(t, Flag::airborne, true); } @@ -2809,12 +2820,11 @@ impl Skill { } } Self::martyr => { - let dmg = data.dmg; - if dmg > 0 { - ctx.incrAtk(c, dmg); + if data.dmg > 0 { + ctx.incrAtk(c, data.dmg); } else { let owner = ctx.get_owner(c); - ctx.dmg(owner, dmg); + ctx.dmg(owner, data.amt); } } Self::mend => { @@ -3057,6 +3067,11 @@ impl Skill { ctx.addCard(foe, inst); } } + Self::ouijadestroy => { + let foe = ctx.get_foe(ctx.get_owner(c)); + let maxhp = ctx.get_mut(foe, Stat::maxhp); + *maxhp = cmp::min(*maxhp + 1, 500); + } Self::ouijagrowth => { let foe = ctx.get_foe(ctx.get_owner(c)); let inst = ctx.new_thing(card::OuijaEssence, foe); @@ -4374,12 +4389,6 @@ impl Skill { data.evade = true; } } - Self::v_gas => { - let owner = ctx.get_owner(c); - let gas = - ctx.new_thing(card::As(ctx.get(c, Stat::card), card::v_UnstableGas), owner); - ctx.addPerm(owner, gas); - } Self::v_gratitude => { let owner = ctx.get_owner(c); ctx.dmg( @@ -4524,8 +4533,8 @@ impl Skill { Skill::summon(1908), Skill::snipe, Skill::dive, - Skill::v_gas, - Skill::v_gas, + Skill::gas, + Skill::gas, ], [ Skill::summon(2010), @@ -4635,7 +4644,7 @@ impl Skill { Skill::summon(_) => 2, Skill::snipe => 2, Skill::dive => 2, - Skill::v_gas => 2, + Skill::gas => 2, Skill::deja => 4, Skill::v_neuro => -2, Skill::precognition => 2, diff --git a/src/skillText.js b/src/skillText.js index 5e64d90f..d38f160e 100644 --- a/src/skillText.js +++ b/src/skillText.js @@ -125,7 +125,7 @@ const data = { 'Remove statuses (positive & negative) from target creature or permanent, & heal target creature 1.', cold: '30% chance to freeze non-ranged attackers for 3 turns.', corpseexplosion: [ - 'Sacrifice one of your creatures to deal 1 spell damage to all creatures. Increase damage by 1 for every 8 HP of the sacrifice. Poisonous sacrifices poison. Also affect opponent.', + 'Sacrifice one of your creatures to deal 1 spell damage to all other creatures. Increase damage by 1 for every 8 HP of the sacrifice. Poisonous sacrifices poison. Also affect opponent.', 'Sacrifice one of your creatures to deal 1 spell damage to all enemy creatures. Increase damage by 1 for every 8 HP of the sacrifice. Poisonous sacrifices poison. Also affect opponent.', ], counter: @@ -389,6 +389,7 @@ const data = { obsession: c => `When discarded, its owner receives ${c.upped ? 13 : 10} spell damage.`, ouija: "Whenever a creature dies, add an Ouija Essence to opponent's hand.", + ouijadestroy: "When destroyed, add 1 to opponent's maximum health.", ouijagrowth: "Summon an Ouija Essence on opponent's side of the field.", pacify: "Set target creature or weapon's strength to 0.", pairproduce: 'Your pillars, pendulums, and towers trigger as if end of turn.', @@ -618,7 +619,7 @@ const data = { "When this creature attacks, if any damage is blocked by opponent's shield, your maximum HP is increased by the amount of this creature's damage that was blocked.", virusdeath: 'When this creature dies, give opponent 1 poison counter.', virusinfect: - 'Sacrifice this creature. Give target creature or player 1 poison counter.', + 'Sacrifice this creature. Give target creature 1 poison counter. Give opponent 1 poison counter.', virusplague: "Sacrifice this creature. Give target player's creatures 1 poison counter.", void: "Reduce opponent's maximum HP by 3.", @@ -626,7 +627,7 @@ const data = { 'Block all damage from attackers. Reduce your maximum HP equal to the damage blocked by this card.', web: 'Target creature loses airborne status.', weight: 'Evade all attackers that have more than 5 HP.', - wind: 'Restore any strentgh lost by halving after attacking.', + wind: 'Restore any strength lost by halving after attacking. Increase HP by amount restored.', wings: 'Evade all non-airborne, non-ranged attackers.', wisdom: 'Target creature or weapon gains 3|0. May target immaterial cards. If it targets an immaterial card, that card gains psionic. Psionic cards deal spell damage and typically bypass shields.', @@ -672,7 +673,6 @@ const data = { v_freeze: x => c => `Freeze target for ${x} turns. Being frozen disables attacking & per turn skills`, v_gaincharge2: 'Gain 2 stacks per death.', - v_gas: 'Summon an Unstable Gas.', v_gpullspell: 'Target creature intercepts attacks directed to its owner.', v_gratitude: 'Heal owner 3, 5 if 1:5.', v_guard: 'Delay target creature & attack target if grounded. Delay self.', diff --git a/src/vanilla/Cards.json b/src/vanilla/Cards.json index 4d810ef4..f89d4e84 100644 --- a/src/vanilla/Cards.json +++ b/src/vanilla/Cards.json @@ -77,7 +77,7 @@ [["Ash Eater",1601,1,"",2,1,"",2],["Brimstone Eater",3601,1,"quanta 6",2,1,"",17],["Crimson Dragon",1602,10,"",12,3,"airborne",4],["Ruby Dragon",3602,12,"",15,2,"airborne",17],["Fire Spirit",1603,2,"1=growth 2 0",0,2,"airborne",2],["Fire Spectre",3603,3,"1=growth 2 0",2,3,"airborne",17],["Lava Golem",1610,5,"1:4=growth 2 2",5,1,"",3],["Lava Destroyer",3610,5,"1:4=growth 2 2",7,1,"",17],["Phoenix",1612,7,"owndeath=v_phoenix",7,1,"airborne",4],["Minor Phoenix",3612,2,"owndeath=v_phoenix",4,1,"airborne",17],["Ash",1613,7,"1=v_rebirth",0,5,"token",0],["Ash",3613,2,"1=v_rebirth",0,5,"token",0],["Seraph",1614,9,"1:8=v_dshield",10,1,"airborne",4],["Seraph",3614,9,"1:8=v_dshield",12,1,"airborne",17],["Red Nymph",1620,8,"3=rage",1,6,"",15],["Fire Nymph",3620,8,"4=rage",1,7,"",20]], [["Chrysaora",1701,1,"1:2=poisonfoe 1",0,2,"poisonous+aquatic",2],["Physalia",3701,1,"1:2=poisonfoe 1",2,2,"poisonous+aquatic",17],["Blue Crawler",1702,3,"",3,3,"aquatic",2],["Abyss Crawler",3702,4,"",6,6,"aquatic",17],["Arctic Squid",1707,3,"2=v_freeze 3",1,2,"aquatic",8],["Arctic Octopus",3707,3,"2=v_freeze 4",1,2,"aquatic",18],["Ice Dragon",1709,10,"",9,6,"airborne+aquatic",4],["Arctic Dragon",3709,11,"",13,5,"airborne+aquatic",17],["Toadfish",1710,5,"1:9=poison 1",6,4,"poisonous+aquatic",2],["Puffer Fish",3710,5,"hit=poison 1",3,5,"poisonous+aquatic",17],["Mind Flayer",1711,2,"1:12=v_lobotomize",2,2,"aquatic",3],["Ulitharid",3711,3,"1:12=v_lobotomize",3,4,"aquatic",17],["Steam Machine",1714,4,"2:6=v_steam",0,6,"aquatic",3],["Steam Machine",3714,5,"2:6=v_steam",0,15,"aquatic",17],["Nymph Queen",1720,8,"4=v_nymph",5,6,"aquatic",15],["Water Nymph",3720,8,"4=v_nymph",6,7,"aquatic",20]], [["Photon",1801,0,"",1,1,"airborne",2],["Ray of Light",3801,0,"quanta 8",1,1,"airborne",17],["Golden Dragon",1802,12,"",10,10,"airborne",4],["Light Dragon",3802,13,"",12,12,"airborne",17],["Pegasus",1803,4,"1:9=dive",3,2,"airborne",3],["Elite Pegasus",3803,4,"1:9=dive",4,4,"airborne",17],["Guardian Angel",1806,3,"1=mend",1,6,"airborne",2],["Archangel",3806,6,"1=mend",7,7,"airborne",17],["Crusader",1813,5,"3=v_endow",2,4,"",3],["Crusader",3813,5,"2=v_endow",3,5,"",17],["Light Nymph",1820,9,"4=v_luciferin",6,9,"",15],["Light Nymph",3820,9,"3=v_luciferin",7,9,"",20]], - [["Dragonfly",1901,1,"quanta 9",1,1,"airborne",2],["Damselfly",3901,0,"quanta 9",2,1,"airborne",17],["Wyrm",1902,4,"2=dive",3,3,"airborne",2],["Elite Wyrm",3902,4,"2=dive",5,3,"airborne",17],["Azure Dragon",1903,10,"",9,6,"airborne",4],["Sky Dragon",3903,12,"",13,7,"airborne",17],["Firefly Queen",1907,6,"2:5=summon 1908",3,7,"airborne",4],["Elite Firefly Queen",3907,6,"2:5=summon 3908",3,7,"airborne",17],["Firefly",1908,3,"quanta 8",3,2,"airborne",2],["Elite Firefly",3908,3,"quanta 6",4,2,"airborne",17],["Blue Nymph",1920,8,"3=v_gas",6,5,"",15],["Air Nymph",3920,8,"3=v_gas",7,6,"",20]], + [["Dragonfly",1901,1,"quanta 9",1,1,"airborne",2],["Damselfly",3901,0,"quanta 9",2,1,"airborne",17],["Wyrm",1902,4,"2=dive",3,3,"airborne",2],["Elite Wyrm",3902,4,"2=dive",5,3,"airborne",17],["Azure Dragon",1903,10,"",9,6,"airborne",4],["Sky Dragon",3903,12,"",13,7,"airborne",17],["Firefly Queen",1907,6,"2:5=summon 1908",3,7,"airborne",4],["Elite Firefly Queen",3907,6,"2:5=summon 3908",3,7,"airborne",17],["Firefly",1908,3,"quanta 8",3,2,"airborne",2],["Elite Firefly",3908,3,"quanta 6",4,2,"airborne",17],["Blue Nymph",1920,8,"3=gas",6,5,"",15],["Air Nymph",3920,8,"3=gas",7,6,"",20]], [["D\u00e9j\u00e0 Vu",2001,1,"1=deja",1,1,"airborne",2],["Elite D\u00e9j\u00e0 Vu",4001,1,"1=deja",2,2,"airborne",17],["Fate Egg",2002,3,"1=v_hatch",0,1,"",3],["Fate Egg",4002,3,"1=v_hatch",0,1,"",17],["Devonian Dragon",2006,10,"",10,5,"airborne",4],["Silurian Dragon",4006,12,"",13,4,"airborne",17],["Anubis",2007,8,"2:12=quint",5,8,"",4],["Elite Anubis",4007,8,"1:12=quint",5,8,"",17],["Scarab",2010,2,"1:3=devour+v_swarm+hp=v_swarmhp",2,1,"airborne",2],["Elite Scarab",4010,2,"1:3=devour+v_swarm+hp=v_swarmhp",3,1,"airborne",17],["Pharaoh",2012,9,"2=summon 2010",4,9,"",8],["Pharaoh",4012,9,"2=summon 4010",4,9,"",18],["Dune Scorpion",2013,3,"hit=v_neuro",0,1,"poisonous",2],["Dune Scorpion",4013,3,"hit=v_neuro",0,3,"poisonous",17],["Ghost of the Past",2014,6,"owndiscard=v_obsession",7,4,"",3],["Ghost of the Past",4014,7,"owndiscard=v_obsession",9,4,"",17],["Golden Nymph",2020,8,"2=precognition",6,8,"",15],["Golden Nymph",4020,8,"2=precognition",7,9,"",20]], [["Black Dragon",2101,10,"",10,5,"airborne+nocturnal",4],["Obsidian Dragon",4101,12,"",12,6,"airborne+nocturnal",17],["Devourer",2102,2,"1:4=v_burrow+v_siphon",0,2,"nocturnal",3],["Pest",4102,2,"1:4=v_burrow+v_siphon",0,4,"nocturnal",17],["Parasite",2103,2,"1:2=poison 1",1,1,"poisonous+nocturnal",3],["Bloodsucker",4103,2,"1:2=poison 1",3,1,"poisonous+nocturnal",17],["Minor Vampire",2109,3,"hit=vampire",2,2,"airborne+nocturnal",3],["Vampire",4109,5,"hit=vampire",4,3,"airborne+nocturnal",17],["Gargoyle",2111,5,"1:4=v_stoneform",5,3,"airborne+nocturnal",2],["Gargoyle",4111,5,"1:4=v_stoneform",7,3,"airborne+nocturnal",17],["Voodoo Doll",2112,2,"",0,16,"voodoo+nocturnal",3],["Voodoo Doll",4112,2,"",0,20,"voodoo+nocturnal",17],["Black Nymph",2120,8,"2=v_liquid",3,5,"nocturnal",15],["Dark Nymph",4120,8,"2=v_liquid",5,5,"nocturnal",20]], [["Spark",2201,0,"",3,0,"airborne",2],["Ball Lightning",4201,0,"",5,0,"airborne",17],["Immortal",2204,6,"",4,3,"immaterial",3],["Elite Immortal",4204,7,"",5,4,"immaterial",17],["Phase Dragon",2207,13,"",8,6,"immaterial+airborne",4],["Elite Phase Dragon",4207,14,"",10,6,"immaterial+airborne",17],["Phase Spider",2208,3,"1:9=v_web",4,2,"",2],["Phase Recluse",4208,4,"1:9=v_web",7,2,"",17],["Psion",2213,4,"v_noluci",4,4,"psionic+airborne",4],["Psion",4213,4,"v_noluci",5,5,"psionic+airborne",17],["Phase Salvager",2214,1,"destroy=v_salvage",4,0,"",2],["Phase Salvager",4214,1,"destroy=v_salvage",6,0,"",17],["Turquoise Nymph",2220,8,"3=quint",7,4,"",15],["Aether Nymph",4220,8,"3=quint",8,5,"",20]]] diff --git a/src/vanilla/views/Result.jsx b/src/vanilla/views/Result.jsx index 12cc822b..a90a8e1f 100644 --- a/src/vanilla/views/Result.jsx +++ b/src/vanilla/views/Result.jsx @@ -38,6 +38,12 @@ export default function OriginalResult({ game }) { document.removeEventListener('keydown', onkeydown); }); + const replay = game.replayJson(); + if (replay) { + store.clearChat('Replay'); + store.chat(() => replay, 'Replay'); + } + if (game.winner === player1.id) { const foedecks = game.data.players.filter(pd => !pd.user); if (foedecks.length !== 0) { diff --git a/src/views/Result.jsx b/src/views/Result.jsx index bfd40d02..b9f86f48 100644 --- a/src/views/Result.jsx +++ b/src/views/Result.jsx @@ -264,21 +264,14 @@ export default function Result(props) { () =>
{(game.duration / 1000).toFixed(1)} seconds
, ]; - store.clearChat('Replay'); - const { replay } = game; + const replay = game.replayJson(); if ( replay && game.data.endurance === undefined && game.data.quest === undefined ) { - const replayJson = JSON.stringify({ - date: game.time, - seed: game.data.seed, - set: game.data.set, - players: game.data.players, - moves: replay, - }); - store.chat(() => replayJson, 'Replay'); + store.clearChat('Replay'); + store.chat(() => replay, 'Replay'); } let streakrate = 0; diff --git a/src/views/Reward.jsx b/src/views/Reward.jsx index fdecc733..dd800220 100644 --- a/src/views/Reward.jsx +++ b/src/views/Reward.jsx @@ -41,7 +41,7 @@ export default function Reward(props) { }, }); } else { - store.chatMsg('Unknown reward ${props.type}', 'System'); + store.chatMsg(`Unknown reward ${props.type}`, 'System'); store.doNav(import('./MainMenu.jsx')); } });