game: added Pillar of the Paruns custom mode (#10633)

* Introduce a new custom match mode: Each player with a Pillar of the Paruns in play.
This commit is contained in:
Susucre 2023-07-18 06:55:46 +02:00 committed by GitHub
parent 6a244c09a7
commit 574321f034
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 269 additions and 0 deletions

1
.gitignore vendored
View file

@ -53,6 +53,7 @@ Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/target
Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/target/ Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/target/
Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/target/ Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/target/
Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/target/ Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/target/
Mage.Server.Plugins/Mage.Game.CustomPillarOfTheParunsDuel/target/
Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/target Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/target
Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/target Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/target
Mage.Server.Plugins/Mage.Player.AI.DraftBot/target Mage.Server.Plugins/Mage.Player.AI.DraftBot/target

View file

@ -0,0 +1,55 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-custompillaroftheparunsduel</artifactId>
<packaging>jar</packaging>
<name>Mage Game Custom Pillar of the Paruns Two Player Duel</name>
<dependencies>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mage</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mage-sets</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<finalName>mage-game-custompillaroftheparunsduel</finalName>
</build>
<properties/>
</project>

View file

@ -0,0 +1,150 @@
package mage.game;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ConjureCardEffect;
import mage.constants.*;
import mage.game.events.GameEvent;
import mage.game.match.MatchType;
import mage.game.mulligan.Mulligan;
import mage.game.turn.TurnMod;
import mage.players.Player;
import java.util.UUID;
/**
* This is a custom match mode for a non-official format,
* derived from limited (drafting from cubes or custom sets),
* that focuses on allowing the players to cast multicolor
* spells more easily.
* <p>
* This is done by having each player conjure a Pillar of the Paruns
* in play on their first turn, instead of their land drop.
* It then lets player play multicolor spells of many combinations,
* in a limited deck, while adding some new layer of strategy
* during the draft.
* <p>
* For balance reason, I did introduce the 6 starting hand size,
* as the extra Pillar of the Paruns is like a 7th card, and I
* did not want the player on the draw to discard to handsize.
* <p> <p>
* To summarize, this uses the default rules for a 1v1 limited match,
* with two additional custom rules: <p>
* -> At the beginning of each player's first main phase, that player
* conjure into play a Pillar of the Paruns. This does count as a
* land drop for the turn. <p>
* -> The starting hand size is 6, not 7.
* <p> <p>
* I did took the inspiration for the mode from this cube list (not
* sure it is the original source for the idea, but i did not found
* anything else but a youtube video discussing that cube): <p>
* https://cubecobra.com/cube/overview/allgoldcube
* <p>
* And I am working on a remastered set with: <p>
* https://cubecobra.com/cube/overview/parunsmaster
*
* @author Susucr
*/
public class CustomPillarOfTheParunsDuel extends GameImpl {
public CustomPillarOfTheParunsDuel(MultiplayerAttackOption attackOption, RangeOfInfluence range, Mulligan mulligan) {
super(attackOption, range, mulligan, 20, 40, 6);
}
@Override
protected void init(UUID choosingPlayerId) {
super.init(choosingPlayerId);
getPlayers().forEach((playerId, p) -> {
addDelayedTriggeredAbility(new AtTheBeginOfPlayerFirstMainPhase(playerId, "Pillar of the Paruns"), null);
});
state.getTurnMods().add(new TurnMod(startingPlayerId, PhaseStep.DRAW));
}
public CustomPillarOfTheParunsDuel(final CustomPillarOfTheParunsDuel game) {
super(game);
}
@Override
public MatchType getGameType() {
return new CustomPillarOfTheParunsDuelType();
}
@Override
public int getNumPlayers() {
return 2;
}
@Override
public CustomPillarOfTheParunsDuel copy() {
return new CustomPillarOfTheParunsDuel(this);
}
}
class InitPillarOfTheParunsEffect extends OneShotEffect {
private UUID playerId;
private String cardName;
InitPillarOfTheParunsEffect(UUID playerId, String cardName){
super(Outcome.PutLandInPlay);
this.playerId = playerId;
this.cardName = cardName;
this.staticText = "conjure " + cardName + " in play. It does count as a land played for the turn.";
}
private InitPillarOfTheParunsEffect(final InitPillarOfTheParunsEffect effect){
super(effect);
this.playerId = effect.playerId;
this.cardName = effect.cardName;
}
@Override
public InitPillarOfTheParunsEffect copy(){
return new InitPillarOfTheParunsEffect(this);
}
@Override
public boolean apply(Game game, Ability source){
Player player = game.getPlayer(playerId);
if(player == null){
return false;
}
new ConjureCardEffect(cardName, Zone.BATTLEFIELD, 1).apply(game, source);
player.incrementLandsPlayed();
return true;
}
}
class AtTheBeginOfPlayerFirstMainPhase extends DelayedTriggeredAbility {
AtTheBeginOfPlayerFirstMainPhase(UUID playerId, String cardName) {
super(new InitPillarOfTheParunsEffect(playerId, cardName), Duration.Custom, true);
setControllerId(playerId);
setTriggerPhrase("At the beginning of your first main phase, ");
}
private AtTheBeginOfPlayerFirstMainPhase(final AtTheBeginOfPlayerFirstMainPhase ability) {
super(ability);
}
@Override
public AtTheBeginOfPlayerFirstMainPhase copy() {
return new AtTheBeginOfPlayerFirstMainPhase(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.PRECOMBAT_MAIN_PHASE_PRE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getPlayerId().equals(getControllerId());
}
}

View file

@ -0,0 +1,25 @@
package mage.game;
import mage.game.match.MatchImpl;
import mage.game.match.MatchOptions;
import mage.game.mulligan.Mulligan;
/**
* @author Susucr
*/
public class CustomPillarOfTheParunsDuelMatch extends MatchImpl {
public CustomPillarOfTheParunsDuelMatch(MatchOptions options) {
super(options);
}
@Override
public void startGame() throws GameException {
Mulligan mulligan = options.getMulliganType().getMulligan(options.getFreeMulligans());
CustomPillarOfTheParunsDuel game = new CustomPillarOfTheParunsDuel(options.getAttackOption(), options.getRange(), mulligan);
game.setStartMessage(this.createGameStartMessage());
initGame(game);
games.add(game);
}
}

View file

@ -0,0 +1,29 @@
package mage.game;
import mage.game.match.MatchType;
/**
* @author Susucr
*/
public class CustomPillarOfTheParunsDuelType extends MatchType {
public CustomPillarOfTheParunsDuelType() {
this.name = "Custom Pillar of the Paruns Two Player Duel";
this.maxPlayers = 2;
this.minPlayers = 2;
this.numTeams = 0;
this.useAttackOption = false;
this.useRange = false;
this.sideboardingAllowed = true;
}
protected CustomPillarOfTheParunsDuelType(final CustomPillarOfTheParunsDuelType matchType) {
super(matchType);
}
@Override
public CustomPillarOfTheParunsDuelType copy() {
return new CustomPillarOfTheParunsDuelType(this);
}
}

View file

@ -29,6 +29,7 @@
<module>Mage.Game.FreeformCommanderDuel</module> <module>Mage.Game.FreeformCommanderDuel</module>
<module>Mage.Game.FreeformCommanderFreeForAll</module> <module>Mage.Game.FreeformCommanderFreeForAll</module>
<module>Mage.Game.FreeformUnlimitedCommander</module> <module>Mage.Game.FreeformUnlimitedCommander</module>
<module>Mage.Game.CustomPillarOfTheParunsDuel</module>
<module>Mage.Game.BrawlDuel</module> <module>Mage.Game.BrawlDuel</module>
<module>Mage.Game.BrawlFreeForAll</module> <module>Mage.Game.BrawlFreeForAll</module>
<module>Mage.Game.OathbreakerDuel</module> <module>Mage.Game.OathbreakerDuel</module>

View file

@ -82,6 +82,7 @@
<gameType name="Freeform Commander Two Player Duel" jar="mage-game-freeformcommanderduel.jar" className="mage.game.FreeformCommanderDuelMatch" typeName="mage.game.FreeformCommanderDuelType"/> <gameType name="Freeform Commander Two Player Duel" jar="mage-game-freeformcommanderduel.jar" className="mage.game.FreeformCommanderDuelMatch" typeName="mage.game.FreeformCommanderDuelType"/>
<gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/> <gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/>
<gameType name="Freeform Unlimited Commander" jar="mage-game-freeformunlimitedcommander.jar" className="mage.game.FreeformUnlimitedCommanderMatch" typeName="mage.game.FreeformUnlimitedCommanderType"/> <gameType name="Freeform Unlimited Commander" jar="mage-game-freeformunlimitedcommander.jar" className="mage.game.FreeformUnlimitedCommanderMatch" typeName="mage.game.FreeformUnlimitedCommanderType"/>
<gameType name="Custom Pillar of the Paruns Two Player Duel" jar="mage-game-custompillaroftheparunsduel.jar" className="mage.game.CustomPillarOfTheParunsDuelMatch" typeName="mage.game.CustomPillarOfTheParunsDuelType"/>
<gameType name="Oathbreaker Two Player Duel" jar="mage-game-oathbreakerduel.jar" className="mage.game.OathbreakerDuelMatch" typeName="mage.game.OathbreakerDuelType"/> <gameType name="Oathbreaker Two Player Duel" jar="mage-game-oathbreakerduel.jar" className="mage.game.OathbreakerDuelMatch" typeName="mage.game.OathbreakerDuelType"/>
<gameType name="Oathbreaker Free For All" jar="mage-game-oathbreakerfreeforall.jar" className="mage.game.OathbreakerFreeForAllMatch" typeName="mage.game.OathbreakerFreeForAllType"/> <gameType name="Oathbreaker Free For All" jar="mage-game-oathbreakerfreeforall.jar" className="mage.game.OathbreakerFreeForAllMatch" typeName="mage.game.OathbreakerFreeForAllType"/>
<gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/> <gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/>

View file

@ -167,6 +167,12 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mage-game-custompillaroftheparunsduel</artifactId>
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>${project.groupId}</groupId> <groupId>${project.groupId}</groupId>
<artifactId>mage-game-oathbreakerduel</artifactId> <artifactId>mage-game-oathbreakerduel</artifactId>

View file

@ -47,6 +47,7 @@
<gameType name="Freeform Commander Two Player Duel" jar="mage-game-freeformcommanderduel.jar" className="mage.game.FreeformCommanderDuelMatch" typeName="mage.game.FreeformCommanderDuelType"/> <gameType name="Freeform Commander Two Player Duel" jar="mage-game-freeformcommanderduel.jar" className="mage.game.FreeformCommanderDuelMatch" typeName="mage.game.FreeformCommanderDuelType"/>
<gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/> <gameType name="Freeform Commander Free For All" jar="mage-game-freeformcommanderfreeforall.jar" className="mage.game.FreeformCommanderFreeForAllMatch" typeName="mage.game.FreeformCommanderFreeForAllType"/>
<gameType name="Freeform Unlimited Commander" jar="mage-game-freeformunlimitedcommander.jar" className="mage.game.FreeformUnlimitedCommanderMatch" typeName="mage.game.FreeformUnlimitedCommanderType"/> <gameType name="Freeform Unlimited Commander" jar="mage-game-freeformunlimitedcommander.jar" className="mage.game.FreeformUnlimitedCommanderMatch" typeName="mage.game.FreeformUnlimitedCommanderType"/>
<gameType name="Custom Pillar of the Paruns Two Player Duel" jar="mage-game-custompillaroftheparunsduel.jar" className="mage.game.CustomPillarOfTheParunsDuelMatch" typeName="mage.game.CustomPillarOfTheParunsDuelType"/>
<gameType name="Oathbreaker Two Player Duel" jar="mage-game-oathbreakerduel.jar" className="mage.game.OathbreakerDuelMatch" typeName="mage.game.OathbreakerDuelType"/> <gameType name="Oathbreaker Two Player Duel" jar="mage-game-oathbreakerduel.jar" className="mage.game.OathbreakerDuelMatch" typeName="mage.game.OathbreakerDuelType"/>
<gameType name="Oathbreaker Free For All" jar="mage-game-oathbreakerfreeforall.jar" className="mage.game.OathbreakerFreeForAllMatch" typeName="mage.game.OathbreakerFreeForAllType"/> <gameType name="Oathbreaker Free For All" jar="mage-game-oathbreakerfreeforall.jar" className="mage.game.OathbreakerFreeForAllMatch" typeName="mage.game.OathbreakerFreeForAllType"/>
<gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/> <gameType name="Brawl Two Player Duel" jar="mage-game-brawlduel.jar" className="mage.game.BrawlDuelMatch" typeName="mage.game.BrawlDuelType"/>