Ok, I've got generic code for auras working (I think.)
I'll post here for feedback rather than integrating at this point.
This code goes at the end of the if-else if block in CardFactory_Auras.java (but before the "
Control Magic" code Chris<?> just added:
- Code: Select all
///////////////////////////////////////////////////////////////////
////
//// CAUTION: Keep this last in the if else if block for cardnames
////
///////////////////////////////////////////////////////////////////
////////////////////DRF test generic aura
//*************** START *********** START **************************
else if(isAuraType(card, "Land") || isAuraType(card, "Creature") ||
isAuraType(card, "Artifact") || isAuraType(card, "Enchantment")) {
System.out.println("In generic Aura code block");
final String type = getAuraType(card);
final boolean curse = isCurseAura(card);
if("" == type) {
System.out.println("Problem in generic Aura code - type is null");
}
final SpellAbility spell = new Spell(card) {
private static final long serialVersionUID = 4191777361540717307L;
@Override
public boolean canPlayAI() {
String player;
if(curse) {
player = Constant.Player.Human;
}
else {
player = Constant.Player.Computer;
}
CardList list = AllZoneUtil.getPlayerTypeInPlay(player, type);
if(list.isEmpty()) return false;
//TODO - maybe do something intelligent here if it's not a curse, like
//checking the aura magnet list
setTargetCard(list.get(0));
return true;
}//canPlayAI()
@Override
public void resolve() {
PlayerZone play = AllZone.getZone(Constant.Zone.Play, card.getController());
play.add(card);
Card c = getTargetCard();
if(AllZone.GameAction.isCardInPlay(c) && CardFactoryUtil.canTarget(card, c)) card.enchantCard(c);
}//resolve()
};//SpellAbility
card.clearSpellAbility();
card.addSpellAbility(spell);
card.addLeavesPlayCommand(unenchant);
Input runtime = new Input() {
private static final long serialVersionUID = -7100800261954421849L;
@Override
public void showMessage() {
CardList land = AllZoneUtil.getTypeInPlay(type);
stopSetNext(CardFactoryUtil.input_targetSpecific(spell, land,
"Select target "+type.toLowerCase(), true, false));
}
};
spell.setBeforePayMana(runtime);
}//*************** END ************ END **************************
///////////////////////////////////////////////////////////////////
////
//// CAUTION: Keep the above code block last in the if else if block
////
///////////////////////////////////////////////////////////////////
////////////////////DRF test generic aura
It would need to stay at the end of that block if/when more auras are added.
It uses a couple of helper functions:
- Code: Select all
private static boolean isAuraType(final Card aura, final String type) {
System.out.println("isAuraType - checking - "+aura.getName());
ArrayList<String> keywords = aura.getKeyword();
for(String keyword:keywords) {
System.out.println("Got keyword: "+keyword);
if(keyword.startsWith("Enchant "+type)) {
System.out.println("Ending isAuraType with true");
return true;
}
}
System.out.println("Ending isAuraType with false");
return false;
}
private static String getAuraType(final Card aura) {
ArrayList<String> keywords = aura.getKeyword();
for(String keyword:keywords) {
if(keyword.startsWith("Enchant ")) {
StringTokenizer st = new StringTokenizer(keyword);
st.nextToken(); //this should be "Enchant"
return st.nextToken(); //should be "land", "artifact", etc
}
}
return "";
}
private static boolean isCurseAura(final Card aura) {
ArrayList<String> keywords = aura.getKeyword();
for(String keyword:keywords) {
if(keyword.startsWith("Enchant ")) {
if(keyword.endsWith("Curse")) return true;
}
}
return false;
}
It will accept keywords of the form:
- Code: Select all
Enchant <type> [Curse]
Enchant - all will have this
<type> - currently [Artifact, Creature, Land, Enchantment]
[Curse] - if this word is present, AI will target human's permanents.
This allows for
Blight to be implemented as:
- Code: Select all
Blight
B B
Enchantment Aura
When enchanted land becomes tapped, destroy it.
Enchant Land Curse
And all you have to do it add the appropriate resolution code to GameActionUtil.executeTapSideEffects():
- Code: Select all
if(c.isEnchantedBy("Blight")) {
final ArrayList<Card> blights = c.getEnchantedBy();
final Card target = c;
for(Card blight:blights) {
if(blight.getName().equals("Blight")) {
Ability ability = new Ability(blight, "0") {
@Override
public void resolve() {
AllZone.GameAction.destroy(target);
}
};//Ability
ability.setStackDescription(blight.getName()+" - Destroy enchanted land.");
AllZone.Stack.add(ability);
}
}
}//end Blight
Does this seem reasonable to people?
Since we just put out the third beta since the last release, I'm going to assume an upcoming release will happen soon. If so, I will hold off on integrating until after the release to allow for maximum testing.
A couple notes:
1) I did test
Control Magic, and it still works after this change
2) I've partially gone through an alphabetical list of auras, and this should enable:
- Code: Select all
Blight - Enchant Land Curse
Backfire - Enchant Creature Curse
Baneswap Affliction - Enchant Creature Curse
Binding Agony - Enchant Creature Curse
Contaminated Bond - Enchant Creature Curse
Curiosity - Enchant Creature
Curse Artifact - Enchant Artifact Curse
Curse of Chains - Enchant Creature Curse
Cursed Land - everything should be there already, just update cards.txt
Druid's Call
Emblem of the War-Mind
Extra Arms
Farmstead - Enchant Land
Fatal Mutation
Feedback - Enchant Enchantment Curse
...
to be implemented without having to worry about the specific aura code.
I can post a patch if code changes aren't clear.
-slapshot5
PS - Obviously this can be extended for YouControl vs. OpponentControls (
Betrayal, et. al.), all permanents (
Elemental Resonance, etc.), specific land types (
Corrupted Roots, etc.), etc...