com.megacrit.cardcrawl.relics.AbstractRelic Java Examples

The following examples show how to use com.megacrit.cardcrawl.relics.AbstractRelic. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: TrueDamagePatch.java    From jorbs-spire-mod with MIT License 6 votes vote down vote up
public static ExprEditor Instrument() {
    return new ExprEditor() {
        @Override
        public void edit(MethodCall mc) throws CannotCompileException {
            String cls = mc.getClassName();
            String method = mc.getMethodName();

            // Clamp all the damage modifier hooks with first parameter of "float tmp"
            if ((
                    cls.equals(AbstractRelic.class.getName()) ||
                    cls.equals(AbstractPower.class.getName()) ||
                    cls.equals(AbstractStance.class.getName())
                ) && (
                    method.equals("atDamageModify") ||
                    method.equals("atDamageGive") ||
                    method.equals("atDamageReceive") ||
                    method.equals("atDamageFinalGive") ||
                    method.equals("atDamageFinalReceive")
            )) {
                mc.replace(String.format("{ $_ = %1$s.updateDamage(this, $1, $proceed($$)); }", TrueDamagePatchName));
            }
        }
    };
}
 
Example #2
Source File: SuperRareRelicPatch.java    From StSLib with MIT License 6 votes vote down vote up
public static String Postfix(String __result, AbstractRelic.RelicTier tier)
{
    if (depth == 0 && RelicLibrary.getRelic(__result) instanceof SuperRareRelic) {
        RelicTools.returnRelicToPool(tier, __result);
        ++depth;
        __result = AbstractDungeon.returnRandomRelicKey(tier);
        --depth;
    }

    return __result;
}
 
Example #3
Source File: RelicTools.java    From StSLib with MIT License 6 votes vote down vote up
public static ArrayList<String> relicTierPool(AbstractRelic.RelicTier tier)
{
    switch (tier) {
        case COMMON:
            return AbstractDungeon.commonRelicPool;
        case UNCOMMON:
            return AbstractDungeon.uncommonRelicPool;
        case RARE:
            return AbstractDungeon.rareRelicPool;
        case BOSS:
            return AbstractDungeon.bossRelicPool;
        case SHOP:
            return AbstractDungeon.shopRelicPool;
        default:
            return null;
    }
}
 
Example #4
Source File: OnPlayerDeathPatch.java    From StSLib with MIT License 6 votes vote down vote up
@SpireInsertPatch(
        locator=Locator.class
)
public static SpireReturn Insert(AbstractPlayer __instance, DamageInfo info)
{
    for (AbstractPower power : __instance.powers) {
        if (power instanceof OnPlayerDeathPower) {
            if (!((OnPlayerDeathPower) power).onPlayerDeath(__instance, info)) {
                return SpireReturn.Return(null);
            }
        }
    }

    for (AbstractRelic relic : __instance.relics) {
        if (relic instanceof OnPlayerDeathRelic) {
            if (!((OnPlayerDeathRelic) relic).onPlayerDeath(__instance, info)) {
                return SpireReturn.Return(null);
            }
        }
    }
    return SpireReturn.Continue();
}
 
Example #5
Source File: OnLoseBlockPatch.java    From StSLib with MIT License 6 votes vote down vote up
public static SpireReturn<Integer> Prefix(AbstractCreature __instance, DamageInfo info, @ByRef int[] damageAmount)
{
    if (info.type != DamageInfo.DamageType.HP_LOSS && __instance.currentBlock > 0) {
        for (AbstractPower power : __instance.powers) {
            if (power instanceof OnLoseBlockPower) {
                damageAmount[0] = ((OnLoseBlockPower) power).onLoseBlock(info, damageAmount[0]);
            }
        }
        if (__instance.isPlayer) {
            for (AbstractRelic relic : AbstractDungeon.player.relics) {
                if (relic instanceof OnLoseBlockRelic) {
                    damageAmount[0] = ((OnLoseBlockRelic) relic).onLoseBlock(info, damageAmount[0]);
                }
            }
        }
    }

    return SpireReturn.Continue();
}
 
