Compare commits
6 Commits
8f6b455daf
...
456b100799
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
456b100799 | ||
|
|
3f03dddab3 | ||
|
|
982e1e2ee2 | ||
|
|
77dd7f4409 | ||
|
|
e334d1cb8d | ||
|
|
9e19ed5126 |
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Gremious
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
9
README.md
Normal file
9
README.md
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
# Construct the Spire (formerly Arena)
|
||||||
|
|
||||||
|
### Custom game Mod for Constructed mode in Slay the Spire
|
||||||
|
|
||||||
|
This patches the addNonDailyMods method in CustomModeScreen to set a static boolean that signals to the rest of the
|
||||||
|
patches that the mod has been enabled.
|
||||||
|
|
||||||
|
This behavior is because I couldn't quite figure out how to detect loaded game mods during runtime from methods called
|
||||||
|
after AbstractDungeon has been initalized.
|
||||||
113
constructTheArena/pom.xml
Normal file
113
constructTheArena/pom.xml
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<!--Hello! You'll basically should only need to change these names and the steam path (just below)-->
|
||||||
|
<!--The author name(s) as they appear in MTS and any other comments are in your ModTheSpire.json-->
|
||||||
|
<groupId>xyz.geniuscartel</groupId>
|
||||||
|
<artifactId>ConstructTheArena</artifactId>
|
||||||
|
<name>Construct The Arena</name>
|
||||||
|
<version>1.1</version>
|
||||||
|
<description>A default base to start your own mod from.</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<SlayTheSpire.version>01-23-2019</SlayTheSpire.version>
|
||||||
|
<ModTheSpire.version>3.8.0</ModTheSpire.version>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<!--CHANGE THIS TO YOUR STEAM INSTALLATION-->
|
||||||
|
<Steam.path>/home/dtookey/.steam/debian-installation/steamapps</Steam.path>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.megacrit.cardcrawl</groupId>
|
||||||
|
<artifactId>slaythespire</artifactId>
|
||||||
|
<version>${SlayTheSpire.version}</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${Steam.path}/common/SlayTheSpire/desktop-1.0.jar</systemPath>
|
||||||
|
<!--<systemPath>${basedir}/../lib/desktop-1.0.jar</systemPath>-->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.evacipated.cardcrawl</groupId>
|
||||||
|
<artifactId>modthespire</artifactId>
|
||||||
|
<version>${ModTheSpire.version}</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${Steam.path}/workshop/content/646570/1605060445/ModTheSpire.jar</systemPath>
|
||||||
|
<!--<systemPath>${basedir}/../lib/ModTheSpire.jar</systemPath>-->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>basemod</groupId>
|
||||||
|
<artifactId>basemod</artifactId>
|
||||||
|
<version>5.0.0</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${Steam.path}/workshop/content/646570/1605833019/BaseMod.jar</systemPath>
|
||||||
|
<!--<systemPath>${basedir}/../lib/BaseMod.jar</systemPath>-->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.evacipated.cardcrawl.mod</groupId>
|
||||||
|
<artifactId>StSLib</artifactId>
|
||||||
|
<version>1.3.2</version>
|
||||||
|
<scope>system</scope>
|
||||||
|
<systemPath>${Steam.path}/workshop/content/646570/1609158507/StSLib.jar</systemPath>
|
||||||
|
<!--<systemPath>${basedir}/../lib/StSLib.jar</systemPath>-->
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- This is how your code is packaged into the jar file-->
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>2.4</version>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>**/*.psd</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
|
<version>1.8</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<configuration>
|
||||||
|
<target>
|
||||||
|
<!-- This moves your mod into a common folder where all mods you make can go. -->
|
||||||
|
<copy file="target/${project.artifactId}.jar" tofile="${Steam.path}/common/SlayTheSpire/mods/${project.artifactId}.jar"/>
|
||||||
|
</target>
|
||||||
|
</configuration>
|
||||||
|
<goals>
|
||||||
|
<goal>run</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>false</filtering>
|
||||||
|
<excludes>
|
||||||
|
<exclude>ModTheSpire.json</exclude>
|
||||||
|
</excludes>
|
||||||
|
</resource>
|
||||||
|
<resource>
|
||||||
|
<directory>src/main/resources</directory>
|
||||||
|
<filtering>true</filtering>
|
||||||
|
<includes>
|
||||||
|
<include>ModTheSpire.json</include>
|
||||||
|
</includes>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@ -0,0 +1,256 @@
|
|||||||
|
package constructTheArena;
|
||||||
|
|
||||||
|
import basemod.BaseMod;
|
||||||
|
import basemod.ModLabeledToggleButton;
|
||||||
|
import basemod.ModPanel;
|
||||||
|
import basemod.helpers.RelicType;
|
||||||
|
import basemod.interfaces.AddCustomModeModsSubscriber;
|
||||||
|
import basemod.interfaces.EditRelicsSubscriber;
|
||||||
|
import basemod.interfaces.EditStringsSubscriber;
|
||||||
|
import basemod.interfaces.PostInitializeSubscriber;
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.graphics.Color;
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpireConfig;
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpireInitializer;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.megacrit.cardcrawl.core.Settings;
|
||||||
|
import com.megacrit.cardcrawl.helpers.CardHelper;
|
||||||
|
import com.megacrit.cardcrawl.helpers.FontHelper;
|
||||||
|
import com.megacrit.cardcrawl.localization.RelicStrings;
|
||||||
|
import com.megacrit.cardcrawl.localization.RunModStrings;
|
||||||
|
import com.megacrit.cardcrawl.localization.UIStrings;
|
||||||
|
import com.megacrit.cardcrawl.screens.custom.CustomMod;
|
||||||
|
import constructTheArena.relics.ConstructorsBurden;
|
||||||
|
import constructTheArena.util.IDCheckDontTouchPls;
|
||||||
|
import constructTheArena.util.ResUtil;
|
||||||
|
import constructTheArena.util.TextureLoader;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
|
||||||
|
// Please don't just mass replace "theDefault" with "yourMod" everywhere.
|
||||||
|
// It'll be a bigger pain for you. You only need to replace it in 3 places.
|
||||||
|
// I comment those places below, under the place where you set your ID.
|
||||||
|
|
||||||
|
//TODO: FIRST THINGS FIRST: RENAME YOUR PACKAGE AND ID NAMES FIRST-THING!!!
|
||||||
|
// Right click the package (Open the project pane on the left. Folder with black dot on it. The name's at the very top) -> Refactor -> Rename, and name it whatever you wanna call your mod.
|
||||||
|
// Scroll down in this file. Change the ID from "theDefault:" to "yourModName:" or whatever your heart desires (don't use spaces). Dw, you'll see it.
|
||||||
|
// In the JSON strings (resources>localization>eng>[all them files] make sure they all go "yourModName:" rather than "theDefault". You can ctrl+R to replace in 1 file, or ctrl+shift+r to mass replace in specific files/directories (Be careful.).
|
||||||
|
// Start with the DefaultCommon cards - they are the most commented cards since I don't feel it's necessary to put identical comments on every card.
|
||||||
|
// After you sorta get the hang of how to make cards, check out the card template which will make your life easier
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With that out of the way:
|
||||||
|
* Welcome to this super over-commented Slay the Spire modding base.
|
||||||
|
* Use it to make your own mod of any type. - If you want to add any standard in-game content (character,
|
||||||
|
* cards, relics), this is a good starting point.
|
||||||
|
* It features 1 character with a minimal set of things: 1 card of each type, 1 debuff, couple of relics, etc.
|
||||||
|
* If you're new to modding, you basically *need* the BaseMod wiki for whatever you wish to add
|
||||||
|
* https://github.com/daviscook477/BaseMod/wiki - work your way through with this base.
|
||||||
|
* Feel free to use this in any way you like, of course. MIT licence applies. Happy modding!
|
||||||
|
*
|
||||||
|
* And pls. Read the comments.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@SpireInitializer
|
||||||
|
public class ConstructTheArena implements
|
||||||
|
AddCustomModeModsSubscriber,
|
||||||
|
EditStringsSubscriber,
|
||||||
|
EditRelicsSubscriber,
|
||||||
|
PostInitializeSubscriber {
|
||||||
|
// Make sure to implement the subscribers *you* are using (read basemod wiki). Editing cards? EditCardsSubscriber.
|
||||||
|
// Making relics? EditRelicsSubscriber. etc., etc., for a full list and how to make your own, visit the basemod wiki.
|
||||||
|
public static final Logger logger = LogManager.getLogger(ConstructTheArena.class.getName());
|
||||||
|
private static String modID;
|
||||||
|
|
||||||
|
// Mod-settings settings. This is if you want an on/off savable button
|
||||||
|
public static Properties constructTheArenaSettings = new Properties();
|
||||||
|
public static final String ENABLE_PLACEHOLDER_SETTINGS = "enablePlaceholder";
|
||||||
|
public static boolean enablePlaceholder = true; // The boolean we'll be setting on/off (true/false)
|
||||||
|
|
||||||
|
//This is for the in-game mod settings panel.
|
||||||
|
private static final String MODNAME = "Construct The Arena";
|
||||||
|
private static final String AUTHOR = "Virgil"; // And pretty soon - You!
|
||||||
|
private static final String DESCRIPTION = "A deck constructor mod for concept testing and general shenanigans.";
|
||||||
|
|
||||||
|
// =============== INPUT TEXTURE LOCATION =================
|
||||||
|
|
||||||
|
|
||||||
|
//Mod Badge - A small icon that appears in the mod settings menu next to your mod.
|
||||||
|
public static final String BADGE_IMAGE = "constructTheArenaResources/images/Badge.png";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// =============== /INPUT TEXTURE LOCATION/ =================
|
||||||
|
|
||||||
|
|
||||||
|
// =============== SUBSCRIBE, CREATE THE COLOR_GRAY, INITIALIZE =================
|
||||||
|
|
||||||
|
public ConstructTheArena() {
|
||||||
|
setModID("constructTheArena");
|
||||||
|
constructTheArenaSettings.setProperty(ENABLE_PLACEHOLDER_SETTINGS, "FALSE"); // This is the default setting. It's actually set...
|
||||||
|
|
||||||
|
try {
|
||||||
|
SpireConfig config = getConfig();
|
||||||
|
config.load();
|
||||||
|
enablePlaceholder = config.getBool(ENABLE_PLACEHOLDER_SETTINGS);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.info("Done adding mod settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====== NO EDIT AREA ======
|
||||||
|
// DON'T TOUCH THIS STUFF. IT IS HERE FOR STANDARDIZATION BETWEEN MODS AND TO ENSURE GOOD CODE PRACTICES.
|
||||||
|
// IF YOU MODIFY THIS I WILL HUNT YOU DOWN AND DOWNVOTE YOUR MOD ON WORKSHOP
|
||||||
|
|
||||||
|
public static void setModID(String ID) { // DON'T EDIT
|
||||||
|
Gson coolG = new Gson(); // EY DON'T EDIT THIS
|
||||||
|
// String IDjson = Gdx.files.internal("IDCheckStringsDONT-EDIT-AT-ALL.json").readString(String.valueOf(StandardCharsets.UTF_8)); // i hate u Gdx.files
|
||||||
|
InputStream in = ConstructTheArena.class.getResourceAsStream("/IDCheckStringsDONT-EDIT-AT-ALL.json"); // DON'T EDIT THIS ETHER
|
||||||
|
IDCheckDontTouchPls EXCEPTION_STRINGS = coolG.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), IDCheckDontTouchPls.class); // OR THIS, DON'T EDIT IT
|
||||||
|
if (ID.equals(EXCEPTION_STRINGS.DEFAULTID)) { // DO *NOT* CHANGE THIS ESPECIALLY, TO EDIT YOUR MOD ID, SCROLL UP JUST A LITTLE, IT'S JUST ABOVE
|
||||||
|
throw new RuntimeException(EXCEPTION_STRINGS.EXCEPTION); // THIS ALSO DON'T EDIT
|
||||||
|
} else if (ID.equals(EXCEPTION_STRINGS.DEVID)) { // NO
|
||||||
|
modID = EXCEPTION_STRINGS.DEFAULTID; // DON'T
|
||||||
|
} else { // NO EDIT AREA
|
||||||
|
modID = ID; // DON'T WRITE OR CHANGE THINGS HERE NOT EVEN A LITTLE
|
||||||
|
} // NO
|
||||||
|
} // NO
|
||||||
|
|
||||||
|
public static String getModID() { // NO
|
||||||
|
return modID; // DOUBLE NO
|
||||||
|
} // NU-UH
|
||||||
|
|
||||||
|
private static void pathCheck() { // ALSO NO
|
||||||
|
Gson coolG = new Gson(); // NOPE DON'T EDIT THIS
|
||||||
|
// String IDjson = Gdx.files.internal("IDCheckStringsDONT-EDIT-AT-ALL.json").readString(String.valueOf(StandardCharsets.UTF_8)); // i still hate u btw Gdx.files
|
||||||
|
InputStream in = ConstructTheArena.class.getResourceAsStream("/IDCheckStringsDONT-EDIT-AT-ALL.json"); // DON'T EDIT THISSSSS
|
||||||
|
IDCheckDontTouchPls EXCEPTION_STRINGS = coolG.fromJson(new InputStreamReader(in, StandardCharsets.UTF_8), IDCheckDontTouchPls.class); // NAH, NO EDIT
|
||||||
|
String packageName = ConstructTheArena.class.getPackage().getName(); // STILL NO EDIT ZONE
|
||||||
|
FileHandle resourcePathExists = Gdx.files.internal(getModID() + "Resources"); // PLEASE DON'T EDIT THINGS HERE, THANKS
|
||||||
|
if (!modID.equals(EXCEPTION_STRINGS.DEVID)) { // LEAVE THIS EDIT-LESS
|
||||||
|
if (!packageName.equals(getModID())) { // NOT HERE ETHER
|
||||||
|
throw new RuntimeException(EXCEPTION_STRINGS.PACKAGE_EXCEPTION + getModID()); // THIS IS A NO-NO
|
||||||
|
} // WHY WOULD U EDIT THIS
|
||||||
|
if (!resourcePathExists.exists()) { // DON'T CHANGE THIS
|
||||||
|
throw new RuntimeException(EXCEPTION_STRINGS.RESOURCE_FOLDER_EXCEPTION + getModID() + "Resources"); // NOT THIS
|
||||||
|
}// NO
|
||||||
|
}// NO
|
||||||
|
}// NO
|
||||||
|
|
||||||
|
// ====== YOU CAN EDIT AGAIN ======
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public static void initialize() {
|
||||||
|
BaseMod.subscribe(new ConstructTheArena());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ============== /SUBSCRIBE, CREATE THE COLOR_GRAY, INITIALIZE/ =================
|
||||||
|
|
||||||
|
|
||||||
|
// =============== POST-INITIALIZE =================
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receivePostInitialize() {
|
||||||
|
logger.info("Loading badge image and mod options");
|
||||||
|
|
||||||
|
// Load the Mod Badge
|
||||||
|
Texture badgeTexture = TextureLoader.getTexture(BADGE_IMAGE);
|
||||||
|
|
||||||
|
// Create the Mod Menu
|
||||||
|
ModPanel settingsPanel = new ModPanel();
|
||||||
|
|
||||||
|
// Create the on/off button:
|
||||||
|
ModLabeledToggleButton enableNormalsButton = new ModLabeledToggleButton("This is the text which goes next to the checkbox.",
|
||||||
|
350.0f, 700.0f, Settings.CREAM_COLOR, FontHelper.charDescFont, // Position (trial and error it), color, font
|
||||||
|
enablePlaceholder, // Boolean it uses
|
||||||
|
settingsPanel, // The mod panel in which this button will be in
|
||||||
|
(label) -> {
|
||||||
|
}, // thing??????? idk
|
||||||
|
(button) -> { // The actual button:
|
||||||
|
|
||||||
|
enablePlaceholder = button.enabled; // The boolean true/false will be whether the button is enabled or not
|
||||||
|
try {
|
||||||
|
// And based on that boolean, set the settings and save them
|
||||||
|
SpireConfig config = getConfig();
|
||||||
|
config.setBool(ENABLE_PLACEHOLDER_SETTINGS, enablePlaceholder);
|
||||||
|
config.save();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
settingsPanel.addUIElement(enableNormalsButton); // Add the button to the settings panel. Button is a go.
|
||||||
|
|
||||||
|
BaseMod.registerModBadge(badgeTexture, MODNAME, AUTHOR, DESCRIPTION, settingsPanel);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// =============== / POST-INITIALIZE/ =================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private SpireConfig getConfig() throws IOException {
|
||||||
|
return new SpireConfig("constructTheArena", "constructTheArenaConfig", constructTheArenaSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// this adds "ModName:" before the ID of any card/relic/power etc.
|
||||||
|
// in order to avoid conflicts if any other mod uses the same ID.
|
||||||
|
public static String makeID(String idText) {
|
||||||
|
return getModID() + ":" + idText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//<editor-fold name="add custom game mode">
|
||||||
|
/*======================================================================================
|
||||||
|
add custom game mode
|
||||||
|
======================================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveCustomModeMods(List<CustomMod> list) {
|
||||||
|
list.add(new CustomMod(getModID() + ":" + getModID(), "b", false));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveEditStrings() {
|
||||||
|
BaseMod.loadCustomStringsFile(RunModStrings.class, ResUtil.getLocRes("eng", "constructTheArena-RunModStrings.json"));
|
||||||
|
BaseMod.loadCustomStringsFile(RelicStrings.class, ResUtil.getLocRes("eng", "constructTheArena-RelicStrings.json"));
|
||||||
|
BaseMod.loadCustomStringsFile(UIStrings.class, ResUtil.getLocRes("eng", "constructTheArena-UIStrings.json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//<editor-fold name="Add Relics">
|
||||||
|
/*======================================================================================
|
||||||
|
Add Relics
|
||||||
|
======================================================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receiveEditRelics() {
|
||||||
|
BaseMod.addRelic(new ConstructorsBurden(), RelicType.SHARED);
|
||||||
|
}
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//</editor-fold>
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package constructTheArena.patches;
|
||||||
|
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpirePatch;
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch;
|
||||||
|
import com.megacrit.cardcrawl.core.Settings;
|
||||||
|
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
|
//generateMap in AbstractDungeon.java
|
||||||
|
@SpirePatch(
|
||||||
|
clz = AbstractDungeon.class,
|
||||||
|
method = "generateMap"
|
||||||
|
)
|
||||||
|
public class CArenaEnableLastActPatch {
|
||||||
|
private final static Logger logger = LogManager.getLogger(CArenaEnableLastActPatch.class.getName());
|
||||||
|
|
||||||
|
@SpirePrefixPatch
|
||||||
|
public static void Prefix() {
|
||||||
|
if (CArenaPatch.isEnabled()) {
|
||||||
|
Settings.isFinalActAvailable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package constructTheArena.patches;
|
||||||
|
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch;
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpirePatch;
|
||||||
|
import com.megacrit.cardcrawl.screens.custom.CustomModeScreen;
|
||||||
|
import com.megacrit.cardcrawl.trials.CustomTrial;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@SpirePatch(
|
||||||
|
clz = CustomModeScreen.class,
|
||||||
|
method = "addNonDailyMods"
|
||||||
|
)
|
||||||
|
public class CArenaPatch {
|
||||||
|
private final static Logger logger = LogManager.getLogger(CArenaPatch.class.getName());
|
||||||
|
|
||||||
|
private static boolean enabled = false;
|
||||||
|
|
||||||
|
@SpireInsertPatch(
|
||||||
|
rloc = 1,
|
||||||
|
localvars = {"modId"}
|
||||||
|
)
|
||||||
|
public static void Insert(CustomModeScreen __instance, CustomTrial trial, ArrayList<String> modIds, String modId) {
|
||||||
|
if (modId.equals("constructTheArena:constructTheArena")) {
|
||||||
|
//do nothing for now
|
||||||
|
enabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isEnabled() {
|
||||||
|
return enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setEnabled(boolean b) {
|
||||||
|
enabled = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
#CArenaPatch
|
||||||
|
|
||||||
|
This method simply detects if the game mod was selected by the user and stores the decision in a boolean.
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
package constructTheArena.patches;
|
||||||
|
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.ByRef;
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpireInsertPatch;
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpirePatch;
|
||||||
|
import com.megacrit.cardcrawl.characters.AbstractPlayer;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
@SpirePatch(
|
||||||
|
clz = AbstractPlayer.class,
|
||||||
|
method = "initializeStarterDeck"
|
||||||
|
)
|
||||||
|
public class CArenaSkipMasterDeckPatch {
|
||||||
|
@SpireInsertPatch(
|
||||||
|
loc = 409,
|
||||||
|
localvars = {"addBaseCards"}
|
||||||
|
)
|
||||||
|
public static void Insert(AbstractPlayer __instance, @ByRef boolean[] addBaseCards) {
|
||||||
|
if (CArenaPatch.isEnabled()) {
|
||||||
|
addBaseCards[0] = false;
|
||||||
|
}else{
|
||||||
|
addBaseCards[0] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
#CArenaSkipMasterDeckPatch
|
||||||
|
|
||||||
|
This patch inserts a call inside initializeStarterDeck in AbstractPlayer
|
||||||
|
|
||||||
|
This encapsulates and provides a reference to addBaseCards inside the method. There was a bug where subsequent games
|
||||||
|
would not load the starting deck because the logic for detecting enabled game mods was not what I was expecting.
|
||||||
|
|
||||||
|
That being said, this checks the [[CArenaPatch]] class to see if the mod was enabled and bases its decision off of that.
|
||||||
|
It's a bit of a hack, yes, but it works.
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package constructTheArena.patches;
|
||||||
|
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpirePatch;
|
||||||
|
import com.evacipated.cardcrawl.modthespire.lib.SpirePrefixPatch;
|
||||||
|
import com.megacrit.cardcrawl.cards.AbstractCard;
|
||||||
|
import com.megacrit.cardcrawl.cards.CardGroup;
|
||||||
|
import com.megacrit.cardcrawl.core.CardCrawlGame;
|
||||||
|
import com.megacrit.cardcrawl.core.Settings;
|
||||||
|
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
|
||||||
|
import com.megacrit.cardcrawl.helpers.CardLibrary;
|
||||||
|
import com.megacrit.cardcrawl.helpers.ModHelper;
|
||||||
|
import com.megacrit.cardcrawl.localization.UIStrings;
|
||||||
|
import com.megacrit.cardcrawl.neow.NeowEvent;
|
||||||
|
import com.megacrit.cardcrawl.unlock.UnlockTracker;
|
||||||
|
import constructTheArena.relics.ConstructorsBurden;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
@SpirePatch(
|
||||||
|
clz = NeowEvent.class,
|
||||||
|
method = "dailyBlessing"
|
||||||
|
)
|
||||||
|
public class ConstructDraftPatch {
|
||||||
|
private final static Logger logger = LogManager.getLogger(ConstructDraftPatch.class.getName());
|
||||||
|
|
||||||
|
private final static int CardLimit = 40;
|
||||||
|
private static final UIStrings uiStrings = CardCrawlGame.languagePack.getUIString("ConstructModeInstructions");
|
||||||
|
|
||||||
|
@SpirePrefixPatch
|
||||||
|
public static void Prefix() {
|
||||||
|
if (CArenaPatch.isEnabled()) {
|
||||||
|
ArrayList<String> mods = ModHelper.getEnabledModIDs();
|
||||||
|
mods.remove("SealedDeck");
|
||||||
|
ModHelper.setMods(mods);
|
||||||
|
|
||||||
|
CardGroup constructGroup = new CardGroup(CardGroup.CardGroupType.UNSPECIFIED);
|
||||||
|
|
||||||
|
//add master deck to draw pool
|
||||||
|
TreeSet<String> dedupedMasterDeck = new TreeSet<>(AbstractDungeon.player.getStartingDeck());
|
||||||
|
|
||||||
|
for (String cardName : dedupedMasterDeck) {
|
||||||
|
AbstractCard card = CardLibrary.getCard(AbstractDungeon.player.chosenClass, cardName);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
constructGroup.addToTop(card.makeCopy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//add all other eligible cards to the draw pool
|
||||||
|
ArrayList<AbstractCard> cardPool = new ArrayList<>();
|
||||||
|
AbstractDungeon.player.getCardPool(cardPool);
|
||||||
|
|
||||||
|
//sort it so it's all pretty
|
||||||
|
cardPool.sort(Comparator.comparing(card -> card.name));
|
||||||
|
|
||||||
|
for (AbstractCard card : cardPool) {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
constructGroup.addToTop(card.makeCopy());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Iterator<AbstractCard> cards = constructGroup.group.iterator();
|
||||||
|
AbstractCard c;
|
||||||
|
while (cards.hasNext()) {
|
||||||
|
c = cards.next();
|
||||||
|
UnlockTracker.markCardAsSeen(c.cardID);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractDungeon.gridSelectScreen.open(constructGroup, 40, true, uiStrings.TEXT[0] + CardLimit + uiStrings.TEXT[1]);
|
||||||
|
|
||||||
|
AbstractDungeon.getCurrRoom().spawnRelicAndObtain(Settings.WIDTH / 2.0F, Settings.HEIGHT / 2.0F, new ConstructorsBurden());
|
||||||
|
|
||||||
|
CArenaPatch.setEnabled(false); //turne off deck skipping and whatnot
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
#ConstructDraftPatch
|
||||||
|
|
||||||
|
This prefixes the dailyBlessing method of the NeowEvent. This checks the [[CArenaPatch]] class to see if the game mod was
|
||||||
|
enabled. At the end of the patched method call, this will set CArenaPatch.enabled to false in order to make sure
|
||||||
|
subsequent (potentially non-cosntructed) games will have the master deck and normal card rewards.
|
||||||
|
|
||||||
|
The current ruleset is thus:
|
||||||
|
|
||||||
|
4 copies of every card available to the player's card pool
|
||||||
|
4 copies of each of the cards in the character's master deck
|
||||||
|
Maximum of 40 selections
|
||||||
|
|
||||||
|
After the card selection dialgue is complete, the [[ConstructorsBurden]] relic will be added to the player
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
package constructTheArena.relics;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.ResolvedType;
|
||||||
|
import com.megacrit.cardcrawl.characters.AbstractPlayer;
|
||||||
|
import com.megacrit.cardcrawl.dungeons.AbstractDungeon;
|
||||||
|
import com.megacrit.cardcrawl.helpers.ImageMaster;
|
||||||
|
import com.megacrit.cardcrawl.relics.AbstractRelic;
|
||||||
|
import constructTheArena.util.ResUtil;
|
||||||
|
|
||||||
|
public class ConstructorsBurden extends AbstractRelic {
|
||||||
|
|
||||||
|
private final static String imgPathLarge = ResUtil.getImageRes("relics", "constructorsBurdenLarge.png");
|
||||||
|
private final static String imgPath = ResUtil.getImageRes("relics", "constructorsBurden.png");
|
||||||
|
|
||||||
|
public ConstructorsBurden() {
|
||||||
|
super("constructTheArena:ConstructorsBurden", "", RelicTier.SPECIAL, LandingSound.HEAVY);
|
||||||
|
|
||||||
|
imgUrl = imgPath;
|
||||||
|
img = ImageMaster.loadImage(imgPath);
|
||||||
|
largeImg = ImageMaster.loadImage(imgPathLarge);
|
||||||
|
outlineImg = ImageMaster.loadImage(imgPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AbstractRelic makeCopy() {
|
||||||
|
return new ConstructorsBurden();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int changeNumberOfCardsInReward(int NumberOfCards) {
|
||||||
|
return -10;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUpdatedDescription() {
|
||||||
|
if (AbstractDungeon.player != null) {
|
||||||
|
return setDescription(AbstractDungeon.player.chosenClass);
|
||||||
|
}
|
||||||
|
return setDescription((AbstractPlayer.PlayerClass) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String setDescription(AbstractPlayer.PlayerClass c) {
|
||||||
|
return this.DESCRIPTIONS[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
#ConstructorsBurden
|
||||||
|
|
||||||
|
Simple abstract relic that reduces card rewards by 10 in order to negate all potential card rewards. There may be a case
|
||||||
|
where card rewards can exceed 10, but I can't think of one.
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package constructTheArena.util;
|
||||||
|
|
||||||
|
public class IDCheckDontTouchPls {
|
||||||
|
public String DEFAULTID;
|
||||||
|
public String DEVID;
|
||||||
|
public String EXCEPTION;
|
||||||
|
public String PACKAGE_EXCEPTION;
|
||||||
|
public String RESOURCE_FOLDER_EXCEPTION;
|
||||||
|
public String RESOURCES;
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package constructTheArena.util;
|
||||||
|
|
||||||
|
public class ResUtil {
|
||||||
|
|
||||||
|
private final static String baseResourceDirectory = "constructTheArenaResources/";
|
||||||
|
|
||||||
|
private static String buildPath(StringBuilder sb, String... parts) {
|
||||||
|
for (int i = 0; i < parts.length; i++) {
|
||||||
|
String s = parts[i];
|
||||||
|
sb.append(s);
|
||||||
|
if (i < parts.length - 1) {
|
||||||
|
sb.append("/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getResource(String... parts){
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(baseResourceDirectory);
|
||||||
|
return buildPath(sb, parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a path string for the desired localized text resource
|
||||||
|
* @param locale localization abbreviateion (i.e. eng, rus, etc...)
|
||||||
|
* @param resourceName name of text asset (myText.json)
|
||||||
|
* @return resource location
|
||||||
|
*/
|
||||||
|
public static String getLocRes(String locale, String resourceName){
|
||||||
|
String localization = "localization/" + locale;
|
||||||
|
|
||||||
|
return getResource(localization, resourceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getImageRes(String category, String resourceName) {
|
||||||
|
String localization = "images/" + category;
|
||||||
|
|
||||||
|
return getResource(localization, resourceName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package constructTheArena.util;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
|
import com.badlogic.gdx.graphics.Texture.TextureFilter;
|
||||||
|
import com.badlogic.gdx.utils.GdxRuntimeException;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// Thank you Blank The Evil!
|
||||||
|
|
||||||
|
// Welcome to the utilities package. This package is for small utilities that make our life easier.
|
||||||
|
// You honestly don't need to bother with this unless you want to know how we're loading the textures.
|
||||||
|
|
||||||
|
|
||||||
|
public class TextureLoader {
|
||||||
|
private final static HashMap<String, Texture> textures = new HashMap<>();
|
||||||
|
public static final Logger logger = LogManager.getLogger(TextureLoader.class.getName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param textureString - String path to the texture you want to load relative to resources,
|
||||||
|
* Example: "theDefaultResources/images/ui/missing_texture.png"
|
||||||
|
* @return <b>com.badlogic.gdx.graphics.Texture</b> - The texture from the path provided
|
||||||
|
*/
|
||||||
|
public static Texture getTexture(final String textureString) {
|
||||||
|
if (textures.get(textureString) == null) {
|
||||||
|
try {
|
||||||
|
loadTexture(textureString);
|
||||||
|
} catch (GdxRuntimeException e) {
|
||||||
|
logger.error("Could not find texture: " + textureString);
|
||||||
|
return getTexture("constructTheArenaResources/images/ui/missing_texture.png");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return textures.get(textureString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of the texture, applies a linear filter to it, and places it in the HashMap
|
||||||
|
*
|
||||||
|
* @param textureString - String path to the texture you want to load relative to resources,
|
||||||
|
* Example: "img/ui/missingtexture.png"
|
||||||
|
* @throws GdxRuntimeException
|
||||||
|
*/
|
||||||
|
private static void loadTexture(final String textureString) throws GdxRuntimeException {
|
||||||
|
Texture texture = new Texture(textureString);
|
||||||
|
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
|
||||||
|
textures.put(textureString, texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"DEFAULTID": "theDefault",
|
||||||
|
"DEVID": "theDefaultDev",
|
||||||
|
"EXCEPTION": "Go to your constructor in your class with SpireInitializer and change your mod ID from \"theDefault\"",
|
||||||
|
"PACKAGE_EXCEPTION": "Rename your theDefault folder (package) to match your mod ID! ",
|
||||||
|
"RESOURCE_FOLDER_EXCEPTION": "Rename your theDefaultResources folder to match your mod ID!",
|
||||||
|
"RESOURCES": "Resources"
|
||||||
|
}
|
||||||
12
constructTheArena/src/main/resources/ModTheSpire.json
Normal file
12
constructTheArena/src/main/resources/ModTheSpire.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"modid": "${project.artifactId}",
|
||||||
|
"name": "${project.name}",
|
||||||
|
"author_list": ["Virgil"],
|
||||||
|
"credits": "Basemod, ModTheSpire",
|
||||||
|
"description": "${project.description}",
|
||||||
|
"version": "${project.version}",
|
||||||
|
"sts_version": "${SlayTheSpire.version}",
|
||||||
|
"mts_version": "${ModTheSpire.version}",
|
||||||
|
"dependencies": ["basemod", "stslib"],
|
||||||
|
"update_json": ""
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"constructTheArena:ConstructorsBurden": {
|
||||||
|
"NAME": "Constructor's Burden",
|
||||||
|
"FLAVOR": "You no longer receive card rewards.",
|
||||||
|
"DESCRIPTIONS": [
|
||||||
|
"Number of card rewards set to 0."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"constructTheArena:constructTheArena": {
|
||||||
|
"NAME": "Construct the Spire",
|
||||||
|
"DESCRIPTION": "Constructed Deck Mode"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ConstructModeInstructions": {
|
||||||
|
"TEXT": [
|
||||||
|
"Select up to ",
|
||||||
|
" cards."
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
7
deploy.sh
Normal file
7
deploy.sh
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
rm ~/.steam/debian-installation/steamapps/common/SlayTheSpire/ConstructTheArena/content/ConstructTheArena.jar
|
||||||
|
cp constructTheArena/target/ConstructTheArena.jar ~/.steam/debian-installation/steamapps/common/SlayTheSpire/ConstructTheArena/content/ConstructTheArena.jar
|
||||||
|
|
||||||
|
cd ~/.steam/debian-installation/steamapps/common/SlayTheSpire || exit
|
||||||
|
|
||||||
|
java -jar mod-uploader.jar upload -w ConstructTheArena
|
||||||
Loading…
Reference in New Issue
Block a user