Pick-a-Beeble and The Most Dangerous Gamer.

Prize mechanic.
This commit is contained in:
Jetz
2024-06-17 19:03:23 -04:00
parent 88c9559eea
commit bf1f1ecb61
8 changed files with 120 additions and 2 deletions

View File

@@ -50,6 +50,7 @@ public enum ApiType {
ChooseSector (ChooseSectorEffect.class),
ChooseSource (ChooseSourceEffect.class),
ChooseType (ChooseTypeEffect.class),
ClaimThePrize (ClaimThePrizeEffect.class),
Clash (ClashEffect.class),
ClassLevelUp (ClassLevelUpEffect.class),
Cleanup (CleanUpEffect.class),

View File

@@ -0,0 +1,38 @@
package forge.game.ability.effects;
import forge.game.Game;
import forge.game.ability.AbilityKey;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
import forge.game.card.Card;
import forge.game.card.CardCollection;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.trigger.TriggerType;
import forge.util.Lang;
import java.util.Map;
public class ClaimThePrizeEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {
final Card host = sa.getHostCard();
final Player activator = sa.getActivatingPlayer();
final Game game = activator.getGame();
final CardCollection attractions = AbilityUtils.getDefinedCards(host, sa.getParamOrDefault("Defined", "Self"), sa);
for(Card c : attractions) {
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(activator);
runParams.put(AbilityKey.Card, c);
game.getTriggerHandler().runTrigger(TriggerType.ClaimPrize, runParams, false);
}
}
@Override
protected String getStackDescription(SpellAbility sa) {
final Card host = sa.getHostCard();
final CardCollection attractions = AbilityUtils.getDefinedCards(host, sa.getParamOrDefault("Defined", "Self"), sa);
return String.format("Claim the Prize from %s!", Lang.joinHomogenous(attractions));
}
}

View File

@@ -1967,7 +1967,6 @@ public class CardFactoryUtil {
inst.addTrigger(parsedSacTrigger);
} else if (keyword.startsWith("Visit")) {
final String[] k = keyword.split(":");
//final String dbVar = card.getSVar(k[1]);
SpellAbility sa = AbilityFactory.getAbility(card, k[1]);
String descStr = "Visit — " + sa.getDescription();
@@ -1979,6 +1978,18 @@ public class CardFactoryUtil {
t.setOverridingAbility(sa);
inst.addTrigger(t);
} else if (keyword.startsWith("Prize")) {
final String[] k = keyword.split(":");
SpellAbility sa = AbilityFactory.getAbility(card, k[1]); //Is this the right thing?
String descStr = "Prize — " + sa.getDescription();
final String trigStr = "Mode$ ClaimPrize | Static$ True | TriggerZones$ Battlefield | ValidCard$ Card.Self" +
"| TriggerDescription$ " + descStr;
final Trigger t = TriggerHandler.parseTrigger(trigStr, card, intrinsic);
t.setOverridingAbility(sa);
inst.addTrigger(t);
} else if (keyword.startsWith("Dungeon")) {
final List<String> abs = Arrays.asList(keyword.substring("Dungeon:".length()).split(","));
final Map<String, SpellAbility> saMap = new LinkedHashMap<>();

View File

@@ -0,0 +1,36 @@
package forge.game.trigger;
import forge.game.ability.AbilityKey;
import forge.game.card.Card;
import forge.game.spellability.SpellAbility;
import forge.util.Localizer;
import java.util.Map;
public class TriggerClaimPrize extends Trigger{
public TriggerClaimPrize(Map<String, String> params, Card host, boolean intrinsic) {
super(params, host, intrinsic);
}
@Override
public boolean performTest(Map<AbilityKey, Object> runParams) {
if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Player))) {
return false;
}
if (!matchesValidParam("ValidCard", runParams.get(AbilityKey.Card))) {
return false;
}
return true;
}
@Override
public void setTriggeringObjects(SpellAbility sa, Map<AbilityKey, Object> runParams) {
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Player, AbilityKey.Card);
}
@Override
public String getImportantStackObjects(SpellAbility sa) {
return Localizer.getInstance().getMessage("lblPlayer") + ": " +
sa.getTriggeringObject(AbilityKey.Player);
}
}