Example #6
Source File: RelicOnChannelPatch.java    From StSLib with MIT License 5 votes vote down vote up
@SpireInsertPatch(
        locator=Locator.class
)
public static void Insert(AbstractPlayer __intance, AbstractOrb orbToSet)
{
    for (AbstractRelic relic : __intance.relics) {
        if (relic instanceof OnChannelRelic) {
            ((OnChannelRelic)relic).onChannel(orbToSet);
        }
    }
}
 
Example #7
Source File: BottledPlaceholderRelic.java    From StS-DefaultModBase with MIT License 5 votes vote down vote up
public void onUseCard(AbstractCard targetCard, UseCardAction useCardAction) { // Whenever we use any card
    boolean fullHandDialog = false; // Create a boolean (to prevent multiple "My hand is full!" dialogues if we have multiple cards bottled)

    for (Iterator<AbstractCard> it = AbstractDungeon.player.drawPile.group.iterator(); it.hasNext(); ) {
        // Create a new Iterator called "it" that checks for all AbstractCards in our draw pile. For each card:
        AbstractCard card = it.next(); // create a new AbstractCard named "card" which is equal to the current card in the for each loop
        if (BottledPlaceholderField.inBottledPlaceholderField.get(card)) { // Check if our SpireField matches said card
            // Essentially, we end up with: Check if the draw pile has a card that is bottled with this bottle

            // So, once we find a card that is bottled:

            this.flash(); // The relic flashes
            it.remove(); // Remove that card from the iterator (to prevent infinite loops)

            if (AbstractDungeon.player.hand.size() < BaseMod.MAX_HAND_SIZE) { // If your hand isn't full
                if (AutoplayField.autoplay.get(card)) { // If the card auto-plays - auto play it
                    AbstractDungeon.actionManager.addToBottom(new AutoplayCardAction(card, AbstractDungeon.player.hand));
                }
                card.triggerWhenDrawn(); // If the card triggers an effect on being drawn - trigger it
                AbstractDungeon.player.drawPile.moveToHand(card, AbstractDungeon.player.drawPile); // Move the card to your hand from your draw pile

                for (AbstractRelic r : AbstractDungeon.player.relics) { // And if you have any relics that trigger on card draw - trigger them
                    r.onCardDraw(card);
                }
            } else { // If your hand IS full - create a single "My hand is full!" dialogue and move the card to the discard pile instead
                if (!fullHandDialog) {
                    AbstractDungeon.player.createHandIsFullDialog();
                    fullHandDialog = true;
                }
                AbstractDungeon.player.drawPile.moveToDiscardPile(card);
            }

        }
    }
}
 
Example #8
Source File: SuperRareRelicPatch.java    From StSLib with MIT License 5 votes vote down vote up
public static String Postfix(String __result, AbstractRelic.RelicTier tier)
{
    if (depth == 0 && RelicLibrary.getRelic(__result) instanceof SuperRareRelic) {
        RelicTools.returnRelicToPool(tier, __result);
        ++depth;
        __result = AbstractDungeon.returnEndRandomRelicKey(tier);
        --depth;
    }

    return __result;
}
 
Example #9
Source File: BetterOnSmithRelicPatch.java    From StSLib with MIT License 5 votes vote down vote up
@SpireInsertPatch(
        locator=Locator.class,
        localvars={"c"}
)
public static void Insert(CampfireSmithEffect __instance, AbstractCard c)
{
    for (AbstractRelic r : AbstractDungeon.player.relics) {
        if (r instanceof BetterOnSmithRelic) {
            ((BetterOnSmithRelic)r).betterOnSmith(c);
        }
    }
}
 
Example #10
Source File: OnSkipCardRelicPatch.java    From StSLib with MIT License 5 votes vote down vote up
@SpireInsertPatch(
        rloc=0,
        localvars={"rItem"}
)
public static void Insert(SingingBowlButton __instance, RewardItem rItem)
{
    for (AbstractRelic r : AbstractDungeon.player.relics) {
        if (r instanceof OnSkipCardRelic) {
            if (AbstractDungeon.player.hasRelic(SingingBowl.ID)) {
                ((OnSkipCardRelic)r).onSkipSingingBowl(rItem);
            }
        }
    }
}
 
