mirror of
https://github.com/correl/mage.git
synced 2025-04-06 17:00:12 -09:00
Fixed some possible null pointer exceptions.
This commit is contained in:
parent
b23d987fe7
commit
1ef74f3293
6 changed files with 164 additions and 79 deletions
Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human
Mage/src/mage
abilities/effects
cards
game
|
@ -251,7 +251,7 @@ public class HumanPlayer extends PlayerImpl {
|
|||
|
||||
@Override
|
||||
public boolean choose(Outcome outcome, Choice choice, Game game) {
|
||||
if (outcome.equals(Outcome.PutManaInPool)) {
|
||||
if (Outcome.PutManaInPool.equals(outcome)) {
|
||||
if (currentlyUnpaidMana != null
|
||||
&& ManaUtil.tryToAutoSelectAManaColor(choice, currentlyUnpaidMana)) {
|
||||
return true;
|
||||
|
|
|
@ -51,13 +51,15 @@ import mage.target.common.TargetCardInGraveyard;
|
|||
/**
|
||||
* Cards with the Aura subtype don't change the zone they are in, if there is no
|
||||
* valid target on the battlefield. Also, when entering the battlefield and it
|
||||
* was not cast (so from Zone != Hand), this effect gets the target to whitch to attach it
|
||||
* and adds the Aura the the battlefield and attachs it to the target.
|
||||
* was not cast (so from Zone != Hand), this effect gets the target to whitch to
|
||||
* attach it and adds the Aura the the battlefield and attachs it to the target.
|
||||
* The "attachTo:" value in game state has to be set therefore.
|
||||
*
|
||||
* If no "attachTo:" value is defined, the controlling player has to chose the aura target.
|
||||
* If no "attachTo:" value is defined, the controlling player has to chose the
|
||||
* aura target.
|
||||
*
|
||||
* This effect is automatically added to ContinuousEffects at the start of a game
|
||||
* This effect is automatically added to ContinuousEffects at the start of a
|
||||
* game
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
|
@ -122,7 +124,8 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
|
|||
}
|
||||
Player player = game.getPlayer(card.getOwnerId());
|
||||
Outcome auraOutcome = Outcome.BoostCreature;
|
||||
Ability: for (Ability ability:card.getAbilities()) {
|
||||
Ability:
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
for (Effect effect : ability.getEffects()) {
|
||||
if (effect instanceof AttachEffect) {
|
||||
|
@ -167,8 +170,11 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
|
|||
game.getBattlefield().addPermanent(permanent);
|
||||
card.setZone(Zone.BATTLEFIELD, game);
|
||||
game.applyEffects();
|
||||
permanent.entersBattlefield(event.getSourceId(), game, fromZone, true);
|
||||
boolean entered = permanent.entersBattlefield(event.getSourceId(), game, fromZone, true);
|
||||
game.applyEffects();
|
||||
if (!entered) {
|
||||
return false;
|
||||
}
|
||||
game.fireEvent(new ZoneChangeEvent(permanent, controllerId, fromZone, Zone.BATTLEFIELD));
|
||||
|
||||
if (targetCard != null) {
|
||||
|
|
|
@ -421,13 +421,17 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
game.setZone(objectId, Zone.BATTLEFIELD);
|
||||
game.setScopeRelevant(true);
|
||||
game.applyEffects();
|
||||
permanent.entersBattlefield(sourceId, game, event.getFromZone(), true);
|
||||
boolean entered = permanent.entersBattlefield(sourceId, game, event.getFromZone(), true);
|
||||
game.setScopeRelevant(false);
|
||||
game.applyEffects();
|
||||
if (entered) {
|
||||
if (flag) {
|
||||
permanent.setTapped(true);
|
||||
}
|
||||
event.setTarget(permanent);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Card sourceCard = game.getCard(sourceId);
|
||||
|
@ -603,12 +607,14 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
game.setScopeRelevant(true);
|
||||
permanent.setTapped(tapped);
|
||||
permanent.setFaceDown(facedown, game);
|
||||
permanent.entersBattlefield(sourceId, game, event.getFromZone(), true);
|
||||
boolean entered = permanent.entersBattlefield(sourceId, game, event.getFromZone(), true);
|
||||
game.setScopeRelevant(false);
|
||||
game.applyEffects();
|
||||
if (entered) {
|
||||
game.addSimultaneousEvent(new ZoneChangeEvent(permanent, event.getPlayerId(), fromZone, Zone.BATTLEFIELD));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (facedown) {
|
||||
this.setFaceDown(false, game);
|
||||
}
|
||||
|
|
|
@ -810,6 +810,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
// check now, if it already blocks a creature that mustBeBlockedByAtLeastOne
|
||||
if (possibleBlocker.getBlocking() > 0) {
|
||||
CombatGroup combatGroupOfPossibleBlocker = findGroupOfBlocker(possibleBlockerId);
|
||||
if (combatGroupOfPossibleBlocker != null) {
|
||||
for (UUID blockedAttackerId : combatGroupOfPossibleBlocker.getAttackers()) {
|
||||
if (mustBeBlockedByAtLeastOne.containsKey(blockedAttackerId)) {
|
||||
// blocks a creature that has to be blocked by at least one
|
||||
|
@ -828,6 +829,7 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -947,9 +949,12 @@ public class Combat implements Serializable, Copyable<Combat> {
|
|||
if (!canDefenderBeAttacked(attackerId, defenderId, game)) {
|
||||
return false;
|
||||
}
|
||||
Permanent attacker = game.getPermanent(attackerId);
|
||||
if (attacker == null) {
|
||||
return false;
|
||||
}
|
||||
CombatGroup newGroup = new CombatGroup(defenderId, defender != null, defender != null ? defender.getControllerId() : defenderId);
|
||||
newGroup.attackers.add(attackerId);
|
||||
Permanent attacker = game.getPermanent(attackerId);
|
||||
attacker.setAttacking(true);
|
||||
groups.add(newGroup);
|
||||
return true;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.game.permanent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -45,60 +44,89 @@ import mage.game.Game;
|
|||
public interface Permanent extends Card, Controllable {
|
||||
|
||||
void setControllerId(UUID controllerId);
|
||||
|
||||
boolean isTapped();
|
||||
|
||||
boolean untap(Game game);
|
||||
|
||||
boolean tap(Game game);
|
||||
|
||||
/**
|
||||
* use tap(game)
|
||||
* <p>setTapped doesn't trigger TAPPED event and should be used
|
||||
* only if you want permanent to enter battlefield tapped</p>
|
||||
* <p>
|
||||
* setTapped doesn't trigger TAPPED event and should be used only if you
|
||||
* want permanent to enter battlefield tapped</p>
|
||||
*
|
||||
* @param tapped
|
||||
* @deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
void setTapped(boolean tapped);
|
||||
|
||||
boolean canTap();
|
||||
|
||||
boolean isFlipped();
|
||||
|
||||
boolean unflip(Game game);
|
||||
|
||||
boolean flip(Game game);
|
||||
|
||||
boolean transform(Game game);
|
||||
|
||||
boolean isTransformed();
|
||||
|
||||
void setTransformed(boolean value);
|
||||
|
||||
boolean isPhasedIn();
|
||||
|
||||
boolean phaseIn(Game game);
|
||||
|
||||
boolean phaseOut(Game game);
|
||||
|
||||
boolean isMonstrous();
|
||||
|
||||
void setMonstrous(boolean value);
|
||||
|
||||
boolean isRenowned();
|
||||
|
||||
void setRenowned(boolean value);
|
||||
|
||||
void setCardNumber(int cid);
|
||||
|
||||
void setExpansionSetCode(String expansionSetCode);
|
||||
|
||||
void setRarity(Rarity rarity);
|
||||
|
||||
void setFlipCard(boolean flipCard);
|
||||
|
||||
void setFlipCardName(String flipCardName);
|
||||
|
||||
void setSecondCardFace(Card card);
|
||||
|
||||
Counters getCounters();
|
||||
|
||||
List<UUID> getAttachments();
|
||||
|
||||
UUID getAttachedTo();
|
||||
|
||||
void attachTo(UUID permanentId, Game game);
|
||||
|
||||
boolean addAttachment(UUID permanentId, Game game);
|
||||
|
||||
boolean removeAttachment(UUID permanentId, Game game);
|
||||
|
||||
boolean canBeTargetedBy(MageObject source, UUID controllerId, Game game);
|
||||
|
||||
boolean hasProtectionFrom(MageObject source, Game game);
|
||||
|
||||
boolean cantBeEnchantedBy(MageObject source, Game game);
|
||||
|
||||
boolean wasControlledFromStartOfControllerTurn();
|
||||
|
||||
boolean hasSummoningSickness();
|
||||
|
||||
int getDamage();
|
||||
|
||||
int damage(int damage, UUID sourceId, Game game, boolean combat, boolean preventable);
|
||||
|
||||
int damage(int damage, UUID sourceId, Game game, boolean combat, boolean preventable, ArrayList<UUID> appliedEffects);
|
||||
|
@ -114,58 +142,83 @@ public interface Permanent extends Card, Controllable {
|
|||
* @return
|
||||
*/
|
||||
int markDamage(int damage, UUID sourceId, Game game, boolean preventable, boolean combat);
|
||||
|
||||
int applyDamage(Game game);
|
||||
|
||||
void removeAllDamage(Game game);
|
||||
|
||||
void reset(Game game);
|
||||
|
||||
boolean destroy(UUID sourceId, Game game, boolean noRegen);
|
||||
|
||||
boolean sacrifice(UUID sourceId, Game game);
|
||||
|
||||
boolean regenerate(UUID sourceId, Game game);
|
||||
|
||||
boolean fight(Permanent fightTarget, Ability source, Game game);
|
||||
|
||||
void entersBattlefield(UUID sourceId, Game game, Zone fromZone, boolean fireEvent);
|
||||
boolean entersBattlefield(UUID sourceId, Game game, Zone fromZone, boolean fireEvent);
|
||||
|
||||
String getValue();
|
||||
|
||||
@Deprecated
|
||||
void addAbility(Ability ability);
|
||||
|
||||
@Deprecated
|
||||
void addAbility(Ability ability, Game game);
|
||||
|
||||
void addAbility(Ability ability, UUID sourceId, Game game);
|
||||
|
||||
void addAbility(Ability ability, UUID sourceId, Game game, boolean createNewId);
|
||||
|
||||
void removeAllAbilities(UUID sourceId, Game game);
|
||||
|
||||
void addLoyaltyUsed();
|
||||
|
||||
boolean canLoyaltyBeUsed(Game game);
|
||||
|
||||
|
||||
public void resetControl();
|
||||
|
||||
boolean changeControllerId(UUID controllerId, Game game);
|
||||
|
||||
boolean checkControlChanged(Game game);
|
||||
|
||||
void beginningOfTurn(Game game);
|
||||
|
||||
void endOfTurn(Game game);
|
||||
|
||||
int getTurnsOnBattlefield();
|
||||
|
||||
void addPower(int power);
|
||||
|
||||
void addToughness(int toughness);
|
||||
|
||||
boolean isAttacking();
|
||||
|
||||
int getBlocking();
|
||||
|
||||
void setAttacking(boolean attacking);
|
||||
|
||||
void setBlocking(int blocking);
|
||||
|
||||
int getMaxBlocks();
|
||||
|
||||
void setMaxBlocks(int maxBlocks);
|
||||
|
||||
int getMinBlockedBy();
|
||||
|
||||
void setMinBlockedBy(int minBlockedBy);
|
||||
|
||||
int getMaxBlockedBy();
|
||||
|
||||
boolean isRemovedFromCombat();
|
||||
|
||||
void setRemovedFromCombat(boolean removedFromCombat);
|
||||
|
||||
/**
|
||||
* Sets the maximum number of blockers the creature can be blocked by.
|
||||
* Default = 0 which means there is no restriction in the number of blockers.
|
||||
* Default = 0 which means there is no restriction in the number of
|
||||
* blockers.
|
||||
*
|
||||
* @param maxBlockedBy maximum number of blockers
|
||||
*/
|
||||
|
@ -180,11 +233,14 @@ public interface Permanent extends Card, Controllable {
|
|||
* @return
|
||||
*/
|
||||
boolean canAttack(UUID defenderId, Game game);
|
||||
|
||||
boolean canBlock(UUID attackerId, Game game);
|
||||
|
||||
boolean canBlockAny(Game game);
|
||||
|
||||
/**
|
||||
* Checks by restriction effects if the permanent can use activated abilities
|
||||
* Checks by restriction effects if the permanent can use activated
|
||||
* abilities
|
||||
*
|
||||
* @param game
|
||||
* @return true - permanent can use activated abilities
|
||||
|
@ -192,11 +248,15 @@ public interface Permanent extends Card, Controllable {
|
|||
boolean canUseActivatedAbilities(Game game);
|
||||
|
||||
boolean removeFromCombat(Game game);
|
||||
|
||||
boolean removeFromCombat(Game game, boolean withInfo);
|
||||
|
||||
boolean isDeathtouched();
|
||||
|
||||
/**
|
||||
* Returns a list of object refrences that dealt damage this turn to this permanent
|
||||
* Returns a list of object refrences that dealt damage this turn to this
|
||||
* permanent
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
HashSet<MageObjectReference> getDealtDamageByThisTurn();
|
||||
|
@ -222,13 +282,14 @@ public interface Permanent extends Card, Controllable {
|
|||
* Get card that was imprinted on this one.
|
||||
*
|
||||
* Can be null if no card was imprinted.
|
||||
*
|
||||
* @return Imprinted card UUID.
|
||||
*/
|
||||
List<UUID> getImprinted();
|
||||
|
||||
/**
|
||||
* Allows to connect any card to permanent.
|
||||
* Very similar to Imprint except that it is for internal use only.
|
||||
* Allows to connect any card to permanent. Very similar to Imprint except
|
||||
* that it is for internal use only.
|
||||
*
|
||||
* @param key
|
||||
* @param connectedCard
|
||||
|
@ -236,8 +297,9 @@ public interface Permanent extends Card, Controllable {
|
|||
void addConnectedCard(String key, UUID connectedCard);
|
||||
|
||||
/**
|
||||
* Returns connected cards.
|
||||
* Very similar to Imprint except that it is for internal use only.
|
||||
* Returns connected cards. Very similar to Imprint except that it is for
|
||||
* internal use only.
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
|
@ -245,6 +307,7 @@ public interface Permanent extends Card, Controllable {
|
|||
|
||||
/**
|
||||
* Clear all connected cards.
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
void clearConnectedCards(String key);
|
||||
|
@ -269,9 +332,11 @@ public interface Permanent extends Card, Controllable {
|
|||
void clearPairedCard();
|
||||
|
||||
void setMorphed(boolean value);
|
||||
|
||||
boolean isMorphed();
|
||||
|
||||
void setManifested(boolean value);
|
||||
|
||||
boolean isManifested();
|
||||
|
||||
@Override
|
||||
|
@ -280,5 +345,6 @@ public interface Permanent extends Card, Controllable {
|
|||
// Simple int counter to set a timewise create order , the lower the number the earlier the object was created
|
||||
// if objects enter the battlefield at the same time they can get (and should) get the same number.
|
||||
int getCreateOrder();
|
||||
|
||||
void setCreateOrder(int createOrder);
|
||||
}
|
||||
|
|
|
@ -159,9 +159,10 @@ public class Token extends MageObjectImpl {
|
|||
this.lastAddedTokenId = newToken.getId();
|
||||
game.setScopeRelevant(true);
|
||||
game.applyEffects();
|
||||
newToken.entersBattlefield(sourceId, game, Zone.OUTSIDE, true);
|
||||
boolean entered = newToken.entersBattlefield(sourceId, game, Zone.OUTSIDE, true);
|
||||
game.setScopeRelevant(false);
|
||||
game.applyEffects();
|
||||
if (entered) {
|
||||
game.fireEvent(new ZoneChangeEvent(newToken, event.getPlayerId(), Zone.OUTSIDE, Zone.BATTLEFIELD));
|
||||
if (attacking && game.getCombat() != null) {
|
||||
game.getCombat().addAttackingCreature(newToken.getId(), game);
|
||||
|
@ -170,6 +171,7 @@ public class Token extends MageObjectImpl {
|
|||
game.informPlayers(controller.getLogName() + " puts a " + newToken.getLogName() + " token onto the battlefield");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue