Added the monarch concept to xmage and all related cards.

This commit is contained in:
LevelX2 2016-11-27 01:14:32 +01:00
parent 8bf299e342
commit 68d0e6b9fa
33 changed files with 2149 additions and 281 deletions

View file

@ -156,7 +156,11 @@ public class BeginningOfEndStepTriggeredAbility extends TriggeredAbilityImpl {
private String generateConditionString() {
if (interveningIfClauseCondition != null) {
return "if {this} is " + interveningIfClauseCondition.toString() + ", ";
if (interveningIfClauseCondition.toString().startsWith("if")) {
return interveningIfClauseCondition.toString() + ", ";
} else {
return "if {this} is " + interveningIfClauseCondition.toString() + ", ";
}
}
switch (getZone()) {
case GRAVEYARD:

View file

@ -0,0 +1,33 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.game.Game;
/**
*
* @author LevelX2
*/
public class MonarchIsSourceControllerCondition implements Condition {
private final static MonarchIsSourceControllerCondition fInstance = new MonarchIsSourceControllerCondition();
public static Condition getInstance() {
return fInstance;
}
@Override
public boolean apply(Game game, Ability source) {
return source.getControllerId().equals(game.getMonarchId());
}
@Override
public String toString() {
return "if you're the monarch";
}
}

View file

@ -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.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author LevelX2
*/
public class BecomesMonarchSourceEffect extends OneShotEffect {
public BecomesMonarchSourceEffect() {
super(Outcome.Benefit);
staticText = "you become the monarch";
}
public BecomesMonarchSourceEffect(final BecomesMonarchSourceEffect effect) {
super(effect);
}
@Override
public BecomesMonarchSourceEffect copy() {
return new BecomesMonarchSourceEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
game.setMonarchId(source, source.getControllerId());
return true;
}
return false;
}
}

View file

@ -335,10 +335,10 @@ public interface Game extends MageItem, Serializable {
void end();
void cleanUp();
/*
* Gives back the number of cards the player has after the next mulligan
*/
int mulliganDownTo(UUID playerId);
void mulligan(UUID playerId);
@ -463,4 +463,8 @@ public interface Game extends MageItem, Serializable {
void setEnterWithCounters(UUID sourceId, Counters counters);
Counters getEnterWithCounters(UUID sourceId);
UUID getMonarchId();
void setMonarchId(Ability source, UUID monarchId);
}

View file

@ -2348,7 +2348,18 @@ public abstract class GameImpl implements Game, Serializable {
it.remove();
}
}
// If the current monarch leaves the game. When that happens, the player whose turn it is becomes the monarch.
// If the monarch leaves the game on their turn, the next player in turn order becomes the monarch.
if (playerId.equals(getMonarchId())) {
if (!getActivePlayerId().equals(playerId)) {
setMonarchId(null, getActivePlayerId());
} else {
Player nextPlayer = getPlayerList().getNext(this);
if (nextPlayer != null) {
setMonarchId(null, nextPlayer.getId());
}
}
}
// 801.2c The particular players within each players range of influence are determined as each turn begins.
// So no update of range if influence yet
}
@ -2896,4 +2907,20 @@ public abstract class GameImpl implements Game, Serializable {
}
return options;
}
@Override
public UUID getMonarchId() {
return getState().getMonarchId();
}
@Override
public void setMonarchId(Ability source, UUID monarchId) {
Player newMonarch = getPlayer(monarchId);
if (newMonarch != null) {
getState().setMonarchId(monarchId);
informPlayers(newMonarch.getLogName() + " is the monarch");
fireEvent(new GameEvent(GameEvent.EventType.BECOMES_MONARCH, monarchId, source == null ? null : source.getSourceId(), monarchId));
}
}
}

View file

@ -110,6 +110,7 @@ public class GameState implements Serializable, Copyable<GameState> {
private UUID activePlayerId; // playerId which turn it is
private UUID priorityPlayerId; // player that has currently priority
private UUID playerByOrderId; // player that has currently priority
private UUID monarchId; // player that is the monarch
private SpellStack stack;
private Command command;
private Exile exile;
@ -164,6 +165,7 @@ public class GameState implements Serializable, Copyable<GameState> {
this.activePlayerId = state.activePlayerId;
this.priorityPlayerId = state.priorityPlayerId;
this.playerByOrderId = state.playerByOrderId;
this.monarchId = state.monarchId;
this.turn = state.turn.copy();
this.stack = state.stack.copy();
@ -214,6 +216,7 @@ public class GameState implements Serializable, Copyable<GameState> {
this.playerList.setCurrent(state.activePlayerId);
this.playerByOrderId = state.playerByOrderId;
this.priorityPlayerId = state.priorityPlayerId;
this.monarchId = state.monarchId;
this.stack = state.stack;
this.command = state.command;
this.exile = state.exile;
@ -430,6 +433,14 @@ public class GameState implements Serializable, Copyable<GameState> {
this.priorityPlayerId = priorityPlayerId;
}
public UUID getMonarchId() {
return monarchId;
}
public void setMonarchId(UUID monarchId) {
this.monarchId = monarchId;
}
public UUID getChoosingPlayerId() {
return choosingPlayerId;
}

View file

@ -237,6 +237,14 @@ public class GameEvent implements Serializable {
TRANSFORM, TRANSFORMED,
BECOMES_MONSTROUS,
BECOMES_RENOWNED,
/* BECOMES_MONARCH
targetId playerId of the player that becomes the monarch
sourceId id of the source object that created that effect, if no effect exist it's null
playerId playerId of the player that becomes the monarch
amount not used for this event
flag not used for this event
*/
BECOMES_MONARCH,
MEDITATED,
PHASE_OUT, PHASED_OUT,
PHASE_IN, PHASED_IN,

View file

@ -24,8 +24,7 @@
* 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.game.permanent.token;
import java.util.ArrayList;
@ -44,7 +43,7 @@ public class DragonToken2 extends Token {
final static private List<String> tokenImageSets = new ArrayList<>();
static {
tokenImageSets.addAll(Arrays.asList("WWK", "10E", "BFZ", "C15"));
tokenImageSets.addAll(Arrays.asList("WWK", "10E", "BFZ", "C15", "CN2"));
}
public DragonToken2() {

View file

@ -1829,6 +1829,9 @@ public abstract class PlayerImpl implements Player, Serializable {
if (sourceAbilities != null && sourceAbilities.containsKey(InfectAbility.getInstance().getId())) {
addCounters(CounterType.POISON.createInstance(actualDamage), game);
} else {
if (getId().equals(game.getMonarchId()) && sourceControllerId != null) {
game.setMonarchId(null, sourceControllerId);
}
GameEvent damageToLifeLossEvent = new GameEvent(EventType.DAMAGE_CAUSES_LIFE_LOSS, playerId, sourceId, playerId, actualDamage, combatDamage);
if (!game.replaceEvent(damageToLifeLossEvent)) {
this.loseLife(damageToLifeLossEvent.getAmount(), game, combatDamage);