Example #11
Source File: OnSkipCardRelicPatch.java    From StSLib with MIT License 5 votes vote down vote up
@SpireInsertPatch(
        locator=Locator.class,
        localvars={"item"}
)
public static void Insert(ProceedButton __instance, RewardItem item)
{
    for (AbstractRelic r : AbstractDungeon.player.relics) {
        if (r instanceof OnSkipCardRelic) {
            ((OnSkipCardRelic)r).onSkipCard(item);
        }
    }
}
 
Example #12
Source File: OnAfterUseCardPatch.java    From StSLib with MIT License 5 votes vote down vote up
@SpireInsertPatch(
        locator=Locator.class,
        localvars={"targetCard"}
)
public static void Insert(UseCardAction __instance, AbstractCard targetCard)
{
    for (AbstractRelic relic : AbstractDungeon.player.relics) {
        if (relic instanceof OnAfterUseCardRelic) {
            ((OnAfterUseCardRelic) relic).onAfterUseCard(targetCard, __instance);
        }
    }
}
 
Example #13
Source File: OnRemoveCardFromMasterDeckPatch.java    From StSLib with MIT License 5 votes vote down vote up
public static void Postfix(CardGroup __instance, AbstractCard c)
{
    if (__instance.type == CardGroup.CardGroupType.MASTER_DECK) {
        for (AbstractRelic r : AbstractDungeon.player.relics) {
            if (r instanceof OnRemoveCardFromMasterDeckRelic) {
                ((OnRemoveCardFromMasterDeckRelic) r).onRemoveCardFromMasterDeck(c);
            }
        }
    }
}
 
Example #14
Source File: RelicTools.java    From StSLib with MIT License 5 votes vote down vote up
public static boolean returnRelicToPool(AbstractRelic.RelicTier tier, String relicID)
{
    ArrayList<String> pool = relicTierPool(tier);
    if (pool != null && !pool.isEmpty()) {
        int insertAt = AbstractDungeon.relicRng.random(0, pool.size()-1);
        pool.add(insertAt, relicID);
        return true;
    }
    return false;
}
 
Example #15
Source File: ClickableRelic.java    From StSLib with MIT License 5 votes vote down vote up
default void clickUpdate()
{
    if (this instanceof AbstractRelic) {
        AbstractRelic relic = (AbstractRelic) this;
        if (HitboxRightClick.rightClicked.get(relic.hb)) {
            onRightClick();
        }
    } else {
        throw new NotImplementedException();
    }
}
 
Example #16
Source File: ClickableRelic.java    From StSLib with MIT License 5 votes vote down vote up
default boolean hovered()
{
    if (this instanceof AbstractRelic) {
        AbstractRelic relic = (AbstractRelic) this;
        return relic.hb.hovered;
    }
    throw new NotImplementedException();
}
 
Example #17
Source File: TrueDamagePatch.java    From jorbs-spire-mod with MIT License 5 votes vote down vote up
public static ExprEditor Instrument() {
    return new ExprEditor() {
        @Override
        public void edit(FieldAccess fa) throws CannotCompileException {
            // suppress the initial Intangible effect on info.output
            if (fa.getClassName().equals(DamageInfo.class.getName()) &&
                fa.getFieldName().equals("output") &&
                fa.isWriter())
            {
                fa.replace(String.format("{ if (!%1$s.isTrueDamage($0)) { $_ = $proceed($$); } }", TrueDamagePatchName));
            }
        }

        @Override
        public void edit(MethodCall mc) throws CannotCompileException {
            String cls = mc.getClassName();
            String method = mc.getMethodName();

            // clamp the onAttackToChangeDamage, onAttackedToChangeDamage, and onAttacked calls
            if ((cls.equals(AbstractPower.class.getName()) || cls.equals(AbstractRelic.class.getName())) &&
                (method.equals("onAttackToChangeDamage") || method.equals("onAttackedToChangeDamage") || method.equals("onAttacked")))
            {
                mc.replace(String.format("{ $_ = %1$s.updateDamage($1, $2, $proceed($$)); }", TrueDamagePatchName));
                return;
            }
        }
    };
}
 
