Implement Villainous Choice mechanic (#11304)

* [WHO] Implement Great Intelligence's Plan

* [WHO] Implement The Valeyard

* add comment for villainous choice event
This commit is contained in:
Evan Kranzler 2023-10-14 15:27:45 -04:00 committed by GitHub
parent 0f987704bb
commit d705fa0e41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 307 additions and 0 deletions

View file

@ -0,0 +1,50 @@
package mage.choices;
import mage.abilities.Ability;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
/**
* @author TheElk801
*/
public class FaceVillainousChoice {
private final Outcome outcome;
private final VillainousChoice firstChoice;
private final VillainousChoice secondChoice;
public FaceVillainousChoice(Outcome outcome, VillainousChoice firstChoice, VillainousChoice secondChoice) {
this.outcome = outcome;
this.firstChoice = firstChoice;
this.secondChoice = secondChoice;
}
public boolean faceChoice(Player player, Game game, Ability source) {
GameEvent event = GameEvent.getEvent(
GameEvent.EventType.FACE_VILLAINOUS_CHOICE,
player.getId(), source, source.getControllerId(), 1
);
if (game.replaceEvent(event)) {
return false;
}
for (int i = 0; i < event.getAmount(); i++) {
handleChoice(player, game, source);
}
return true;
}
private boolean handleChoice(Player player, Game game, Ability source) {
VillainousChoice chosenChoice = player.chooseUse(
outcome, "You face a villanous choice:", null,
firstChoice.getMessage(game, source), secondChoice.getMessage(game, source), source, game
) ? firstChoice : secondChoice;
return chosenChoice.doChoice(player, game, source);
}
public String generateRule() {
return "faces a villanous choice &mdash; " + firstChoice.getRule() + ", or " + secondChoice.getRule();
}
}

View file

@ -0,0 +1,40 @@
package mage.choices;
import mage.abilities.Ability;
import mage.game.Game;
import mage.players.Player;
import java.util.Objects;
import java.util.Optional;
/**
* @author TheElk801
*/
public abstract class VillainousChoice {
private final String rule;
private final String message;
protected VillainousChoice(String rule, String message) {
this.rule = rule;
this.message = message;
}
public abstract boolean doChoice(Player player, Game game, Ability source);
public String getRule() {
return rule;
}
public String getMessage(Game game, Ability source) {
if (!message.contains("{controller}")) {
return message;
}
String controllerName = Optional
.ofNullable(game.getPlayer(source.getControllerId()))
.filter(Objects::nonNull)
.map(Player::getName)
.orElse("Opponent");
return message.replace("{controller}", controllerName);
}
}

View file

@ -508,6 +508,14 @@ public class GameEvent implements Serializable {
REMOVED_FROM_COMBAT, // targetId id of permanent removed from combat
FORETOLD, // targetId id of card foretold
FORETELL, // targetId id of card foretell playerId id of the controller
/* villainous choice
targetId player making the choice
sourceId sourceId of the ability forcing the choice
playerId controller of the ability forcing the choice
amount numner of times choice is repeated
flag not used for this event
*/
FACE_VILLAINOUS_CHOICE,
//custom events
CUSTOM_EVENT
}