mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
- AF_Damage can now handle Defined$ Parameters.
- Updated Psionic Entity, Orcish Cannonade, and Breath of Malfegor
This commit is contained in:
@@ -2,7 +2,7 @@ Name:Breath of Malfegor
|
||||
ManaCost:3 B R
|
||||
Types:Instant
|
||||
Text:no text
|
||||
K:spDamageTgtP:5
|
||||
A:SP$DealDamage | Cost$ 3 B R | Defined$ Opponent | NumDmg$ 5 | SpellDescription$ Breath of Malfegor deals 5 damage to each opponent.
|
||||
SVar:Rarity:Common
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/breath_of_malfegor.jpg
|
||||
SetInfo:ARB|Common|http://magiccards.info/scans/en/arb/35.jpg
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 R R
|
||||
Types:Instant
|
||||
Text:no text
|
||||
A:SP$DealDamage | Cost$ 1 R R | Tgt$ CP | NumDmg$2 | SubAbility$SVar=DB1 | SpellDescription$ Orcish Cannonade deals 2 damage to target creature or player and 3 damage to you. Draw a card.
|
||||
SVar:DB1:DB$DealDamage | NumDmg$ 3 | Affected$ You | SubAbility$SVar=DB2
|
||||
SVar:DB1:DB$DealDamage | NumDmg$ 3 | Defined$ You | SubAbility$SVar=DB2
|
||||
SVar:DB2:DB$Draw | NumCards$ 1
|
||||
SVar:Rarity:Common
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/orcish_cannonade.jpg
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Illusion
|
||||
Text:no text
|
||||
PT:2/2
|
||||
A:AB$DealDamage | Cost$ T | Tgt$ CP | NumDmg$2 | SubAbility$SVar=DB1 | SpellDescription$ Psionic Entity deals 2 damage to target creature or player and 3 damage to itself.
|
||||
SVar:DB1:DB$DealDamage | NumDmg$ 3 | Affected$ Self
|
||||
SVar:DB1:DB$DealDamage | NumDmg$ 3 | Defined$ Self
|
||||
SVar:Rarity:Rare
|
||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/psionic_entity.jpg
|
||||
SetInfo:4ED|Rare|http://magiccards.info/scans/en/4e/95.jpg
|
||||
|
||||
@@ -534,13 +534,17 @@ public class AbilityFactory {
|
||||
return Integer.parseInt(amount) * multiplier;
|
||||
}
|
||||
|
||||
// should the three getDefined functions be merged into one? Or better to have separate?
|
||||
// If we only have one, each function needs to Cast the Object to the appropriate type when using
|
||||
// But then we only need update one function at a time once the casting is everywhere.
|
||||
// Probably will move to One function solution sometime in the future
|
||||
public static ArrayList<Card> getDefinedCards(Card hostCard, String def, SpellAbility sa){
|
||||
ArrayList<Card> cards = new ArrayList<Card>();
|
||||
String defined = (def == null) ? "Self" : def;
|
||||
String defined = (def == null) ? "Self" : def; // default to Self
|
||||
|
||||
Card c = null;
|
||||
|
||||
if (defined == null || defined.equals("Self")) // default to Self
|
||||
if (defined.equals("Self"))
|
||||
c = hostCard;
|
||||
|
||||
else if (defined.equals("Equipped"))
|
||||
@@ -563,7 +567,7 @@ public class AbilityFactory {
|
||||
|
||||
public static ArrayList<Player> getDefinedPlayers(Card card, String def, SpellAbility sa){
|
||||
ArrayList<Player> players = new ArrayList<Player>();
|
||||
String defined = (def == null) ? "Self" : def;
|
||||
String defined = (def == null) ? "You" : def;
|
||||
|
||||
players = new ArrayList<Player>();
|
||||
if (defined.equals("Targeted")){
|
||||
@@ -575,30 +579,67 @@ public class AbilityFactory {
|
||||
players.addAll(parent.getTarget().getTargetPlayers());
|
||||
}
|
||||
else{
|
||||
if (defined.equals("Self") || defined.equals("Each"))
|
||||
if (defined.equals("You") || defined.equals("Each"))
|
||||
players.add(sa.getActivatingPlayer());
|
||||
if (defined.equals("Each"))
|
||||
|
||||
if (defined.equals("Opponent") || defined.equals("Each"))
|
||||
players.add(sa.getActivatingPlayer().getOpponent());
|
||||
}
|
||||
return players;
|
||||
}
|
||||
|
||||
public static SpellAbility findRootAbility(SpellAbility sa){
|
||||
if (!(sa instanceof Ability_Sub))
|
||||
return sa;
|
||||
public static ArrayList<Object> getDefinedObjects(Card card, String def, SpellAbility sa){
|
||||
ArrayList<Object> objects = new ArrayList<Object>();
|
||||
String defined = (def == null) ? "Self" : def;
|
||||
|
||||
objects = new ArrayList<Object>();
|
||||
if (defined.equals("Targeted")){
|
||||
SpellAbility parent;
|
||||
do{
|
||||
parent = ((Ability_Sub)sa).getParent();
|
||||
}while(parent.getTarget() == null && parent.getTarget().getTargets().size() == 0);
|
||||
|
||||
objects.addAll(parent.getTarget().getTargets());
|
||||
}
|
||||
else{
|
||||
// Player checks
|
||||
if (defined.equals("You") || defined.equals("Each"))
|
||||
objects.add(sa.getActivatingPlayer());
|
||||
|
||||
if (defined.equals("Opponent") || defined.equals("Each"))
|
||||
objects.add(sa.getActivatingPlayer().getOpponent());
|
||||
|
||||
// Card checks
|
||||
Card c = null;
|
||||
|
||||
if (defined.equals("Self"))
|
||||
c = card;
|
||||
|
||||
if (defined.equals("Equipped"))
|
||||
c = card.getEquippingCard();
|
||||
|
||||
if (defined.equals("Enchanted"))
|
||||
c = card.getEnchantingCard();
|
||||
|
||||
if (c != null)
|
||||
objects.add(c);
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
|
||||
public static SpellAbility findRootAbility(SpellAbility sa){
|
||||
SpellAbility parent = sa;
|
||||
do{
|
||||
while (parent instanceof Ability_Sub)
|
||||
parent = ((Ability_Sub)parent).getParent();
|
||||
}while(parent instanceof Ability_Sub);
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
public static SpellAbility findParentsTargetedCard(SpellAbility sa){
|
||||
SpellAbility parent;
|
||||
SpellAbility parent = sa;
|
||||
do{
|
||||
parent = ((Ability_Sub)sa).getParent();
|
||||
parent = ((Ability_Sub)parent).getParent();
|
||||
}while(parent.getTarget() == null && parent.getTarget().getTargetCards().size() == 0);
|
||||
|
||||
return parent;
|
||||
|
||||
@@ -19,74 +19,69 @@ import java.util.Random;
|
||||
// Note: TgtOpp should not be used, Please use ValidTgts$ Opponent instead
|
||||
}
|
||||
|
||||
public SpellAbility getAbility()
|
||||
{
|
||||
final SpellAbility abDamage = new Ability_Activated(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt())
|
||||
{
|
||||
private static final long serialVersionUID = -7560349014757367722L;
|
||||
|
||||
@Override
|
||||
public boolean canPlay(){
|
||||
return super.canPlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayAI() {
|
||||
return doCanPlayAI(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStackDescription(){
|
||||
return damageStackDescription(AF, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
doResolve(this);
|
||||
AF.getHostCard().setAbilityUsed(AF.getHostCard().getAbilityUsed() + 1);
|
||||
|
||||
}
|
||||
};//Ability_Activated
|
||||
|
||||
return abDamage;
|
||||
}
|
||||
|
||||
public SpellAbility getSpell()
|
||||
{
|
||||
final SpellAbility spDealDamage = new Spell(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()) {
|
||||
private static final long serialVersionUID = 7239608350643325111L;
|
||||
public SpellAbility getAbility() {
|
||||
final SpellAbility abDamage = new Ability_Activated(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()) {
|
||||
private static final long serialVersionUID = -7560349014757367722L;
|
||||
|
||||
@Override
|
||||
public boolean canPlay(){
|
||||
return super.canPlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayAI() {
|
||||
return doCanPlayAI(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStackDescription(){
|
||||
return damageStackDescription(AF, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
doResolve(this);
|
||||
|
||||
}
|
||||
@Override
|
||||
public boolean canPlay() {
|
||||
return super.canPlay();
|
||||
}
|
||||
|
||||
|
||||
}; // Spell
|
||||
|
||||
return spDealDamage;
|
||||
}
|
||||
@Override
|
||||
public boolean canPlayAI() {
|
||||
return doCanPlayAI(this);
|
||||
|
||||
public SpellAbility getDrawback()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStackDescription() {
|
||||
return damageStackDescription(AF, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
doResolve(this);
|
||||
AF.getHostCard().setAbilityUsed(AF.getHostCard().getAbilityUsed() + 1);
|
||||
|
||||
}
|
||||
};// Ability_Activated
|
||||
|
||||
return abDamage;
|
||||
}
|
||||
|
||||
public SpellAbility getSpell() {
|
||||
final SpellAbility spDealDamage = new Spell(AF.getHostCard(), AF.getAbCost(), AF.getAbTgt()) {
|
||||
private static final long serialVersionUID = 7239608350643325111L;
|
||||
|
||||
@Override
|
||||
public boolean canPlay() {
|
||||
return super.canPlay();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPlayAI() {
|
||||
return doCanPlayAI(this);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStackDescription() {
|
||||
return damageStackDescription(AF, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolve() {
|
||||
doResolve(this);
|
||||
|
||||
}
|
||||
|
||||
}; // Spell
|
||||
|
||||
return spDealDamage;
|
||||
}
|
||||
|
||||
public SpellAbility getDrawback() {
|
||||
final SpellAbility dbDealDamage = new Ability_Sub(AF.getHostCard(), AF.getAbTgt()) {
|
||||
private static final long serialVersionUID = 7239608350643325111L;
|
||||
|
||||
@@ -119,7 +114,7 @@ import java.util.Random;
|
||||
int restDamage = d;
|
||||
|
||||
if (!noPrevention)
|
||||
restDamage = AllZone.HumanPlayer.staticDamagePrevention(restDamage,AF.getHostCard(),false);
|
||||
restDamage = AllZone.HumanPlayer.staticDamagePrevention(restDamage, AF.getHostCard(), false);
|
||||
|
||||
if (restDamage == 0) return false;
|
||||
|
||||
@@ -157,11 +152,13 @@ import java.util.Random;
|
||||
return best;
|
||||
}
|
||||
|
||||
// Combo alert!!
|
||||
// Combo alert!! Casting burn on your own Stuffy Dolls is a waste
|
||||
/*
|
||||
PlayerZone compy = AllZone.getZone(Constant.Zone.Play, AllZone.ComputerPlayer);
|
||||
CardList cPlay = new CardList(compy.getCards());
|
||||
if(cPlay.size() > 0) for(int i = 0; i < cPlay.size(); i++)
|
||||
if(cPlay.get(i).getName().equals("Stuffy Doll")) return cPlay.get(i);
|
||||
*/
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -191,6 +188,7 @@ import java.util.Random;
|
||||
|
||||
// TODO handle proper calculation of X values based on Cost
|
||||
|
||||
// todo: this should only happen during Players EOT
|
||||
if(AF.getHostCard().equals("Stuffy Doll")) {
|
||||
return true;
|
||||
}
|
||||
@@ -220,17 +218,20 @@ import java.util.Random;
|
||||
|
||||
boolean noPrevention = params.containsKey("NoPrevention");
|
||||
|
||||
// AI handle multi-targeting?
|
||||
if (tgt == null){
|
||||
if (AF.getMapParams().containsKey("Affected")){
|
||||
String affected = AF.getMapParams().get("Affected");
|
||||
if (affected.equals("You"))
|
||||
// todo: when should AI not use an SA like Psionic Blast?
|
||||
;
|
||||
else if (affected.equals("Self"))
|
||||
// todo: when should AI not use an SA like Orcish Artillery?
|
||||
;
|
||||
}
|
||||
// todo: Improve circumstances where the Defined Damage is unwanted
|
||||
ArrayList<Object> objects = AbilityFactory.getDefinedObjects(saMe.getSourceCard(), params.get("Defined"), saMe);
|
||||
|
||||
for(Object o : objects){
|
||||
if (o instanceof Card){
|
||||
//Card c = (Card)o;
|
||||
}
|
||||
else if (o instanceof Player){
|
||||
Player p = (Player)o;
|
||||
if (p.isComputer() && dmg >= p.getLife()) // Damage from this spell will kill me
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -282,33 +283,29 @@ import java.util.Random;
|
||||
private String damageStackDescription(AbilityFactory af, SpellAbility sa){
|
||||
// when damageStackDescription is called, just build exactly what is happening
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String name = af.getHostCard().getName();
|
||||
String name = af.getHostCard().toString();
|
||||
int dmg = getNumDamage(sa);
|
||||
|
||||
ArrayList<Object> tgts = findTargets(sa);
|
||||
ArrayList<Object> tgts;
|
||||
if(sa.getTarget() == null)
|
||||
tgts = AbilityFactory.getDefinedObjects(sa.getSourceCard(), af.getMapParams().get("Defined"), sa);
|
||||
else
|
||||
tgts = sa.getTarget().getTargets();
|
||||
|
||||
if (!(sa instanceof Ability_Sub))
|
||||
sb.append(name).append(" - ");
|
||||
|
||||
sb.append("Deals ").append(dmg).append(" damage to ");
|
||||
if(tgts == null || tgts.size() == 0) {
|
||||
sb.append("itself");
|
||||
}
|
||||
else {
|
||||
for(int i = 0; i < tgts.size(); i++){
|
||||
if (i != 0)
|
||||
sb.append(" ");
|
||||
|
||||
for(int i = 0; i < tgts.size(); i++){
|
||||
if (i != 0)
|
||||
sb.append(" ");
|
||||
|
||||
Object o = tgts.get(0);
|
||||
if (o instanceof Player){
|
||||
sb.append(((Player)o).getName());
|
||||
}
|
||||
else{
|
||||
sb.append(((Card)o).getName());
|
||||
}
|
||||
Object o = tgts.get(0);
|
||||
if (o instanceof Card || o instanceof Player)
|
||||
sb.append(o.toString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
sb.append(". ");
|
||||
|
||||
if (sa.getSubAbility() != null){
|
||||
@@ -317,24 +314,6 @@ import java.util.Random;
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private ArrayList<Object> findTargets(SpellAbility saMe){
|
||||
Target tgt = AF.getAbTgt();
|
||||
ArrayList<Object> tgts;
|
||||
if (tgt != null)
|
||||
tgts = tgt.getTargets();
|
||||
else{
|
||||
tgts = new ArrayList<Object>();
|
||||
if (AF.getMapParams().containsKey("Affected")){
|
||||
String affected = AF.getMapParams().get("Affected");
|
||||
if (affected.equals("You"))
|
||||
tgts.add(saMe.getActivatingPlayer());
|
||||
else if (affected.equals("Self"))
|
||||
tgts.add(saMe.getSourceCard());
|
||||
}
|
||||
}
|
||||
return tgts;
|
||||
}
|
||||
|
||||
private void doResolve(SpellAbility saMe)
|
||||
{
|
||||
@@ -343,43 +322,35 @@ import java.util.Random;
|
||||
|
||||
boolean noPrevention = params.containsKey("NoPrevention");
|
||||
|
||||
ArrayList<Object> tgts = findTargets(saMe);
|
||||
ArrayList<Object> tgts;
|
||||
if(saMe.getTarget() == null)
|
||||
tgts = AbilityFactory.getDefinedObjects(saMe.getSourceCard(), params.get("Defined"), saMe);
|
||||
else
|
||||
tgts = saMe.getTarget().getTargets();
|
||||
|
||||
boolean targeted = (AF.getAbTgt() != null);
|
||||
|
||||
if (tgts == null || tgts.size() == 0){
|
||||
System.out.println("AF_DealDamage ("+AF.getHostCard()+") - No targets? Ok. Just making sure.");
|
||||
//if no targets, damage goes to self (Card; i.e. Stuffy Doll)
|
||||
Card c = saMe.getSourceCard();
|
||||
if(AllZone.GameAction.isCardInPlay(c)) {
|
||||
if (noPrevention)
|
||||
c.addDamageWithoutPrevention(dmg, AF.getHostCard());
|
||||
else
|
||||
c.addDamage(dmg, AF.getHostCard());
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(Object o : tgts){
|
||||
if (o instanceof Card){
|
||||
Card c = (Card)o;
|
||||
if(AllZone.GameAction.isCardInPlay(c) && (!targeted || CardFactoryUtil.canTarget(AF.getHostCard(), c))) {
|
||||
if (noPrevention)
|
||||
c.addDamageWithoutPrevention(dmg, AF.getHostCard());
|
||||
else
|
||||
c.addDamage(dmg, AF.getHostCard());
|
||||
}
|
||||
for(Object o : tgts){
|
||||
if (o instanceof Card){
|
||||
Card c = (Card)o;
|
||||
if(AllZone.GameAction.isCardInPlay(c) && (!targeted || CardFactoryUtil.canTarget(AF.getHostCard(), c))) {
|
||||
if (noPrevention)
|
||||
c.addDamageWithoutPrevention(dmg, AF.getHostCard());
|
||||
else
|
||||
c.addDamage(dmg, AF.getHostCard());
|
||||
}
|
||||
|
||||
}
|
||||
else if (o instanceof Player){
|
||||
Player p = (Player) o;
|
||||
if (!targeted || p.canTarget(AF.getHostCard())) {
|
||||
if (noPrevention)
|
||||
p.addDamageWithoutPrevention(dmg, AF.getHostCard());
|
||||
else
|
||||
p.addDamage(dmg, AF.getHostCard());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (o instanceof Player){
|
||||
Player p = (Player) o;
|
||||
if (!targeted || p.canTarget(AF.getHostCard())) {
|
||||
if (noPrevention)
|
||||
p.addDamageWithoutPrevention(dmg, AF.getHostCard());
|
||||
else
|
||||
p.addDamage(dmg, AF.getHostCard());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AF.hasSubAbility()){
|
||||
Ability_Sub abSub = saMe.getSubAbility();
|
||||
|
||||
Reference in New Issue
Block a user