View File

@@ -43,6 +43,7 @@ public enum TriggerType {
ChangesZone(TriggerChangesZone.class),
ChangesZoneAll(TriggerChangesZoneAll.class),
ChaosEnsues(TriggerChaosEnsues.class),
ClaimPrize(TriggerClaimPrize.class),
Clashed(TriggerClashed.class),
ClassLevelGained(TriggerClassLevelGained.class),
CommitCrime(TriggerCommitCrime.class),

View File

@@ -33,7 +33,6 @@ public class TriggerVisitAttraction extends Trigger {
@Override
public String getImportantStackObjects(SpellAbility sa) {
//TODO: Do I even need this much? Someone would need to implement a card to visit someone else's attraction...
return Localizer.getInstance().getMessage("lblPlayer") + ": " +
sa.getTriggeringObject(AbilityKey.Player);
}

View File

@@ -0,0 +1,19 @@
Name:Pick-a-Beeble
ManaCost:no cost
Types:Artifact Attraction
Variant:A:Lights:2 3 6
Variant:B:Lights:2 4 6
Variant:C:Lights:2 5 6
Variant:D:Lights:3 4 6
Variant:E:Lights:3 5 6
Variant:F:Lights:4 5 6
K:Visit:TrigRoll
K:Prize:TrigPrize
SVar:TrigRoll:DB$ RollDice | ResultSVar$ Result | Sides$ 6 | SubAbility$ DBCounters | SpellDescription$ Roll a six-sided die. Put a number of luck counters on CARDNAME equal to the result and create a Treasure token. Then if there are six or more luck counters on CARDNAME, claim the prize!
SVar:DBCounters:DB$ PutCounter | Defined$ Self | CounterType$ LUCK | CounterNum$ Result | SubAbility$ DBTreasure
SVar:DBTreasure:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_treasure_sac | SubAbility$ DBClaim
SVar:DBClaim:DB$ ClaimThePrize | ConditionDefined$ Self | ConditionPresent$ Card.Self+counters_GE6_LUCK
SVar:TrigPrize:DB$ Token | TokenAmount$ 2 | TokenScript$ c_a_treasure_sac | SubAbility$ DBSack | SpellDescription$ Create two Treasure tokens, then sacrifice CARDNAME and open an Attraction.
SVar:DBSack:DB$ Sacrifice | SacValid$ Self | SubAbility$ DBOpen
SVar:DBOpen:DB$ OpenAttraction
Oracle:Visit — Roll a six-sided die. Put a number of luck counters on Pick-a-Beeble equal to the result and create a Treasure token. Then if there are six or more luck counters on Pick-a-Beeble, claim the prize!\nPrize — Create two Treasure tokens, then sacrifice Pick-a-Beeble and open an Attraction.

View File

@@ -0,0 +1,13 @@
Name:The Most Dangerous Gamer
ManaCost:2 B G
Types:Legendary Creature Human Gamer Guest
PT:2/2
K:Deathtouch
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBOpen | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, open an Attraction.
T:Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True | Execute$ DBOpen | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, open an Attraction.
SVar:DBOpen:DB$ OpenAttraction
T:Mode$ ChangesZone | Origin$ AttractionDeck | Destination$ Battlefield | ValidCard$ Attraction.YouCtrl | TriggerZones$ Battlefield | Execute$ DBCounter | TriggerDescription$ Whenever you open an Attraction, put a +1/+1 counter on CARDNAME.
SVar:DBCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
T:Mode$ ClaimPrize | ValidCard$ Attraction.YouCtrl | TriggerZones$ Battlefield | Execute$ DBDestroy | TriggerDescription$ Whenever you claim the prize of an Attraction, destroy target permanent.
SVar:DBDestroy:DB$ Destroy | ValidTgts$ Permanent | TgtPrompt$ Select target permanent.
Oracle:Deathtouch\nWhenever The Most Dangerous Gamer enters the battlefield or attacks, open an Attraction.\nWhenever you open an Attraction, put a +1/+1 counter on The Most Dangerous Gamer.\nWhenever you claim the prize of an Attraction, destroy target permanent.