package fruitymod.seeker.powers; import basemod.BaseMod; import basemod.interfaces.PostBattleSubscriber; import basemod.interfaces.PostDrawSubscriber; import basemod.interfaces.PostDungeonInitializeSubscriber; import com.badlogic.gdx.graphics.Texture; import com.megacrit.cardcrawl.cards.AbstractCard; import com.megacrit.cardcrawl.core.AbstractCreature; import com.megacrit.cardcrawl.dungeons.AbstractDungeon; import com.megacrit.cardcrawl.powers.AbstractPower; import com.megacrit.cardcrawl.rooms.AbstractRoom; import fruitymod.SeekerMod; import fruitymod.seeker.actions.common.MakeTempCardInDrawPileEtherealAction; public class NexusPower extends AbstractPower implements PostDrawSubscriber, PostBattleSubscriber, PostDungeonInitializeSubscriber { public static final String POWER_ID = "Nexus"; public static final String NAME = "Nexus"; public static final String[] DESCRIPTIONS = new String[]{ "Whenever you draw a non-Ethereal Attack or Skill, Shuffle-Cycle ", " Ethereal copy of it into your draw pile.", " Ethereal copies of it into your draw pile." }; public NexusPower(AbstractCreature owner, int amount) { this.name = NAME; this.ID = POWER_ID; this.owner = owner; this.amount = amount; updateDescription(); this.type = AbstractPower.PowerType.BUFF; this.isTurnBased = false; this.img = new Texture(SeekerMod.makePowerImagePath(POWER_ID)); } @Override public void updateDescription() { this.description = DESCRIPTIONS[0] + (this.amount == 1 ? DESCRIPTIONS[1] : DESCRIPTIONS[2]); } @Override public void onInitialApplication() { BaseMod.subscribe(this); } @Override public void receivePostDraw(AbstractCard c) { if (!c.isEthereal && (c.type == AbstractCard.CardType.ATTACK || c.type == AbstractCard.CardType.SKILL)) { AbstractDungeon.actionManager.addToBottom( new MakeTempCardInDrawPileEtherealAction(this.owner, this.owner, c, this.amount, true, true)); } } @Override public void receivePostBattle(AbstractRoom arg0) { BaseMod.unsubscribe(this, PostDrawSubscriber.class); BaseMod.unsubscribe(this, PostDungeonInitializeSubscriber.class); /* * calling unsubscribeFromPostBattle inside the callback * for receivePostBattle means that when we're calling it * there is currently an iterator going over the list * of subscribers and calling receivePostBattle on each of * them therefore if we immediately try to remove the this * callback from the post battle subscriber list it will * throw a concurrent modification exception in the iterator * * for now we just add a delay - yes this is an atrocious solution * PLEASE someone with a better idea replace it */ Thread delayed = new Thread(() -> { try { Thread.sleep(200); } catch (Exception e) { System.out.println("could not delay unsubscribe to avoid ConcurrentModificationException"); e.printStackTrace(); } BaseMod.unsubscribe(this, PostBattleSubscriber.class); }); delayed.start(); } @Override public void receivePostDungeonInitialize() { BaseMod.unsubscribe(this, PostDrawSubscriber.class); BaseMod.unsubscribe(this, PostBattleSubscriber.class); /* * calling unsubscribeFromPostDungeonInitialize inside the callback * for receivePostDungeonInitialize means that when we're calling it * there is currently an iterator going over the list * of subscribers and calling receivePostDungeonInitialize on each of * them therefore if we immediately try to remove the this * callback from the post battle subscriber list it will * throw a concurrent modification exception in the iterator * * for now we just add a delay - yes this is an atrocious solution * PLEASE someone with a better idea replace it */ Thread delayed = new Thread(() -> { try { Thread.sleep(200); } catch (Exception e) { System.out.println("could not delay unsubscribe to avoid ConcurrentModificationException"); e.printStackTrace(); } BaseMod.unsubscribe(this, PostDungeonInitializeSubscriber.class); }); delayed.start(); } }