mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-11 16:26:22 +00:00
Compare commits
1 Commits
ee045d854d
...
bestowStat
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e635f811ff |
@@ -4,6 +4,8 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
@@ -51,13 +53,18 @@ public abstract class SpellAbilityAi {
|
||||
* Handles the AI decision to play a "main" SpellAbility
|
||||
*/
|
||||
protected boolean canPlayAI(final Player ai, final SpellAbility sa) {
|
||||
final Card source = sa.getHostCard();
|
||||
Card source = sa.getHostCard();
|
||||
try {
|
||||
source = ObjectUtils.firstNonNull(sa.getAlternateHost(source), source);
|
||||
|
||||
if (sa.getRestrictions() != null && !sa.getRestrictions().canPlay(source, sa)) {
|
||||
return false;
|
||||
if (sa.getRestrictions() != null && !sa.getRestrictions().canPlay(source, sa)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return canPlayWithoutRestrict(ai, sa);
|
||||
} finally {
|
||||
sa.undoAlternateHost(source);
|
||||
}
|
||||
|
||||
return canPlayWithoutRestrict(ai, sa);
|
||||
}
|
||||
|
||||
protected boolean canPlayWithoutRestrict(final Player ai, final SpellAbility sa) {
|
||||
|
||||
@@ -262,6 +262,8 @@ public final class GameActionUtil {
|
||||
|
||||
// reset static abilities
|
||||
if (lkicheck) {
|
||||
// unanimate host again
|
||||
sa.undoAlternateHost(newHost);
|
||||
game.getAction().checkStaticAbilities(false);
|
||||
// clear delayed changes, this check should not have updated the view
|
||||
game.getTracker().clearDelayed();
|
||||
@@ -468,6 +470,7 @@ public final class GameActionUtil {
|
||||
|
||||
// reset static abilities
|
||||
if (lkicheck) {
|
||||
sa.undoAlternateHost(newHost);
|
||||
game.getAction().checkStaticAbilities(false);
|
||||
// clear delayed changes, this check should not have updated the view
|
||||
game.getTracker().clearDelayed();
|
||||
|
||||
@@ -250,7 +250,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
private int exertThisTurn = 0;
|
||||
private PlayerCollection exertedByPlayer = new PlayerCollection();
|
||||
|
||||
private long bestowTimestamp = -1;
|
||||
private Card bestowEffect = null;
|
||||
private long transformedTimestamp = 0;
|
||||
private long prototypeTimestamp = -1;
|
||||
private long mutatedTimestamp = -1;
|
||||
@@ -3741,7 +3741,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
public final void addLeavesPlayCommand(final GameCommand c) {
|
||||
leavePlayCommandList.add(c);
|
||||
}
|
||||
|
||||
|
||||
public void addStaticCommandList(Object[] objects) {
|
||||
staticCommandList.add(objects);
|
||||
}
|
||||
@@ -4757,7 +4757,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
public void addDraftAction(String s) {
|
||||
draftActions.add(s);
|
||||
}
|
||||
|
||||
|
||||
private int intensity = 0;
|
||||
public final void addIntensity(final int n) {
|
||||
intensity += n;
|
||||
@@ -6827,43 +6827,40 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
}
|
||||
|
||||
public final void animateBestow() {
|
||||
animateBestow(true);
|
||||
}
|
||||
public final void animateBestow(final boolean updateView) {
|
||||
if (isBestowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bestowTimestamp = getGame().getNextTimestamp();
|
||||
addChangedCardTypes(new CardType(Collections.singletonList("Aura"), true),
|
||||
new CardType(Collections.singletonList("Creature"), true),
|
||||
false, EnumSet.of(RemoveType.EnchantmentTypes), bestowTimestamp, 0, updateView, false);
|
||||
addChangedCardKeywords(Collections.singletonList("Enchant creature"), Lists.newArrayList(),
|
||||
false, bestowTimestamp, null, updateView);
|
||||
bestowEffect = SpellAbilityEffect.createEffect(null, this, this.getController(), "Bestow Effect", getImageKey(), getGame().getNextTimestamp());
|
||||
bestowEffect.setRenderForUI(false);
|
||||
bestowEffect.addRemembered(this);
|
||||
|
||||
String s = "Mode$ Continuous | AffectedDefined$ RememberedCard | EffectZone$ Command "
|
||||
+ " | AddType$ Aura | RemoveType$ Creature | RemoveEnchantmentTypes$ True | AddKeyword$ Enchant creature";
|
||||
bestowEffect.addStaticAbility(s);
|
||||
|
||||
GameCommand until = SpellAbilityEffect.exileEffectCommand(getGame(), bestowEffect);
|
||||
addLeavesPlayCommand(until);
|
||||
getGame().getAction().moveToCommand(bestowEffect, null);
|
||||
}
|
||||
|
||||
public final void unanimateBestow() {
|
||||
unanimateBestow(true);
|
||||
}
|
||||
public final void unanimateBestow(final boolean updateView) {
|
||||
if (!isBestowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
removeChangedCardKeywords(bestowTimestamp, 0, updateView);
|
||||
removeChangedCardTypes(bestowTimestamp, 0, updateView);
|
||||
bestowTimestamp = -1;
|
||||
getGame().getAction().exileEffect(bestowEffect);
|
||||
bestowEffect = null;
|
||||
}
|
||||
|
||||
public final boolean isBestowed() {
|
||||
return bestowTimestamp != -1;
|
||||
return bestowEffect != null;
|
||||
}
|
||||
|
||||
public final long getBestowTimestamp() {
|
||||
return bestowTimestamp;
|
||||
public final Card getBestowEffect() {
|
||||
return this.bestowEffect;
|
||||
}
|
||||
public final void setBestowTimestamp(final long t) {
|
||||
bestowTimestamp = t;
|
||||
public void setBestowEffect(final Card effect) {
|
||||
this.bestowEffect = effect;
|
||||
}
|
||||
|
||||
public final long getGameTimestamp() {
|
||||
|
||||
@@ -314,6 +314,9 @@ public class CardCopyService {
|
||||
if (copyFrom.isSuspected()) {
|
||||
newCopy.setSuspectedEffect(getLKICopy(copyFrom.getSuspectedEffect(), cachedMap));
|
||||
}
|
||||
if (copyFrom.isBestowed()) {
|
||||
newCopy.setBestowEffect(getLKICopy(copyFrom.getBestowEffect(), cachedMap));
|
||||
}
|
||||
|
||||
newCopy.setColor(copyFrom.getColor().getColor());
|
||||
newCopy.setPhasedOut(copyFrom.getPhasedOut());
|
||||
@@ -369,8 +372,6 @@ public class CardCopyService {
|
||||
newCopy.setGameTimestamp(copyFrom.getGameTimestamp());
|
||||
newCopy.setLayerTimestamp(copyFrom.getLayerTimestamp());
|
||||
|
||||
newCopy.setBestowTimestamp(copyFrom.getBestowTimestamp());
|
||||
|
||||
newCopy.setForetold(copyFrom.isForetold());
|
||||
newCopy.setTurnInZone(copyFrom.getTurnInZone());
|
||||
newCopy.setForetoldCostByEffect(copyFrom.isForetoldCostByEffect());
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@@ -39,7 +39,7 @@ import forge.game.zone.ZoneType;
|
||||
* <p>
|
||||
* Abstract Spell class.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Forge
|
||||
* @version $Id$
|
||||
*/
|
||||
@@ -96,15 +96,19 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
||||
card.setController(activator, 0);
|
||||
}
|
||||
|
||||
card = ObjectUtils.firstNonNull(getAlternateHost(card), card);
|
||||
try {
|
||||
card = ObjectUtils.firstNonNull(getAlternateHost(card), card);
|
||||
|
||||
if (!this.getRestrictions().canPlay(card, this)) {
|
||||
return false;
|
||||
}
|
||||
if (!this.getRestrictions().canPlay(card, this)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!activator.getController().isFullControl(FullControlFlag.AllowPaymentStartWithMissingResources) &&
|
||||
!CostPayment.canPayAdditionalCosts(this.getPayCosts(), this, false)) {
|
||||
return false;
|
||||
if (!activator.getController().isFullControl(FullControlFlag.AllowPaymentStartWithMissingResources) &&
|
||||
!CostPayment.canPayAdditionalCosts(this.getPayCosts(), this, false)) {
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
undoAlternateHost(card);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -165,7 +169,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
||||
source = CardCopyService.getLKICopy(source);
|
||||
}
|
||||
|
||||
source.animateBestow(false);
|
||||
source.animateBestow();
|
||||
lkicheck = true;
|
||||
} else if (isCastFaceDown()) {
|
||||
// need a copy of the card to turn facedown without trigger anything
|
||||
@@ -205,6 +209,12 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
||||
return lkicheck ? source : null;
|
||||
}
|
||||
|
||||
public void undoAlternateHost(Card source) {
|
||||
if (isBestow()) {
|
||||
source.unanimateBestow();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCounterableBy(final SpellAbility sa) {
|
||||
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(getHostCard());
|
||||
repParams.put(AbilityKey.SpellAbility, this);
|
||||
|
||||
@@ -2595,6 +2595,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
||||
return null;
|
||||
}
|
||||
|
||||
public void undoAlternateHost(Card source) {
|
||||
|
||||
}
|
||||
|
||||
public boolean hasOptionalKeywordAmount(KeywordInterface kw) {
|
||||
long staticId = kw.getStatic() == null ? 0 : kw.getStatic().getId();
|
||||
return this.optionalKeywordAmount.contains(kw.getKeyword(), Pair.of(kw.getIdx(), staticId));
|
||||
|
||||
@@ -208,24 +208,6 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
||||
public final boolean checkZoneRestrictions(final Card c, final SpellAbility sa) {
|
||||
final Player activator = sa.getActivatingPlayer();
|
||||
final Zone cardZone = c.getLastKnownZone();
|
||||
Card cp = c;
|
||||
|
||||
// for Bestow need to check the animated State
|
||||
if (sa.isSpell() && sa.isBestow()) {
|
||||
// already bestowed or in battlefield, no need to check for spell
|
||||
if (c.isInPlay()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if card is lki and bestowed, then do nothing there, it got already animated
|
||||
if (!(c.isLKI() && c.isBestowed())) {
|
||||
if (!c.isLKI()) {
|
||||
cp = CardCopyService.getLKICopy(c);
|
||||
}
|
||||
|
||||
cp.animateBestow(!cp.isLKI());
|
||||
}
|
||||
}
|
||||
|
||||
if (cardZone == null || this.getZone() == null || !cardZone.is(this.getZone())) {
|
||||
// If Card is not in the default activating zone, do some additional checks
|
||||
@@ -277,7 +259,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
||||
}
|
||||
|
||||
if (params.containsKey("Affected")) {
|
||||
if (!cp.isValid(params.get("Affected").split(","), activator, o.getHost(), o.getAbility())) {
|
||||
if (!c.isValid(params.get("Affected").split(","), activator, o.getHost(), o.getAbility())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@ public class HumanPlay {
|
||||
if (rollback.isInZone(ZoneType.Exile)) {
|
||||
rollback.addMayLookTemp(p);
|
||||
}
|
||||
} else {
|
||||
sa.undoAlternateHost(rollback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +153,9 @@ public class HumanPlay {
|
||||
source.setSplitStateToPlayAbility(sa);
|
||||
|
||||
final HumanPlaySpellAbility req = new HumanPlaySpellAbility(controller, sa);
|
||||
req.playAbility(mayChooseNewTargets, true, false);
|
||||
if (!req.playAbility(mayChooseNewTargets, true, false)) {
|
||||
sa.undoAlternateHost(source);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user