Example #18
Source File: ClickableRelicUpdatePatch.java    From StSLib with MIT License 5 votes vote down vote up
@SpireInsertPatch(
        locator=Locator.class,
        localvars={"r"}
)
public static void Insert(OverlayMenu __instance, AbstractRelic relic)
{
    if (relic instanceof ClickableRelic) {
        ((ClickableRelic) relic).clickUpdate();
    }
}
 
Example #19
Source File: ShovelClickPatch.java    From jorbs-spire-mod with MIT License 5 votes vote down vote up
@SpireInsertPatch(
        locator = Locator.class,
        localvars = {"r"}
)
public static void Insert(OverlayMenu __instance, AbstractRelic relic) {
    if (relic instanceof Shovel) {
        if (HitboxRightClick.rightClicked.get(relic.hb)) {
            AbstractDungeon.effectList.add(new ThoughtBubble(AbstractDungeon.player.dialogX, AbstractDungeon.player.dialogY, 3.0F, TEXT[0], true));
        }
    }
}
 
Example #20
Source File: AdvanceRelicsThroughTimeAction.java    From jorbs-spire-mod with MIT License 5 votes vote down vote up
private static void forEachRelic(Consumer<AbstractRelic> callback) {
    for (AbstractRelic relic : AbstractDungeon.player.relics) {
        if (relic.counter >= 0) {
            callback.accept(relic);
        }
    }
}
 
Example #21
Source File: Toll.java    From jorbs-spire-mod with MIT License 5 votes vote down vote up
@Override
protected int calculateBonusBaseDamage() {
    int bonusDamage = 0;
    for(AbstractRelic relic : AbstractDungeon.player.relics){
        if (relic.counter >= 0) {
            bonusDamage += relic.counter;
        }
    }
    return bonusDamage*magicNumber;
}
 
Example #22
Source File: AtStartOfActRelicSubscriber.java    From jorbs-spire-mod with MIT License 5 votes vote down vote up
static void doAtStartOfAct() {
    for (AbstractRelic r : AbstractDungeon.player.relics) {
        if (r instanceof AtStartOfActRelicSubscriber) {
            ((AtStartOfActRelicSubscriber) r).atStartOfAct();
        }
    }
}
 
Example #23
Source File: BetterOnUsePotionPatch.java    From StSLib with MIT License 5 votes vote down vote up
private static void Do(AbstractPotion potion)
{
    for (AbstractRelic relic : AbstractDungeon.player.relics) {
        if (relic instanceof BetterOnUsePotionRelic) {
            ((BetterOnUsePotionRelic)relic).betterOnUsePotion(potion);
        }
    }
}
 
Example #24
Source File: BetterOnLoseHpPatch.java    From StSLib with MIT License 5 votes vote down vote up
public static ExprEditor Instrument()
{
    return new ExprEditor() {
        @Override
        public void edit(MethodCall m) throws CannotCompileException
        {
            if (m.getClassName().equals(AbstractRelic.class.getName()) && m.getMethodName().equals("onLoseHp")) {
                m.replace("{" +
                        "damageAmount = " + BetterOnLoseHpPatch.class.getName() + ".Do(info, r, damageAmount);" +
                        "$proceed(damageAmount);" +
                        "}");
            }
        }
    };
}
 
Example #25
Source File: BetterOnLoseHpPatch.java    From StSLib with MIT License 5 votes vote down vote up
@SuppressWarnings("unused")
public static int Do(DamageInfo info, AbstractRelic r, int damageAmount)
{
    if (r instanceof BetterOnLoseHpRelic) {
        return ((BetterOnLoseHpRelic) r).betterOnLoseHp(info, damageAmount);
    }
    return damageAmount;
}
 
Example #26
Source File: RodOfNegation.java    From FruityMod-StS with MIT License 4 votes vote down vote up
@Override
public AbstractRelic makeCopy() {
    return new RodOfNegation();
}
 
