kiooeht / ModTheSpire

External mod loader for Slay The Spire
MIT License
415 stars 87 forks source link

ClassNotFoundException: ModInitializer #165

Open XononoX opened 5 years ago

XononoX commented 5 years ago

Before submitting, have you read the Troubleshooting guide? Yes

Crash Log

ModVersion Info:
 - Java version (1.8.0_144)
 - Slay the Spire (07-17-2019)
 - ModTheSpire (3.11.0)
Mod list:
 - basemod (5.15.1)
 - stslib (1.17.1)
 - XonoMod_0_0_1 (0.1)

Begin patching...
Patching enums...Done.
Finding core patches...
Finding patches...
Patching Overrides...
Injecting patches...Done.
Compiling patched classes...Done.
Busting enums...Done.

Setting isModded = true...Done.

Adding ModTheSpire to version...Done.

Initializing mods...
 - BaseMod
   - basemod.BaseMod
libgdx version 1.9.5
05:33:17.929 INFO basemod.BaseMod> initializeGson
05:33:17.947 INFO basemod.BaseMod> initializeTypeMaps
05:33:17.949 INFO basemod.BaseMod> Registered MonsterStrings
05:33:17.952 INFO basemod.BaseMod> Registered PowerStrings
05:33:17.954 INFO basemod.BaseMod> Registered CardStrings
05:33:17.954 INFO basemod.BaseMod> Registered RelicStrings
05:33:17.955 INFO basemod.BaseMod> Registered EventStrings
05:33:17.956 INFO basemod.BaseMod> Registered PotionStrings
05:33:17.957 INFO basemod.BaseMod> Registered CreditStrings
05:33:17.958 INFO basemod.BaseMod> Registered TutorialStrings
05:33:17.958 INFO basemod.BaseMod> Registered KeywordStrings
05:33:17.962 INFO basemod.BaseMod> Registered ScoreBonusStrings
05:33:17.962 INFO basemod.BaseMod> Registered CharacterStrings
05:33:17.963 INFO basemod.BaseMod> Registered UIStrings
05:33:17.964 INFO basemod.BaseMod> Registered OrbStrings
05:33:17.965 INFO basemod.BaseMod> Registered RunModStrings
05:33:17.965 INFO basemod.BaseMod> Registered BlightStrings
05:33:17.966 INFO basemod.BaseMod> Registered AchievementStrings
05:33:17.966 INFO basemod.BaseMod> initializePowerMap
05:33:18.424 INFO basemod.BaseMod> initializeUnderscorePowerIDs
   - 520ms
 - StSLib
   - com.evacipated.cardcrawl.mod.stslib.StSLib
   - 1ms
 - XonoMod
   - ModInitializer
java.lang.ClassNotFoundException: ModInitializer
    at com.evacipated.cardcrawl.modthespire.MTSClassLoader.findClass(MTSClassLoader.java:88)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at com.evacipated.cardcrawl.modthespire.MTSClassLoader.loadClass(MTSClassLoader.java:72)
    at com.evacipated.cardcrawl.modthespire.Patcher.initializeMods(Patcher.java:37)
    at com.evacipated.cardcrawl.modthespire.Loader.runMods(Loader.java:394)
    at com.evacipated.cardcrawl.modthespire.ui.ModSelectWindow.lambda$null$1(ModSelectWindow.java:265)
    at java.lang.Thread.run(Thread.java:748)

Additional context Howdy!

I'm trying to get started building a very simplistic mod, but I can't even get it to initialize when I launch MTS. It gives me the error when it starts to load my code.

I have been following the Getting Started guide found here to write this, and copied a lot of my code from existing mod sources. https://github.com/daviscook477/BaseMod/wiki/Starting-Your-Mod

I think I just missed some crucial step which is preventing the .jar file from properly loading.

All my mod is intended to do is modify the existing Defect card, Blizzard, to make it 2-cost, Rare, and channel 2 Frost before it performs the area attack. I copied the Blizzard.java code from the decompiled Slay the Spire directory, the VFX file, and the 1024 portrait. My directory looks like this:

