mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- Initial code to Combine Combat and pwCombat into a unified combat front.
- Human can now attack more than one Planeswalker.
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -6367,9 +6367,7 @@ src/forge/ImagePreviewPanel.java -text svneol=native#text/plain
|
||||
src/forge/Input.java svneol=native#text/plain
|
||||
src/forge/InputControl.java svneol=native#text/plain
|
||||
src/forge/Input_Attack.java svneol=native#text/plain
|
||||
src/forge/Input_Attack_Planeswalker.java svneol=native#text/plain
|
||||
src/forge/Input_Block.java svneol=native#text/plain
|
||||
src/forge/Input_Block_Planeswalker.java svneol=native#text/plain
|
||||
src/forge/Input_Cleanup.java svneol=native#text/plain
|
||||
src/forge/Input_Mulligan.java svneol=native#text/plain
|
||||
src/forge/Input_PassPriority.java -text svneol=native#text/plain
|
||||
|
||||
@@ -346,9 +346,6 @@ public class AbilityFactory_GainControl {
|
||||
CardList list = new CardList(AllZone.Combat.getAttackers());
|
||||
if(list.contains(c)) AllZone.Combat.removeFromCombat(c);
|
||||
|
||||
CardList pwlist = new CardList(AllZone.pwCombat.getAttackers());
|
||||
if(pwlist.contains(c)) AllZone.pwCombat.removeFromCombat(c);
|
||||
|
||||
PlayerZone to = AllZone.getZone(Constant.Zone.Battlefield, c.getOwner());
|
||||
to.add(c);
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ public class AllZone implements NewConstants {
|
||||
//shared between Input_Attack, Input_Block, Input_CombatDamage , InputState_Computer
|
||||
|
||||
public static Combat Combat = new Combat();
|
||||
public static Combat pwCombat = new Combat();//for Planeswalker combat
|
||||
|
||||
//Human_Play, Computer_Play is different because Card.comesIntoPlay() is called when a card is added by PlayerZone.add(Card)
|
||||
public final static PlayerZone Human_Battlefield = new PlayerZone_ComesIntoPlay(Constant.Zone.Battlefield, AllZone.HumanPlayer);
|
||||
|
||||
@@ -2710,14 +2710,11 @@ public class Card extends MyObservable {
|
||||
}
|
||||
|
||||
public boolean isAttacking() {
|
||||
CardList attackers = new CardList(AllZone.Combat.getAttackers());
|
||||
attackers.addAll(AllZone.pwCombat.getAttackers());
|
||||
return attackers.contains(this);
|
||||
return AllZone.Combat.isAttacking(this);
|
||||
}
|
||||
|
||||
public boolean isBlocking() {
|
||||
CardList blockers = AllZone.Combat.getAllBlockers();
|
||||
blockers.add(AllZone.pwCombat.getAllBlockers());
|
||||
return blockers.contains(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -5802,9 +5802,6 @@ public class CardFactory_Creatures {
|
||||
CardList list = new CardList(AllZone.Combat.getAttackers());
|
||||
if(list.contains(c)) AllZone.Combat.removeFromCombat(c);
|
||||
|
||||
CardList pwlist = new CardList(AllZone.pwCombat.getAttackers());
|
||||
if(pwlist.contains(c)) AllZone.pwCombat.removeFromCombat(c);
|
||||
|
||||
PlayerZone to = AllZone.getZone(Constant.Zone.Battlefield, c.getOwner());
|
||||
to.add(c);
|
||||
|
||||
|
||||
@@ -2902,7 +2902,7 @@ class CardFactory_Planeswalkers {
|
||||
{
|
||||
public boolean addCard(Card crd)
|
||||
{
|
||||
return crd.isCreature() && CombatUtil.canAttack(crd);
|
||||
return CombatUtil.canAttack(crd);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -13,31 +13,28 @@ public class Combat {
|
||||
private HashMap<Card, Integer> defendingFirstStrikeDamageMap = new HashMap<Card, Integer>();
|
||||
private HashMap<Card, Integer> defendingDamageMap = new HashMap<Card, Integer>();
|
||||
|
||||
// Defenders are the Defending Player + Each Planeswalker that player controls
|
||||
private ArrayList<Object> defenders = new ArrayList<Object>();
|
||||
private int currentDefender = 0;
|
||||
private int nextDefender = 0;
|
||||
|
||||
// This Hash keeps track of
|
||||
private HashMap<Card, Object> attackerToDefender = new HashMap<Card, Object>();
|
||||
|
||||
private int attackingDamage;
|
||||
// private int defendingDamage;
|
||||
|
||||
// private int defendingFirstStrikeDamage;
|
||||
// private int trampleDamage;
|
||||
// private int trampleFirstStrikeDamage;
|
||||
|
||||
private Player attackingPlayer;
|
||||
private Player defendingPlayer;
|
||||
|
||||
private int declaredAttackers;
|
||||
|
||||
private Card planeswalker;
|
||||
private Player attackingPlayer = null;
|
||||
private Player defendingPlayer = null;
|
||||
|
||||
private CardList attackersWithLure = new CardList();
|
||||
private CardList canBlockAttackerWithLure = new CardList();
|
||||
|
||||
public Combat() {
|
||||
reset();
|
||||
// Let the Begin Turn/Untap Phase Reset Combat properly
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
planeswalker = null;
|
||||
|
||||
map.clear();
|
||||
resetAttackers();
|
||||
blocked.clear();
|
||||
|
||||
unblockedMap.clear();
|
||||
@@ -46,24 +43,70 @@ public class Combat {
|
||||
defendingDamageMap.clear();
|
||||
defendingFirstStrikeDamageMap.clear();
|
||||
|
||||
declaredAttackers = 0;
|
||||
attackingPlayer = null;
|
||||
defendingPlayer = null;
|
||||
|
||||
attackersWithLure = new CardList();
|
||||
canBlockAttackerWithLure = new CardList();
|
||||
attackersWithLure.clear();
|
||||
canBlockAttackerWithLure.clear();
|
||||
|
||||
defenders.clear();
|
||||
currentDefender = 0;
|
||||
nextDefender = 0;
|
||||
|
||||
initiatePossibleDefenders(AllZone.Phase.getPlayerTurn().getOpponent());
|
||||
}
|
||||
|
||||
public void setPlaneswalker(Card c) {
|
||||
planeswalker = c;
|
||||
public void initiatePossibleDefenders(Player defender){
|
||||
defenders.add(defender);
|
||||
CardList planeswalkers = AllZoneUtil.getPlayerCardsInPlay(defender);
|
||||
planeswalkers = planeswalkers.getType("Planeswalker");
|
||||
for(Card pw : planeswalkers)
|
||||
defenders.add(pw);
|
||||
}
|
||||
|
||||
public Card getPlaneswalker() {
|
||||
return planeswalker;
|
||||
public Object nextDefender(){
|
||||
if (nextDefender >= defenders.size())
|
||||
return null;
|
||||
|
||||
currentDefender = nextDefender;
|
||||
nextDefender++;
|
||||
|
||||
return defenders.get(currentDefender);
|
||||
}
|
||||
|
||||
public void setCurrentDefender(int def){
|
||||
currentDefender = def;
|
||||
}
|
||||
|
||||
public int getRemainingDefenders(){
|
||||
return defenders.size() - nextDefender;
|
||||
}
|
||||
|
||||
public ArrayList<Object> getDefenders(){
|
||||
return defenders;
|
||||
}
|
||||
|
||||
public void setDefenders(ArrayList<Object> newDef){
|
||||
defenders = newDef;
|
||||
}
|
||||
|
||||
public Card[] getDefendingPlaneswalkers(){
|
||||
Card[] pwDefending = new Card[defenders.size()-1];
|
||||
|
||||
int i = 0;
|
||||
|
||||
for(Object o : defenders){
|
||||
if (o instanceof Card){
|
||||
pwDefending[i] = (Card)o;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return pwDefending;
|
||||
}
|
||||
|
||||
public int getDeclaredAttackers() {
|
||||
return declaredAttackers;
|
||||
return attackerToDefender.size();
|
||||
}
|
||||
|
||||
public void setAttackingPlayer(Player player) {
|
||||
@@ -162,12 +205,9 @@ public class Combat {
|
||||
damageDealt = att.get(i).getNetDefense();
|
||||
|
||||
if (damageDealt > 0) {
|
||||
// if the creature has first strike do not do damage in the
|
||||
// normal combat phase
|
||||
// if(att.get(i).hasSecondStrike())
|
||||
// if the creature has first strike do not do damage in the normal combat phase
|
||||
if (!att.get(i).hasFirstStrike()
|
||||
|| (att.get(i).hasFirstStrike() && att.get(i)
|
||||
.hasDoubleStrike()))
|
||||
|| (att.get(i).hasFirstStrike() && att.get(i).hasDoubleStrike()))
|
||||
addDefendingDamage(damageDealt, att.get(i));
|
||||
}
|
||||
} // ! isBlocked...
|
||||
@@ -185,8 +225,7 @@ public class Combat {
|
||||
damageDealt = att.get(i).getNetDefense();
|
||||
|
||||
if (damageDealt > 0) {
|
||||
// if the creature has first strike or double strike do
|
||||
// damage in the first strike combat phase
|
||||
// if the creature has first strike or double strike do damage in the first strike combat phase
|
||||
if (att.get(i).hasFirstStrike()
|
||||
|| att.get(i).hasDoubleStrike()) {
|
||||
addDefendingFirstStrikeDamage(damageDealt, att.get(i));
|
||||
@@ -197,6 +236,16 @@ public class Combat {
|
||||
}
|
||||
|
||||
public void addDefendingDamage(int n, Card source) {
|
||||
String slot = getDefenderByAttacker(source).toString();
|
||||
Object o = defenders.get(Integer.parseInt(slot));
|
||||
|
||||
if (o instanceof Card){
|
||||
Card pw = (Card)o;
|
||||
pw.addAssignedDamage(n, source);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defendingDamageMap.containsKey(source))
|
||||
defendingDamageMap.put(source, n);
|
||||
else {
|
||||
@@ -205,11 +254,21 @@ public class Combat {
|
||||
}
|
||||
|
||||
public void addDefendingFirstStrikeDamage(int n, Card source) {
|
||||
String slot = getDefenderByAttacker(source).toString();
|
||||
Object o = defenders.get(Integer.parseInt(slot));
|
||||
|
||||
if (o instanceof Card){
|
||||
Card pw = (Card)o;
|
||||
pw.addAssignedDamage(n, source);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!defendingFirstStrikeDamageMap.containsKey(source))
|
||||
defendingFirstStrikeDamageMap.put(source, n);
|
||||
else {
|
||||
defendingFirstStrikeDamageMap.put(source,
|
||||
defendingFirstStrikeDamageMap.get(source) + n);
|
||||
defendingFirstStrikeDamageMap.get(source) + n);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,19 +280,41 @@ public class Combat {
|
||||
return attackingDamage;
|
||||
}
|
||||
|
||||
public CardList[] sortAttackerByDefender(){
|
||||
CardList attackers[] = new CardList[defenders.size()];
|
||||
for(int i = 0; i < attackers.length; i++)
|
||||
attackers[i] = new CardList();
|
||||
|
||||
for(Card atk : attackerToDefender.keySet()){
|
||||
Object o = attackerToDefender.get(atk);
|
||||
int i = Integer.parseInt(o.toString());
|
||||
attackers[i].add(atk);
|
||||
}
|
||||
|
||||
return attackers;
|
||||
}
|
||||
|
||||
public boolean isAttacking(Card c) {
|
||||
return map.get(c) != null;
|
||||
}
|
||||
|
||||
public void addAttacker(Card c) {
|
||||
map.put(c, new CardList());
|
||||
declaredAttackers++;
|
||||
attackerToDefender.put(c, currentDefender);
|
||||
}
|
||||
|
||||
public Object getDefenderByAttacker(Card c) {
|
||||
return attackerToDefender.get(c);
|
||||
}
|
||||
|
||||
public void resetAttackers() {
|
||||
map.clear();
|
||||
attackerToDefender.clear();
|
||||
}
|
||||
|
||||
public Card[] getAttackers() {
|
||||
CardList out = new CardList();
|
||||
Iterator<Card> it = map.keySet().iterator();
|
||||
// int i = 0; //unused
|
||||
|
||||
while (it.hasNext()) {
|
||||
out.add((Card) it.next());
|
||||
@@ -284,8 +365,10 @@ public class Combat {
|
||||
public void removeFromCombat(Card c) {
|
||||
// is card an attacker?
|
||||
CardList att = new CardList(getAttackers());
|
||||
if (att.contains(c))
|
||||
if (att.contains(c)){
|
||||
map.remove(c);
|
||||
attackerToDefender.remove(c);
|
||||
}
|
||||
else// card is a blocker
|
||||
{
|
||||
for (int i = 0; i < att.size(); i++)
|
||||
@@ -312,8 +395,6 @@ public class Combat {
|
||||
CardList block;
|
||||
CardList attacking = new CardList(getAttackers());
|
||||
for (int i = 0; i < attacking.size(); i++) {
|
||||
// if(attacking.get(i).hasFirstStrike() ||
|
||||
// (attacking.get(i).hasDoubleStrike() )){
|
||||
block = getBlockers(attacking.get(i));
|
||||
|
||||
// attacker always gets all blockers' attack
|
||||
@@ -327,16 +408,12 @@ public class Combat {
|
||||
}
|
||||
}
|
||||
|
||||
if (block.size() == 0)// this damage is assigned to a player by
|
||||
// setPlayerDamage()
|
||||
{
|
||||
// GameActionUtil.executePlayerCombatDamageEffects(attacking.get(i));
|
||||
if (block.size() == 0){
|
||||
// this damage is assigned to a player by setPlayerDamage()
|
||||
addUnblockedAttacker(attacking.get(i));
|
||||
}
|
||||
|
||||
else if (attacking.get(i).hasFirstStrike()
|
||||
|| (attacking.get(i).hasDoubleStrike())) {
|
||||
|
||||
else if (attacking.get(i).hasFirstStrike() || (attacking.get(i).hasDoubleStrike())) {
|
||||
if (block.size() == 1) {
|
||||
if (attacking.get(i).hasFirstStrike()
|
||||
|| attacking.get(i).hasDoubleStrike()) {
|
||||
@@ -371,49 +448,20 @@ public class Combat {
|
||||
addAssignedFirstStrikeDamage(attacking.get(i), block,
|
||||
damageDealt);
|
||||
}
|
||||
} else// human
|
||||
{
|
||||
if (attacking.get(i).hasFirstStrike()
|
||||
|| attacking.get(i).hasDoubleStrike()) {
|
||||
// GuiDisplay2 gui = (GuiDisplay2) AllZone.Display;
|
||||
}
|
||||
else{
|
||||
// human
|
||||
if (attacking.get(i).hasFirstStrike() || attacking.get(i).hasDoubleStrike()) {
|
||||
int damageDealt = attacking.get(i).getNetAttack();
|
||||
if (CombatUtil.isDoranInPlay())
|
||||
damageDealt = attacking.get(i).getNetDefense();
|
||||
AllZone.Display.assignDamage(attacking.get(i), block,
|
||||
damageDealt);
|
||||
AllZone.Display.assignDamage(attacking.get(i), block, damageDealt);
|
||||
|
||||
/*
|
||||
* for (Card b : block) {
|
||||
* AllZone.Display.assignDamage(attacking.get(i), b,
|
||||
* damageDealt);//System.out.println(
|
||||
* "setAssignedFirstStrikeDmg called for:" + damageDealt
|
||||
* + " damage."); }
|
||||
* AllZone.Display.addAssignDamage(attacking
|
||||
* .get(i),damageDealt);
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
}// if(hasFirstStrike || doubleStrike)
|
||||
}// for
|
||||
|
||||
// should first strike affect the following?
|
||||
if (getPlaneswalker() != null) {
|
||||
// System.out.println("defendingDmg (setAssignedFirstStrikeDamage) :"
|
||||
// +defendingFirstStrikeDamage);
|
||||
//
|
||||
|
||||
Iterator<Card> iter = defendingFirstStrikeDamageMap.keySet()
|
||||
.iterator();
|
||||
while (iter.hasNext()) {
|
||||
Card crd = iter.next();
|
||||
planeswalker.addAssignedDamage(defendingFirstStrikeDamageMap
|
||||
.get(crd), crd);
|
||||
}
|
||||
|
||||
defendingFirstStrikeDamageMap.clear();
|
||||
}
|
||||
|
||||
}// setAssignedFirstStrikeDamage()
|
||||
|
||||
private void addAssignedFirstStrikeDamage(Card attacker, CardList block,
|
||||
@@ -449,16 +497,9 @@ public class Combat {
|
||||
CardList block;
|
||||
CardList attacking = new CardList(getAttackers());
|
||||
for (int i = 0; i < attacking.size(); i++) {
|
||||
// if(!attacking.get(i).hasSecondStrike() ){
|
||||
// if(!attacking.get(i).hasFirstStrike() ||
|
||||
// (attacking.get(i).hasFirstStrike() &&
|
||||
// attacking.get(i).hasDoubleStrike() )){
|
||||
block = getBlockers(attacking.get(i));
|
||||
|
||||
// attacker always gets all blockers' attack
|
||||
// attacking.get(i).setAssignedDamage(CardListUtil.sumAttack(block));
|
||||
// AllZone.GameAction.setAssignedDamage(attacking.get(i), block,
|
||||
// CardListUtil.sumAttack(block));
|
||||
|
||||
for (Card b : block) {
|
||||
if (!b.hasFirstStrike()
|
||||
@@ -470,17 +511,12 @@ public class Combat {
|
||||
}
|
||||
}
|
||||
|
||||
if (block.size() == 0)// this damage is assigned to a player by
|
||||
// setPlayerDamage()
|
||||
{
|
||||
// GameActionUtil.executePlayerCombatDamageEffects(attacking.get(i));
|
||||
if (block.size() == 0){
|
||||
// this damage is assigned to a player by setPlayerDamage()
|
||||
addUnblockedAttacker(attacking.get(i));
|
||||
}
|
||||
|
||||
else if (!attacking.get(i).hasFirstStrike()
|
||||
|| (attacking.get(i).hasFirstStrike() && attacking.get(i)
|
||||
.hasDoubleStrike())) {
|
||||
|
||||
else if (!attacking.get(i).hasFirstStrike() || attacking.get(i).hasDoubleStrike()) {
|
||||
if (block.size() == 1) {
|
||||
int damageDealt = attacking.get(i).getNetAttack();
|
||||
if (CombatUtil.isDoranInPlay())
|
||||
@@ -503,70 +539,22 @@ public class Combat {
|
||||
damageDealt = attacking.get(i).getNetDefense();
|
||||
addAssignedDamage(attacking.get(i), block, damageDealt);
|
||||
|
||||
} else// human attacks
|
||||
{
|
||||
// GuiDisplay2 gui = (GuiDisplay2) AllZone.Display;
|
||||
}
|
||||
else{ // human attacks
|
||||
int damageDealt = attacking.get(i).getNetAttack();
|
||||
if (CombatUtil.isDoranInPlay())
|
||||
damageDealt = attacking.get(i).getNetDefense();
|
||||
|
||||
AllZone.Display.assignDamage(attacking.get(i), block,
|
||||
damageDealt);
|
||||
AllZone.Display.assignDamage(attacking.get(i), block, damageDealt);
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
* for (Card b :block)
|
||||
* AllZone.Display.addAssignDamage(attacking.get(i), b,
|
||||
* damageDealt);
|
||||
* //System.out.println("setAssignedDmg called for:" +
|
||||
* damageDealt + " damage.");
|
||||
*/
|
||||
}
|
||||
|
||||
}// if !hasFirstStrike ...
|
||||
// hacky code, to ensure surviving non-first-strike blockers will
|
||||
// hit first strike attackers:
|
||||
/*
|
||||
* else { block = getBlockers(attacking.get(i));
|
||||
* //System.out.println("block size: " + block.size()); if(
|
||||
* (attacking.get(i).hasFirstStrike() ||
|
||||
* attacking.get(i).hasDoubleStrike()) ) { for(int j=0; j <
|
||||
* block.size(); j++) { //blockerDamage +=
|
||||
* block.get(j).getNetAttack(); int damage =
|
||||
* block.get(j).getNetAttack(); if (CombatUtil.isDoranInPlay())
|
||||
* damage = block.get(j).getNetDefense();
|
||||
* AllZone.GameAction.addAssignedDamage(attacking.get(i),
|
||||
* block.get(j), damage); }
|
||||
* //attacking.get(i).setAssignedDamage(blockerDamage);
|
||||
* //AllZone.GameAction.setAssignedDamage(attacking.get(i), block ,
|
||||
* blockerDamage); } }
|
||||
*/
|
||||
}// for
|
||||
|
||||
// should first strike affect the following?
|
||||
if (getPlaneswalker() != null) {
|
||||
// System.out.println("defendingDmg (setAssignedDamage): " +
|
||||
// defendingDamage);
|
||||
Iterator<Card> iter = defendingDamageMap.keySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Card crd = iter.next();
|
||||
planeswalker
|
||||
.addAssignedDamage(defendingDamageMap.get(crd), crd);
|
||||
}
|
||||
defendingDamageMap.clear();
|
||||
}
|
||||
}// assignDamage()
|
||||
|
||||
/*
|
||||
* private void setAssignedDamage(Card attacker, CardList list, int damage)
|
||||
* { CardListUtil.sortAttack(list); Card c; for(int i = 0; i < list.size();
|
||||
* i++) { c = list.get(i); //if(!c.hasFirstStrike() || (c.hasFirstStrike()
|
||||
* && c.hasDoubleStrike()) ){ if(c.getKillDamage() <= damage) { damage -=
|
||||
* c.getKillDamage(); CardList cl = new CardList(); cl.add(attacker);
|
||||
* AllZone.GameAction.addAssignedDamage(c, cl, c.getKillDamage());
|
||||
* //c.setAssignedDamage(c.getKillDamage()); } //} }//for }//assignDamage()
|
||||
*/
|
||||
}// assignDamage()
|
||||
|
||||
private void addAssignedDamage(Card attacker, CardList block, int damage) {
|
||||
Card c = attacker;
|
||||
@@ -617,85 +605,33 @@ public class Combat {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (bFirstStrike){
|
||||
CardList pwAttackers = new CardList(AllZone.pwCombat.getAttackers());
|
||||
CardList pwBlockers = new CardList(AllZone.pwCombat.getAllBlockers().toArray());
|
||||
|
||||
|
||||
for(int i = 0; i < pwAttackers.size(); i++) {
|
||||
if((pwAttackers.getCard(i).hasFirstStrike() || pwAttackers.getCard(i).hasDoubleStrike())) {
|
||||
CombatUtil.executeCombatDamageEffects(pwAttackers.getCard(i));
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < pwBlockers.size(); i++) {
|
||||
if((pwBlockers.getCard(i).hasFirstStrike() || pwBlockers.getCard(i).hasDoubleStrike())) {
|
||||
CombatUtil.executeCombatDamageEffects(pwBlockers.getCard(i));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
//get all attackers and blockers
|
||||
CardList check = new CardList();
|
||||
check.addAll(AllZone.Human_Battlefield.getCards());
|
||||
check.addAll(AllZone.Computer_Battlefield.getCards());
|
||||
|
||||
CardList all = check.getType("Creature");
|
||||
|
||||
if(AllZone.pwCombat.getPlaneswalker() != null) all.add(AllZone.pwCombat.getPlaneswalker());
|
||||
|
||||
|
||||
CardList pwAttackers = new CardList(AllZone.pwCombat.getAttackers());
|
||||
CardList pwBlockers = new CardList(AllZone.pwCombat.getAllBlockers().toArray());
|
||||
|
||||
if (!bFirstStrike){
|
||||
/*
|
||||
for(int i = 0; i < pwAttackers.size(); i++) {
|
||||
//System.out.println("attacker #" + i + ": " + attackers.getCard(i).getName() +" " + attackers.getCard(i).getAttack());
|
||||
if((!pwAttackers.getCard(i).hasFirstStrike() || (pwAttackers.getCard(i).hasFirstStrike() && pwAttackers.getCard(
|
||||
i).hasDoubleStrike()))) {
|
||||
CombatUtil.executeCombatDamageEffects(pwAttackers.getCard(i));
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < pwBlockers.size(); i++) {
|
||||
if((!pwBlockers.getCard(i).hasFirstStrike() || (pwBlockers.getCard(i).hasFirstStrike() && pwBlockers.getCard(
|
||||
i).hasDoubleStrike()))) {
|
||||
CombatUtil.executeCombatDamageEffects(pwBlockers.getCard(i));
|
||||
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//hacky stuff, hope it won't cause any bugs:
|
||||
for(int i = 0; i < pwAttackers.size(); i++) {
|
||||
AllZone.pwCombat.removeFromCombat(pwAttackers.get(i));
|
||||
}
|
||||
|
||||
for(int i = 0; i < pwBlockers.size(); i++) {
|
||||
AllZone.pwCombat.removeFromCombat(pwBlockers.get(i));
|
||||
}
|
||||
}
|
||||
// this can be much better below here...
|
||||
|
||||
CardList combatants = new CardList();
|
||||
combatants.addAll(AllZone.Combat.getAttackers());
|
||||
combatants.add(AllZone.Combat.getAllBlockers());
|
||||
combatants.addAll(AllZone.Combat.getDefendingPlaneswalkers());
|
||||
|
||||
Card c;
|
||||
for(int i = 0; i < all.size(); i++) {
|
||||
c = all.get(i);
|
||||
//because this sets off Jackal Pup, and Filthly Cur damage ability
|
||||
//and the stack says "Jack Pup causes 0 damage to the Computer"
|
||||
if(c.getTotalAssignedDamage() != 0) {
|
||||
HashMap<Card, Integer> assignedDamageMap = c.getAssignedDamageHashMap();
|
||||
HashMap<Card, Integer> damageMap = new HashMap<Card, Integer>();
|
||||
for(int i = 0; i < combatants.size(); i++) {
|
||||
c = combatants.get(i);
|
||||
|
||||
for(Entry<Card, Integer> entry : assignedDamageMap.entrySet()){
|
||||
Card crd = entry.getKey();
|
||||
if(CardFactoryUtil.canDamage(crd, c))
|
||||
damageMap.put(crd, entry.getValue());
|
||||
}
|
||||
c.addCombatDamage(damageMap);
|
||||
// if no assigned damage to resolve, move to next
|
||||
if(c.getTotalAssignedDamage() == 0)
|
||||
continue;
|
||||
|
||||
damageMap.clear();
|
||||
c.clearAssignedDamage();
|
||||
HashMap<Card, Integer> assignedDamageMap = c.getAssignedDamageHashMap();
|
||||
HashMap<Card, Integer> damageMap = new HashMap<Card, Integer>();
|
||||
|
||||
for(Entry<Card, Integer> entry : assignedDamageMap.entrySet()){
|
||||
Card crd = entry.getKey();
|
||||
if(CardFactoryUtil.canDamage(crd, c))
|
||||
damageMap.put(crd, entry.getValue());
|
||||
}
|
||||
c.addCombatDamage(damageMap);
|
||||
|
||||
damageMap.clear();
|
||||
c.clearAssignedDamage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -350,6 +350,7 @@ public class CombatUtil {
|
||||
|
||||
//can a creature attack att all?
|
||||
public static boolean canAttack(Card c) {
|
||||
if (!c.isCreature()) return false;
|
||||
|
||||
if(AllZoneUtil.isCardInPlay("Peacekeeper")) return false;
|
||||
|
||||
@@ -412,7 +413,7 @@ public class CombatUtil {
|
||||
if(allislands.size() < 5) return false;
|
||||
}
|
||||
|
||||
if(c.isTapped() || c.hasSickness()
|
||||
if(c.isTapped() || c.isSick()
|
||||
|| AllZoneUtil.isCardInPlay("Blazing Archon", c.getController().getOpponent())
|
||||
|| c.getKeyword().contains("CARDNAME can't attack.")
|
||||
|| c.getKeyword().contains("CARDNAME can't attack or block.")
|
||||
@@ -459,7 +460,7 @@ public class CombatUtil {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//if Card has Haste, Card.hasSickness() will return false
|
||||
|
||||
return true;
|
||||
}//canAttack()
|
||||
|
||||
@@ -522,10 +523,12 @@ public class CombatUtil {
|
||||
|
||||
//Checks if the life of the attacked Player/Planeswalker is in danger
|
||||
public static boolean lifeInDanger(Combat combat) {
|
||||
// life in danger only cares about the player's life. Not about a Planeswalkers life
|
||||
|
||||
int damage = 0;
|
||||
int poison = 0;
|
||||
CardList attackers = new CardList(combat.getAttackers());
|
||||
|
||||
CardList attackers = combat.sortAttackerByDefender()[0];
|
||||
CardList unblocked = new CardList();
|
||||
CardList blockers = new CardList();
|
||||
Card attacker = new Card();
|
||||
@@ -549,14 +552,7 @@ public class CombatUtil {
|
||||
damage += sumAttack(unblocked, AllZone.ComputerPlayer);
|
||||
poison += sumPoison(unblocked, AllZone.ComputerPlayer);
|
||||
|
||||
if (combat.getPlaneswalker() == null) {
|
||||
if (damage + 3 > AllZone.ComputerPlayer.getLife() || poison + 2 > 10 - AllZone.ComputerPlayer.getPoisonCounters())
|
||||
return true;
|
||||
} else {
|
||||
if (damage + 1 > combat.getPlaneswalker().getCounters(Counters.LOYALTY))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return (damage + 3 > AllZone.ComputerPlayer.getLife() || poison + 2 > 10 - AllZone.ComputerPlayer.getPoisonCounters());
|
||||
}
|
||||
|
||||
// This calculates the amount of damage a blockgang can deal to the attacker (first strike not supported)
|
||||
@@ -816,104 +812,59 @@ public class CombatUtil {
|
||||
}
|
||||
|
||||
public static void showCombat() {
|
||||
//clear
|
||||
AllZone.Display.showCombat("");
|
||||
|
||||
Card attack[] = AllZone.Combat.getAttackers();
|
||||
Card defend[] = null;
|
||||
StringBuilder display = new StringBuilder();
|
||||
String attackerName = "";
|
||||
String blockerName = "";
|
||||
|
||||
//loop through attackers
|
||||
for(int i = 0; i < attack.length; i++) {
|
||||
//GameActionUtil.executeExaltedEffects2(attack[i], AllZone.Combat);
|
||||
//checkDeclareAttackers(attack[i]);
|
||||
attackerName = attack[i].getName();
|
||||
if(attack[i].isFaceDown()) attackerName = "Morph";
|
||||
display.append(attackerName);
|
||||
display.append(" (");
|
||||
display.append(attack[i].getUniqueNumber());
|
||||
display.append(") ");
|
||||
display.append(attack[i].getNetAttack());
|
||||
display.append("/");
|
||||
display.append(attack[i].getNetDefense());
|
||||
display.append(" is attacking \n");
|
||||
// Loop through Defenders
|
||||
// Append Defending Player/Planeswalker
|
||||
ArrayList<Object> defenders = AllZone.Combat.getDefenders();
|
||||
CardList attackers[] = AllZone.Combat.sortAttackerByDefender();
|
||||
|
||||
defend = AllZone.Combat.getBlockers(attack[i]).toArray();
|
||||
// Not a big fan of the triple nested loop here
|
||||
for(int def = 0; def < defenders.size(); def++){
|
||||
if (attackers[def] == null || attackers[def].size() == 0)
|
||||
continue;
|
||||
|
||||
//loop through blockers
|
||||
for(int inner = 0; inner < defend.length; inner++) {
|
||||
//checkDeclareBlockers(defend[inner]);
|
||||
blockerName = defend[inner].getName();
|
||||
if(defend[inner].isFaceDown()) blockerName = "Morph";
|
||||
if (def > 0)
|
||||
display.append("\n");
|
||||
|
||||
display.append(" ");
|
||||
display.append(blockerName);
|
||||
display.append(" (");
|
||||
display.append(defend[inner].getUniqueNumber());
|
||||
display.append(") ");
|
||||
display.append(defend[inner].getNetAttack());
|
||||
display.append("/");
|
||||
display.append(defend[inner].getNetDefense());
|
||||
display.append(" is blocking \n");
|
||||
display.append("Defender - ");
|
||||
display.append(defenders.get(def).toString());
|
||||
display.append("\n");
|
||||
|
||||
}
|
||||
}//while - loop through attackers
|
||||
String s = display.toString() + getPlaneswalkerBlockers();
|
||||
AllZone.Display.showCombat(s.trim());
|
||||
int len = attackers[def].size();
|
||||
//loop through attackers
|
||||
for(int i = 0; i < len; i++) {
|
||||
display.append("-> ");
|
||||
display.append(combatantToString(attack[i])).append("\n");
|
||||
|
||||
defend = AllZone.Combat.getBlockers(attack[i]).toArray();
|
||||
|
||||
//loop through blockers
|
||||
for(int inner = 0; inner < defend.length; inner++) {
|
||||
display.append("---< ");
|
||||
display.append(combatantToString(defend[inner])).append("\n");
|
||||
}
|
||||
}//loop through attackers
|
||||
}
|
||||
AllZone.Display.showCombat(display.toString().trim());
|
||||
|
||||
}//showBlockers()
|
||||
|
||||
private static String getPlaneswalkerBlockers() {
|
||||
Card attack[] = AllZone.pwCombat.getAttackers();
|
||||
Card defend[] = null;
|
||||
StringBuilder display = new StringBuilder();
|
||||
private static String combatantToString(Card c){
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
if(attack.length != 0) display.append("Planeswalker Combat\r\n");
|
||||
String name = (c.isFaceDown()) ? "Morph" : c.getName();
|
||||
|
||||
String attackerName = "";
|
||||
String blockerName = "";
|
||||
//loop through attackers
|
||||
for(int i = 0; i < attack.length; i++) {
|
||||
//GameActionUtil.executeExaltedEffects2(attack[i], AllZone.pwCombat);
|
||||
|
||||
//checkDeclareAttackers(attack[i]);
|
||||
attackerName = attack[i].getName();
|
||||
if(attack[i].isFaceDown()) attackerName = "Morph";
|
||||
|
||||
display.append(attackerName);
|
||||
display.append(" (");
|
||||
display.append(attack[i].getUniqueNumber());
|
||||
display.append(") ");
|
||||
display.append(attack[i].getNetAttack());
|
||||
display.append("/");
|
||||
display.append(attack[i].getNetDefense());
|
||||
display.append(" is attacking \n");
|
||||
|
||||
defend = AllZone.pwCombat.getBlockers(attack[i]).toArray();
|
||||
|
||||
//loop through blockers
|
||||
for(int inner = 0; inner < defend.length; inner++) {
|
||||
//checkDeclareBlockers(defend[inner]);
|
||||
blockerName = defend[inner].getName();
|
||||
if(defend[inner].isFaceDown()) blockerName = "Morph";
|
||||
|
||||
display.append(" ");
|
||||
display.append(blockerName);
|
||||
display.append(" (");
|
||||
display.append(defend[inner].getUniqueNumber());
|
||||
display.append(") ");
|
||||
display.append(defend[inner].getNetAttack());
|
||||
display.append("/");
|
||||
display.append(defend[inner].getNetDefense());
|
||||
display.append(" is blocking \n");
|
||||
}
|
||||
}//while - loop through attackers
|
||||
|
||||
return display.toString();
|
||||
}//getPlaneswalkerBlockers()
|
||||
sb.append(name);
|
||||
sb.append(" (").append(c.getUniqueNumber()).append(") ");
|
||||
sb.append(c.getNetAttack()).append("/").append(c.getNetDefense());
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static boolean isDoranInPlay() {
|
||||
return AllZoneUtil.isCardInPlay("Doran, the Siege Tower");
|
||||
@@ -921,14 +872,19 @@ public class CombatUtil {
|
||||
|
||||
public static boolean checkPropagandaEffects(Card c) {
|
||||
String cost = CardFactoryUtil.getPropagandaCost(c);
|
||||
if(cost.equals("0"))
|
||||
if(cost.equals("0")){
|
||||
if(!c.getKeyword().contains("Vigilance"))
|
||||
c.tap();
|
||||
return true;
|
||||
}
|
||||
|
||||
final Card crd = c;
|
||||
final boolean[] canAttack = new boolean[1];
|
||||
canAttack[0] = false;
|
||||
|
||||
if( AllZone.Phase.getPhase().equals(Constant.Phase.Combat_Declare_Attackers)) {
|
||||
String phase = AllZone.Phase.getPhase();
|
||||
|
||||
if(phase.equals(Constant.Phase.Combat_Declare_Attackers) || phase.equals(Constant.Phase.Combat_Declare_Attackers)) {
|
||||
if(!cost.equals("0")) {
|
||||
final Ability ability = new Ability(c, cost) {
|
||||
@Override
|
||||
@@ -943,8 +899,8 @@ public class CombatUtil {
|
||||
|
||||
public void execute() {
|
||||
canAttack[0] = false;
|
||||
// TODO: remove the below line after Propaganda occurs during Declare_Attackers
|
||||
AllZone.Combat.removeFromCombat(crd);
|
||||
crd.untap();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -952,6 +908,9 @@ public class CombatUtil {
|
||||
private static final long serialVersionUID = -8303368287601871955L;
|
||||
|
||||
public void execute() {
|
||||
// if Propaganda is paid, tap this card
|
||||
if(!crd.getKeyword().contains("Vigilance"))
|
||||
crd.tap();
|
||||
canAttack[0] = true;
|
||||
}
|
||||
};
|
||||
@@ -959,13 +918,18 @@ public class CombatUtil {
|
||||
if(c.getController().isHuman()) {
|
||||
AllZone.InputControl.setInput(new Input_PayManaCost_Ability(c + " - Pay to Attack\r\n",
|
||||
ability.getManaCost(), paidCommand, unpaidCommand));
|
||||
} else //computer
|
||||
{
|
||||
if(ComputerUtil.canPayCost(ability)) ComputerUtil.playNoStack(ability);
|
||||
}
|
||||
else{ //computer
|
||||
if(ComputerUtil.canPayCost(ability)){
|
||||
ComputerUtil.playNoStack(ability);
|
||||
if(!crd.getKeyword().contains("Vigilance"))
|
||||
crd.tap();
|
||||
}
|
||||
else {
|
||||
canAttack[0] = false;
|
||||
// TODO: remove the below two lines after Propaganda occurs during Declare_Attackers
|
||||
AllZone.Combat.removeFromCombat(crd);
|
||||
crd.untap();
|
||||
//crd.untap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1105,7 +1069,7 @@ public class CombatUtil {
|
||||
}
|
||||
}//Raging Ravine
|
||||
|
||||
if ((AllZone.Combat.getAttackers().length + AllZone.pwCombat.getAttackers().length) == 1)
|
||||
if (AllZone.Combat.getAttackers().length == 1)
|
||||
{
|
||||
if (c.getKeyword().contains("Whenever this creature attacks alone, it gets +2/+0 until end of turn.") ||
|
||||
c.getKeyword().contains("Whenever CARDNAME attacks alone, it gets +2/+0 until end of turn."))
|
||||
@@ -1568,13 +1532,9 @@ public class CombatUtil {
|
||||
public void resolve() {
|
||||
CardList list = new CardList();
|
||||
list.addAll(AllZone.Combat.getAttackers());
|
||||
list.addAll(AllZone.pwCombat.getAttackers());
|
||||
list = list.filter(new CardListFilter() {
|
||||
public boolean addCard(Card card) {
|
||||
return (!card.equals(piledriver) && card.isCreature() && (card.getType().contains(
|
||||
"Goblin") || card.getKeyword().contains("Changeling")));
|
||||
}
|
||||
});
|
||||
list = list.getType("Goblin");
|
||||
list.remove(piledriver);
|
||||
|
||||
final int otherGoblins = list.size();
|
||||
|
||||
final Command untilEOT = new Command() {
|
||||
|
||||
@@ -183,25 +183,17 @@ public class ComputerAI_General implements Computer {
|
||||
}
|
||||
|
||||
public void declare_attackers() {
|
||||
final Combat c = ComputerUtil.getAttackers();
|
||||
c.setAttackingPlayer(AllZone.Combat.getAttackingPlayer());
|
||||
c.setDefendingPlayer(AllZone.Combat.getDefendingPlayer());
|
||||
// 12/2/10(sol) the decision making here has moved to getAttackers()
|
||||
|
||||
//check for planeswalker
|
||||
Card walker = AllZone.HumanPlayer.getPlaneswalker();
|
||||
AllZone.Combat = ComputerUtil.getAttackers();
|
||||
|
||||
if(walker != null && MyRandom.random.nextBoolean()) {
|
||||
c.setPlaneswalker(walker);
|
||||
AllZone.pwCombat = c;
|
||||
} else AllZone.Combat = c;
|
||||
|
||||
|
||||
Card[] att = c.getAttackers();
|
||||
Card[] att = AllZone.Combat.getAttackers();
|
||||
if (att.length > 0)
|
||||
AllZone.Phase.setCombat(true);
|
||||
|
||||
for(int i = 0; i < att.length; i++) {
|
||||
if(!att[i].getKeyword().contains("Vigilance")) att[i].tap();
|
||||
// tapping of attackers happens after Propaganda is paid for
|
||||
//if(!att[i].getKeyword().contains("Vigilance")) att[i].tap();
|
||||
Log.debug("Computer just assigned " + att[i].getName() + " as an attacker.");
|
||||
}
|
||||
|
||||
@@ -219,23 +211,7 @@ public class ComputerAI_General implements Computer {
|
||||
public void declare_blockers() {
|
||||
CardList blockers = AllZoneUtil.getCreaturesInPlay(AllZone.ComputerPlayer);
|
||||
|
||||
//If Player life is in danger protect it first
|
||||
if(CombatUtil.lifeInDanger(AllZone.Combat)) {
|
||||
AllZone.Combat = ComputerUtil_Block2.getBlockers(AllZone.Combat, blockers);
|
||||
CardList remove = AllZone.Combat.getAllBlockers();
|
||||
for(int i = 0; i < remove.size(); i++)
|
||||
blockers.remove(remove.get(i));
|
||||
|
||||
AllZone.pwCombat = ComputerUtil_Block2.getBlockers(AllZone.pwCombat, blockers);
|
||||
} else { // Otherwise protect Planeswalkers first
|
||||
AllZone.pwCombat = ComputerUtil_Block2.getBlockers(AllZone.pwCombat, blockers);
|
||||
|
||||
CardList remove = AllZone.pwCombat.getAllBlockers();
|
||||
for(int i = 0; i < remove.size(); i++)
|
||||
blockers.remove(remove.get(i));
|
||||
|
||||
AllZone.Combat = ComputerUtil_Block2.getBlockers(AllZone.Combat, blockers);
|
||||
}
|
||||
AllZone.Combat = ComputerUtil_Block2.getBlockers(AllZone.Combat, blockers);
|
||||
|
||||
CombatUtil.showCombat();
|
||||
|
||||
@@ -246,26 +222,6 @@ public class ComputerAI_General implements Computer {
|
||||
stackResponse();
|
||||
}
|
||||
|
||||
/*
|
||||
private Combat getCombat(Card[] attackers, CardList availableBlockers) {
|
||||
|
||||
|
||||
ComputerUtil_Block2 com = new ComputerUtil_Block2(attackers, availableBlockers.toArray(),
|
||||
AllZone.ComputerPlayer.getLife());
|
||||
|
||||
Combat c = com.getBlockers();
|
||||
c.setAttackingPlayer(AllZone.Combat.getAttackingPlayer());
|
||||
c.setDefendingPlayer(AllZone.Combat.getDefendingPlayer());
|
||||
|
||||
|
||||
CardList attacks = new CardList(attackers);
|
||||
|
||||
Combat c = ComputerUtil_Block2.getBlockers(attacks,availableBlockers);
|
||||
|
||||
return c;
|
||||
}
|
||||
*/
|
||||
|
||||
public void end_of_combat(){
|
||||
stackResponse();
|
||||
}
|
||||
|
||||
@@ -743,7 +743,7 @@ public class ComputerUtil
|
||||
list = list.filter(new CardListFilter()
|
||||
{
|
||||
public boolean addCard(Card c) {
|
||||
return c.isCreature() && CombatUtil.canAttack(c);
|
||||
return CombatUtil.canAttack(c);
|
||||
}
|
||||
});
|
||||
return list;
|
||||
|
||||
@@ -32,6 +32,7 @@ public class ComputerUtil_Attack2 {
|
||||
blockers = getPossibleBlockers(possibleBlockers);
|
||||
this.blockerLife = blockerLife;
|
||||
|
||||
// todo: get rid of valuable
|
||||
final ArrayList<String> valuable = new ArrayList<String>();
|
||||
valuable.add("Kamahl, Pit Fighter");
|
||||
valuable.add("Elvish Piper");
|
||||
@@ -50,7 +51,7 @@ public class ComputerUtil_Attack2 {
|
||||
CardList list = new CardList(in.toArray());
|
||||
list = list.filter(new CardListFilter()
|
||||
{
|
||||
public boolean addCard(Card c) { return c.isCreature() && CombatUtil.canAttack(c); }
|
||||
public boolean addCard(Card c) { return CombatUtil.canAttack(c); }
|
||||
});
|
||||
return list;
|
||||
}//getUntappedCreatures()
|
||||
@@ -159,6 +160,24 @@ public class ComputerUtil_Attack2 {
|
||||
return blockerLife <= totalAttack;
|
||||
}//doAssault()
|
||||
|
||||
public void chooseDefender(Combat c, boolean bAssault){
|
||||
// TODO: split attackers to different planeswalker/human
|
||||
// AI will only attack one Defender per combat for now
|
||||
ArrayList<Object> defs = c.getDefenders();
|
||||
|
||||
if (defs.size() == 1 || bAssault){
|
||||
c.setCurrentDefender(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Randomnly determine who EVERYONE is attacking
|
||||
// would be better to determine more individually
|
||||
int n = MyRandom.random.nextInt(defs.size());
|
||||
c.setCurrentDefender(n);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public Combat getAttackers()
|
||||
{
|
||||
//if this method is called multiple times during a turn,
|
||||
@@ -169,11 +188,19 @@ public class ComputerUtil_Attack2 {
|
||||
random.setSeed(AllZone.Phase.getTurn() + randomInt);
|
||||
|
||||
Combat combat = new Combat();
|
||||
combat.setAttackingPlayer(AllZone.Combat.getAttackingPlayer());
|
||||
combat.setDefendingPlayer(AllZone.Combat.getDefendingPlayer());
|
||||
|
||||
combat.setDefenders(AllZone.Combat.getDefenders());
|
||||
|
||||
boolean bAssault = doAssault();
|
||||
// Determine who will be attacked
|
||||
chooseDefender(combat, bAssault);
|
||||
|
||||
CardList attackersLeft = new CardList(attackers.toArray());
|
||||
|
||||
//Atackers that don't really have a choice
|
||||
for (int i=0; i<attackersLeft.size();i++)
|
||||
for (int i=0; i < attackersLeft.size(); i++)
|
||||
{
|
||||
Card attacker = attackersLeft.get(i);
|
||||
if ( (attacker.getKeyword().contains("CARDNAME attacks each turn if able.")
|
||||
@@ -192,8 +219,9 @@ public class ComputerUtil_Attack2 {
|
||||
if (combat.getAttackers().length == 0 && (countExaltedBonus(AllZone.ComputerPlayer) >= 3 ||
|
||||
AllZoneUtil.isCardInPlay("Rafiq of the Many", AllZone.ComputerPlayer) ||
|
||||
AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer, "Battlegrace Angel").size() >= 2 ||
|
||||
(AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer, "Finest Hour").size()>=1) && AllZone.Phase.isFirstCombat())
|
||||
&& !doAssault())
|
||||
(AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer, "Finest Hour").size()>=1) &&
|
||||
AllZone.Phase.isFirstCombat())
|
||||
&& !bAssault)
|
||||
{
|
||||
int biggest = 0;
|
||||
Card att = null;
|
||||
@@ -209,7 +237,7 @@ public class ComputerUtil_Attack2 {
|
||||
|
||||
//do assault (all creatures attack) if the computer would win the game
|
||||
//or if the computer has 4 creatures and the player has 1
|
||||
else if(doAssault() || (humanList.size() == 1 && 3 < attackers.size()))
|
||||
else if(bAssault || (humanList.size() == 1 && 3 < attackers.size()))
|
||||
{
|
||||
CardListUtil.sortAttack(attackersLeft);
|
||||
for(int i = 0; i < attackersLeft.size(); i++)
|
||||
@@ -254,32 +282,11 @@ public class ComputerUtil_Attack2 {
|
||||
}
|
||||
}//getAttackers()
|
||||
|
||||
|
||||
|
||||
return combat;
|
||||
}//getAttackers()
|
||||
|
||||
/*
|
||||
//returns null if no blockers found
|
||||
public Card getBiggestAttack(Card attack)
|
||||
{
|
||||
CardListUtil.sortAttack(blockers);
|
||||
for(int i = 0; i < blockers.size(); i++)
|
||||
if(CombatUtil.canBlock(attack, blockers.get(i)))
|
||||
return blockers.get(i);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
//returns null if no blockers found
|
||||
public Card getBiggestDefense(Card attack)
|
||||
{
|
||||
CardListUtil.sortDefense(blockers);
|
||||
for(int i = 0; i < blockers.size(); i++)
|
||||
if(CombatUtil.canBlock(attack, blockers.get(i)))
|
||||
return blockers.get(i);
|
||||
|
||||
return null;
|
||||
}*/
|
||||
|
||||
public int countExaltedBonus(Player player)
|
||||
{
|
||||
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, player);
|
||||
@@ -349,8 +356,6 @@ public class ComputerUtil_Attack2 {
|
||||
else if(CombatUtil.canBlock(c)) plannedBlockers.add(c);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return combat;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
|
||||
package forge;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class ComputerUtil_Block2
|
||||
{
|
||||
@@ -481,7 +483,7 @@ public class ComputerUtil_Block2
|
||||
if(CombatUtil.canBlock(attacker,blocker,combat)) blockers.add(blocker);
|
||||
}
|
||||
|
||||
return blockers;
|
||||
return blockers;
|
||||
}
|
||||
|
||||
//finds blockers that won't be destroyed
|
||||
@@ -493,7 +495,7 @@ public class ComputerUtil_Block2
|
||||
if(!CombatUtil.canDestroyBlocker(b,attacker)) blockers.add(b);
|
||||
}
|
||||
|
||||
return blockers;
|
||||
return blockers;
|
||||
}
|
||||
|
||||
//finds blockers that destroy the attacker
|
||||
@@ -505,14 +507,49 @@ public class ComputerUtil_Block2
|
||||
if(CombatUtil.canDestroyAttacker(attacker,b)) blockers.add(b);
|
||||
}
|
||||
|
||||
return blockers;
|
||||
return blockers;
|
||||
}
|
||||
|
||||
public static Combat getBlockers(Combat originalCombat, CardList possibleBlockers) {
|
||||
public static CardList sortPotentialAttackers(Combat combat){
|
||||
CardList[] attackerLists = combat.sortAttackerByDefender();
|
||||
CardList sortedAttackers = new CardList();
|
||||
|
||||
ArrayList<Object> defenders = combat.getDefenders();
|
||||
|
||||
// If I don't have any planeswalkers than sorting doesn't really matter
|
||||
if (defenders.size() == 1)
|
||||
return attackerLists[0];
|
||||
|
||||
boolean bLifeInDanger = CombatUtil.lifeInDanger(combat);
|
||||
|
||||
// todo: Add creatures attacking Planeswalkers in order of which we want to protect
|
||||
// defend planeswalkers with more loyalty before planeswalkers with less loyalty
|
||||
// if planeswalker will be too difficult to defend don't even bother
|
||||
for(int i = 1; i < attackerLists.length; i++){
|
||||
for(Card c : attackerLists[i])
|
||||
sortedAttackers.add(c);
|
||||
}
|
||||
|
||||
if(bLifeInDanger) {
|
||||
// add creatures attacking the Player to the front of the list
|
||||
for(Card c : attackerLists[0])
|
||||
sortedAttackers.add(0, c);
|
||||
|
||||
}
|
||||
else{
|
||||
// add creatures attacking the Player to the back of the list
|
||||
for(Card c : attackerLists[0])
|
||||
sortedAttackers.add(c);
|
||||
}
|
||||
|
||||
return sortedAttackers;
|
||||
}
|
||||
|
||||
public static Combat getBlockers(Combat originalCombat, CardList possibleBlockers) {
|
||||
|
||||
Combat combat = originalCombat;
|
||||
|
||||
CardList attackers = new CardList(combat.getAttackers());
|
||||
CardList attackers = sortPotentialAttackers(combat);
|
||||
|
||||
if (attackers.size() == 0)
|
||||
return combat;
|
||||
@@ -564,8 +601,10 @@ public class ComputerUtil_Block2
|
||||
if(!CombatUtil.canBlock(b, combat)) blockersLeft.remove(b);
|
||||
}
|
||||
|
||||
boolean bLifeInDanger = CombatUtil.lifeInDanger(combat);
|
||||
|
||||
//These creatures won't prevent any damage
|
||||
if (CombatUtil.lifeInDanger(combat))
|
||||
if (bLifeInDanger)
|
||||
blockersLeft = blockersLeft.getNotKeyword("Whenever CARDNAME is dealt damage, you lose that much life.");
|
||||
|
||||
if (blockersLeft.size() == 0)
|
||||
@@ -624,7 +663,7 @@ public class ComputerUtil_Block2
|
||||
if(blockersLeft.size() == 0) return combat;
|
||||
|
||||
//choose necessary trade blocks if life is in danger
|
||||
if (CombatUtil.lifeInDanger(combat))
|
||||
if (bLifeInDanger)
|
||||
for(int i = 0; i < attackersLeft.size(); i++) {
|
||||
attacker = attackersLeft.get(i);
|
||||
killingBlockers =
|
||||
@@ -640,7 +679,7 @@ public class ComputerUtil_Block2
|
||||
attackersLeft = new CardList(currentAttackers.toArray());
|
||||
|
||||
//choose necessary chump blocks if life is still in danger
|
||||
if (CombatUtil.lifeInDanger(combat))
|
||||
if (bLifeInDanger)
|
||||
for(int i = 0; i < attackersLeft.size(); i++) {
|
||||
attacker = attackersLeft.get(i);
|
||||
chumpBlockers = getPossibleBlockers(attacker, blockersLeft, combat);
|
||||
@@ -656,7 +695,7 @@ public class ComputerUtil_Block2
|
||||
attackersLeft = new CardList(currentAttackers.toArray());
|
||||
|
||||
//Reinforce blockers blocking attackers with trample if life is still in danger
|
||||
if (CombatUtil.lifeInDanger(combat)) {
|
||||
if (bLifeInDanger) {
|
||||
tramplingAttackers = attackers.getKeyword("Trample");
|
||||
tramplingAttackers = tramplingAttackers.getKeywordsDontContain("Rampage"); //Don't make it worse
|
||||
tramplingAttackers = tramplingAttackers.
|
||||
|
||||
@@ -98,6 +98,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
|
||||
// Special Inputs needed for the following phases:
|
||||
if(phase.equals(Constant.Phase.Combat_Declare_Attackers)) {
|
||||
AllZone.Stack.freezeStack();
|
||||
|
||||
if (playerTurn.isHuman())
|
||||
return new Input_Attack();
|
||||
}
|
||||
@@ -109,11 +110,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
|
||||
return null;
|
||||
}
|
||||
else{
|
||||
// test this. probably should just call Input_Block and let block pass along?
|
||||
if(AllZone.Combat.getAttackers().length == 0){
|
||||
if (AllZone.pwCombat.getAttackers().length != 0)
|
||||
return new Input_Block_Planeswalker();
|
||||
|
||||
// no active attackers, skip the Blocking phase
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
return null;
|
||||
|
||||
@@ -7,20 +7,31 @@ public class Input_Attack extends Input {
|
||||
|
||||
@Override
|
||||
public void showMessage() {
|
||||
// TODO: still seems to have some issues with multiple planeswalkers
|
||||
|
||||
ButtonUtil.enableOnlyOK();
|
||||
AllZone.Display.showMessage("Declare Attackers: Select creatures that you want to attack with");
|
||||
|
||||
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, AllZone.HumanPlayer);
|
||||
CardList creats = new CardList(play.getCards());
|
||||
creats = creats.getType("Creature");
|
||||
Object o = AllZone.Combat.nextDefender();
|
||||
if (o == null){
|
||||
return;
|
||||
}
|
||||
|
||||
if(getPlaneswalker() == null) {
|
||||
for(int i = 0; i < creats.size(); i++) {
|
||||
Card c = creats.get(i);
|
||||
if(CombatUtil.canAttack(c) && c.getKeyword().contains("CARDNAME attacks each turn if able.")) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Declare Attackers: Select Creatures to Attack ");
|
||||
sb.append(o.toString());
|
||||
|
||||
AllZone.Display.showMessage(sb.toString());
|
||||
|
||||
if(AllZone.Combat.getRemainingDefenders() == 0) {
|
||||
// Nothing left to attack, has to attack this defender
|
||||
CardList possibleAttackers = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer);
|
||||
possibleAttackers = possibleAttackers.getType("Creature");
|
||||
for(int i = 0; i < possibleAttackers.size(); i++) {
|
||||
Card c = possibleAttackers.get(i);
|
||||
if(c.getKeyword().contains("CARDNAME attacks each turn if able.") && CombatUtil.canAttack(c) && !c.isAttacking()) {
|
||||
AllZone.Combat.addAttacker(c);
|
||||
if(!c.getKeyword().contains("Vigilance")) c.tap();
|
||||
//if(!c.getKeyword().contains("Vigilance"))
|
||||
// c.tap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,37 +42,23 @@ public class Input_Attack extends Input {
|
||||
if (AllZone.Combat.getAttackers().length > 0)
|
||||
AllZone.Phase.setCombat(true);
|
||||
|
||||
Card check = getPlaneswalker();
|
||||
if(check == null) {
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
} else {
|
||||
AllZone.pwCombat.setPlaneswalker(check);
|
||||
AllZone.InputControl.setInput(new Input_Attack_Planeswalker());
|
||||
}
|
||||
}
|
||||
if (AllZone.Combat.getRemainingDefenders() != 0)
|
||||
AllZone.Phase.repeatPhase();
|
||||
|
||||
//return Computer's planeswalker if there is one
|
||||
//just returns 1, does not return multiple planeswalkers
|
||||
private Card getPlaneswalker() {
|
||||
CardList c = new CardList(AllZone.Computer_Battlefield.getCards());
|
||||
c = c.getType("Planeswalker");
|
||||
|
||||
if(c.isEmpty()) return null;
|
||||
|
||||
return c.get(0);
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
AllZone.InputControl.resetInput();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectCard(Card card, PlayerZone zone) {
|
||||
if(zone.is(Constant.Zone.Battlefield, AllZone.HumanPlayer) && card.isCreature() && card.isUntapped()
|
||||
&& CombatUtil.canAttack(card)) {
|
||||
if(zone.is(Constant.Zone.Battlefield, AllZone.HumanPlayer) && CombatUtil.canAttack(card) && !card.isAttacking()) {
|
||||
|
||||
// todo add the propaganda code here and remove it in Phase.nextPhase()
|
||||
// if (!CombatUtil.checkPropagandaEffects(card))
|
||||
// return;
|
||||
|
||||
if(!card.getKeyword().contains("Vigilance")) {
|
||||
card.tap();
|
||||
//otherwise cards stay untapped, not sure why this is needed but it works
|
||||
AllZone.Human_Battlefield.updateObservers();
|
||||
}
|
||||
AllZone.Combat.addAttacker(card);
|
||||
AllZone.Human_Battlefield.updateObservers(); // just to make sure the attack symbol is marked
|
||||
|
||||
//for Castle Raptors, since it gets a bonus if untapped
|
||||
for(String effect:AllZone.StaticEffects.getStateBasedMap().keySet()) {
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
|
||||
package forge;
|
||||
|
||||
|
||||
public class Input_Attack_Planeswalker extends Input {
|
||||
private static final long serialVersionUID = 5738375759147611797L;
|
||||
|
||||
@Override
|
||||
public void showMessage() {
|
||||
ButtonUtil.enableOnlyOK();
|
||||
AllZone.Display.showMessage("Planeswalker Declare Attackers:\r\nSelect creatures that you want to attack "
|
||||
+ AllZone.pwCombat.getPlaneswalker());
|
||||
|
||||
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, AllZone.HumanPlayer);
|
||||
CardList creats = new CardList(play.getCards());
|
||||
creats = creats.getType("Creature");
|
||||
CardList attackers = new CardList(AllZone.Combat.getAttackers());
|
||||
|
||||
for(int i = 0; i < creats.size(); i++) {
|
||||
Card c = creats.get(i);
|
||||
if(CombatUtil.canAttack(c) && c.getKeyword().contains("CARDNAME attacks each turn if able.")
|
||||
&& !attackers.contains(c)) {
|
||||
AllZone.pwCombat.addAttacker(c);
|
||||
if(!c.getKeyword().contains("Vigilance")) c.tap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectButtonOK() {
|
||||
if (AllZone.pwCombat.getAttackers().length > 0)
|
||||
AllZone.Phase.setCombat(true);
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
this.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectCard(Card card, PlayerZone zone) {
|
||||
if(zone.is(Constant.Zone.Battlefield, AllZone.HumanPlayer) && card.isCreature() && card.isUntapped()
|
||||
&& CombatUtil.canAttack(card)) {
|
||||
if(!card.getKeyword().contains("Vigilance")) {
|
||||
card.tap();
|
||||
|
||||
//otherwise cards stay untapped, not sure why this is needed but it works
|
||||
AllZone.Human_Battlefield.updateObservers();
|
||||
}
|
||||
AllZone.pwCombat.addAttacker(card);
|
||||
|
||||
//for Castle Raptors, since it gets a bonus if untapped
|
||||
for(String effect:AllZone.StaticEffects.getStateBasedMap().keySet()) {
|
||||
Command com = GameActionUtil.commands.get(effect);
|
||||
com.execute();
|
||||
}
|
||||
|
||||
GameActionUtil.executeCardStateEffects();
|
||||
|
||||
CombatUtil.showCombat();
|
||||
}
|
||||
}//selectCard()
|
||||
}
|
||||
@@ -52,15 +52,10 @@ public class Input_Block extends Input {
|
||||
|
||||
@Override
|
||||
public void selectButtonOK() {
|
||||
// Done blocking
|
||||
ButtonUtil.reset();
|
||||
if(AllZone.pwCombat.getAttackers().length == 0) {
|
||||
|
||||
//AllZone.Phase.nextPhase();
|
||||
//for debugging: System.out.println("need to nextPhase(Input_Cleanup.showMessage(), n<=7) = true");
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
} else {
|
||||
AllZone.InputControl.setInput(new Input_Block_Planeswalker());
|
||||
}
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
|
||||
package forge;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class Input_Block_Planeswalker extends Input {
|
||||
private static final long serialVersionUID = 8504632360578751473L;
|
||||
|
||||
private Card currentAttacker = null;
|
||||
private ArrayList<Card> allBlocking = new ArrayList<Card>();
|
||||
|
||||
@Override
|
||||
public void showMessage() {
|
||||
//for Castle Raptors, since it gets a bonus if untapped
|
||||
for(String effect:AllZone.StaticEffects.getStateBasedMap().keySet()) {
|
||||
Command com = GameActionUtil.commands.get(effect);
|
||||
com.execute();
|
||||
}
|
||||
GameActionUtil.executeCardStateEffects();
|
||||
|
||||
//could add "Reset Blockers" button
|
||||
ButtonUtil.enableOnlyOK();
|
||||
|
||||
if(currentAttacker == null) {
|
||||
//Lure
|
||||
CardList attackers = new CardList(AllZone.Combat.getAttackers());
|
||||
for(Card attacker:attackers) {
|
||||
if(attacker.hasKeyword("All creatures able to block CARDNAME do so.")) {
|
||||
CardList bls = AllZoneUtil.getCreaturesInPlay(AllZone.HumanPlayer);
|
||||
for(Card bl:bls) {
|
||||
if(CombatUtil.canBlock(attacker, bl, AllZone.Combat)) {
|
||||
allBlocking.add(bl);
|
||||
AllZone.Combat.addBlocker(attacker, bl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AllZone.Display.showMessage("Planeswalker Combat\r\nTo Block, click on your Opponents attacker first , then your blocker(s)");
|
||||
}
|
||||
else {
|
||||
String attackerName = currentAttacker.isFaceDown() ? "Morph" : currentAttacker.getName();
|
||||
AllZone.Display.showMessage("Select a creature to block " + attackerName + " ("
|
||||
+ currentAttacker.getUniqueNumber() + ") ");
|
||||
}
|
||||
|
||||
CombatUtil.showCombat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectButtonOK() {
|
||||
if (AllZone.Combat.getAttackers().length > 0)
|
||||
AllZone.Phase.setCombat(true);
|
||||
ButtonUtil.reset();
|
||||
|
||||
//AllZone.Phase.nextPhase();
|
||||
//for debugging: System.out.println("need to nextPhase(Input_Block_Planeswalker.selectButtonOK) = true; Note, this has not been tested, did it work?");
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
this.stop();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectCard(Card card, PlayerZone zone) {
|
||||
//is attacking?
|
||||
if(CardUtil.toList(AllZone.pwCombat.getAttackers()).contains(card)) {
|
||||
currentAttacker = card;
|
||||
} else if(zone.is(Constant.Zone.Battlefield, AllZone.HumanPlayer) && card.isCreature()
|
||||
&& CombatUtil.canBlock(currentAttacker, card, AllZone.Combat)) {
|
||||
if(currentAttacker != null && (!allBlocking.contains(card))) {
|
||||
allBlocking.add(card);
|
||||
AllZone.pwCombat.addBlocker(currentAttacker, card);
|
||||
}
|
||||
}
|
||||
showMessage();
|
||||
}//selectCard()
|
||||
}
|
||||
@@ -191,8 +191,7 @@ public class Phase extends MyObservable
|
||||
|
||||
else if(phase.equals(Constant.Phase.Combat_Begin)){
|
||||
if (AllZone.Display.stopAtPhase(turn, phase)){
|
||||
AllZone.Combat.verifyCreaturesInPlay();
|
||||
CombatUtil.showCombat();
|
||||
PhaseUtil.verifyCombat();
|
||||
}
|
||||
else {
|
||||
this.setNeedToNextPhase(true);
|
||||
@@ -201,8 +200,7 @@ public class Phase extends MyObservable
|
||||
|
||||
else if (phase.equals(Constant.Phase.Combat_Declare_Attackers_InstantAbility)){
|
||||
if(inCombat()) {
|
||||
AllZone.Combat.verifyCreaturesInPlay();
|
||||
CombatUtil.showCombat();
|
||||
PhaseUtil.handleDeclareAttackers();
|
||||
}
|
||||
else
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
@@ -211,8 +209,7 @@ public class Phase extends MyObservable
|
||||
// we can skip AfterBlockers and AfterAttackers if necessary
|
||||
else if(phase.equals(Constant.Phase.Combat_Declare_Blockers)){
|
||||
if(inCombat()) {
|
||||
AllZone.Combat.verifyCreaturesInPlay();
|
||||
CombatUtil.showCombat();
|
||||
PhaseUtil.verifyCombat();
|
||||
}
|
||||
else
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
@@ -223,40 +220,7 @@ public class Phase extends MyObservable
|
||||
if(!inCombat())
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
else{
|
||||
AllZone.Combat.verifyCreaturesInPlay();
|
||||
|
||||
AllZone.Stack.freezeStack();
|
||||
CardList list = new CardList();
|
||||
list.addAll(AllZone.Combat.getAllBlockers().toArray());
|
||||
list.addAll(AllZone.pwCombat.getAllBlockers().toArray());
|
||||
list = list.filter(new CardListFilter(){
|
||||
public boolean addCard(Card c)
|
||||
{
|
||||
return !c.getCreatureBlockedThisCombat();
|
||||
}
|
||||
});
|
||||
|
||||
CardList attList = new CardList();
|
||||
attList.addAll(AllZone.Combat.getAttackers());
|
||||
|
||||
CardList pwAttList = new CardList();
|
||||
pwAttList.addAll(AllZone.pwCombat.getAttackers());
|
||||
|
||||
CombatUtil.checkDeclareBlockers(list);
|
||||
|
||||
for (Card a:attList){
|
||||
CardList blockList = AllZone.Combat.getBlockers(a);
|
||||
for (Card b:blockList)
|
||||
CombatUtil.checkBlockedAttackers(a, b);
|
||||
}
|
||||
|
||||
for (Card a:pwAttList){
|
||||
CardList blockList = AllZone.pwCombat.getBlockers(a);
|
||||
for (Card b:blockList)
|
||||
CombatUtil.checkBlockedAttackers(a, b);
|
||||
}
|
||||
AllZone.Stack.unfreezeStack();
|
||||
CombatUtil.showCombat();
|
||||
PhaseUtil.handleDeclareBlockers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,10 +229,8 @@ public class Phase extends MyObservable
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
else{
|
||||
AllZone.Combat.verifyCreaturesInPlay();
|
||||
AllZone.pwCombat.verifyCreaturesInPlay();
|
||||
|
||||
AllZone.Combat.setAssignedFirstStrikeDamage();
|
||||
AllZone.pwCombat.setAssignedFirstStrikeDamage();
|
||||
|
||||
if (!AllZone.GameInfo.isPreventCombatDamageThisTurn())
|
||||
Combat.dealAssignedDamage();
|
||||
@@ -283,10 +245,8 @@ public class Phase extends MyObservable
|
||||
AllZone.Phase.setNeedToNextPhase(true);
|
||||
else{
|
||||
AllZone.Combat.verifyCreaturesInPlay();
|
||||
AllZone.pwCombat.verifyCreaturesInPlay();
|
||||
|
||||
AllZone.Combat.setAssignedDamage();
|
||||
AllZone.pwCombat.setAssignedDamage();
|
||||
|
||||
if (!AllZone.GameInfo.isPreventCombatDamageThisTurn())
|
||||
Combat.dealAssignedDamage();
|
||||
@@ -350,33 +310,6 @@ public class Phase extends MyObservable
|
||||
if (getPhase().equals(Constant.Phase.Combat_Declare_Attackers)) {
|
||||
AllZone.Stack.unfreezeStack();
|
||||
nCombatsThisTurn++;
|
||||
CardList list = new CardList();
|
||||
list.addAll(AllZone.Combat.getAttackers());
|
||||
|
||||
// Remove illegal Propaganda attacks first only for attacking the Player
|
||||
for(Card c:list)
|
||||
CombatUtil.checkPropagandaEffects(c);
|
||||
|
||||
list.addAll(AllZone.pwCombat.getAttackers());
|
||||
|
||||
// Then run other Attacker bonuses
|
||||
//check for exalted:
|
||||
if (list.size() == 1){
|
||||
AllZone.GameAction.checkWheneverKeyword(list.get(0), "Attack - Alone", null);
|
||||
Player attackingPlayer = AllZone.Combat.getAttackingPlayer();
|
||||
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, attackingPlayer);
|
||||
CardList exalted = new CardList(play.getCards());
|
||||
exalted = exalted.filter(new CardListFilter() {
|
||||
public boolean addCard(Card c) {
|
||||
return c.getKeyword().contains("Exalted");
|
||||
}
|
||||
});
|
||||
if(exalted.size() > 0) CombatUtil.executeExaltedAbility(list.get(0), exalted.size());
|
||||
// Make sure exalted effects get applied only once per combat
|
||||
}
|
||||
|
||||
for(Card c:list)
|
||||
CombatUtil.checkDeclareAttackers(c);
|
||||
}
|
||||
else if (getPhase().equals(Constant.Phase.Untap)) {
|
||||
nCombatsThisTurn = 0;
|
||||
@@ -384,7 +317,6 @@ public class Phase extends MyObservable
|
||||
|
||||
if (getPhase().equals(Constant.Phase.Combat_End)) {
|
||||
AllZone.Combat.reset();
|
||||
AllZone.pwCombat.reset();
|
||||
AllZone.Display.showCombat("");
|
||||
resetAttackedThisCombat(getPlayerTurn());
|
||||
this.bCombat = false;
|
||||
@@ -410,9 +342,6 @@ public class Phase extends MyObservable
|
||||
AllZone.Combat.reset();
|
||||
AllZone.Combat.setAttackingPlayer(player);
|
||||
AllZone.Combat.setDefendingPlayer(opp);
|
||||
AllZone.pwCombat.reset();
|
||||
AllZone.Combat.setAttackingPlayer(player);
|
||||
AllZone.Combat.setDefendingPlayer(opp);
|
||||
phaseIndex = findIndex(Constant.Phase.Combat_Declare_Attackers);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -30,10 +30,6 @@ public class PhaseUtil {
|
||||
AllZone.Combat.setAttackingPlayer(turn);
|
||||
AllZone.Combat.setDefendingPlayer(turn.getOpponent());
|
||||
|
||||
AllZone.pwCombat.reset();
|
||||
AllZone.pwCombat.setAttackingPlayer(turn);
|
||||
AllZone.pwCombat.setDefendingPlayer(turn.getOpponent());
|
||||
|
||||
// For tokens a player starts the game with they don't recover from Sum. Sickness on first turn
|
||||
if (turn.getTurn() > 0){
|
||||
for(int i = 0; i < c.length; i++)
|
||||
@@ -349,6 +345,77 @@ public class PhaseUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
// ********* Declare Attackers ***********
|
||||
|
||||
public static void verifyCombat(){
|
||||
AllZone.Combat.verifyCreaturesInPlay();
|
||||
CombatUtil.showCombat();
|
||||
}
|
||||
|
||||
public static void handleDeclareAttackers(){
|
||||
verifyCombat();
|
||||
CardList list = new CardList();
|
||||
list.addAll(AllZone.Combat.getAttackers());
|
||||
|
||||
// TODO move propaganda to happen as the Attacker is Declared
|
||||
// Remove illegal Propaganda attacks first only for attacking the Player
|
||||
for(Card c:list)
|
||||
CombatUtil.checkPropagandaEffects(c);
|
||||
|
||||
AllZone.Stack.freezeStack();
|
||||
// Then run other Attacker bonuses
|
||||
//check for exalted:
|
||||
if (list.size() == 1){
|
||||
AllZone.GameAction.checkWheneverKeyword(list.get(0), "Attack - Alone", null);
|
||||
Player attackingPlayer = AllZone.Combat.getAttackingPlayer();
|
||||
PlayerZone play = AllZone.getZone(Constant.Zone.Battlefield, attackingPlayer);
|
||||
CardList exalted = new CardList(play.getCards());
|
||||
exalted = exalted.filter(new CardListFilter() {
|
||||
public boolean addCard(Card c) {
|
||||
return c.getKeyword().contains("Exalted");
|
||||
}
|
||||
});
|
||||
if(exalted.size() > 0) CombatUtil.executeExaltedAbility(list.get(0), exalted.size());
|
||||
// Make sure exalted effects get applied only once per combat
|
||||
}
|
||||
|
||||
for(Card c:list)
|
||||
CombatUtil.checkDeclareAttackers(c);
|
||||
AllZone.Stack.unfreezeStack();
|
||||
}
|
||||
|
||||
public static void handleDeclareBlockers(){
|
||||
verifyCombat();
|
||||
|
||||
AllZone.Stack.freezeStack();
|
||||
CardList list = new CardList();
|
||||
list.addAll(AllZone.Combat.getAllBlockers().toArray());
|
||||
|
||||
list = list.filter(new CardListFilter(){
|
||||
public boolean addCard(Card c)
|
||||
{
|
||||
return !c.getCreatureBlockedThisCombat();
|
||||
}
|
||||
});
|
||||
|
||||
CardList attList = new CardList();
|
||||
attList.addAll(AllZone.Combat.getAttackers());
|
||||
|
||||
CombatUtil.checkDeclareBlockers(list);
|
||||
|
||||
for (Card a:attList){
|
||||
CardList blockList = AllZone.Combat.getBlockers(a);
|
||||
for (Card b:blockList)
|
||||
CombatUtil.checkBlockedAttackers(a, b);
|
||||
}
|
||||
|
||||
AllZone.Stack.unfreezeStack();
|
||||
CombatUtil.showCombat();
|
||||
}
|
||||
|
||||
|
||||
// ***** Combat Utility **********
|
||||
// todo: the below functions should be removed and the code blocks that use them should instead use SA_Restriction
|
||||
public static boolean isBeforeAttackersAreDeclared() {
|
||||
String phase = AllZone.Phase.getPhase();
|
||||
return phase.equals(Constant.Phase.Untap) || phase.equals(Constant.Phase.Upkeep)
|
||||
|
||||
Reference in New Issue
Block a user