Word of Command & Mindslaver interaction fixes

This commit is contained in:
L_J 2018-06-08 20:22:25 +02:00 committed by GitHub
parent 5fa69cb8a9
commit 3e180267ed
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 13 deletions

View file

@ -1,3 +1,4 @@
package mage.cards.w;
import java.util.UUID;
@ -71,11 +72,23 @@ class WordOfCommandEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player sourceController = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
MageObject sourceObject = game.getObject(source.getSourceId());
Card card = null;
if (controller != null && targetPlayer != null && sourceObject != null) {
if (sourceController != null && targetPlayer != null && sourceObject != null) {
Player controller = null;
Spell wordOfCommand = game.getSpell(source.getSourceId());
if (wordOfCommand != null) {
if (wordOfCommand.getCommandedBy() != null) {
controller = game.getPlayer(wordOfCommand.getCommandedBy());
} else {
controller = game.getPlayer(sourceController.getTurnControlledBy());
}
}
if (controller == null) {
controller = sourceController; // reset the controller to avoid NPE
}
// Look at target opponent's hand and choose a card from it
TargetCard targetCard = new TargetCard(Zone.HAND, new FilterCard());
@ -140,13 +153,15 @@ class WordOfCommandEffect extends OneShotEffect {
spell.setCommandedBy(controller.getId()); // If the chosen card is cast as a spell, you control the player while that spell is resolving
}
}
Spell wordOfCommand = game.getSpell(source.getSourceId());
wordOfCommand = game.getSpell(source.getSourceId());
if (wordOfCommand != null) {
wordOfCommand.setCommandedBy(controller.getId()); // You control the player until Word of Command finishes resolving
} else {
controller.resetOtherTurnsControlled();
targetPlayer.setGameUnderYourControl(true);
targetPlayer.setGameUnderYourControl(true, false);
if (!targetPlayer.getTurnControlledBy().equals(controller.getId())) {
controller.getPlayersUnderYourControl().remove(targetPlayer.getId());
}
}
return true;
}

View file

@ -393,7 +393,7 @@ public interface Game extends MageItem, Serializable {
boolean checkStateAndTriggered();
void playPriority(UUID activePlayerId, boolean resuming);
void resetControlAfterSpellResolve(UUID topId);
boolean endTurn(Ability source);

View file

@ -1429,12 +1429,15 @@ public abstract class GameImpl implements Game, Serializable {
if (turnController != null) {
Player targetPlayer = getPlayer(spellControllerId);
if (targetPlayer != null) {
targetPlayer.setGameUnderYourControl(true, false);
informPlayers(turnController.getLogName() + " lost control over " + targetPlayer.getLogName());
turnController.resetOtherTurnsControlled();
targetPlayer.setGameUnderYourControl(true);
if (targetPlayer.getTurnControlledBy().equals(turnController.getId())) {
turnController.getPlayersUnderYourControl().remove(targetPlayer.getId());
}
}
}
}
spell.setCommandedBy(null);
}
}
}

View file

@ -279,6 +279,8 @@ public interface Player extends MageItem, Copyable<Player> {
*/
void setTurnControlledBy(UUID playerId);
List<UUID> getTurnControllers();
UUID getTurnControlledBy();
/**
@ -306,6 +308,8 @@ public interface Player extends MageItem, Copyable<Player> {
*/
void setGameUnderYourControl(boolean value);
void setGameUnderYourControl(boolean value, boolean fullRestore);
boolean isTestMode();
void setTestMode(boolean value);
@ -852,6 +856,8 @@ public interface Player extends MageItem, Copyable<Player> {
Set<UUID> getUsersAllowedToSeeHandCards();
void setPayManaMode(boolean payManaMode);
boolean isInPayManaMode();
void setMatchPlayer(MatchPlayer matchPlayer);

View file

@ -156,6 +156,7 @@ public abstract class PlayerImpl implements Player, Serializable {
protected boolean isGameUnderControl = true;
protected UUID turnController;
protected List<UUID> turnControllers = new ArrayList<>();
protected Set<UUID> playersUnderYourControl = new HashSet<>();
protected Set<UUID> usersAllowedToSeeHandCards = new HashSet<>();
@ -263,6 +264,8 @@ public abstract class PlayerImpl implements Player, Serializable {
this.isGameUnderControl = player.isGameUnderControl;
this.turnController = player.turnController;
this.turnControllers.clear();
this.turnControllers.addAll(player.turnControllers);
this.passed = player.passed;
this.passedTurn = player.passedTurn;
@ -343,6 +346,8 @@ public abstract class PlayerImpl implements Player, Serializable {
this.isGameUnderControl = player.isGameUnderControl();
this.turnController = player.getTurnControlledBy();
this.turnControllers.clear();
this.turnControllers.addAll(player.getTurnControllers());
this.reachedNextTurnAfterLeaving = player.hasReachedNextTurnAfterLeaving();
this.castSourceIdWithAlternateMana = player.getCastSourceIdWithAlternateMana();
this.castSourceIdManaCosts = player.getCastSourceIdManaCosts();
@ -398,6 +403,7 @@ public abstract class PlayerImpl implements Player, Serializable {
this.turns = 0;
this.isGameUnderControl = true;
this.turnController = this.getId();
this.turnControllers.clear();
this.playersUnderYourControl.clear();
this.passed = false;
@ -520,13 +526,13 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public void controlPlayersTurn(Game game, UUID playerId) {
Player player = game.getPlayer(playerId);
player.setTurnControlledBy(this.getId());
game.informPlayers(getLogName() + " controls the turn of " + player.getLogName());
if (!playerId.equals(this.getId())) {
this.playersUnderYourControl.add(playerId);
Player player = game.getPlayer(playerId);
if (!player.hasLeft() && !player.hasLost()) {
player.setGameUnderYourControl(false);
player.setTurnControlledBy(this.getId());
game.informPlayers(getLogName() + " controls the turn of " + player.getLogName());
}
DelayedTriggeredAbility ability = new AtTheEndOfTurnStepPostDelayedTriggeredAbility(new LoseControlOnOtherPlayersControllerEffect(this.getLogName(), player.getLogName()));
ability.setSourceId(getId());
@ -538,6 +544,12 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public void setTurnControlledBy(UUID playerId) {
this.turnController = playerId;
this.turnControllers.add(playerId);
}
@Override
public List<UUID> getTurnControllers() {
return this.turnControllers;
}
@Override
@ -563,9 +575,27 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public void setGameUnderYourControl(boolean value) {
setGameUnderYourControl(value, true);
}
@Override
public void setGameUnderYourControl(boolean value, boolean fullRestore) {
this.isGameUnderControl = value;
if (isGameUnderControl) {
this.turnController = getId();
if (fullRestore) {
this.turnControllers.clear();
this.turnController = getId();
} else {
if (turnControllers.size() > 0) {
this.turnControllers.remove(turnControllers.size() - 1);
}
if (turnControllers.isEmpty()) {
this.turnController = getId();
} else {
this.turnController = turnControllers.get(turnControllers.size() - 1);
isGameUnderControl = false;
}
}
}
}
@ -980,6 +1010,11 @@ public abstract class PlayerImpl implements Player, Serializable {
return castSourceIdManaCosts;
}
@Override
public void setPayManaMode(boolean payManaMode) {
this.payManaMode = payManaMode;
}
@Override
public boolean isInPayManaMode() {
return payManaMode;