-XonoMod -_ModTheSpire XonoMod.jar (generated by the maven package code) -lib BaseMod.jar desktop-1.0.jar ModTheSpire.jar -src -main -java -xonomod -cards Blizzard.java XonoMod.java -resources -images -1024Portrait -blue -attack Blizzard.png -localization -eng cards.json -vfx -combat BlizzardEffect.java ModTheSpire.json -target -antrun -classes -generated-sources -maven-archiver -maven-status original-XonoMod XonoMod XonoMod-0.0.1-shaded dependency-reduced-pom.xml help_pom.txt LICENSE pom.xml README.md

I'm going to show the contents of my main XonoMod.java file here:

***XonoMod.java

package xonomod;

import basemod.BaseMod;
import basemod.interfaces.*;
import com.evacipated.cardcrawl.modthespire.lib.SpireInitializer;
import com.megacrit.cardcrawl.localization.CardStrings;
import xonomod.cards.Blizzard;

//import com.megacrit.cardcrawl.cards.AbstractCard;
//import com.megacrit.cardcrawl.characters.AbstractPlayer;
//import com.megacrit.cardcrawl.core.Settings;
//import com.megacrit.cardcrawl.dungeons.AbstractDungeon;

@SpireInitializer
public class XonoMod implements
        PostInitializeSubscriber,
        EditCardsSubscriber,
        EditRelicsSubscriber,
        EditKeywordsSubscriber,
        EditStringsSubscriber,
        StartGameSubscriber {
    //private static SpireConfig modConfig = null;

    public XonoMod() {
        BaseMod.subscribe(this);
    }

    public static void initialize() {
        new XonoMod();

        //try {
        //    Properties defaults = new Properties();
        //    modConfig = new SpireConfig("Xono", "Config", defaults);
        //} catch (IOException e) {
        //    e.printStackTrace();
        //}
    }

    @Override
    public void receiveStartGame() {
        //loadData();
    }

    @Override
    public void receivePostInitialize() {
        //BaseMod.addEvent(TheFatedDie.ID, TheFatedDie.class);

        //BaseMod.addMonster(GrandSnecko.ID, GrandSnecko::new);

        //BaseMod.addBoss(TheBeyond.ID, GrandSnecko.ID, assetPath("images/ui/map/boss/grandSnecko.png"), assetPath("images/ui/map/bossOutline/grandSnecko.png"));
    }

    @Override
    public void receiveEditCards() {
        BaseMod.addCard(new Blizzard()); // Replaces Blizzard Defect Attack, Now Rare 2-cost, Channels Frost.
    }

    @Override
    public void receiveEditRelics() {
        //BaseMod.addRelic(new Icosahedron(), RelicType.SHARED);

        // Ironclad only
        //BaseMod.addRelic(new IronBody(), RelicType.RED);
        //BaseMod.addRelic(new ChampionShield(), RelicType.RED);

        // Silent only
        //BaseMod.addRelic(new AncientText(), RelicType.GREEN);

        // Defect only
        //BaseMod.addRelic(new RGBLights(), RelicType.BLUE);
        //BaseMod.addRelic(new BallOfYels(), RelicType.BLUE);
        //BaseMod.addRelic(new SoftwareUpdate(), RelicType.BLUE);
    }

    @Override
    public void receiveEditKeywords() {

    }

    @Override
    public void receiveEditStrings() {
        //BaseMod.loadCustomStringsFile(RelicStrings.class, assetPath("localization/Hubris-RelicStrings.json"));
        BaseMod.loadCustomStringsFile(CardStrings.class, "C:/spirecomm-master/XonoMod/src/main/resources/localization/cards.json");
        //BaseMod.loadCustomStringsFile(PowerStrings.class, assetPath("localization/Hubris-PowerStrings.json"));
        //BaseMod.loadCustomStringsFile(EventStrings.class, assetPath("localization/Hubris-EventStrings.json"));
    }
}

***Blizzard.java

/*     */
package xonomod.cards;
/*     */
/*     */