Example #27
Source File: ClickableRelicUpdatePatch.java    From StSLib with MIT License 4 votes vote down vote up
@Override
public int[] Locate(CtBehavior ctMethodToPatch) throws Exception
{
    Matcher finalMatcher = new Matcher.MethodCallMatcher(AbstractRelic.class, "update");
    return LineFinder.findInOrder(ctMethodToPatch, finalMatcher);
}
 
Example #28
Source File: IdentityCrisisEvent.java    From StS-DefaultModBase with MIT License 4 votes vote down vote up
@Override
protected void buttonEffect(int i) { // This is the event:
    switch (screenNum) {
        case 0: // While you are on screen number 0 (The starting screen)
            switch (i) {
                case 0: // If you press button the first button (Button at index 0), in this case: Inspiration.
                    this.imageEventText.updateBodyText(DESCRIPTIONS[1]); // Update the text of the event
                    this.imageEventText.updateDialogOption(0, OPTIONS[5]); // 1. Change the first button to the [Leave] button
                    this.imageEventText.clearRemainingOptions(); // 2. and remove all others
                    screenNum = 1; // Screen set the screen number to 1. Once we exit the switch (i) statement,
                    // we'll still continue the switch (screenNum) statement. It'll find screen 1 and do it's actions
                    // (in our case, that's the final screen, but you can chain as many as you want like that)

                    AbstractRelic relicToAdd = RelicLibrary.starterList.get(AbstractDungeon.relicRng.random(RelicLibrary.starterList.size() - 1)).makeCopy();
                    // Get a random starting relic

                    AbstractDungeon.getCurrRoom().spawnRelicAndObtain((float)(Settings.WIDTH / 2), (float)(Settings.HEIGHT / 2), relicToAdd);


                    break; // Onto screen 1 we go.
                case 1: // If you press button the second button (Button at index 1), in this case: Deinal

                    CardCrawlGame.screenShake.shake(ScreenShake.ShakeIntensity.MED, ScreenShake.ShakeDur.MED, false);
                    // Shake the screen
                    CardCrawlGame.sound.play("BLUNT_FAST");  // Play a hit sound
                    AbstractDungeon.player.decreaseMaxHealth(healthdamage); // Lose max HP
                    if (CardGroup.getGroupWithoutBottledCards(AbstractDungeon.player.masterDeck.getPurgeableCards()).size() > 0) {
                        // If you have cards you can remove - remove a card
                        AbstractDungeon.gridSelectScreen.open(
                                CardGroup.getGroupWithoutBottledCards(
                                        AbstractDungeon.player.masterDeck.getPurgeableCards()),
                                1, OPTIONS[6], false, false, false, true);
                    }

                    this.imageEventText.updateBodyText(DESCRIPTIONS[2]);
                    this.imageEventText.updateDialogOption(0, OPTIONS[5]);
                    this.imageEventText.clearRemainingOptions();
                    screenNum = 1;

                    // Same as before. A note here is that you can also do
                    // imageEventText.clearAllDialogs();
                    // imageEventText.setDialogOption(OPTIONS[1]);
                    // imageEventText.setDialogOption(OPTIONS[4]);
                    // (etc.)
                    // And that would also just set them into slot 0, 1, 2... in order, just like what we do in the very beginning

                    break; // Onto screen 1 we go.
                case 2: // If you press button the third button (Button at index 2), in this case: Acceptance

                    AbstractCard c = new Apotheosis().makeCopy();
                    AbstractDungeon.effectList.add(new ShowCardAndObtainEffect(c, (float) (Settings.WIDTH / 2), (float) (Settings.HEIGHT / 2)));

                    this.imageEventText.updateBodyText(DESCRIPTIONS[3]);
                    this.imageEventText.updateDialogOption(0, OPTIONS[5]);
                    this.imageEventText.clearRemainingOptions();
                    screenNum = 1;
                    break;
                case 3: // If you press button the fourth button (Button at index 3), in this case: TOUCH
                    imageEventText.loadImage("theDefaultResources/images/events/IdentityCrisisEvent2.png"); // Change the shown image
                    // Other than that, this option doesn't do anything special.
                    this.imageEventText.updateBodyText(DESCRIPTIONS[4]);
                    this.imageEventText.updateDialogOption(0, OPTIONS[5]);
                    this.imageEventText.clearRemainingOptions();
                    screenNum = 1;
                    break;
            }
            break;
        case 1: // Welcome to screenNum = 1;
            switch (i) {
                case 0: // If you press the first (and this should be the only) button,
                    openMap(); // You'll open the map and end the event.
                    break;
            }
            break;
    }
}
 
