mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Merge pull request #8500 from Jetz72/setEventCommand
Refactor event generation, add `set event` command.
This commit is contained in:
@@ -9,9 +9,7 @@ import forge.util.storage.StorageExtendable;
|
||||
import forge.util.storage.StorageReaderFileSections;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -93,19 +91,6 @@ public class PrintSheet {
|
||||
return fetchRoulette(sum + 1, roulette, toSkip); // start over from beginning, in case last cards were to skip
|
||||
}
|
||||
|
||||
public boolean containsCardNamed(String name,int atLeast) {
|
||||
int count=0;
|
||||
for (Entry<PaperCard, Integer> kv : cardsWithWeights) {
|
||||
for (int i = 0; i < kv.getValue(); i++) {
|
||||
if(kv.getKey().getName().equals(name))
|
||||
{
|
||||
count++;
|
||||
if(count>=atLeast)return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -147,6 +132,10 @@ public class PrintSheet {
|
||||
return cardsWithWeights.toFlatList();
|
||||
}
|
||||
|
||||
public Map<String, Integer> toNameLookup() {
|
||||
return cardsWithWeights.toNameLookup();
|
||||
}
|
||||
|
||||
public static class Reader extends StorageReaderFileSections<PrintSheet> {
|
||||
public Reader(File file) {
|
||||
super(file, PrintSheet::getName);
|
||||
|
||||
@@ -23,14 +23,15 @@ import forge.util.Aggregates;
|
||||
import forge.util.IterableUtil;
|
||||
import forge.util.MyRandom;
|
||||
import forge.util.StreamUtil;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class AdventureEventData implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final int JUMPSTART_TO_PICK_FROM = 6;
|
||||
public transient BoosterDraft draft;
|
||||
@@ -69,6 +70,7 @@ public class AdventureEventData implements Serializable {
|
||||
style = other.style;
|
||||
random.setSeed(eventSeed);
|
||||
eventStatus = other.eventStatus;
|
||||
format = other.format;
|
||||
registeredDeck = other.registeredDeck;
|
||||
isDraftComplete = other.isDraftComplete;
|
||||
description = other.description;
|
||||
@@ -94,28 +96,39 @@ public class AdventureEventData implements Serializable {
|
||||
}
|
||||
|
||||
public AdventureEventData(Long seed, AdventureEventController.EventFormat selectedFormat) {
|
||||
this(seed, selectedFormat, null, pickCardBlockByFormat(selectedFormat));
|
||||
}
|
||||
|
||||
public AdventureEventData(Long seed, AdventureEventController.EventFormat selectedFormat, CardBlock cardBlock) {
|
||||
this(seed, selectedFormat, null, cardBlock);
|
||||
}
|
||||
|
||||
public AdventureEventData(Long seed, AdventureEventController.EventFormat selectedFormat, AdventureEventController.EventStyle style, CardBlock cardBlock) {
|
||||
setEventSeed(seed);
|
||||
eventStatus = AdventureEventController.EventStatus.Available;
|
||||
registeredDeck = new Deck();
|
||||
format = selectedFormat;
|
||||
if (format == AdventureEventController.EventFormat.Draft) {
|
||||
cardBlock = pickWeightedCardBlock();
|
||||
this.cardBlock = cardBlock;
|
||||
if (cardBlock == null)
|
||||
return;
|
||||
cardBlockName = cardBlock.getName();
|
||||
|
||||
if (format == AdventureEventController.EventFormat.Draft) {
|
||||
setupDraftRewards();
|
||||
} else if (format == AdventureEventController.EventFormat.Jumpstart) {
|
||||
cardBlock = pickJumpstartCardBlock();
|
||||
if (cardBlock == null)
|
||||
return;
|
||||
cardBlockName = cardBlock.getName();
|
||||
|
||||
jumpstartBoosters = AdventureEventController.instance().getJumpstartBoosters(cardBlock, JUMPSTART_TO_PICK_FROM);
|
||||
packConfiguration = new String[]{cardBlock.getLandSet().getCode(), cardBlock.getLandSet().getCode(), cardBlock.getLandSet().getCode()};
|
||||
|
||||
setupJumpstartRewards();
|
||||
}
|
||||
|
||||
if(style == null) {
|
||||
// If the chosen event seed recommends a four-person pod, run it as a RoundRobin
|
||||
if (getRecommendedPodSize(cardBlock) == 4)
|
||||
style = AdventureEventController.EventStyle.RoundRobin;
|
||||
else
|
||||
style = AdventureEventController.EventStyle.Bracket;
|
||||
}
|
||||
this.style = style;
|
||||
}
|
||||
|
||||
public void setEventSeed(long seed) {
|
||||
@@ -147,6 +160,15 @@ public class AdventureEventData implements Serializable {
|
||||
return draft;
|
||||
}
|
||||
|
||||
private static CardBlock pickCardBlockByFormat(AdventureEventController.EventFormat format) {
|
||||
return switch (format) {
|
||||
case Draft -> pickWeightedCardBlock();
|
||||
case Jumpstart -> pickJumpstartCardBlock();
|
||||
case Constructed -> null;
|
||||
case Sealed -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private static final Predicate<CardEdition> filterPioneer = FModel.getFormats().getPioneer().editionLegalPredicate;
|
||||
private static final Predicate<CardEdition> filterModern = FModel.getFormats().getModern().editionLegalPredicate;
|
||||
private static final Predicate<CardEdition> filterVintage = FModel.getFormats().getVintage().editionLegalPredicate;
|
||||
@@ -168,10 +190,11 @@ public class AdventureEventData implements Serializable {
|
||||
return rolledFilter;
|
||||
}
|
||||
|
||||
private CardBlock pickWeightedCardBlock() {
|
||||
private static final Set<String> POWER_NINE = Set.of("Black Lotus", "Mox Emerald", "Mox Pearl", "Mox Ruby", "Mox Sapphire", "Mox Jet", "Ancestral Recall", "Timetwister", "Time Walk");
|
||||
|
||||
private static CardBlock pickWeightedCardBlock() {
|
||||
CardEdition.Collection editions = FModel.getMagicDb().getEditions();
|
||||
ConfigData configData = Config.instance().getConfigData();
|
||||
Iterable<CardBlock> src = FModel.getBlocks(); //all blocks
|
||||
Predicate<CardEdition> filter = CardEdition.Predicates.CAN_MAKE_BOOSTER.and(selectSetPool());
|
||||
|
||||
if(configData.restrictedEvents != null) {
|
||||
@@ -195,52 +218,41 @@ public class AdventureEventData implements Serializable {
|
||||
.filter(CardEdition::hasBoosterTemplate)
|
||||
.forEach(allEditions::add);
|
||||
|
||||
List<CardBlock> legalBlocks = new ArrayList<>();
|
||||
for (CardBlock b : src) { // for each block
|
||||
if (b.getSets().isEmpty() || (b.getCntBoostersDraft() < 1))
|
||||
continue;
|
||||
boolean isOkay = true;
|
||||
for (CardEdition c : b.getSets()) {
|
||||
if (!allEditions.contains(c)) {
|
||||
isOkay = false;
|
||||
break;
|
||||
}
|
||||
if (!c.hasBoosterTemplate()) {
|
||||
isOkay = false;
|
||||
break;
|
||||
} else {
|
||||
final List<Pair<String, Integer>> slots = c.getBoosterTemplate().getSlots();
|
||||
int boosterSize = 0;
|
||||
for (Pair<String, Integer> slot : slots) {
|
||||
boosterSize += slot.getRight();
|
||||
}
|
||||
isOkay = boosterSize > 11;
|
||||
}
|
||||
for (PrintSheet ps : c.getPrintSheetsBySection()) {
|
||||
//exclude block with sets containing P9 cards..
|
||||
if (ps.containsCardNamed("Black Lotus", 1)
|
||||
|| ps.containsCardNamed("Mox Emerald", 1)
|
||||
|| ps.containsCardNamed("Mox Pearl", 1)
|
||||
|| ps.containsCardNamed("Mox Ruby", 1)
|
||||
|| ps.containsCardNamed("Mox Sapphire", 1)
|
||||
|| ps.containsCardNamed("Mox Jet", 1)
|
||||
|| ps.containsCardNamed("Ancestral Recall", 1)
|
||||
|| ps.containsCardNamed("Timetwister", 1)
|
||||
|| ps.containsCardNamed("Time Walk", 1)) {
|
||||
isOkay = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isOkay) {
|
||||
legalBlocks.add(b);
|
||||
}
|
||||
}
|
||||
List<CardBlock> legalBlocks = getValidDraftBlocks(allEditions);
|
||||
|
||||
return legalBlocks.isEmpty() ? null : Aggregates.random(legalBlocks);
|
||||
}
|
||||
|
||||
private CardBlock pickJumpstartCardBlock() {
|
||||
public static List<CardBlock> getValidDraftBlocks(List<CardEdition> validEditions) {
|
||||
List<CardBlock> legalBlocks = new ArrayList<>();
|
||||
for (CardBlock b : FModel.getBlocks()) { // for each block
|
||||
if (b.getSets().isEmpty() || (b.getCntBoostersDraft() < 1))
|
||||
continue;
|
||||
if (!isValidDraftBlock(b, validEditions))
|
||||
continue;
|
||||
legalBlocks.add(b);
|
||||
}
|
||||
return legalBlocks;
|
||||
}
|
||||
|
||||
private static boolean isValidDraftBlock(CardBlock b, List<CardEdition> validEditions) {
|
||||
for (CardEdition c : b.getSets()) {
|
||||
if (!validEditions.contains(c))
|
||||
return false;
|
||||
if (!c.hasBoosterTemplate())
|
||||
return false;
|
||||
if(c.getBoosterTemplate().getNumberOfCardsExpected() <= 11)
|
||||
return false;
|
||||
for (PrintSheet ps : c.getPrintSheetsBySection()) {
|
||||
//exclude block with sets containing P9 cards.
|
||||
if(!Collections.disjoint(ps.toNameLookup().keySet(), POWER_NINE))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static CardBlock pickJumpstartCardBlock() {
|
||||
Iterable<CardBlock> src = FModel.getBlocks(); //all blocks
|
||||
List<CardBlock> legalBlocks = new ArrayList<>();
|
||||
ConfigData configData = Config.instance().getConfigData();
|
||||
@@ -359,6 +371,10 @@ public class AdventureEventData implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public void generateParticipants() {
|
||||
this.generateParticipants(getRecommendedPodSize(this.cardBlock) - 1); //-1 to account for the player
|
||||
}
|
||||
|
||||
public void generateParticipants(int numberOfOpponents) {
|
||||
participants = new AdventureEventParticipant[numberOfOpponents + 1];
|
||||
|
||||
@@ -457,11 +473,10 @@ public class AdventureEventData implements Serializable {
|
||||
//3. If no matching color found and need more packs, add any available at random.
|
||||
if (packConfiguration.length > chosenPacks.size() && colorAdded.isEmpty() && !availableOptions.isEmpty()) {
|
||||
chosenPacks.add(Aggregates.removeRandom(availableOptions));
|
||||
colorAdded = "";
|
||||
} else {
|
||||
done = colorAdded.isEmpty() || packConfiguration.length <= chosenPacks.size();
|
||||
colorAdded = "";
|
||||
}
|
||||
colorAdded = "";
|
||||
}
|
||||
participant.registeredDeck = new Deck();
|
||||
for (Deck chosen : chosenPacks) {
|
||||
@@ -469,6 +484,22 @@ public class AdventureEventData implements Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (this.style) {
|
||||
case Swiss:
|
||||
case Bracket:
|
||||
this.rounds = (participants.length / 2) - 1;
|
||||
break;
|
||||
case RoundRobin:
|
||||
this.rounds = participants.length - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getRecommendedPodSize(CardBlock cardBlock) {
|
||||
// Set can be null when it is only a meta set such as some Jumpstart events.
|
||||
CardEdition firstSet = cardBlock.getSets().isEmpty() ? null : cardBlock.getSets().get(0);
|
||||
return firstSet == null ? 8 : firstSet.getDraftOptions().getRecommendedPodSize();
|
||||
}
|
||||
|
||||
private void assignPlayerNames(BoosterDraft draft) {
|
||||
@@ -664,29 +695,13 @@ public class AdventureEventData implements Serializable {
|
||||
eventStatus = AdventureEventController.EventStatus.Awarded;
|
||||
}
|
||||
|
||||
public String getPairingDescription() {
|
||||
switch (eventRules.pairingStyle) {
|
||||
case Swiss:
|
||||
return "swiss";
|
||||
case SwissWithCut:
|
||||
return "swiss (with cut)";
|
||||
case RoundRobin:
|
||||
return "round robin";
|
||||
case SingleElimination:
|
||||
return "single elimination";
|
||||
case DoubleElimination:
|
||||
return "double elimination";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getDescription(PointOfInterestChanges changes) {
|
||||
float townPriceModifier = changes == null ? 1f : changes.getTownPriceModifier();
|
||||
if (format.equals(AdventureEventController.EventFormat.Draft)) {
|
||||
if (format == AdventureEventController.EventFormat.Draft) {
|
||||
description = "Event Type: Booster Draft\n";
|
||||
description += "Block: " + getCardBlock() + "\n";
|
||||
description += "Boosters: " + String.join(", ", packConfiguration) + "\n";
|
||||
description += "Competition Style: " + participants.length + " players, matches played as best of " + eventRules.gamesPerMatch + ", " + (getPairingDescription()) + "\n\n";
|
||||
description += "Competition Style: " + participants.length + " players, matches played as best of " + eventRules.gamesPerMatch + ", " + (eventRules.getPairingDescription()) + "\n\n";
|
||||
|
||||
if (eventStatus == AdventureEventController.EventStatus.Available) {
|
||||
description += String.format("Pay 1 Entry Fee\n- Gold %d[][+Gold][BLACK]\n- Mana Shards %d[][+Shards][BLACK]\n", Math.round(eventRules.goldToEnter * townPriceModifier), Math.round(eventRules.shardsToEnter * townPriceModifier));
|
||||
@@ -701,10 +716,10 @@ public class AdventureEventData implements Serializable {
|
||||
}
|
||||
}
|
||||
description += String.format("Prizes\nChampion: Keep drafted deck\n2+ round wins: Challenge Coin \n1+ round wins: %s Booster, %s Booster\n0 round wins: %s Booster", rewardPacks[0].getComment(), rewardPacks[1].getComment(), rewardPacks[2].getComment());
|
||||
} else if (format.equals(AdventureEventController.EventFormat.Jumpstart)) {
|
||||
} else if (format == AdventureEventController.EventFormat.Jumpstart) {
|
||||
description = "Event Type: Jumpstart\n";
|
||||
description += "Block: " + getCardBlock() + "\n";
|
||||
description += "Competition Style: " + participants.length + " players, matches played as best of " + eventRules.gamesPerMatch + ", " + (getPairingDescription()) + "\n\n";
|
||||
description += "Competition Style: " + participants.length + " players, matches played as best of " + eventRules.gamesPerMatch + ", " + (eventRules.getPairingDescription()) + "\n\n";
|
||||
description += String.format("Pay 1 Entry Fee\n- Gold %d[][+Gold][BLACK]\n- Mana Shards %d[][+Shards][BLACK]\n", Math.round(eventRules.goldToEnter * townPriceModifier), Math.round(eventRules.shardsToEnter * townPriceModifier));
|
||||
if (eventRules.acceptsBronzeChallengeCoin) {
|
||||
description += "- Bronze Challenge Coin [][+BronzeChallengeCoin][BLACK]\n\n";
|
||||
@@ -723,6 +738,7 @@ public class AdventureEventData implements Serializable {
|
||||
|
||||
|
||||
public static class AdventureEventParticipant implements Serializable, Comparable<AdventureEventParticipant> {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
private transient EnemySprite sprite;
|
||||
String enemyDataName;
|
||||
@@ -810,6 +826,7 @@ public class AdventureEventData implements Serializable {
|
||||
}
|
||||
|
||||
public static class AdventureEventRules implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = -2902188278147984885L;
|
||||
public int goldToEnter;
|
||||
public int shardsToEnter;
|
||||
@@ -869,9 +886,20 @@ public class AdventureEventData implements Serializable {
|
||||
goldToEnter = baseGoldEntry;
|
||||
shardsToEnter = baseShardEntry;
|
||||
}
|
||||
|
||||
public String getPairingDescription() {
|
||||
return switch (pairingStyle) {
|
||||
case Swiss -> "swiss";
|
||||
case SwissWithCut -> "swiss (with cut)";
|
||||
case RoundRobin -> "round robin";
|
||||
case SingleElimination -> "single elimination";
|
||||
case DoubleElimination -> "double elimination";
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static class AdventureEventMatch implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
public AdventureEventParticipant p1;
|
||||
public AdventureEventParticipant p2;
|
||||
@@ -880,6 +908,7 @@ public class AdventureEventData implements Serializable {
|
||||
}
|
||||
|
||||
public static class AdventureEventReward implements Serializable {
|
||||
@Serial
|
||||
private final static long serialVersionUID = -2605375040895115477L;
|
||||
public int minWins = -1;
|
||||
public int maxWins = -1;
|
||||
|
||||
@@ -11,6 +11,7 @@ import forge.adventure.stage.GameHUD;
|
||||
import forge.adventure.util.AdventureEventController;
|
||||
import forge.adventure.util.Controls;
|
||||
import forge.adventure.util.Current;
|
||||
import forge.model.CardBlock;
|
||||
|
||||
/**
|
||||
* Scene for the Inn in towns
|
||||
@@ -34,7 +35,7 @@ public class InnScene extends UIScene {
|
||||
localObjectId = objectId;
|
||||
if (lastGameScene != null)
|
||||
object.lastGameScene=lastGameScene;
|
||||
getLocalEvent();
|
||||
initLocalEvent();
|
||||
|
||||
return object;
|
||||
}
|
||||
@@ -109,7 +110,7 @@ public class InnScene extends UIScene {
|
||||
tempHitPointCost.setDisabled(!purchaseable);
|
||||
tempHitPointCost.setText("[+GoldCoin] " + tempHealthCost);
|
||||
|
||||
getLocalEvent();
|
||||
initLocalEvent();
|
||||
if (localEvent == null){
|
||||
eventDescription.setText("[GREY]No events at this time");
|
||||
event.setDisabled(true);
|
||||
@@ -148,9 +149,7 @@ public class InnScene extends UIScene {
|
||||
Forge.switchScene(ShopScene.instance());
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void getLocalEvent() {
|
||||
private static void initLocalEvent() {
|
||||
localEvent = null;
|
||||
for (AdventureEventData data : AdventurePlayer.current().getEvents()){
|
||||
if (data.sourceID.equals(localPointOfInterestId) && data.eventOrigin == localObjectId){
|
||||
@@ -158,7 +157,18 @@ public class InnScene extends UIScene {
|
||||
return;
|
||||
}
|
||||
}
|
||||
localEvent = AdventureEventController.instance().createEvent(AdventureEventController.EventStyle.Bracket, localPointOfInterestId, localObjectId, changes);
|
||||
AdventureEventController controller = AdventureEventController.instance();
|
||||
localEvent = controller.createEvent(localPointOfInterestId);
|
||||
if(localEvent != null)
|
||||
controller.initializeEvent(localEvent, localPointOfInterestId, localObjectId, changes);
|
||||
}
|
||||
|
||||
public static void replaceLocalEvent(AdventureEventController.EventFormat format, CardBlock cardBlock) {
|
||||
AdventurePlayer.current().getEvents().removeIf((data) -> data.sourceID.equals(localPointOfInterestId) && data.eventOrigin == localObjectId);
|
||||
AdventureEventController controller = AdventureEventController.instance();
|
||||
localEvent = controller.createEvent(format, cardBlock, localPointOfInterestId);
|
||||
if(localEvent != null)
|
||||
controller.initializeEvent(localEvent, localPointOfInterestId, localObjectId, changes);
|
||||
}
|
||||
|
||||
private void startEvent(){
|
||||
|
||||
@@ -8,6 +8,7 @@ import forge.StaticData;
|
||||
import forge.adventure.character.PlayerSprite;
|
||||
import forge.adventure.data.*;
|
||||
import forge.adventure.pointofintrest.PointOfInterest;
|
||||
import forge.adventure.scene.InnScene;
|
||||
import forge.adventure.scene.InventoryScene;
|
||||
import forge.adventure.util.AdventureEventController;
|
||||
import forge.adventure.util.Current;
|
||||
@@ -21,7 +22,10 @@ import forge.deck.DeckProxy;
|
||||
import forge.game.GameType;
|
||||
import forge.gui.FThreads;
|
||||
import forge.item.PaperCard;
|
||||
import forge.model.CardBlock;
|
||||
import forge.model.FModel;
|
||||
import forge.screens.CoverScreen;
|
||||
import forge.util.Aggregates;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -510,5 +514,26 @@ public class ConsoleCommandInterpreter {
|
||||
}
|
||||
return message;
|
||||
});
|
||||
registerCommand(new String[]{"set", "event"}, s -> {
|
||||
if(s.length < 1) return "Command needs 1 parameter: Block or edition name. ";
|
||||
String blockName = s[0];
|
||||
if(MapStage.getInstance().findLocalInn() == null)
|
||||
return "Must be used within a town with an inn.";
|
||||
CardBlock eventCardBlock = FModel.getBlocks().find(b -> b.getName().equalsIgnoreCase(blockName));
|
||||
if(eventCardBlock == null) {
|
||||
CardEdition edition = FModel.getMagicDb().getEditions().find(e -> e.getCode().equalsIgnoreCase(blockName) || e.getName().equalsIgnoreCase(blockName));
|
||||
if(edition == null)
|
||||
return "Unable to find edition or block: " + blockName;
|
||||
eventCardBlock = Aggregates.random(AdventureEventData.getValidDraftBlocks(List.of(edition)));
|
||||
if(eventCardBlock == null)
|
||||
return "Unable to find a valid event block that exclusively contains edition " + edition.getName();
|
||||
}
|
||||
AdventureEventController.EventFormat eventFormat = s.length > 1 ? AdventureEventController.EventFormat.smartValueOf(s[1])
|
||||
: eventCardBlock.getName().contains("Jumpstart") ? AdventureEventController.EventFormat.Jumpstart : AdventureEventController.EventFormat.Draft;
|
||||
if(eventFormat == null)
|
||||
return "Unknown event format: " + s[1];
|
||||
InnScene.replaceLocalEvent(eventFormat, eventCardBlock);
|
||||
return "Replaced local event with " + eventFormat.name() + " - " + eventCardBlock.getName();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,6 +260,7 @@ public class MapStage extends GameStage {
|
||||
spawnClassified.clear();
|
||||
sourceMapMatch.clear();
|
||||
enemies.clear();
|
||||
localInnID = -1;
|
||||
for (MapLayer layer : map.getLayers()) {
|
||||
if (layer.getProperties().containsKey("spriteLayer") && layer.getProperties().get("spriteLayer", boolean.class)) {
|
||||
spriteLayer = layer;
|
||||
@@ -578,6 +579,7 @@ public class MapStage extends GameStage {
|
||||
//TODO: Ability to move them (using a sequence such as "UULU" for up, up, left, up).
|
||||
break;
|
||||
case "inn":
|
||||
localInnID = id;
|
||||
addMapActor(obj, new OnCollide(() -> Forge.switchScene(InnScene.instance(TileMapScene.instance(), TileMapScene.instance().rootPoint.getID(), changes, id))));
|
||||
break;
|
||||
case "spellsmith":
|
||||
@@ -750,6 +752,14 @@ public class MapStage extends GameStage {
|
||||
}
|
||||
}
|
||||
|
||||
//We could track MapObject IDs more generally but for now this is the only one we might need.
|
||||
private int localInnID = -1;
|
||||
public InnScene findLocalInn() {
|
||||
if(localInnID == -1)
|
||||
return null;
|
||||
return InnScene.instance(TileMapScene.instance(), TileMapScene.instance().rootPoint.getID(), changes, localInnID);
|
||||
}
|
||||
|
||||
public boolean exitDungeon(boolean defeated, boolean defeatedByBoss) {
|
||||
AdventureQuestController.instance().updateQuestsLeave();
|
||||
clearIsInMap();
|
||||
|
||||
@@ -4,7 +4,6 @@ import forge.StaticData;
|
||||
import forge.adventure.data.AdventureEventData;
|
||||
import forge.adventure.player.AdventurePlayer;
|
||||
import forge.adventure.pointofintrest.PointOfInterestChanges;
|
||||
import forge.card.CardEdition;
|
||||
import forge.deck.Deck;
|
||||
import forge.item.BoosterPack;
|
||||
import forge.item.PaperCard;
|
||||
@@ -29,7 +28,13 @@ public class AdventureEventController implements Serializable {
|
||||
Draft,
|
||||
Sealed,
|
||||
Jumpstart,
|
||||
Constructed
|
||||
Constructed;
|
||||
|
||||
public static EventFormat smartValueOf(String name) {
|
||||
return Arrays.stream(EventFormat.values())
|
||||
.filter(e -> e.name().equalsIgnoreCase(name))
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
public enum EventStyle {
|
||||
@@ -67,27 +72,16 @@ public class AdventureEventController implements Serializable {
|
||||
object = null;
|
||||
}
|
||||
|
||||
public AdventureEventData createEvent(EventStyle style, String pointID, int eventOrigin, PointOfInterestChanges changes) {
|
||||
public AdventureEventData createEvent(String pointID) {
|
||||
if (nextEventDate.containsKey(pointID) && nextEventDate.get(pointID) >= LocalDate.now().toEpochDay()) {
|
||||
// No event currently available here
|
||||
return null;
|
||||
}
|
||||
|
||||
long eventSeed;
|
||||
long timeSeed = LocalDate.now().toEpochDay();
|
||||
long placeSeed = Long.parseLong(pointID.replaceAll("[^0-9]", ""));
|
||||
long room = Long.MAX_VALUE - placeSeed;
|
||||
if (timeSeed > room) {
|
||||
//ensuring we don't ever hit an overflow
|
||||
eventSeed = Long.MIN_VALUE + timeSeed - room;
|
||||
} else {
|
||||
eventSeed = timeSeed + placeSeed;
|
||||
}
|
||||
|
||||
long eventSeed = getEventSeed(pointID);
|
||||
Random random = new Random(eventSeed);
|
||||
|
||||
AdventureEventData e;
|
||||
|
||||
// After a certain number of wins, stop offering Jumpstart events
|
||||
if (Current.player().getStatistic().totalWins() < 10 &&
|
||||
random.nextInt(10) <= 2) {
|
||||
@@ -100,15 +94,34 @@ public class AdventureEventController implements Serializable {
|
||||
//covers cases where (somehow) editions that do not match the event style have been picked up
|
||||
return null;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
// If the chosen event seed recommends a four-person pod, run it as a RoundRobin
|
||||
// Set can be null when it is only a meta set such as some Jumpstart events.
|
||||
CardEdition firstSet = e.cardBlock.getSets().isEmpty() ? null : e.cardBlock.getSets().get(0);
|
||||
int podSize = firstSet == null ? 8 : firstSet.getDraftOptions().getRecommendedPodSize();
|
||||
public AdventureEventData createEvent(EventFormat format, CardBlock cardBlock, String pointID) {
|
||||
long eventSeed = getEventSeed(pointID);
|
||||
AdventureEventData e = new AdventureEventData(eventSeed, format, cardBlock);
|
||||
if(e.cardBlock == null)
|
||||
return null;
|
||||
return e;
|
||||
}
|
||||
|
||||
private static long getEventSeed(String pointID) {
|
||||
long eventSeed;
|
||||
long timeSeed = LocalDate.now().toEpochDay();
|
||||
long placeSeed = Long.parseLong(pointID.replaceAll("[^0-9]", ""));
|
||||
long room = Long.MAX_VALUE - placeSeed;
|
||||
if (timeSeed > room) {
|
||||
//ensuring we don't ever hit an overflow
|
||||
eventSeed = Long.MIN_VALUE + timeSeed - room;
|
||||
} else {
|
||||
eventSeed = timeSeed + placeSeed;
|
||||
}
|
||||
return eventSeed;
|
||||
}
|
||||
|
||||
public void initializeEvent(AdventureEventData e, String pointID, int eventOrigin, PointOfInterestChanges changes) {
|
||||
e.sourceID = pointID;
|
||||
e.eventOrigin = eventOrigin;
|
||||
e.style = podSize == 4 ? EventStyle.RoundRobin : style;
|
||||
|
||||
AdventureEventData.PairingStyle pairingStyle;
|
||||
if (e.style == EventStyle.RoundRobin) {
|
||||
@@ -118,21 +131,11 @@ public class AdventureEventController implements Serializable {
|
||||
}
|
||||
|
||||
e.eventRules = new AdventureEventData.AdventureEventRules(e.format, pairingStyle, changes == null ? 1f : changes.getTownPriceModifier());
|
||||
e.generateParticipants(podSize - 1); //-1 to account for the player
|
||||
|
||||
switch (e.style) {
|
||||
case Swiss:
|
||||
case Bracket:
|
||||
e.rounds = (e.participants.length / 2) - 1;
|
||||
break;
|
||||
case RoundRobin:
|
||||
e.rounds = e.participants.length - 1;
|
||||
break;
|
||||
}
|
||||
e.generateParticipants();
|
||||
|
||||
AdventurePlayer.current().addEvent(e);
|
||||
nextEventDate.put(pointID, LocalDate.now().toEpochDay() + new Random().nextInt(2)); //next local event availability date
|
||||
return e;
|
||||
}
|
||||
|
||||
public Deck generateBooster(String setCode) {
|
||||
@@ -144,7 +147,6 @@ public class AdventureEventController implements Serializable {
|
||||
output.setComment(setCode);
|
||||
return output;
|
||||
}
|
||||
|
||||
public Deck generateBoosterByColor(String color) {
|
||||
List<PaperCard> cards = BoosterPack.fromColor(color).getCards();
|
||||
Deck output = new Deck();
|
||||
|
||||
Reference in New Issue
Block a user