mirror of
https://github.com/correl/mage.git
synced 2025-01-11 19:13:02 +00:00
Controlling other players turns (only effect, replacing message is not implemented yet). ControlTargetPlayerNextTurnEffect.
This commit is contained in:
parent
25b78736c6
commit
752569874d
9 changed files with 327 additions and 12 deletions
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.common.delayed;
|
||||
|
||||
import mage.abilities.DelayedTriggeredAbility;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
public class AtTheEndOfTurnDelayedTriggeredAbility extends DelayedTriggeredAbility<AtTheEndOfTurnDelayedTriggeredAbility> {
|
||||
|
||||
public AtTheEndOfTurnDelayedTriggeredAbility(Effect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
public AtTheEndOfTurnDelayedTriggeredAbility(Effect effect, boolean usesStack) {
|
||||
super(effect);
|
||||
this.usesStack = usesStack;
|
||||
}
|
||||
|
||||
|
||||
public AtTheEndOfTurnDelayedTriggeredAbility(AtTheEndOfTurnDelayedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtTheEndOfTurnDelayedTriggeredAbility copy() {
|
||||
return new AtTheEndOfTurnDelayedTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.COMBAT_PHASE_POST) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "At end of turn " + modes.getText();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.effects.common;
|
||||
|
||||
import mage.Constants.Outcome;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author nantuko
|
||||
*/
|
||||
public class LoseControlOnOtherPlayersControllerEffect extends OneShotEffect<LoseControlOnOtherPlayersControllerEffect> {
|
||||
|
||||
public LoseControlOnOtherPlayersControllerEffect() {
|
||||
super(Outcome.Detriment);
|
||||
}
|
||||
|
||||
public LoseControlOnOtherPlayersControllerEffect(final LoseControlOnOtherPlayersControllerEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoseControlOnOtherPlayersControllerEffect copy() {
|
||||
return new LoseControlOnOtherPlayersControllerEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
player.resetOtherTurnsControlled();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.effects.common.turn;
|
||||
|
||||
import mage.Constants;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.game.Game;
|
||||
import mage.game.turn.TurnMod;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
public class ControlTargetPlayerNextTurnEffect extends OneShotEffect<ControlTargetPlayerNextTurnEffect> {
|
||||
|
||||
public ControlTargetPlayerNextTurnEffect() {
|
||||
super(Constants.Outcome.Benefit);
|
||||
staticText = "You control target player during that player's next turn. (You see all cards that player could see and make all decisions for the player.)";
|
||||
}
|
||||
|
||||
public ControlTargetPlayerNextTurnEffect(ControlTargetPlayerNextTurnEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
UUID targetId = source.getFirstTarget();
|
||||
UUID controllerId = source.getControllerId();
|
||||
if (targetId != null && controllerId != null && !targetId.equals(controllerId)) {
|
||||
game.getState().getTurnMods().add(new TurnMod(targetId, controllerId));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ControlTargetPlayerNextTurnEffect copy() {
|
||||
return new ControlTargetPlayerNextTurnEffect();
|
||||
}
|
||||
}
|
|
@ -56,8 +56,10 @@ public class CleanupStep extends Step<CleanupStep> {
|
|||
super.beginStep(game, activePlayerId);
|
||||
Player activePlayer = game.getPlayer(activePlayerId);
|
||||
//20091005 - 514.1
|
||||
if (!activePlayer.hasLeft() && !activePlayer.hasLost())
|
||||
if (!activePlayer.hasLeft() && !activePlayer.hasLost()) {
|
||||
activePlayer.discardToMax(game);
|
||||
activePlayer.setGameUnderYourControl(true);
|
||||
}
|
||||
//20100423 - 514.2
|
||||
game.getBattlefield().endOfTurn(activePlayerId, game);
|
||||
game.getState().removeEotEffects(game);
|
||||
|
|
|
@ -106,6 +106,8 @@ public class Turn implements Serializable {
|
|||
if (game.getState().getTurnMods().skipTurn(activePlayerId))
|
||||
return;
|
||||
|
||||
checkTurnIsControlledByOtherPlayer(game, activePlayerId);
|
||||
|
||||
this.activePlayerId = activePlayerId;
|
||||
resetCounts();
|
||||
game.getPlayer(activePlayerId).beginTurn(game);
|
||||
|
@ -127,6 +129,13 @@ public class Turn implements Serializable {
|
|||
playExtraTurns(game);
|
||||
}
|
||||
|
||||
private void checkTurnIsControlledByOtherPlayer(Game game, UUID activePlayerId) {
|
||||
UUID newControllerId = game.getState().getTurnMods().controlsTurn(activePlayerId);
|
||||
if (newControllerId != null && !newControllerId.equals(activePlayerId)) {
|
||||
game.getPlayer(newControllerId).controlPlayersTurn(game, activePlayerId);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetCounts() {
|
||||
for (Phase phase: phases) {
|
||||
phase.resetCount();
|
||||
|
|
|
@ -41,6 +41,7 @@ import mage.Constants.TurnPhase;
|
|||
public class TurnMod implements Serializable {
|
||||
|
||||
private UUID playerId;
|
||||
private UUID newControllerId;
|
||||
private boolean extraTurn;
|
||||
private boolean skipTurn;
|
||||
private TurnPhase extraPhase;
|
||||
|
@ -58,8 +59,14 @@ public class TurnMod implements Serializable {
|
|||
this.extraTurn = true;
|
||||
}
|
||||
|
||||
public TurnMod(UUID playerId, UUID newControllerId) {
|
||||
this.playerId = playerId;
|
||||
this.newControllerId = newControllerId;
|
||||
}
|
||||
|
||||
public TurnMod(final TurnMod mod) {
|
||||
this.playerId = mod.playerId;
|
||||
this.newControllerId = mod.newControllerId;
|
||||
this.extraTurn = mod.extraTurn;
|
||||
this.skipTurn = mod.skipTurn;
|
||||
this.extraPhase = mod.extraPhase;
|
||||
|
@ -74,7 +81,7 @@ public class TurnMod implements Serializable {
|
|||
/**
|
||||
*
|
||||
* @param playerId
|
||||
* @param extraPhase
|
||||
* @param phase
|
||||
* @param afterPhase - set to null if extraPhase is after the next phase
|
||||
*/
|
||||
public TurnMod(UUID playerId, TurnPhase phase, TurnPhase afterPhase, boolean skip) {
|
||||
|
@ -89,7 +96,7 @@ public class TurnMod implements Serializable {
|
|||
/**
|
||||
*
|
||||
* @param playerId
|
||||
* @param extraStep
|
||||
* @param step
|
||||
* @param afterStep - set to null if extraStep is after the next step
|
||||
*/
|
||||
public TurnMod(UUID playerId, Step step, PhaseStep afterStep) {
|
||||
|
@ -139,6 +146,10 @@ public class TurnMod implements Serializable {
|
|||
return afterStep;
|
||||
}
|
||||
|
||||
public UUID getNewControllerId() {
|
||||
return newControllerId;
|
||||
}
|
||||
|
||||
public TurnMod copy() {
|
||||
return new TurnMod(this);
|
||||
}
|
||||
|
|
|
@ -72,6 +72,27 @@ public class TurnMods extends ArrayList<TurnMod> {
|
|||
return false;
|
||||
}
|
||||
|
||||
public UUID controlsTurn(UUID playerId) {
|
||||
ListIterator<TurnMod> it = this.listIterator(this.size());
|
||||
UUID newControllerId = null;
|
||||
while (it.hasPrevious()) {
|
||||
TurnMod turnMod = it.previous();
|
||||
if (turnMod.getNewControllerId() != null && turnMod.getPlayerId().equals(playerId)) {
|
||||
newControllerId = turnMod.getNewControllerId();
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
// now delete all other - control next turn effect is not cumulative
|
||||
it = this.listIterator(this.size());
|
||||
while (it.hasPrevious()) {
|
||||
TurnMod turnMod = it.previous();
|
||||
if (turnMod.getNewControllerId() != null && turnMod.getPlayerId().equals(playerId)) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
return newControllerId;
|
||||
}
|
||||
|
||||
public Step extraStep(UUID playerId, PhaseStep afterStep) {
|
||||
ListIterator<TurnMod> it = this.listIterator(this.size());
|
||||
while (it.hasPrevious()) {
|
||||
|
|
|
@ -102,6 +102,43 @@ public interface Player extends MageItem, Copyable<Player> {
|
|||
public ManaPool getManaPool();
|
||||
public Set<UUID> getInRange();
|
||||
|
||||
/**
|
||||
* Returns a set of players which turns under you control.
|
||||
* Doesn't include yourself.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Set<UUID> getPlayersUnderYourControl();
|
||||
|
||||
/**
|
||||
* Defines player whose turn you control at the moment.
|
||||
* @param playerId
|
||||
*/
|
||||
public void controlPlayersTurn(Game game, UUID playerId);
|
||||
|
||||
/**
|
||||
* Resets players whose turns you control at the moment.
|
||||
*/
|
||||
public void resetOtherTurnsControlled();
|
||||
|
||||
/**
|
||||
* Returns false in case you don't control the game.
|
||||
*
|
||||
* Note: For effects like "You control target player during that player's next turn".
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isGameUnderYourControl();
|
||||
|
||||
/**
|
||||
* Returns false in case you don't control the game.
|
||||
*
|
||||
* Note: For effects like "You control target player during that player's next turn".
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
public void setGameUnderYourControl(boolean value);
|
||||
|
||||
public boolean isTestMode();
|
||||
public void setTestMode(boolean value);
|
||||
|
||||
|
|
|
@ -42,17 +42,11 @@ import mage.Constants.RangeOfInfluence;
|
|||
import mage.Constants.Zone;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.AbilitiesImpl;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.ActivatedAbility;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.PlayLandAbility;
|
||||
import mage.abilities.SpecialAction;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.TriggeredAbility;
|
||||
import mage.abilities.*;
|
||||
import mage.abilities.common.PassAbility;
|
||||
import mage.abilities.common.delayed.AtTheEndOfTurnDelayedTriggeredAbility;
|
||||
import mage.abilities.effects.RestrictionEffect;
|
||||
import mage.abilities.effects.common.LoseControlOnOtherPlayersControllerEffect;
|
||||
import mage.abilities.keyword.*;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
import mage.abilities.mana.ManaOptions;
|
||||
|
@ -100,6 +94,8 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
protected Set<UUID> inRange = new HashSet<UUID>();
|
||||
protected boolean isTestMode = false;
|
||||
protected boolean lifeTotalCanChange = true;
|
||||
protected boolean isGameUnderYourControl = true;
|
||||
protected Set<UUID> playersUnderYourControl = new HashSet<UUID>();
|
||||
|
||||
@Override
|
||||
public abstract T copy();
|
||||
|
@ -234,6 +230,41 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
|||
return inRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getPlayersUnderYourControl() {
|
||||
return this.playersUnderYourControl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void controlPlayersTurn(Game game, UUID playerId) {
|
||||
if (!playerId.equals(getId())) {
|
||||
this.playersUnderYourControl.add(playerId);
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (!player.hasLeft() && !player.hasLost()) {
|
||||
player.setGameUnderYourControl(false);
|
||||
}
|
||||
DelayedTriggeredAbility ability = new AtTheEndOfTurnDelayedTriggeredAbility(new LoseControlOnOtherPlayersControllerEffect());
|
||||
ability.setSourceId(getId());
|
||||
ability.setControllerId(getId());
|
||||
game.addDelayedTriggeredAbility(ability);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetOtherTurnsControlled() {
|
||||
playersUnderYourControl.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGameUnderYourControl() {
|
||||
return isGameUnderYourControl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGameUnderYourControl(boolean value) {
|
||||
this.isGameUnderYourControl = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endOfTurn(Game game) {
|
||||
this.passedTurn = false;
|
||||
|
|
Loading…
Reference in a new issue