added chaos battle on adventure

- mimic (Doppelganger) will use random quest challenge decks on chaos mode. winning the challenge grants 1 life, random amount of gold, 2 rares, 2 uncommons and 3 common cards.
This commit is contained in:
Anthony Calosa
2022-05-22 20:58:07 +08:00
parent 3b0f6fc11a
commit ab622322b9
7 changed files with 135 additions and 47 deletions

View File

@@ -5,6 +5,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.LobbyPlayer;
@@ -26,6 +27,7 @@ public class RegisteredPlayer {
private int startingLife = 20;
private int startingHand = 7;
private Iterable<IPaperCard> cardsOnBattlefield = null;
private Iterable<IPaperCard> extraCardsOnBattlefield = null;
private Iterable<? extends IPaperCard> schemes = null;
private Iterable<PaperCard> planes = null;
private Iterable<PaperCard> conspiracies = null;
@@ -48,7 +50,8 @@ public class RegisteredPlayer {
return startingLife;
}
public final Iterable<? extends IPaperCard> getCardsOnBattlefield() {
return cardsOnBattlefield == null ? EmptyList : cardsOnBattlefield;
return Iterables.concat(cardsOnBattlefield == null ? EmptyList : cardsOnBattlefield,
extraCardsOnBattlefield == null ? EmptyList : extraCardsOnBattlefield);
}
public final void setStartingLife(int startingLife) {
@@ -59,6 +62,10 @@ public class RegisteredPlayer {
this.cardsOnBattlefield = cardsOnTable;
}
public final void addExtraCardsOnBattlefield(Iterable<IPaperCard> extraCardsonTable) {
this.extraCardsOnBattlefield = extraCardsonTable;
}
public int getStartingHand() {
return startingHand;
}

View File

@@ -12,9 +12,17 @@ import forge.Forge;
import forge.adventure.data.EffectData;
import forge.adventure.data.EnemyData;
import forge.adventure.data.RewardData;
import forge.adventure.player.AdventurePlayer;
import forge.adventure.util.Current;
import forge.adventure.util.MapDialog;
import forge.adventure.util.Reward;
import forge.card.CardRarity;
import forge.item.PaperCard;
import forge.util.Aggregates;
import forge.util.MyRandom;
import java.util.List;
import java.util.stream.Collectors;
/**
* EnemySprite
@@ -55,14 +63,51 @@ public class EnemySprite extends CharacterSprite {
public Array<Reward> getRewards() {
Array<Reward> ret=new Array<>();
if(data.rewards != null) { //Collect standard rewards.
for (RewardData rdata : data.rewards) {
ret.addAll(rdata.generate(false, (Current.latestDeck() != null ? Current.latestDeck().getMain().toFlatList() : null)));
//Collect custom rewards for chaos battles
if (data.copyPlayerDeck && AdventurePlayer.current().isFantasyMode()) {
if (Current.latestDeck() != null) {
List<PaperCard> paperCardList = Current.latestDeck().getMain().toFlatList().stream()
.filter(paperCard -> !paperCard.isVeryBasicLand() && !paperCard.getName().startsWith("Mox"))
.collect(Collectors.toList());
//random uncommons from deck
List<PaperCard> uncommonCards = paperCardList.stream()
.filter(paperCard -> CardRarity.Uncommon.equals(paperCard.getRarity()) || CardRarity.Special.equals(paperCard.getRarity()))
.collect(Collectors.toList());
if (!uncommonCards.isEmpty()) {
ret.add(new Reward(Aggregates.random(uncommonCards)));
ret.add(new Reward(Aggregates.random(uncommonCards)));
}
//random commons from deck
List<PaperCard> commmonCards = paperCardList.stream()
.filter(paperCard -> CardRarity.Common.equals(paperCard.getRarity()))
.collect(Collectors.toList());
if (!commmonCards.isEmpty()) {
ret.add(new Reward(Aggregates.random(commmonCards)));
ret.add(new Reward(Aggregates.random(commmonCards)));
ret.add(new Reward(Aggregates.random(commmonCards)));
}
//random rare from deck
List<PaperCard> rareCards = paperCardList.stream()
.filter(paperCard -> CardRarity.Rare.equals(paperCard.getRarity()) || CardRarity.MythicRare.equals(paperCard.getRarity()))
.collect(Collectors.toList());
if (!rareCards.isEmpty()) {
ret.add(new Reward(Aggregates.random(rareCards)));
ret.add(new Reward(Aggregates.random(rareCards)));
}
}
}
if(rewards != null) { //Collect additional rewards.
for(RewardData rdata:rewards) {
ret.addAll(rdata.generate(false,(Current.latestDeck()!=null? Current.latestDeck().getMain().toFlatList():null)));
int val = ((MyRandom.getRandom().nextInt(2)+1)*100)+(MyRandom.getRandom().nextInt(101));
ret.add(new Reward(val));
ret.add(new Reward(Reward.Type.Life, 1));
} else {
if(data.rewards != null) { //Collect standard rewards.
for (RewardData rdata : data.rewards) {
ret.addAll(rdata.generate(false, (Current.latestDeck() != null ? Current.latestDeck().getMain().toFlatList() : null)));
}
}
if(rewards != null) { //Collect additional rewards.
for(RewardData rdata:rewards) {
ret.addAll(rdata.generate(false,(Current.latestDeck()!=null? Current.latestDeck().getMain().toFlatList():null)));
}
}
}
return ret;

View File

@@ -13,11 +13,13 @@ import forge.adventure.util.Config;
import forge.adventure.util.Current;
import forge.assets.FSkin;
import forge.deck.Deck;
import forge.deck.DeckProxy;
import forge.game.GameRules;
import forge.game.GameType;
import forge.game.player.Player;
import forge.game.player.RegisteredPlayer;
import forge.gamemodes.match.HostedMatch;
import forge.gamemodes.quest.QuestUtil;
import forge.gui.interfaces.IGuiGame;
import forge.item.IPaperCard;
import forge.player.GamePlayerUtil;
@@ -27,6 +29,8 @@ import forge.screens.match.MatchController;
import forge.sound.MusicPlaylist;
import forge.sound.SoundSystem;
import forge.trackable.TrackableCollection;
import forge.util.Aggregates;
import org.apache.commons.lang3.tuple.Pair;
import java.util.*;
@@ -42,6 +46,11 @@ public class DuelScene extends ForgeScene {
PlayerSprite player;
RegisteredPlayer humanPlayer;
private EffectData dungeonEffect;
Deck playerDeck, enemyDeck;
boolean chaosBattle = false;
List<IPaperCard> playerExtras = new ArrayList<>();
List<IPaperCard> AIExtras = new ArrayList<>();
public DuelScene() {
@@ -101,7 +110,6 @@ public class DuelScene extends ForgeScene {
AdventurePlayer advPlayer = Current.player();
List<RegisteredPlayer> players = new ArrayList<>();
Deck playerDeck=(Deck)AdventurePlayer.current().getSelectedDeck().copyTo("PlayerDeckCopy");
int missingCards= Config.instance().getConfigData().minDeckSize-playerDeck.getMain().countAll();
if( missingCards > 0 ) //Replace unknown cards for a Wastes.
playerDeck.getMain().add("Wastes",missingCards);
@@ -111,7 +119,6 @@ public class DuelScene extends ForgeScene {
playerObject.setAvatarIndex(90001);
humanPlayer.setPlayer(playerObject);
humanPlayer.setStartingLife(advPlayer.getLife());
Deck enemyDeck = ( enemy.getData().copyPlayerDeck ? playerDeck : enemy.getData().generateDeck(Current.player().isFantasyMode()));
Current.setLatestDeck(enemyDeck);
RegisteredPlayer aiPlayer = RegisteredPlayer.forVariants(2, appliedVariants, Current.latestDeck(), null, false, null, null);
LobbyPlayer enemyPlayer = GamePlayerUtil.createAiPlayer(this.enemy.getData().name, selectAI(this.enemy.getData().ai));
@@ -162,6 +169,12 @@ public class DuelScene extends ForgeScene {
addEffects(humanPlayer,playerEffects);
addEffects(aiPlayer,oppEffects);
//add extra cards for challenger mode
if (chaosBattle) {
humanPlayer.addExtraCardsOnBattlefield(playerExtras);
aiPlayer.addExtraCardsOnBattlefield(AIExtras);
}
players.add(humanPlayer);
players.add(aiPlayer);
@@ -204,12 +217,33 @@ public class DuelScene extends ForgeScene {
return MatchController.getView();
}
public void setEnemy(EnemySprite data) {
this.enemy = data;
}
public void setPlayer(PlayerSprite sprite) {
this.player = sprite;
public void initDuels(PlayerSprite playerSprite, EnemySprite enemySprite) {
this.player = playerSprite;
this.enemy = enemySprite;
this.playerDeck = (Deck)AdventurePlayer.current().getSelectedDeck().copyTo("PlayerDeckCopy");
this.chaosBattle = this.enemy.getData().copyPlayerDeck && Current.player().isFantasyMode();
if (this.chaosBattle) { //random challenge for chaos mode
Map<DeckProxy, Pair<List<String>, List<String>>> deckProxyMapMap = DeckProxy.getAllQuestChallenges();
List<DeckProxy> decks = new ArrayList<>(deckProxyMapMap.keySet());
DeckProxy deck = Aggregates.random(decks);
//playerextras
List<IPaperCard> playerCards = new ArrayList<>();
for (String s : deckProxyMapMap.get(deck).getLeft()) {
playerCards.add(QuestUtil.readExtraCard(s));
}
this.playerExtras = playerCards;
//aiextras
List<IPaperCard> aiCards = new ArrayList<>();
for (String s : deckProxyMapMap.get(deck).getRight()) {
aiCards.add(QuestUtil.readExtraCard(s));
}
this.AIExtras = aiCards;
this.enemyDeck = deck.getDeck();
} else {
this.AIExtras.clear();
this.playerExtras.clear();
this.enemyDeck = this.enemy.getData().copyPlayerDeck ? this.playerDeck : this.enemy.getData().generateDeck(Current.player().isFantasyMode());
}
}
private String selectAI(String ai) { //Decide opponent AI.

View File

@@ -32,6 +32,7 @@ import forge.adventure.scene.RewardScene;
import forge.adventure.scene.SceneType;
import forge.adventure.util.*;
import forge.adventure.world.WorldSave;
import forge.gui.FThreads;
import forge.screens.TransitionScreen;
import forge.sound.SoundEffectType;
import forge.sound.SoundSystem;
@@ -574,23 +575,18 @@ public class MapStage extends GameStage {
Gdx.input.vibrate(50);
Forge.setCursor(null, Forge.magnifyToggle ? "1" : "2");
SoundSystem.instance.play(SoundEffectType.ManaBurn, false);
if (!isLoadingMatch) {
isLoadingMatch = true;
Forge.setTransitionScreen(new TransitionScreen(new Runnable() {
@Override
public void run() {
FThreads.invokeInEdtNowOrLater(() -> {
if (!isLoadingMatch) {
isLoadingMatch = true;
Forge.setTransitionScreen(new TransitionScreen(() -> {
DuelScene duelScene = ((DuelScene) SceneType.DuelScene.instance);
duelScene.initDuels(player, mob);
Forge.clearTransitionScreen();
}
}, ScreenUtils.getFrameBufferTexture(), true, false));
}
startPause(0.3f, new Runnable() {
@Override
public void run() {
DuelScene S = ((DuelScene) SceneType.DuelScene.instance);
S.setEnemy(mob);
S.setPlayer(player);
if(isInMap && effect != null) S.setDungeonEffect(effect);
Forge.switchScene(SceneType.DuelScene.instance);
startPause(0.3f, () -> {
if(isInMap && effect != null) duelScene.setDungeonEffect(effect);
Forge.switchScene(SceneType.DuelScene.instance);
});
}, ScreenUtils.getFrameBufferTexture(), true, false));
}
});
}

View File

@@ -22,6 +22,7 @@ import forge.adventure.util.SaveFileContent;
import forge.adventure.util.SaveFileData;
import forge.adventure.world.World;
import forge.adventure.world.WorldSave;
import forge.gui.FThreads;
import forge.screens.TransitionScreen;
import forge.sound.SoundEffectType;
import forge.sound.SoundSystem;
@@ -86,22 +87,15 @@ public class WorldStage extends GameStage implements SaveFileContent {
Gdx.input.vibrate(50);
Forge.setCursor(null, Forge.magnifyToggle ? "1" : "2");
SoundSystem.instance.play(SoundEffectType.ManaBurn, false);
Forge.setTransitionScreen(new TransitionScreen(new Runnable() {
@Override
public void run() {
FThreads.invokeInEdtNowOrLater(() -> {
Forge.setTransitionScreen(new TransitionScreen(() -> {
((DuelScene) SceneType.DuelScene.instance).initDuels(player, mob);
Forge.clearTransitionScreen();
}
}, ScreenUtils.getFrameBufferTexture(), true, false));
startPause(0.3f, new Runnable() {
@Override
public void run() {
((DuelScene) SceneType.DuelScene.instance).setEnemy(currentMob);
((DuelScene) SceneType.DuelScene.instance).setPlayer(player);
Forge.switchScene(SceneType.DuelScene.instance);
}
startPause(0.3f, () -> Forge.switchScene(SceneType.DuelScene.instance));
}, ScreenUtils.getFrameBufferTexture(), true, false));
currentMob = mob;
WorldSave.getCurrentSave().autoSave();
});
currentMob = mob;
WorldSave.getCurrentSave().autoSave();
break;
}
}

View File

@@ -23,6 +23,8 @@ import forge.util.BinaryUtil;
import forge.util.IHasName;
import forge.util.storage.IStorage;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import java.util.*;
import java.util.Map.Entry;
@@ -563,6 +565,16 @@ public class DeckProxy implements InventoryItem {
return decks;
}
public static Map<DeckProxy, Pair<List<String>, List<String>>> getAllQuestChallenges() {
final Map<DeckProxy, Pair<List<String>, List<String>>> deckMap = new HashMap<>();
final QuestController quest = FModel.getQuest();
for (final QuestEvent e : quest.getChallenges()) {
Pair<List<String>, List<String>> extras = new ImmutablePair<>(e.getHumanExtraCards(), e.getAiExtraCards());
deckMap.put(new DeckProxy(e.getEventDeck(), "Quest Event", null, null), extras);
}
return deckMap;
}
public static List<DeckProxy> getNonEasyQuestDuelDecks() {
final List<DeckProxy> decks = new ArrayList<>();
final QuestController quest = FModel.getQuest();

View File

@@ -441,7 +441,7 @@ public class DeckgenUtil {
advPrecons.addAll(DeckProxy.getAllPreconstructedDecks(QuestController.getPrecons()));
}
if (advThemes.isEmpty()) {
advThemes.addAll(DeckProxy.getAllThemeDecks());
advThemes.addAll(DeckProxy.getAllPreconstructedDecks(QuestController.getPrecons()));
advThemes.addAll(DeckProxy.getNonEasyQuestDuelDecks());
}
if (!colors.isEmpty()) {