From 84c9667c71abdcc3059f8b570613a1167ab6cbc7 Mon Sep 17 00:00:00 2001 From: Eduardo MG Date: Mon, 15 May 2023 20:10:42 -0600 Subject: [PATCH] Reduced sacrifice efficiency for AI. Bug fixes in primitives The AI is too willing to sacrifice permanents. The AI sometimes doesn't use a Planeswalker ability, increasing efficiency. Gonti, Lord of Luxury. An effect that instructs you to "cast" a card doesn't allow you to play lands. Rona, Tolarian Obliterator exra ) Oblivion Strike Steel Seraph True Love's Kiss --- projects/mtg/bin/Res/sets/primitives/borderline.txt | 10 +++++----- projects/mtg/bin/Res/sets/primitives/mtg.txt | 2 +- projects/mtg/bin/Res/sets/primitives/planeswalkers.txt | 4 ++-- projects/mtg/src/AIPlayerBaka.cpp | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/projects/mtg/bin/Res/sets/primitives/borderline.txt b/projects/mtg/bin/Res/sets/primitives/borderline.txt index d2a65e4f8..45097b433 100644 --- a/projects/mtg/bin/Res/sets/primitives/borderline.txt +++ b/projects/mtg/bin/Res/sets/primitives/borderline.txt @@ -36048,7 +36048,7 @@ name=Gonti, Lord of Luxury abilities=deathtouch aicode=activate target(*[zpos<=4]|opponentlibrary) moveto(opponentexile) and!( transforms((,newability[counter(0/0.1.GontiExiled)],newability[all(*[zpos<=3]|opponentlibrary) moveto(myreveal) and!( bottomoflibrary )!])) oneshot )! auto=name(look) reveal:4 revealzone(opponentlibrary) optionone name(Exile a card) target(*|reveal) moveto(opponentexile) and!( counter(0/0.1.GontiExiled) )! optiononeend optiontwo name(put on bottom) all(*|reveal) bottomoflibrary optiontwoend revealend -auto={0}:name(Cast card with Gonti) name(Cast card with Gonti) target(*[counter{0/0.1.GontiExiled}]|opponentexile) moveto(myexile) and!( transforms((,newability[counter(0/0.1.GontiExiled)],newability[canplayfromexile],newability[anytypeofmana],newability[phaseaction[endofturn once checkex] moveTo(ownerexile)],newability[phaseaction[untap once checkex] counter(0/0.1.GontiExiled)])) ueot )! +auto={0}:name(Cast card with Gonti) name(Cast card with Gonti) target(*[-land;counter{0/0.1.GontiExiled}]|opponentexile) moveto(myexile) and!( transforms((,newability[counter(0/0.1.GontiExiled)],newability[canplayfromexile],newability[anytypeofmana],newability[phaseaction[endofturn once checkex] moveTo(ownerexile)],newability[phaseaction[untap once checkex] counter(0/0.1.GontiExiled)])) ueot )! text=Deathtouch -- When Gonti, Lord of Luxury enters the battlefield, look at the top four cards of target opponent's library, exile one of them face down, then put the rest on the bottom of that library in a random order. You may look at and cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell. mana={2}{B}{B} type=Legendary Creature @@ -71119,8 +71119,8 @@ toughness=4 [card] name=Rona, Tolarian Obliterator abilities=trample -auto=@damaged(this) from(*|opponentzones):name(Discard at random) name(Discard at random) ability$!name(Discard at random) name(Discard at random) all(*[zpos=genrandzpos=type:*:myhandplus1plusend]|myhand) reject and!( transforms((,newability[if cantargetcard(*[land]|*) then transforms((,newability[choice name(Put land in play) moveto(mybattlefield)],newability[choice name(Don't put land in play) donothing])) oneshot],newability[if cantargetcard(*[-land]|*) then transforms((,newability[choice name(Cast for zero) activate castcard(normal))],newability[choice name(Don't cast) donothing])) oneshot])) oneshot )!!$ opponent -auto=@damaged(this) from(*|myzones):name(Discard at random) name(Discard at random) all(*[zpos=genrandzpos=type:*:myhandplus1plusend]|myhand) reject and!( transforms((,newability[if cantargetcard(*[land]|*) then transforms((,newability[choice name(Put in play) moveto(mybattlefield)],newability[choice name(Don't put in play) donothing])) oneshot],newability[if cantargetcard(*[-land]|*) then transforms((,newability[choice name(Cast spell for zero) activate castcard(normal))],newability[choice name(Don't cast spell) donothing])) oneshot])) oneshot )! +auto=@damaged(this) from(*|opponentzones):name(Discard at random) name(Discard at random) ability$!name(Discard at random) name(Discard at random) all(*[zpos=genrandzpos=type:*:myhandplus1plusend]|myhand) reject and!( transforms((,newability[if cantargetcard(*[land]|*) then transforms((,newability[choice name(Put land in play) moveto(mybattlefield)],newability[choice name(Don't put land in play) donothing])) oneshot],newability[if cantargetcard(*[-land]|*) then transforms((,newability[choice name(Cast for zero) activate castcard(normal)],newability[choice name(Don't cast) donothing])) oneshot])) oneshot )!!$ opponent +auto=@damaged(this) from(*|myzones):name(Discard at random) name(Discard at random) all(*[zpos=genrandzpos=type:*:myhandplus1plusend]|myhand) reject and!( transforms((,newability[if cantargetcard(*[land]|*) then transforms((,newability[choice name(Put in play) moveto(mybattlefield)],newability[choice name(Don't put in play) donothing])) oneshot],newability[if cantargetcard(*[-land]|*) then transforms((,newability[choice name(Cast spell for zero) activate castcard(normal)],newability[choice name(Don't cast spell) donothing])) oneshot])) oneshot )! text=Trample -- Whenever a source deals damage to Rona, Tolarian Obliterator, that source's controller exiles a card from their hand at random. If it's a land card, you may put it onto the battlefield under your control. Otherwise, you may cast it without paying its mana cost. type=Legendary Creature subtype=Phyrexian Wizard @@ -82650,7 +82650,7 @@ toughness=4 [/card] [card] name=Steel Seraph -abilities=flying,vigilance +abilities=flying other={1}{W}{W} name(prototype) auto=if paid(alternative) then becomes(,3/3,white) auto=@each my combatbegins:ability$!choice target(creature|myBattlefield) flying ueot _ choice target(creature|myBattlefield) vigilance ueot _ choice target(creature|myBattlefield) lifelink ueot !$ controller @@ -91032,7 +91032,7 @@ type=Enchantment name=True Love's Kiss target=artifact,enchantment auto=moveto(exile) -auto=draw:1 +auto=draw:1 controller text=Exile target artifact or enchantment. -- Draw a card. mana={2}{W}{W} type=Instant diff --git a/projects/mtg/bin/Res/sets/primitives/mtg.txt b/projects/mtg/bin/Res/sets/primitives/mtg.txt index 1297db600..1ebbb1b7d 100644 --- a/projects/mtg/bin/Res/sets/primitives/mtg.txt +++ b/projects/mtg/bin/Res/sets/primitives/mtg.txt @@ -81512,7 +81512,7 @@ type=Artifact [card] name=Oblivion Strike target=creature -auto=exile +auto=moveTo(exile) text=Devoid (This card has no color.) -- Exile target creature. mana={3}{B} abilities=devoid diff --git a/projects/mtg/bin/Res/sets/primitives/planeswalkers.txt b/projects/mtg/bin/Res/sets/primitives/planeswalkers.txt index e2f51266f..063d94ab4 100644 --- a/projects/mtg/bin/Res/sets/primitives/planeswalkers.txt +++ b/projects/mtg/bin/Res/sets/primitives/planeswalkers.txt @@ -539,7 +539,7 @@ auto=counter(0/0,5,loyalty) auto=@movedTo(*[instant;sorcery]|mystack) turnlimited:name(Copy spell) name(Copy spell) all(trigger[to]) transforms((,newability[name(Copy spell) activate castcard(copied noevent)])) oneshot auto={C(0/0,+2,Loyalty)}:name(+2: Add 2 mana) thisforeach(variable{2}) ability$!name(Choose one) choice name(Add white) add{W} _ choice name(Add blue) add{U} _ choice name(Add red) add{R} _ choice name(Add green) add{G} _ choice name(Add black) add{B}!$ controller auto={C(0/0,+1,Loyalty)}:name(+1: Exile top 5 cards) all(*[zpos<=5]|mylibrary) moveto(myexile) and!( if cantargetcard(*[instant;sorcery]|*) then transforms((,newability[canplayfromexile])) ueot )! -auto={C(0/0,-1,Loyalty)}:name(-1: Damage one target) ability$!name(Damage target) name(Damage target(player,creature,planeswalker) damage:1!$ controller +auto={C(0/0,-1,Loyalty)}:name(-1: Damage one target) ability$!name(Damage target) name(Damage target) target(player,creature,planeswalker) damage:1!$ controller auto={C(0/0,-1,Loyalty)}:name(-1: Damage two target) ability$!name(Damage targets) name(Damage targets) target(<2>player,creature,planeswalker) damage:1!$ controller auto={C(0/0,-2,Loyalty)}:name(-2: Damage one target) ability$!name(Damage target) name(Damage target) target(player,creature,planeswalker) damage:2!$ controller auto={C(0/0,-2,Loyalty)}:name(-2: Damage two target) ability$!name(Damage targets) name(Damage targets) target(<2>player,creature,planeswalker) damage:2!$ controller @@ -576,7 +576,7 @@ auto={C(0/0,-17,Loyalty)}:name(-17: Damage two target) ability$!name(Damage targ auto={C(0/0,-18,Loyalty)}:name(-18: Damage one target) ability$!name(Damage target) name(Damage target) target(player,creature,planeswalker) damage:18!$ controller auto={C(0/0,-18,Loyalty)}:name(-18: Damage two target) ability$!name(Damage targets) name(Damage targets) target(<2>player,creature,planeswalker) damage:18!$ controller auto={C(0/0,-19,Loyalty)}:name(-19: Damage one target) ability$!name(Damage target) name(Damage target) target(player,creature,planeswalker) damage:19!$ controller -auto={C(0/0,-19,Loyalty)}:name(-29: Damage two target) ability$!name(Damage targets) name(Damage targets) target(<2>player,creature,planeswalker) damage:19!$ controller +auto={C(0/0,-19,Loyalty)}:name(-19: Damage two target) ability$!name(Damage targets) name(Damage targets) target(<2>player,creature,planeswalker) damage:19!$ controller auto={C(0/0,-20,Loyalty)}:name(-20: Damage one target) ability$!name(Damage target) name(Damage target) target(player,creature,planeswalker) damage:20!$ controller auto={C(0/0,-20,Loyalty)}:name(-20: Damage two target) ability$!name(Damage targets) name(Damage targets) target(<2>player,creature,planeswalker) damage:20!$ controller text=Whenever you cast an instant or sorcery spell, copy it. You may choose new targets for the copy. This ability triggers only once each turn. -- [+2]: Add two mana in any combination of colors. -- [+1]: Exile the top five cards of your library. Until the end of your next turn, you may cast an instant or sorcery spell from among those exiled cards. -- [−X]: Chandra, Hope's Beacon deals X damage to each of up to two targets. diff --git a/projects/mtg/src/AIPlayerBaka.cpp b/projects/mtg/src/AIPlayerBaka.cpp index d00154caf..8806415ba 100644 --- a/projects/mtg/src/AIPlayerBaka.cpp +++ b/projects/mtg/src/AIPlayerBaka.cpp @@ -701,7 +701,7 @@ int OrderedAIAction::getEfficiency() if(tapper) continue; else if(sacrifice) - efficiency = efficiency / 3; + efficiency = efficiency / 9; else efficiency = efficiency / 2; } @@ -724,7 +724,7 @@ int OrderedAIAction::getEfficiency() if (ability->source) { if(ability->source->hasType(Subtypes::TYPE_PLANESWALKER) || ability->source->hasType(Subtypes::TYPE_BATTLE)) - efficiency += 40; + efficiency += 50; else if(ability->source->hasType(Subtypes::TYPE_LAND)) { // probably a shockland, don't pay life if hand is empty if (p->life<=2)