import com.megacrit.cardcrawl.actions.AbstractGameAction;
import com.megacrit.cardcrawl.actions.animations.VFXAction;
import com.megacrit.cardcrawl.actions.common.DamageAllEnemiesAction;
import com.megacrit.cardcrawl.actions.defect.ChannelAction;
import com.megacrit.cardcrawl.cards.AbstractCard;
import com.megacrit.cardcrawl.characters.AbstractPlayer;
import com.megacrit.cardcrawl.core.CardCrawlGame;
import com.megacrit.cardcrawl.core.Settings;
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
import com.megacrit.cardcrawl.localization.CardStrings;
import com.megacrit.cardcrawl.monsters.AbstractMonster;
import com.megacrit.cardcrawl.orbs.AbstractOrb;
import com.megacrit.cardcrawl.orbs.Frost;
import com.megacrit.cardcrawl.vfx.combat.BlizzardEffect;

/*     */
/*     */
/*     */
/*     */
/*     */
/*     */
/*     */
/*     */
/*     */
/*     */
/*     */
/*     */

/*     */
/*     */ public class Blizzard
        /*     */ extends AbstractCard {
    /*     */   public static final String ID = "Blizzard";
    /*  19 */   private static final CardStrings cardStrings = CardCrawlGame.languagePack.getCardStrings("Blizzard");
    /*  20 */   public static final String NAME = cardStrings.NAME;
    /*  21 */   public static final String DESCRIPTION = cardStrings.DESCRIPTION; //"Channel 2 Frost. Deal damage equal to !M! times the number of Frost Channeled this combat to ALL enemies."
    /*  22 */   public static final String[] EXTENDED_DESCRIPTION = cardStrings.EXTENDED_DESCRIPTION;
    /*     */   private static final int COST = 2;

    /*     */
    /*     */
    public Blizzard() {
        /*  26 */
        super("Blizzard", NAME, "blue/attack/blizzard", 2, DESCRIPTION, AbstractCard.CardType.ATTACK, AbstractCard.CardColor.BLUE, AbstractCard.CardRarity.RARE, AbstractCard.CardTarget.ALL_ENEMY);
        /*     */
        /*     */
        /*     */
        /*  37 */
        this.baseDamage = 0;
        /*  38 */
        this.baseMagicNumber = 2;
        /*  39 */
        this.magicNumber = this.baseMagicNumber;
        /*  40 */
        this.isMultiDamage = true;
        /*     */
    }

    /*     */
    /*     */
    /*     */
    public void use(AbstractPlayer p, AbstractMonster m) {

        AbstractDungeon.actionManager.addToBottom(new ChannelAction(new Frost()));
        AbstractDungeon.actionManager.addToBottom(new ChannelAction(new Frost()));

        /*  45 */
        int frostCount = 0;
        /*  46 */
        for (AbstractOrb o : AbstractDungeon.actionManager.orbsChanneledThisCombat) {
            /*  47 */
            if (o instanceof com.megacrit.cardcrawl.orbs.Frost) {
                /*  48 */
                frostCount++;
                /*     */
            }
            /*     */
        }
        /*     */
        /*  52 */
        this.baseDamage = frostCount * this.magicNumber;
        /*  53 */
        calculateCardDamage(null);
        /*     */
        /*  55 */
        if (Settings.FAST_MODE) {
            /*  56 */
            AbstractDungeon.actionManager.addToBottom(new VFXAction(new BlizzardEffect(frostCount,
                    /*  57 */               AbstractDungeon.getMonsters().shouldFlipVfx()), 0.25F));
            /*     */
        } else {
            /*  59 */
            AbstractDungeon.actionManager.addToBottom(new VFXAction(new BlizzardEffect(frostCount,
                    /*  60 */               AbstractDungeon.getMonsters().shouldFlipVfx()), 1.0F));
            /*     */
        }
        /*     */
        /*  63 */
        AbstractDungeon.actionManager.addToBottom(new DamageAllEnemiesAction(p, this.multiDamage, this.damageTypeForTurn, AbstractGameAction.AttackEffect.BLUNT_HEAVY, false));
        /*     */
    }

    /*     */
    /*     */
    public void applyPowers() {
        /*  69 */
        int frostCount = 0;
        /*  70 */
        for (AbstractOrb o : AbstractDungeon.actionManager.orbsChanneledThisCombat) {
            /*  71 */
            if (o instanceof com.megacrit.cardcrawl.orbs.Frost) {
                /*  72 */
                frostCount++;
                /*     */
            }
            /*     */
        }
        /*     */
        /*  76 */
        if (frostCount > 0) {
            /*  77 */
            this.baseDamage = frostCount * this.magicNumber;
            /*  78 */
            super.applyPowers();
            /*  79 */
            this.rawDescription = DESCRIPTION + EXTENDED_DESCRIPTION[0];
            /*  80 */
            initializeDescription();
            /*     */
        }
        /*     */
    }

    /*     */
    /*     */
    public void onMoveToDiscard() {
        /*  86 */
        this.rawDescription = DESCRIPTION;
        /*  87 */
        initializeDescription();
        /*     */
    }

    /*     */
    /*     */
    public void calculateCardDamage(AbstractMonster mo) {
        /*  92 */
        super.calculateCardDamage(mo);
        /*     */
        /*  94 */
        this.rawDescription = DESCRIPTION;
        /*  95 */
        this.rawDescription += EXTENDED_DESCRIPTION[0];
        /*  96 */
        initializeDescription();
        /*     */
    }

    /*     */
    /* 101 */
    public AbstractCard makeCopy() {
        return new Blizzard();
    }

    /*     */
    /*     */
    /*     */
    public void upgrade() {
        /* 106 */
        if (!this.upgraded) {
            /* 107 */
            upgradeName();
            /* 108 */
            upgradeMagicNumber(1);
            /*     */
        }
        /*     */
    }
    /*     */
}