Example #29
Source File: DefaultInsertPatch.java    From StS-DefaultModBase with MIT License 4 votes vote down vote up
@SpireInsertPatch( // This annotation of our patch method specifies the type of patch we will be using. In our case - a Spire Insert Patch
        
        locator = Locator.class, // Spire insert patches require a locator - this isn't something you import - this is something we write.
        // (Or as is usually the case with them - copy paste cause they're always nearly the same thing.
        // In fact, most insert patches are fairly boiler-plate. You could easily make an insert patch template, if you'd like.)
        // You can find our Locator class just below, as an inner class, underneath our actual patch method.
        
        localvars = {"retVal"} // The method we're patching, returnRandomRelicKey(), has a local variable that we'd like to access and manipulate -
        // "String retVal = null;". So, we simply write out it's name here and then add it as a parameter to our patch method.
        // Keep in mind that localvars can also be used to capture class variables, not just local method ones. This also includes private ones.
)
//"A patch method must be a public static method."
public static void thisIsOurActualPatchMethod(
        // 1. "Patch methods are passed all the arguments of the original method,
        // 2. as well as the instance if original method is not static (instance first, then parameters).
        // 3. localvars are passed as arguments, appearing the in parameter list after the original method's parameters."
        
        // Example: if returnEndRandomRelicKey(RelicTier tier) were NOT static we would write our method parameters as such:
        // thisIsOurActualPatchMethod(AbstractDungeon __instance, AbstractRelic.RelicTier tier, String retVal)
        // As it stands, that method is static so it's not tied to a specific instance of AbstractDungeon. (Read up on what "static" means in java
        // if you don't understand this part).
        // As such we write our method parameters like this instead:
        AbstractRelic.RelicTier tier, String retVal) {
    
    // Wow time to actually put stuff in the basegame code!!! Everything here will be executed exactly as written, at the line which we specified.
    // You can change retVal (using @byRef) to always return the same relic, or return a specific relic if it passes some check.
    // You can execute any other static method you have, you can save retVal to your personal public static variable to always be able to
    // reference the last relic you grabbed - etc. etc. The possibilities are endless. We're gonna do the following:
    logger.info("Hey our patch triggered. The relic we're about to get is " + retVal);
    // Incredible.
    
    // Let's talk about @byRef for a bit.
    // https://github.com/kiooeht/ModTheSpire/wiki/@ByRef - Read the documentation it is really helpful!
    // If you grabbed retVal right now and did:
    
    // retVal = Anchor().relicID
    // logger.info("Hey our patch triggered. The relic we're about to get is " + retVal);
    
    // The logger would correctly print out saying "we're about to get Anchor".
    // However you wouldn't get anchor. You would get the standard relic roll.
    // The reason behind that is because by default, in patches, all variables are passed by Value, not by Reference.
    // (You can google what this means in java if you don't understand).
    // This means that while we can change retVal within our own method, it won't change in the actual, original basegame method.
    // If you want to do that, you'll need to use @byRef on the variable you want to change - this makes it get passed by reference.
    // In our case that would be retVal - so we can annotate it with @byRef in our parameters. Another thing to note is that non-array
    // objects must be converted to arrays.
    
    // So if our current method parameters are:
    // (AbstractRelic.RelicTier tier, String retVal)
    // We would instead have:
    // (AbstractRelic.RelicTier tier, @ByRef String[] retVal)
    
    // Then, when we want to use it, can just access the (for us) one and only value in that array of Strings - which would be placed at index 0.
    // retVal[0] = Anchor().relicID
    // Then the retVal would actually be changed outside of this method - inside returnRandomRelicKey();
}
 
Example #30
Source File: Blueberries.java    From FruityMod-StS with MIT License 4 votes vote down vote up
@Override
public AbstractRelic makeCopy() {
    return new Blueberries();
}