Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pack Attack zone #73

Merged
merged 14 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/main/java/spireMapOverhaul/abstracts/AbstractZone.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,14 @@ public void updateDescription() {
}
if (icons.length > 0)
sb.append(" NL ");
sb.append(TEXT[1]);
sb.append(getDescriptionText());
tooltipBody = sb.toString();
}

public String getDescriptionText() {
return TEXT[1];
}

public void renderOnMap(SpriteBatch sb, float alpha) {
if (alpha > 0) {
if (shapeRegion == null) {
Expand Down
172 changes: 172 additions & 0 deletions src/main/java/spireMapOverhaul/zones/packattack/PackAttackZone.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package spireMapOverhaul.zones.packattack;

import basemod.ReflectionHacks;
import com.badlogic.gdx.graphics.Color;
import com.evacipated.cardcrawl.modthespire.Loader;
import com.megacrit.cardcrawl.actions.common.MakeTempCardInHandAction;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.helpers.FontHelper;
import com.megacrit.cardcrawl.map.MapRoomNode;
import com.megacrit.cardcrawl.random.Random;
import com.megacrit.cardcrawl.relics.AbstractRelic;
import com.megacrit.cardcrawl.rooms.AbstractRoom;
import com.megacrit.cardcrawl.rooms.EventRoom;
import spireMapOverhaul.abstracts.AbstractZone;
import spireMapOverhaul.util.Wiz;
import spireMapOverhaul.zoneInterfaces.CombatModifyingZone;
import spireMapOverhaul.zoneInterfaces.ModifiedEventRateZone;
import spireMapOverhaul.zoneInterfaces.RewardModifyingZone;
import spireMapOverhaul.zoneInterfaces.ShopModifyingZone;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class PackAttackZone extends AbstractZone implements CombatModifyingZone, RewardModifyingZone, ShopModifyingZone, ModifiedEventRateZone {
public static final String ID = "PackAttack";

public static Class<?> anniv5;
public static Class<?> abstractCardPack;

private ArrayList<AbstractCard> cards;
private ArrayList<AbstractCard> commonPool;
private ArrayList<AbstractCard> uncommonPool;
private ArrayList<AbstractCard> rarePool;

private ArrayList<String> packNames;

public PackAttackZone() {
super(ID, Icons.MONSTER, Icons.EVENT, Icons.SHOP);
this.width = 2;
this.maxHeight = 4;
this.height = 3;
this.maxHeight = 4;

if (Loader.isModLoaded("anniv5")) {
try {
anniv5 = Class.forName("thePackmaster.SpireAnniversary5Mod");
abstractCardPack = Class.forName("thePackmaster.packs.AbstractCardPack");
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("Error retrieving classes from Packmaster", e);
}
}
}

public ArrayList<AbstractCard> getCards() {
return cards;
}

@Override
public AbstractZone copy() {
return new PackAttackZone();
}

@Override
public Color getColor() {
return new Color(0.76f, 0.65f, 0.52f, 1);
}

@Override
public String getDescriptionText() {
if (this.packNames == null) {
return TEXT[1];
}

List<String> packNameStrings = this.packNames.stream().map(name -> FontHelper.colorString(name, "b")).collect(Collectors.toList());
return TEXT[2].replace("{0}", packNameStrings.get(0)).replace("{1}", packNameStrings.get(1)).replace("{2}", packNameStrings.get(2));
}

@Override
@SuppressWarnings("unchecked")
public boolean canSpawn() {
return anniv5 != null && abstractCardPack != null && ((ArrayList<Object>)ReflectionHacks.getPrivateStatic(anniv5, "allPacks")).size() >= 3;
}

@Override
public void distributeRooms(Random rng, ArrayList<AbstractRoom> roomList) {
//Guarantee at least one event
placeRoomRandomly(rng, roomOrDefault(roomList, (room)->room instanceof EventRoom, EventRoom::new));
}

@Override
@SuppressWarnings("unchecked")
public void mapGenDone(ArrayList<ArrayList<MapRoomNode>> map) {
ArrayList<Object> allPacks = new ArrayList<>(ReflectionHacks.getPrivateStatic(anniv5, "allPacks"));
Collections.shuffle(allPacks, new java.util.Random(AbstractDungeon.mapRng.randomLong()));
ArrayList<Object> packs = allPacks.stream().limit(3).collect(Collectors.toCollection(ArrayList::new));
this.packNames = new ArrayList<>();
this.cards = new ArrayList<>();
for (Object pack : packs) {
try {
this.packNames.add((String)ReflectionHacks.getCachedField(abstractCardPack, "name").get(pack));
this.cards.addAll((ArrayList<AbstractCard>)ReflectionHacks.getCachedField(abstractCardPack, "cards").get(pack));
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new RuntimeException("Error determining packs for Pack zone", e);
}
}
this.commonPool = this.cards.stream().filter(c -> c.rarity == AbstractCard.CardRarity.COMMON).collect(Collectors.toCollection(ArrayList::new));
this.uncommonPool = this.cards.stream().filter(c -> c.rarity == AbstractCard.CardRarity.UNCOMMON).collect(Collectors.toCollection(ArrayList::new));
this.rarePool = this.cards.stream().filter(c -> c.rarity == AbstractCard.CardRarity.RARE).collect(Collectors.toCollection(ArrayList::new));
this.updateDescription();
}

@Override
public float zoneSpecificEventRate() {
return 1;
}

@Override
public void atPreBattle() {
AbstractDungeon.player.gameHandSize -= 1;
}

@Override
public void atTurnStart() {
AbstractCard c = this.cards.get(AbstractDungeon.cardRandomRng.random(this.cards.size() - 1)).makeCopy();
Wiz.atb(new MakeTempCardInHandAction(c, 1));
}

@Override
public void modifyRewardCards(ArrayList<AbstractCard> cards) {
this.replaceWithPackCards(cards, AbstractDungeon.cardRng);
this.applyStandardUpgradeLogic(cards);
}

@Override
public void postCreateShopCards(ArrayList<AbstractCard> coloredCards, ArrayList<AbstractCard> colorlessCards) {
this.replaceWithPackCards(coloredCards, AbstractDungeon.merchantRng);
for (AbstractCard c : coloredCards) {
for (AbstractRelic relic : AbstractDungeon.player.relics) {
relic.onPreviewObtainCard(c);
erasels marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

private void replaceWithPackCards(ArrayList<AbstractCard> cards, Random rng) {
for (int i = 0; i < cards.size(); i++) {
cards.set(i, this.getPackCard(cards.get(i).rarity, rng));
}
}

private AbstractCard getPackCard(AbstractCard.CardRarity rarity, Random rng) {
ArrayList<AbstractCard> options;
switch(rarity) {
case UNCOMMON:
options = this.uncommonPool;
break;
case RARE:
options = this.rarePool;
break;
default:
options = this.commonPool;
break;
}

return options.get(rng.random(options.size() - 1)).makeCopy();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package spireMapOverhaul.zones.packattack.events;

import com.evacipated.cardcrawl.modthespire.Loader;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.cards.DamageInfo;
import com.megacrit.cardcrawl.core.CardCrawlGame;
import com.megacrit.cardcrawl.core.Settings;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.events.AbstractImageEvent;
import com.megacrit.cardcrawl.helpers.CardLibrary;
import com.megacrit.cardcrawl.helpers.FontHelper;
import com.megacrit.cardcrawl.helpers.RelicLibrary;
import com.megacrit.cardcrawl.localization.EventStrings;
import com.megacrit.cardcrawl.relics.AbstractRelic;
import com.megacrit.cardcrawl.vfx.cardManip.ShowCardAndObtainEffect;
import spireMapOverhaul.SpireAnniversary6Mod;
import spireMapOverhaul.util.Wiz;
import spireMapOverhaul.zones.packattack.PackAttackZone;

import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Collectors;

public class BlackMarketTwo extends AbstractImageEvent {
public static final String ID = SpireAnniversary6Mod.makeID("BlackMarketTwo");
private static final EventStrings eventStrings = CardCrawlGame.languagePack.getEventString(ID);
private static final String NAME = eventStrings.NAME;
private static final String[] DESCRIPTIONS = eventStrings.DESCRIPTIONS;
private static final String[] OPTIONS = eventStrings.OPTIONS;
public static final String IMG = SpireAnniversary6Mod.makeImagePath("events/PackAttack/BlackMarketTwo.png");
private static final int CARDS = 3;
private static final int HP_LOSS = 4;
private static final int A15_HP_LOSS = 5;
private static final int GOLD = 20;
private static final int A15_GOLD = 25;

private int hpLoss;
private int gold;
private AbstractRelic boosterBox;
private AbstractCard vexed;
private AbstractCard cardistry;

private int screenNum = 0;

public BlackMarketTwo() {
super(NAME, DESCRIPTIONS[0], IMG);

if (!Loader.isModLoaded("anniv5")) {
SpireAnniversary6Mod.logger.error("This event requires Packmaster to be loaded");
this.imageEventText.setDialogOption(OPTIONS[5]);
return;
}

this.gold = AbstractDungeon.ascensionLevel >= 15 ? A15_GOLD : GOLD;
this.hpLoss = AbstractDungeon.ascensionLevel >= 15 ? A15_HP_LOSS : HP_LOSS;
this.boosterBox = RelicLibrary.getRelic("anniv5:PMBoosterBox").makeCopy();
this.vexed = CardLibrary.getCard("anniv5:Vexed").makeCopy();
this.cardistry = CardLibrary.getCard("anniv5:Cardistry").makeCopy();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using string literals for Ids, smh 😝


if (!AbstractDungeon.player.hasRelic(this.boosterBox.relicId)) {
this.imageEventText.setDialogOption(OPTIONS[0].replace("{0}", FontHelper.colorString(this.boosterBox.name, "g")).replace("{1}", FontHelper.colorString(this.vexed.name, "r")), this.vexed, this.boosterBox);
} else {
this.imageEventText.setDialogOption(OPTIONS[1], true);

}
this.imageEventText.setDialogOption(OPTIONS[2].replace("{0}", CARDS + "").replace("{1}", this.hpLoss + ""));
if (AbstractDungeon.player.gold >= this.gold) {
this.imageEventText.setDialogOption(OPTIONS[3].replace("{0}", FontHelper.colorString(this.cardistry.name, "g")).replace("{1}", this.gold + ""), this.cardistry);
} else {
this.imageEventText.setDialogOption(OPTIONS[4].replace("{0}", this.gold + ""), true);
}
this.imageEventText.setDialogOption(OPTIONS[5]);
}

@Override
protected void buttonEffect(int buttonPressed) {
if (!Loader.isModLoaded("anniv5")) {
this.openMap();
return;
}
switch (screenNum) {
case 0:
switch (buttonPressed) {
case 0: // Box
this.imageEventText.updateBodyText(DESCRIPTIONS[1]);
this.screenNum = 1;
this.imageEventText.updateDialogOption(0, OPTIONS[5]);
this.imageEventText.clearRemainingOptions();
AbstractDungeon.getCurrRoom().spawnRelicAndObtain((float) (Settings.WIDTH / 2), (float) (Settings.HEIGHT / 2), this.boosterBox);
AbstractDungeon.rareRelicPool.remove(this.boosterBox.relicId);
AbstractDungeon.effectList.add(new ShowCardAndObtainEffect(this.vexed, (float)Settings.WIDTH / 2.0F, (float)Settings.HEIGHT / 2.0F));
logMetricObtainCardAndRelic(ID, "Box", this.vexed, this.boosterBox);
break;
case 1: // Bag
this.imageEventText.updateBodyText(DESCRIPTIONS[2]);
this.screenNum = 1;
this.imageEventText.updateDialogOption(0, OPTIONS[5]);
this.imageEventText.clearRemainingOptions();
ArrayList<AbstractCard> cards = new ArrayList<>();
PackAttackZone zone = (PackAttackZone)Wiz.getCurZone();
ArrayList<AbstractCard> packCards = new ArrayList<>(zone.getCards());
Collections.shuffle(packCards, new java.util.Random(AbstractDungeon.miscRng.randomLong()));
for (int i = 0; i < CARDS; i++) {
AbstractCard c = packCards.get(i).makeCopy();
cards.add(c);
int offset = i - CARDS/2;
AbstractDungeon.effectList.add(new ShowCardAndObtainEffect(c, (float)Settings.WIDTH / 2.0F - offset * 300.0F * Settings.scale, (float)Settings.HEIGHT / 2.0F));
}
AbstractDungeon.player.damage(new DamageInfo(null, this.hpLoss));
logMetric(ID, "Bag", cards.stream().map(c -> c.cardID).collect(Collectors.toList()), null, null, null, null, null, null, 0, 0, this.hpLoss, 0, 0, 0);
break;
case 2: // Bin
this.imageEventText.updateBodyText(DESCRIPTIONS[3]);
this.screenNum = 1;
this.imageEventText.updateDialogOption(0, OPTIONS[5]);
this.imageEventText.clearRemainingOptions();
AbstractDungeon.effectList.add(new ShowCardAndObtainEffect(this.cardistry, (float)Settings.WIDTH / 2.0F, (float)Settings.HEIGHT / 2.0F));
AbstractDungeon.player.loseGold(this.gold);
logMetric(ID, "Bin", Collections.singletonList(this.cardistry.cardID), null, null, null, null, null, null, 0, 0, this.hpLoss, 0, 0, this.gold);
break;
default: // Leave
this.imageEventText.updateBodyText(DESCRIPTIONS[4]);
this.screenNum = 1;
this.imageEventText.updateDialogOption(0, OPTIONS[5]);
this.imageEventText.clearRemainingOptions();
logMetricIgnored(ID);
break;
}
break;
default:
this.openMap();
break;
}
}
}
Loading