/* Location:              C:\Program Files (x86)\Steam\steamapps\common\SlayTheSpire\desktop-1.0.jar!\com\megacrit\cardcrawl\cards\blue\Blizzard.class
 * Java compiler version: 8 (52.0)
 * JD-Core Version:       1.0.6
 */

***pom.xml

<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">

    <modelVersion>4.0.0</modelVersion>

    <!-- Change These to match your mod -->
    <groupId>xonomod</groupId>
    <artifactId>XonoMod</artifactId>
    <version>0.0.1</version>
    <packaging>jar</packaging>
    <name>XonoMod</name>
    <description>Slay the Spire mod</description>

    <!-- These are the dependencies that were placed in the libs folder.
         Try to keep the version numbers the same as from their GitHub.  -->
    <dependencies>
        <dependency>
            <groupId>com.megacrit.cardcrawl</groupId>
            <artifactId>slaythespire</artifactId>
            <version>017</version>
            <scope>system</scope>
            <systemPath>C:/spirecomm-master/XonoMod/lib/desktop-1.0.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.evacipated.cardcrawl</groupId>
            <artifactId>ModTheSpire</artifactId>
            <version>2.7.0</version>
            <scope>system</scope>
            <systemPath>C:/spirecomm-master/XonoMod/lib/ModTheSpire.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>com.evacipated.cardcrawl</groupId>
            <artifactId>BaseMod</artifactId>
            <version>2.14.0</version>
            <scope>system</scope>
            <systemPath>C:/spirecomm-master/XonoMod/lib/BaseMod.jar</systemPath>
        </dependency>

    </dependencies>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <!-- This is how your code is packaged into the jar file-->
    <build>
        <!-- Change this to match your mods name -->
        <finalName>XonoMod</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.4.2</version>
                <executions>
                    <execution>
                        <!-- Change this to match your mods artifactId -->
                        <id>XonoMod</id>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <!-- Change this to match your mods groupId:artifactId -->
                                    <artifact>xonomod:XonoMod</artifact>
                                </filter>
                            </filters>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <version>1.8</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <configuration>
                            <target>
                                <!-- Change to match your mods name.
                                     This moves your mod into a common folder where all mods you make can go. -->
                                <copy file="target/XonoMod.jar" tofile="../_ModTheSpire/mods/XonoMod.jar"/>
                            </target>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

***ModTheSpire.json

{
  "modid": "XonoMod_0_0_1",
  "name": "XonoMod",
  "author_list": ["XononoX"],
  "description": "Modifies Blizzard to Rare, 2-cost, channels 2 frost before damage.",
  "version": "0.1",
  "sts_version": "07-17-2018",
  "mts_version": "2.7.0",
  "dependencies": ["basemod"]
}