Fix for Flowstone Giant suicide
by mtgrares
Moderators: timmermac, Blacksmith, KrazyTheFox, Agetian, friarsol, CCGHQ Admins
Fix for Flowstone Giant suicide
by jpb » 09 Jan 2009, 07:17
As Bog Wraith pointed out the computer will kill Flowstone Giant by pumping it to death. To fix this add the this code to the beginning of the SSP_canPlay method in CardFactoryUtil.java. Like so.
- Code: Select all
public static boolean SSP_canPlay(Card card)
{
//hack so computer doesn't kill Flowstone Giant
if(Constant.Player.Computer.equals(card.getController()) && card.getName().equals("Flowstone Giant")){
if(card.getDefense() <= 2){
return false;
}
else{
return true;
}
}
- jpb
- Posts: 132
- Joined: 05 Sep 2008, 13:12
- Has thanked: 0 time
- Been thanked: 0 time
Re: Fix for Flowstone Giant suicide
by Rob Cashwalker » 09 Jan 2009, 20:00
The other fix for this is to ditch all the SSP_ code and the pump keyword, in favor of the PTPump, KPump and PTKPump code submitted in this post. I took this into account with the canPlayAI functionality.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Fix for Flowstone Giant suicide
by DennisBergkamp » 09 Jan 2009, 20:47
Oh, yeah Rob I've been meaning to ask you... have you tested your custom P/T pump code? I'd be happy to include it into the next version.
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Fix for Flowstone Giant suicide
by Rob Cashwalker » 09 Jan 2009, 20:51
I haven't personally tested any of my code... I haven't gotten it to run from source, or compile it.DennisBergkamp wrote:Oh, yeah Rob I've been meaning to ask you... have you tested your custom P/T pump code? I'd be happy to include it into the next version.
I just follow patterns of known working code....
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Fix for Flowstone Giant suicide
by DennisBergkamp » 09 Jan 2009, 21:15
Ahh, alright. No problems, I'll add it in and see if I can get it to work.
I usually test my stuff, but even then there's usually a million bugs in it
I see this is quite a big task though, since we'd have to update a lot of cards in cards.txt (also new cards added?).
I usually test my stuff, but even then there's usually a million bugs in it

I see this is quite a big task though, since we'd have to update a lot of cards in cards.txt (also new cards added?).
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Fix for Flowstone Giant suicide
by Rob Cashwalker » 09 Jan 2009, 21:46
As I went through the CardFactory for the 1/8 beta, I only saw a handful of explicitly coded cards that I had done with the expanded pump keywords....
The SSP_ code was the wrong avenue of attack - it's very simple, but difficult to know where to stick new cards in. The post I linked to should cover almost all cards Forge added with his pump keyword, it should replace all the SSP_ defined cards, and probably has a few extras. It is still not updated for alara, but I'm sure someone else here is helping to keep up with adding newly released cards.
The SSP_ code was the wrong avenue of attack - it's very simple, but difficult to know where to stick new cards in. The post I linked to should cover almost all cards Forge added with his pump keyword, it should replace all the SSP_ defined cards, and probably has a few extras. It is still not updated for alara, but I'm sure someone else here is helping to keep up with adding newly released cards.
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Fix for Flowstone Giant suicide
by Chris H. » 09 Jan 2009, 22:35
This is starting to get a little over my head. I guess we would first add Rob's code and release a new beta. At that point someone (me?DennisBergkamp wrote:I see this is quite a big task though, since we'd have to update a lot of cards in cards.txt (also new cards added?).

-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Fix for Flowstone Giant suicide
by DennisBergkamp » 10 Jan 2009, 17:26
Exactly, I haven't added Rob's code yet though, I'm still in the process of finishing up some new cards first. After I finish those I'll attempt to add his code in. I've already looked at it, for some of the things it's a little unclear what to replace exactly, but I'll give it a shot.This is starting to get a little over my head. I guess we would first add Rob's code and release a new beta. At that point someone (me?) could slowly go through the cards.txt file and concentrate on updating the existing pump creatures. Once we had a stable cards.txt file with the previous released cards we could have someone(s) add new cards to card.txt and card-pictures.txt.
At that point, yes it would be awesome if someone else could update the cards.txt file

-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Fix for Flowstone Giant suicide
by Chris H. » 10 Jan 2009, 19:09
Your and jpb's current crop of code repairs plus a few new cards will get us to the point where you could release a fairly stable beta. That should keep the people on the sidelines happy.DennisBergkamp wrote:Exactly, I haven't added Rob's code yet though, I'm still in the process of finishing up some new cards first. After I finish those I'll attempt to add his code in. I've already looked at it, for some of the things it's a little unclear what to replace exactly, but I'll give it a shot.This is starting to get a little over my head. I guess we would first add Rob's code and release a new beta. At that point someone (me?) could slowly go through the cards.txt file and concentrate on updating the existing pump creatures. Once we had a stable cards.txt file with the previous released cards we could have someone(s) add new cards to card.txt and card-pictures.txt.
At that point, yes it would be awesome if someone else could update the cards.txt file
You and Rob could exchange a few privs about his version of the pump code. At some point Rob's code will be ready for an Alpha release. Rob can let us know if his code would require modifications to the existing cards.txt file.
With the cards.txt file corrected to work with Rob's version of the pump code work could then start on adding additional new cards via the new versions of the pump keyword. I could take a portion of the alphabet. Gando, would you be interested in taking on a slice of this?
-
Chris H. - Forge Moderator
- Posts: 6320
- Joined: 04 Nov 2008, 12:11
- Location: Mac OS X Yosemite
- Has thanked: 644 times
- Been thanked: 643 times
Re: Fix for Flowstone Giant suicide
by Rob Cashwalker » 11 Jan 2009, 18:27
The post I referenced should already contain all the self-pump cards that used pump or were defined in SSP_ code. There may have been a few Alara cards added since.
I'll clarify the changes here, based on the source from the 1/8 release:
In CardFactory, replace:
I'll clarify the changes here, based on the source from the 1/8 release:
In CardFactory, replace:
- Code: Select all
// -1 means "Pump" is not found
// any other int means that "Pump" was found in the Card keyword
private final int shouldPumpCard(Card c) {
ArrayList a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if (a.get(i).toString().startsWith("Pump"))
return i;
return -1;
}
- Code: Select all
//self-targeted power and/or toughness pumping abilities
//-1 means "PTPump" is not found
//any other int means that "PTPump" was found in the Card keyword
private final int shouldPTPumpCard(Card c)
{
ArrayList a = c.getKeyword();
for(int i = 0; i < a.size(); i++)
if(a.get(i).toString().startsWith("PTPump"))
return i;
return -1;
}
//same thing, for "KPump" - self-targeted keyword adding abilities
private final int shouldKPumpCard(Card c)
{
ArrayList a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if(a.get(i).toString().startsWith("KPump"))
return i;
return -1;
}
//same thing, for "PTKPump" - self-targeted power and/or toughness pumping
//plus keyword adding abilities
private final int shouldPTKPumpCard(Card c)
{
ArrayList a = c.getKeyword();
for (int i = 0; i < a.size(); i++)
if(a.get(i).toString().startsWith("PTKPump"))
return i;
return -1;
}
- Code: Select all
//is the card "self pumper" like Furnance Whelp - this card gets +1/+1 until end of turn?
//-1 means not found
while(shouldPumpCard(card) != -1)
{
int n = shouldPumpCard(card);
if(n != -1)
{
String parse = card.getKeyword().get(n).toString();
card.removeKeyword(parse);
final int attack[] = new int[1];
final int defense[] = new int[1];
attack[0] = Integer.parseInt(parse.substring(8,9));
defense[0] = Integer.parseInt(parse.substring(10,11));
final String manaCost = parse.substring(5,6);
final Command untilEOT = new Command()
{
public void execute()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.setAttack(card.getAttack() - attack[0]);
card.setDefense(card.getDefense() - defense[0]);
}
}
};
SpellAbility ability = new Ability_Activated(card, manaCost)
{
public boolean canPlayAI() {return CardFactoryUtil.AI_doesCreatureAttack(card);}
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.setAttack(card.getAttack() + attack[0]);
card.setDefense(card.getDefense() + defense[0]);
AllZone.EndOfTurn.addUntil(untilEOT);
}
}
};
ability.setDescription(manaCost + " : " +cardName +" gets +" +attack[0] +"/+" +defense[0] +" until end of turn.");
ability.setStackDescription(cardName +" gets +" +attack[0] +"/+" +defense[0] +" until end of turn.");
card.addSpellAbility(ability);
}//if (should pump card)
}//while - card has more pump keywords - Blistering Dieflyn has two pump keywords
- Code: Select all
//Creatures with simple, self-targeted mana-activated keyword adding abilities
//-1 means not found
while(shouldKPumpCard(card) != -1)
{
int n = shouldKPumpCard(card);
if(n != -1)
{
String parse = card.getKeyword().get(n).toString();
card.removeKeyword(parse);
String k[] = parse.split(":");
final String manaCost = k[0].substring(6);
final String keyword = k[1];
final Command untilEOT = new Command()
{
public void execute()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.removeKeyword(keyword);
}
}
};
SpellAbility ability = new Ability_Activated(card, manaCost)
{
public boolean canPlayAI() {return CardFactoryUtil.AI_doesCreatureAttack(card);}
public boolean canPlay()
{
return CardFactoryUtil.canUseAbility(card);
}
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.addKeyword(keyword);
card.abilityUsed++;
AllZone.EndOfTurn.addUntil(untilEOT);
}
}
};
String Desc = new String();
Desc = cardName + " gains " + keyword + " until end of turn.";
ability.setDescription(manaCost + " : " + Desc);
ability.setStackDescription(Desc);
card.addSpellAbility(ability);
}//if (should pump card)
}//while - card has more pump keywords - Blistering Dieflyn has two pump keywords
//Creatures with simple, self-targeted mana-activated power and/or toughness
//pumping abilities
//is the card "self pumper" like Furnance Whelp - this card gets +1/+1 until end of turn?
//-1 means not found
while(shouldPTPumpCard(card) != -1)
{
int n = shouldPTPumpCard(card);
if(n != -1)
{
String parse = card.getKeyword().get(n).toString();
card.removeKeyword(parse);
final int attack[] = new int[1];
final int defense[] = new int[1];
String k[] = parse.split(":");
String pt[] = k[1].split("/");
final String manaCost = k[0].substring(7);
attack[0] = Integer.parseInt(pt[0]);
defense[0] = Integer.parseInt(pt[1]);
final Command untilEOT = new Command()
{
public void execute()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.setAttack(card.getAttack() - attack[0]);
card.setDefense(card.getDefense() - defense[0]);
}
}
};
SpellAbility ability = new Ability_Activated(card, manaCost)
{
public boolean canPlayAI()
{
if (card.getDefense() + defense[0] < 1) // no point if it would kill the creature outright
return false;
return CardFactoryUtil.AI_doesCreatureAttack(card);
}
public boolean canPlay()
{
return CardFactoryUtil.canUseAbility(card);
}
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.setAttack(card.getAttack() + attack[0]);
card.setDefense(card.getDefense() + defense[0]);
card.abilityUsed++;
AllZone.EndOfTurn.addUntil(untilEOT);
}
}
};
String Desc = new String();
Desc = cardName + " gets ";
if (attack[0] > 0)
Desc = Desc + "+" + attack[0];
else
Desc = Desc + attack[0];
Desc = Desc + "/";
if (defense[0] > 0)
Desc = Desc + "+" + defense[0];
else
Desc = Desc + defense[0];
Desc = Desc + " until end of turn.";
ability.setDescription(manaCost + " : " + Desc);
ability.setStackDescription(Desc);
card.addSpellAbility(ability);
}//if (should pump card)
}//while - card has more pump keywords - Blistering Dieflyn has two pump keywords
//Creatures with simple, self-targeted mana-activated power and/or toughness
//pumping plus keyword adding abilities
//is the card "self pumper" like Furnance Whelp - this card gets +1/+1 until end of turn?
//-1 means not found
while(shouldPTKPumpCard(card) != -1)
{
int n = shouldPTKPumpCard(card);
if(n != -1)
{
String parse = card.getKeyword().get(n).toString();
card.removeKeyword(parse);
final int attack[] = new int[1];
final int defense[] = new int[1];
String k[] = parse.split(":");
String ptk[] = k[1].split("/");
final String manaCost = k[0].substring(8);
attack[0] = Integer.parseInt(ptk[0]);
defense[0] = Integer.parseInt(ptk[1]);
final String keyword = ptk[2];
final Command untilEOT = new Command()
{
public void execute()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.removeKeyword(keyword);
card.setAttack(card.getAttack() - attack[0]);
card.setDefense(card.getDefense() - defense[0]);
}
}
};
SpellAbility ability = new Ability_Activated(card, manaCost)
{
public boolean canPlayAI()
{
if (card.getDefense() + defense[0] < 1) // no point if it would kill the creature outright
return false;
return CardFactoryUtil.AI_doesCreatureAttack(card);
}
public boolean canPlay()
{
return CardFactoryUtil.canUseAbility(card);
}
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.addKeyword(keyword);
card.setAttack(card.getAttack() + attack[0]);
card.setDefense(card.getDefense() + defense[0]);
card.abilityUsed++;
AllZone.EndOfTurn.addUntil(untilEOT);
}
}
};
String Desc = new String();
Desc = cardName + " gets ";
if (attack[0] > 0)
Desc = Desc + "+" + attack[0];
else
Desc = Desc + attack[0];
Desc = Desc + "/";
if (defense[0] > 0)
Desc = Desc + "+" + defense[0];
else
Desc = Desc + defense[0];
Desc = Desc + " and gains " + keyword + " until end of turn.";
ability.setDescription(manaCost + " : " + Desc);
ability.setStackDescription(Desc);
card.addSpellAbility(ability);
}//if (should pump card)
}//while - card has more pump keywords - Blistering Dieflyn has two pump keywords
- Code: Select all
///////////////////////////////////////////////////////////////
//processes the cards in CardFactoryUtil.SSP_CardInList()
//this is going to be a long method so hold onto your hat
if(CardFactoryUtil.SSP_CardInList(cardName))
{
//basically we are trying to construct an activated ability using SpellAbility
//then that SpellAbility will be added to the card
final int attack[] = new int[1];
final int defense[] = new int[1];
final String keyword[] = new String[1];
attack[0] = CardFactoryUtil.SSP_getPowerBoost(cardName);
defense[0] = CardFactoryUtil.SSP_getToughBoost(cardName);
keyword[0] = CardFactoryUtil.SSP_getKeywordBoost(cardName);
final Command untilEOT = new Command()
{
public void execute()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.setAttack(card.getAttack() - attack[0]);
card.setDefense(card.getDefense() - defense[0]);
if(keyword[0] != null)
card.removeKeyword(keyword[0]);
}
}
};
String manaCost = CardFactoryUtil.SSP_getBoostCost(cardName);
SpellAbility ability = new Ability_Hand(card, manaCost)
{
public boolean canPlay()
{
//is this card in play?
PlayerZone zone = AllZone.getZone(getSourceCard());
boolean inPlay = zone.is(Constant.Zone.Play, getSourceCard().getController());
return inPlay && CardFactoryUtil.SSP_canPlay(card);
}
public boolean canPlayAI() {return CardFactoryUtil.AI_doesCreatureAttack(card);}
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.setAttack(card.getAttack() + attack[0]);
card.setDefense(card.getDefense() + defense[0]);
if(keyword[0] != null)
card.addKeyword(keyword[0]);
AllZone.EndOfTurn.addUntil(untilEOT);
}
}
};
if(keyword[0] != null)
{
//card gets keyword until end of turn
ability.setDescription(manaCost + " : " +cardName +" gets " +keyword[0] +" until end of turn.");
ability.setStackDescription(cardName +" gets " +keyword[0] +" until end of turn.");
}
else
{
//card gets +x/+x until end of turn
ability.setDescription(manaCost + " : " +cardName +" gets " +CardFactoryUtil.getPumpString(attack[0]) +"/" +CardFactoryUtil.getPumpString(defense[0]) +" until end of turn.");
ability.setStackDescription(cardName +" gets " +CardFactoryUtil.getPumpString(attack[0]) +"/" +CardFactoryUtil.getPumpString(defense[0]) +" until end of turn.");
}
card.addSpellAbility(ability);
return card;
}//if (CardFactoryUtil.SSP_CardInList(cardName))
- Code: Select all
// Simple Self Pumpers (SSP_)
public final static boolean SSP_CardInList(String cardName)
{
return
(
cardName.equals("Breathstealer") ||
cardName.equals("Azimaet Drake") ||
cardName.equals("Cavern Crawler") || cardName.equals("Cobalt Golem") ||
cardName.equals("Dauthi Mercenary") || cardName.equals("Deeptread Merrow") ||
cardName.equals("Drake Hatchling") ||
cardName.equals("Ebony Treefolk") || cardName.equals("Enslaved Scout") ||
cardName.equals("Fire Drake") ||
cardName.equals("Flowstone Crusher") || cardName.equals("Flowstone Giant") ||
cardName.equals("Flowstone Hellion") || cardName.equals("Flowstone Mauler") || cardName.equals("Flowstone Shambler") ||
cardName.equals("Flowstone Thopter") || cardName.equals("Flowstone Wall") || cardName.equals("Flowstone Wyvern") ||
cardName.equals("Folk of the Pines") ||
cardName.equals("Glintwing Invoker") ||
cardName.equals("Hematite Golem") ||
cardName.equals("Henge Guardian") ||
cardName.equals("Hooded Kavu") || cardName.equals("Igneous Golem") ||
cardName.equals("Kitsune Loreweaver") ||
cardName.equals("Lionheart Maverick") || cardName.equals("Llanowar Cavalry") ||
cardName.equals("Malachite Golem") ||
cardName.equals("Mesa Falcon") ||
cardName.equals("Patagia Golem") || cardName.equals("Pavel Maliki") || cardName.equals("Pearl Dragon") ||
cardName.equals("Phyrexian Battleflies") || cardName.equals("Pit Imp") || cardName.equals("Plated Rootwalla") ||
cardName.equals("River Merfolk") || cardName.equals("Roofstalker Wight") ||
cardName.equals("Rootwalla") || cardName.equals("Roterothopter") ||
cardName.equals("Serpentine Kavu") || cardName.equals("Shambling Strider") ||
cardName.equals("Soltari Crusader") || cardName.equals("Soltari Emissary") || cardName.equals("Spitting Drake") ||
cardName.equals("Stonewood Invoker") ||
cardName.equals("Torch Drake") ||
cardName.equals("Vampire Bats") || cardName.equals("Viashino Grappler") ||
cardName.equals("Wall of Fire") || cardName.equals("Wall of Lava") ||
cardName.equals("Wall of Opposition") || cardName.equals("Wall of Water") ||
cardName.equals("Yavimaya Ancients"));
} // SSP_CardInList(cardName)
public static String SSP_getBoostCost(String cardName)
{
// W:
if (cardName.equals("Aven Flock") || cardName.equals("Capashen Templar") || cardName.equals("Honor Guard") ||
cardName.equals("Kjeldoran Outrider") || cardName.equals("Llanowar Cavalry") || cardName.equals("Loxodon Stalwart") ||
cardName.equals("Moonwing Moth") || cardName.equals("Soltari Emissary") || cardName.equals("Tower Drake"))
return "W";
// U:
if (cardName.equals("Azimaet Drake") || cardName.equals("Deeptread Merrow") || cardName.equals("Drake Hatchling") ||
cardName.equals("Killer Whale") || cardName.equals("Manta Riders") || cardName.equals("Sea Spirit") ||
cardName.equals("Thunder Wall") || cardName.equals("Wall of Water") || cardName.equals("Whiptongue Frog")
|| cardName.equals("River Merfolk"))
return "U";
// B:
if (cardName.equals("Balshan Collaborator") || cardName.equals("Breathstealer") || cardName.equals("Dirtwater Wraith") ||
cardName.equals("Dungeon Shade") || cardName.equals("Fetid Horror") || cardName.equals("Frozen Shade") ||
cardName.equals("Hoar Shade") || cardName.equals("Hooded Kavu") || cardName.equals("Looming Shade") ||
cardName.equals("Nantuko Shade") || cardName.equals("Phyrexian Battleflies") || cardName.equals("Pit Imp") ||
cardName.equals("Primeval Shambler") || cardName.equals("Undercity Shade") || cardName.equals("Vampire Bats") ||
cardName.equals("Whispering Shade"))
return "B";
// R:
if (cardName.equals("Angelfire Crusader") || cardName.equals("Cavern Crawler") ||
cardName.equals("Colos Yearling") || cardName.equals("Fire Drake") || cardName.equals("Firefly") ||
cardName.equals("Firescreamer") || cardName.equals("Flame Spirit") || cardName.equals("Flamekin Brawler") ||
cardName.equals("Flowstone Crusher") || cardName.equals("Flowstone Giant") || cardName.equals("Flowstone Mauler") ||
cardName.equals("Flowstone Shambler") || cardName.equals("Flowstone Wall") || cardName.equals("Flowstone Wyvern") ||
cardName.equals("Furnace Spirit") || cardName.equals("Furnace Whelp") || cardName.equals("Goblin Balloon Brigade") ||
cardName.equals("Granite Gargoyle") || cardName.equals("Pygmy Pyrosaur") || cardName.equals("Pyre Charger") ||
cardName.equals("Ridgeline Rager") || cardName.equals("Serpentine Kavu") || cardName.equals("Shivan Dragon") ||
cardName.equals("Spitting Drake") || cardName.equals("Steam Spitter") || cardName.equals("Storm Shaman") ||
cardName.equals("Viashino Slasher") || cardName.equals("Wall of Fire") || cardName.equals("Wall of Lava"))
return "R";
// G:
if (cardName.equals("Killer Bees") || cardName.equals("Viashino Grappler") || cardName.equals("Yavimaya Ancients"))
return "G";
// 1:
if (cardName.equals("Adarkar Sentinel") || cardName.equals("Carrion Ants") || cardName.equals("Flowstone Thopter") ||
cardName.equals("Wall of Opposition"))
return "1";
// 1W:
if (cardName.equals("Kitsune Loreweaver") || cardName.equals("Mesa Falcon") || cardName.equals("Pearl Dragon") ||
cardName.equals("Soltari Crusader"))
return "1 W";
// 1U:
if (cardName.equals("Cobalt Golem") || cardName.equals("Roofstalker Wight"))
return "1 U";
// 1B:
if (cardName.equals("Dauthi Mercenary"))
return "1 B";
// 1R:
if (cardName.equals("Greater Forgeling") || cardName.equals("Hematite Golem") || cardName.equals("Torch Drake"))
return "1 R";
// 1G:
if (cardName.equals("Folk of the Pines") || cardName.equals("Malachite Golem") || cardName.equals("Rootwalla"))
return "1 G";
// BR:
if (cardName.equals("Pavel Maliki"))
return "B R";
// BG:
if (cardName.equals("Ebony Treefolk"))
return "B G";
// RG:
if (cardName.equals("Shambling Strider"))
return "R G";
// 2:
if (cardName.equals("Dragon Engine") || cardName.equals("Enslaved Scout") || cardName.equals("Henge Guardian") ||
cardName.equals("Igneous Golem") || cardName.equals("Roterothopter"))
return "2";
// 2G:
if (cardName.equals("Plated Rootwalla"))
return "2 G";
// 3:
if (cardName.equals("Patagia Golem"))
return "3";
// 4W:
if (cardName.equals("Lionheart Maverick"))
return "4 W";
// 7U:
if (cardName.equals("Glintwing Invoker"))
return "7 U";
// 7G:
if (cardName.equals("Stonewood Invoker"))
return "7 G";
return "0";
} // SSP_getBoostCost(cardName, card)
public static int SSP_getPowerBoost(String cardName)
{
// +1/
if (cardName.equals("Angelfire Crusader") || cardName.equals("Azimaet Drake") ||
cardName.equals("Balshan Collaborator") || cardName.equals("Breathstealer") || cardName.equals("Carrion Ants") ||
cardName.equals("Cavern Crawler") || cardName.equals("Colos Yearling") || cardName.equals("Dauthi Mercenary") ||
cardName.equals("Dirtwater Wraith") || cardName.equals("Dragon Engine") || cardName.equals("Drake Hatchling") ||
cardName.equals("Dungeon Shade") || cardName.equals("Ebony Treefolk") || cardName.equals("Fetid Horror") ||
cardName.equals("Fire Drake") || cardName.equals("Firefly") || cardName.equals("Firescreamer") ||
cardName.equals("Flame Spirit") || cardName.equals("Flamekin Brawler") || cardName.equals("Flowstone Crusher") ||
cardName.equals("Flowstone Hellion") || cardName.equals("Flowstone Mauler") || cardName.equals("Flowstone Shambler") ||
cardName.equals("Flowstone Thopter") || cardName.equals("Flowstone Wall") || cardName.equals("Folk of the Pines") ||
cardName.equals("Frozen Shade") || cardName.equals("Furnace Spirit") || cardName.equals("Furnace Whelp") ||
cardName.equals("Hoar Shade") || cardName.equals("Killer Bees") || cardName.equals("Lionheart Maverick") ||
cardName.equals("Looming Shade") || cardName.equals("Nantuko Shade") || cardName.equals("Pavel Maliki") ||
cardName.equals("Phyrexian Battleflies") || cardName.equals("Pit Imp") || cardName.equals("Primeval Shambler") ||
cardName.equals("Pygmy Pyrosaur") || cardName.equals("Pyre Charger") || cardName.equals("Ridgeline Rager") ||
cardName.equals("Roterothopter") || cardName.equals("Sea Spirit") || cardName.equals("Shambling Strider") ||
cardName.equals("Shivan Dragon") || cardName.equals("Soltari Crusader") || cardName.equals("Spitting Drake") ||
cardName.equals("Steam Spitter") || cardName.equals("Storm Shaman") || cardName.equals("Thunder Wall") ||
cardName.equals("Torch Drake") || cardName.equals("Undercity Shade") || cardName.equals("Vampire Bats") ||
cardName.equals("Viashino Slasher") || cardName.equals("Wall of Fire") || cardName.equals("Wall of Lava") ||
cardName.equals("Wall of Opposition") || cardName.equals("Wall of Water") || cardName.equals("Whispering Shade") ||
cardName.equals("Yavimaya Ancients"))
return 1;
// +2/
if (cardName.equals("Flowstone Giant") || cardName.equals("Flowstone Wyvern") || cardName.equals("Hematite Golem") ||
cardName.equals("Rootwalla") || cardName.equals("Breathstealer") || cardName.equals("Carrion Ants"))
return 2;
// +3
if (cardName.equals("Glintwing Invoker") || cardName.equals("Greater Forgeling") || cardName.equals("Plated Rootwalla"))
return 3;
// +5
if (cardName.equals("Stonewood Invoker"))
return 5;
return 0;
} // SSP_getPowerBoost(cardName, card)
public static int SSP_getToughBoost(String cardName)
{
// /+1
if (cardName.equals("Adarkar Sentinel") || cardName.equals("Aven Flock") || cardName.equals("Balshan Collaborator") ||
cardName.equals("Capashen Templar") || cardName.equals("Carrion Ants") || cardName.equals("Dungeon Shade") ||
cardName.equals("Ebony Treefolk") || cardName.equals("Fetid Horror") || cardName.equals("Frozen Shade") ||
cardName.equals("Granite Gargoyle") || cardName.equals("Hoar Shade") || cardName.equals("Honor Guard") ||
cardName.equals("Killer Bees") || cardName.equals("Kjeldoran Outrider") || cardName.equals("Looming Shade") ||
cardName.equals("Loxodon Stalwart") || cardName.equals("Mesa Falcon") || cardName.equals("Moonwing Moth") ||
cardName.equals("Nantuko Shade") || cardName.equals("Pearl Dragon") || cardName.equals("Primeval Shambler") ||
cardName.equals("Thunder Wall") || cardName.equals("Tower Drake") || cardName.equals("Undercity Shade") ||
cardName.equals("Wall of Lava") || cardName.equals("Whispering Shade"))
return 1;
// /+2
if (cardName.equals("Lionheart Maverick") || cardName.equals("Rootwalla"))
return 2;
// /+3
if (cardName.equals("Glintwing Invoker") || cardName.equals("Plated Rootwalla"))
return 3;
// /+5
if (cardName.equals("Stonewood Invoker"))
return 5;
// /-1
if (cardName.equals("Breathstealer") || cardName.equals("Cavern Crawler") || cardName.equals("Flowstone Crusher") ||
cardName.equals("Flowstone Hellion") || cardName.equals("Flowstone Mauler") || cardName.equals("Flowstone Shambler") ||
cardName.equals("Flowstone Thopter") || cardName.equals("Flowstone Wall") || cardName.equals("Shambling Strider") ||
cardName.equals("Viashino Slasher"))
return -1;
// /-2
if (cardName.equals("Flowstone Giant") || cardName.equals("Flowstone Wyvern") || cardName.equals("Yavimaya Ancients"))
return -2;
// /-3
if (cardName.equals("Greater Forgeling"))
return -3;
return 0;
} // SSP_getToughBoost(cardName, card)
public static String SSP_getKeywordBoost(String cardName)
{
// Flying
if (cardName.equals("Cobalt Golem") || cardName.equals("Flowstone Thopter") || cardName.equals("Glintwing Invoker") ||
cardName.equals("Goblin Balloon Brigade") || cardName.equals("Killer Whale") || cardName.equals("Manta Riders") ||
cardName.equals("Patagia Golem") || cardName.equals("Roofstalker Wight") || cardName.equals("Roofastalker Wight"))
return "Flying";
// Trample
if (cardName.equals("Henge Guardian") || cardName.equals("Igneous Golem") ||
cardName.equals("Malachite Golem") || cardName.equals("Viashino Grappler"))
return "Trample";
// Fear
if (cardName.equals("Hooded Kavu"))
return "Fear";
// Mountainwalk
if (cardName.equals("Enslaved Scout") || cardName.equals("River Merfolk"))
return "Mountainwalk";
// Islandwalk
if (cardName.equals("Deeptread Merrow"))
return "Islandwalk";
// Vigilance
if (cardName.equals("Llanowar Cavalry"))
return "Vigilance";
// Haste
if (cardName.equals("Serpentine Kavu"))
return "Haste";
// Shadow
if (cardName.equals("Soltari Emissary"))
return "Shadow";
return null;
} // SSP_getKeywordBoost(cardName, card)
- Code: Select all
// Some abilities have use-per-turn limits
// [0][0] - Number of unique cards being tracked
// [1+][0] - Unique Number
// [1+][1] - Last Turn Resolved
// [1+][2] - Resolutions This Turn
private static int SSP_TurnCounts[][] = new int[256][2];
//yes this is more hacky code
//Object[0] is the cardname
//Object[1] is the max number of times it can be used per turn
//Object[1] has to be an Object like Integer and not just an int
private static Object[][] limitAbility =
{
{"Azimaet Drake" , new Integer(1)},
{"Drake Hatchling" , new Integer(1)},
{"Fire Drake" , new Integer(1)},
{"Plated Rootwalla" , new Integer(1)},
{"Rootwalla" , new Integer(1)},
{"Spitting Drake" , new Integer(1)},
{"Phyrexian Battleflies" , new Integer(2)},
{"Pit Imp" , new Integer(2)},
{"Roterothopter" , new Integer(2)},
{"Vampire Bats" , new Integer(2)},
};
public static boolean SSP_canPlay(Card card)
{
int found = -1;
//try to find card name in limitAbility[][]
for(int i = 0; i < limitAbility.length; i++)
if(limitAbility[i][0].equals(card.getName()))
found = i;
if(found == -1)
return true;
//card was found
if(card.abilityTurnUsed != AllZone.Phase.getTurn())
{
card.abilityTurnUsed = AllZone.Phase.getTurn();
card.abilityUsed = 0;
}
card.abilityUsed++;
Integer check = (Integer) limitAbility[found][1];
return card.abilityUsed <= check.intValue();
}//SSP_canPlay(Card card)
public static boolean SSP_canCreatureUseAbility(String cardName, Card card)
{
for (int i=1; i <= SSP_TurnCounts[0][0]; i++)
{
if (SSP_TurnCounts[i][0] == card.getUniqueNumber())
if (SSP_TurnCounts[i][1] == AllZone.Phase.getTurn())
// once per turn
if (cardName.equals("Azimaet Drake") || cardName.equals("Drake Hatchling") ||
cardName.equals("Fire Drake") || cardName.equals("Plated Rootwalla") ||
cardName.equals("Rootwalla") || cardName.equals("Spitting Drake"))
return SSP_TurnCounts[i][2] < 1;
// twice per turn
if (cardName.equals("Phyrexian Battleflies") || cardName.equals("Pit Imp") ||
cardName.equals("Roterothopter") || cardName.equals("Vampire Bats"))
return SSP_TurnCounts[i][2] < 2;
else
{
SSP_TurnCounts[i][2] = 0;
return true;
}
}
return true;
}
public static void SSP_ResolveTurnCount(Card card)
{
for (int i = 1; i <= SSP_TurnCounts[0][0]; i++)
{
if (SSP_TurnCounts[i][0] == card.getUniqueNumber())
{
SSP_TurnCounts[i][1] = AllZone.Phase.getTurn();
SSP_TurnCounts[i][2]++;
return;
}
}
SSP_TurnCounts[0][0]++;
SSP_TurnCounts[SSP_TurnCounts[0][0]][0] = card.getUniqueNumber();
SSP_TurnCounts[SSP_TurnCounts[0][0]][1] = AllZone.Phase.getTurn();
SSP_TurnCounts[SSP_TurnCounts[0][0]][2] = 1;
}
- Code: Select all
//yes this is more hacky code
//Object[0] is the cardname
//Object[1] is the max number of times it can be used per turn
//Object[1] has to be an Object like Integer and not just an int
private static Object[][] AbilityLimits =
{
{"Azimaet Drake" , new Integer(1)},
{"Drake Hatchling" , new Integer(1)},
{"Fire Drake" , new Integer(1)},
{"Plated Rootwalla" , new Integer(1)},
{"Rootwalla" , new Integer(1)},
{"Spitting Drake" , new Integer(1)},
{"Phyrexian Battleflies" , new Integer(2)},
{"Pit Imp" , new Integer(2)},
{"Roterothopter" , new Integer(2)},
{"Vampire Bats" , new Integer(2)},
};
public static boolean canUseAbility(Card card)
{
int found = -1;
//try to find card name in AbilityLimits[][]
for(int i = 0; i < AbilityLimits.length; i++)
if(AbilityLimits[i][0].equals(card.getName()))
found = i;
if(found == -1)
return true;
//card was found
if(card.abilityTurnUsed != AllZone.Phase.getTurn())
{
card.abilityTurnUsed = AllZone.Phase.getTurn();
card.abilityUsed = 0;
}
Integer check = (Integer) AbilityLimits[found][1];
return card.abilityUsed <= check.intValue();
}//canUseAbility(Card card)
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Fix for Flowstone Giant suicide
by DennisBergkamp » 14 Jan 2009, 03:59
Rob,
Alright, I replaced all of those but I'm running into a few bugs. As a test case, I used:
Azimaet Drake
2 U
Creature Drake
Play this ability only once each turn.
1/3
Flying
PTPump U:+1/+0
However, when I run compile + run, I get the following error:
Azimaet Drake
2 U
Creature Drake
Play this ability only once each turn.
1/3
Flying
PTPump U:1/0
Things run fine, but then once I start playing with a test deck containing Azimaet Drakes, I can pump the card in my hand (I see the two options: "Azimaet Drake - Creature 1/3" and "U: Azimaet Drake gets +1/0 until end of turn." ).
And if I do play the card, I am able to play its pump ability twice each turn (instead of just once).
EDIT: even worse, I'm able to use its ability as many times as I want, if I put the pump on the stack, and respond to it by pumping again.
Alright, I replaced all of those but I'm running into a few bugs. As a test case, I used:
Azimaet Drake
2 U
Creature Drake
Play this ability only once each turn.
1/3
Flying
PTPump U:+1/+0
However, when I run compile + run, I get the following error:
Something goes wrong with the parseInt, I guess. If I change it to:
Azimaet Drake
2 U
Creature Drake
Play this ability only once each turn.
1/3
Flying
PTPump U:1/0
Things run fine, but then once I start playing with a test deck containing Azimaet Drakes, I can pump the card in my hand (I see the two options: "Azimaet Drake - Creature 1/3" and "U: Azimaet Drake gets +1/0 until end of turn." ).
And if I do play the card, I am able to play its pump ability twice each turn (instead of just once).
EDIT: even worse, I'm able to use its ability as many times as I want, if I put the pump on the stack, and respond to it by pumping again.
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Fix for Flowstone Giant suicide
by Rob Cashwalker » 14 Jan 2009, 15:29
OK, so that explains the "+" sign not working. I'm thinking that we should leave the "+" in the keyword notation, but filter it before it gets into parseInt.Java docs on parseInt wrote:public static int parseInt(String s)
throws NumberFormatException
Parses the string argument as a signed decimal integer. The characters in the string must all be decimal digits, except that the first character may be an ASCII minus sign '-' ('\u002D') to indicate a negative value.
- Code: Select all
attack[0] = Integer.parseInt(pt[0].replace("+", "");
defense[0] = Integer.parseInt(pt[1].replace("+", "");
- Code: Select all
Input abCheck = new Input()
{
public void showMessage()
{
ability.getSourceCard().abilityUsed++;
if (!CardFactoryUtil.canUseAbility(ability.getSourceCard().card))
{
AllZone.Display.showMessage("This ability can't be used.");
ButtonUtil.enableOnlyCancel();
}
}
public void selectButtonCancel() {stop();}
}
};
ability.setBeforePayMana(abCheck);
- Code: Select all
public void resolve()
{
if(AllZone.GameAction.isCardInPlay(card))
{
card.setAttack(card.getAttack() + attack[0]);
card.setDefense(card.getDefense() + defense[0]);
if (AllZone.Phase.getActivePlayer() == Constant.Player.Computer)
card.abilityUsed++;
AllZone.EndOfTurn.addUntil(untilEOT);
}
}
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Fix for Flowstone Giant suicide
by DennisBergkamp » 14 Jan 2009, 16:28
Rob,
Thanks, I'll give these changes a shot. As for disallowing playing the ability when it's in hand, that should be easy:
Thanks, I'll give these changes a shot. As for disallowing playing the ability when it's in hand, that should be easy:
- Code: Select all
public boolean canPlay()
{
if (CardFactoryUtil.canUseAbility(card) && AllZone.GameAction.isCardInPlay(card))
return true;
else
return false;
}
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
Re: Fix for Flowstone Giant suicide
by Rob Cashwalker » 14 Jan 2009, 17:02
But look at the explicit implementation of Shivan Dragon. There's no hack there to make sure it doesn't try to play from the hand....
The Force will be with you, Always.
-
Rob Cashwalker - Programmer
- Posts: 2167
- Joined: 09 Sep 2008, 15:09
- Location: New York
- Has thanked: 5 times
- Been thanked: 40 times
Re: Fix for Flowstone Giant suicide
by DennisBergkamp » 14 Jan 2009, 17:10
You're right! Very strange, there's not even a canPlay() method in there... so I wonder why I was getting it with Azimaet Drake?
-
DennisBergkamp - AI Programmer
- Posts: 2602
- Joined: 09 Sep 2008, 15:46
- Has thanked: 0 time
- Been thanked: 0 time
38 posts
• Page 1 of 3 • 1, 2, 3
Who is online
Users browsing this forum: No registered users and 36 guests