support for texture packs

This commit is contained in:
minjaesong
2022-02-23 17:59:38 +09:00
parent 841a77403b
commit 7c966b0da8
36 changed files with 2818 additions and 142 deletions

View File

@@ -29,7 +29,7 @@ import net.torvald.tsvm.peripheral.VMProgramRom
class FixtureHomeComputer : FixtureBase {
private val vm = VM(0x200000, TheRealWorld(), arrayOf(
VMProgramRom(ModMgr.getPath("dwarventech", "bios/tsvmbios.js"))
VMProgramRom(ModMgr.getGdxFile("dwarventech", "bios/tsvmbios.js").path())
))
private val vmRunner: VMRunner
private val coroutineJob: Job
@@ -49,7 +49,7 @@ class FixtureHomeComputer : FixtureBase {
actorValue[AVKey.BASEMASS] = 20.0
val gpu = ReferenceGraphicsAdapter(ModMgr.getPath("dwarventech", "gui"), vm)
val gpu = ReferenceGraphicsAdapter(ModMgr.getGdxFile("dwarventech", "gui").path(), vm)
// vm.getIO().blockTransferPorts[0].attachDevice(TestDiskDrive(vm, 0, ...))
vm.peripheralTable[1] = PeripheralEntry(
@@ -65,7 +65,7 @@ class FixtureHomeComputer : FixtureBase {
(mainUI as UIHomeComputer).vm = vm
vmRunner = VMRunnerFactory(ModMgr.getPath("dwarventech", "bios"), vm, "js")
vmRunner = VMRunnerFactory(ModMgr.getGdxFile("dwarventech", "bios").path(), vm, "js")
coroutineJob = GlobalScope.launch {
vmRunner.executeCommand(vm.roms[0]!!.readAll())
}

View File

@@ -41,8 +41,8 @@ class ItemWearableWorldRadar(originalID: String) : GameItem(originalID) {
private val vm = VM(73728, TheRealWorld(), arrayOf(
VMProgramRom(ModMgr.getPath("dwarventech", "bios/pipboot.rom")),
VMProgramRom(ModMgr.getPath("dwarventech", "bios/pipcode.bas"))
VMProgramRom(ModMgr.getGdxFile("dwarventech", "bios/pipboot.rom").path()),
VMProgramRom(ModMgr.getGdxFile("dwarventech", "bios/pipcode.bas").path())
))
private val vmRunner: VMRunner
private val coroutineJob: Job
@@ -62,7 +62,7 @@ class ItemWearableWorldRadar(originalID: String) : GameItem(originalID) {
vm.getErrorStream = { System.err }
vm.getInputStream = { System.`in` }
vmRunner = VMRunnerFactory(ModMgr.getPath("dwarventech", "bios"), vm, "js")
vmRunner = VMRunnerFactory(ModMgr.getGdxFile("dwarventech", "bios").path(), vm, "js")
coroutineJob = GlobalScope.launch {
vmRunner.executeCommand(vm.roms[0]!!.readAll())
}

View File

@@ -16,5 +16,7 @@
"MENU_OPTIONS_DITHER": "Farbmischung",
"MENU_OPTIONS_BLUR": "Weichzeichnen",
"MENU_OPTIONS_PARTICLES": "Partikel",
"MENU_IO_IMPORT": "Importieren"
"MENU_IO_IMPORT": "Importieren",
"APP_NOMODULE_1": "Derzeit ist kein Modul geladen.",
"APP_NOMODULE_2": "Bitte konfigurieren Sie Ihren Ladeauftrag neu auf:"
}

View File

@@ -20,5 +20,7 @@
"MENU_OPTIONS_DITHER": "Dithering",
"MENU_OPTIONS_BLUR": "Blur",
"MENU_OPTIONS_PARTICLES": "Particles",
"MENU_IO_IMPORT": "Import"
"MENU_IO_IMPORT": "Import",
"APP_NOMODULE_1": "No Module is currently loaded.",
"APP_NOMODULE_2": "Please reconfigure your Load Order on:"
}

View File

@@ -16,5 +16,7 @@
"MENU_OPTIONS_DITHER": "Interpolación de colores",
"MENU_OPTIONS_BLUR": "Desenfocar",
"MENU_OPTIONS_PARTICLES": "Partícula",
"MENU_IO_IMPORT": "Importar"
"MENU_IO_IMPORT": "Importar",
"APP_NOMODULE_1": "Actualmente no hay ningún módulo cargado.",
"APP_NOMODULE_2": "Vuelva a configurar su orden de carga en:"
}

View File

@@ -16,5 +16,7 @@
"MENU_OPTIONS_DITHER": "Sekoitussävytys",
"MENU_OPTIONS_BLUR": "Sumea",
"MENU_OPTIONS_PARTICLES": "Hiukkaset",
"MENU_IO_IMPORT": "Tuo"
"MENU_IO_IMPORT": "Tuo",
"APP_NOMODULE_1": "Moduulia ei ole ladattu tällä hetkellä.",
"APP_NOMODULE_2": "Määritä lataustilauksesi uudelleen:"
}

View File

@@ -17,5 +17,7 @@
"MENU_OPTIONS_DITHER": "Tramage",
"MENU_OPTIONS_BLUR": "Flou",
"MENU_OPTIONS_PARTICLES": "Particules",
"MENU_IO_IMPORT": "Importer"
"MENU_IO_IMPORT": "Importer",
"APP_NOMODULE_1": "Aucun module nest actuellement chargé.",
"APP_NOMODULE_2": "Veuillez reconfigurer votre ordre de chargement sur :"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
{
"CONTEXT_CHARACTER": "अवतार",
"MENU_LABEL_COPYRIGHT": "कॉपीराइट",
"COPYRIGHT_ALL_RIGHTS_RESERVED": "All rights reserved",
"COPYRIGHT_GNU_GPL_3": "GNU GPL 3 के तहत वितरित ",
"APP_WARNING_HEALTH_AND_SAFETY": "चेतावनी-स्वास्थ्य और सुरक्षा",
"MENU_LABEL_PRESS_START_SYMBOL": "Press >",
"MENU_MODULES" : "मॉड्यूल",
"GAME_ACTION_MOVE_VERB" : "हिलना",
"GAME_ACTION_ZOOM" : "ज़ूम",
"MENU_LABEL_RESET" : "रीसेट",
"MENU_OPTION_STREAMERS_LAYOUT": "Chat Overlay",
"MENU_LABEL_RESTART_REQUIRED": "पुनः शुरआत जरुरी है",
"MENU_LABEL_KEYBOARD_LAYOUT": "कीबोर्ड विन्यास",
"MENU_LABEL_IME": "इनपुट विधि",
"MENU_OPTIONS_DITHER": "Dithering",
"MENU_OPTIONS_BLUR": "Blur",
"MENU_OPTIONS_PARTICLES": "कणों",
"MENU_IO_IMPORT": "Import",
"APP_NOMODULE_1": "वर्तमान में कोई मॉड्यूल लोड नहीं है।",
"APP_NOMODULE_2": "कृपया निम्न फ़ाइल पर अपना लोड ऑर्डर पुन: कॉन्फ़िगर करें:"
}

View File

@@ -16,5 +16,7 @@
"MENU_OPTIONS_DITHER": "ディザリング",
"MENU_OPTIONS_BLUR": "ぼかし",
"MENU_OPTIONS_PARTICLES": "粒子の数",
"MENU_IO_IMPORT": "インポート"
"MENU_IO_IMPORT": "インポート",
"APP_NOMODULE_1": "現在ロードされたモジュールがありません。",
"APP_NOMODULE_2": "次のファイルでロードオーダーを再設定してください。"
}

View File

@@ -19,5 +19,7 @@
"MENU_OPTIONS_DITHER": "디더링",
"MENU_OPTIONS_BLUR": "흐림",
"MENU_OPTIONS_PARTICLES": "입자 수",
"MENU_IO_IMPORT": "가져오기"
"MENU_IO_IMPORT": "가져오기",
"APP_NOMODULE_1": "현재 불러와진 모듈이 없습니다.",
"APP_NOMODULE_2": "다음의 파일에서 불러오기 순서를 재설정하십시오."
}

View File

@@ -15,5 +15,7 @@
"MENU_OPTIONS_DITHER": "Сглаживание",
"MENU_OPTIONS_BLUR": "Размытие",
"MENU_OPTIONS_PARTICLES": "Частица",
"MENU_IO_IMPORT": "Импорт"
"MENU_IO_IMPORT": "Импорт",
"APP_NOMODULE_1": "В настоящее время модуль не загружен.",
"APP_NOMODULE_2": "Измените конфигурацию вашего порядка загрузки на:"
}

View File

@@ -22,5 +22,7 @@
"MENU_OPTIONS_DITHER": "递色",
"MENU_OPTIONS_BLUR": "模糊",
"MENU_OPTIONS_PARTICLES": "微粒数",
"MENU_IO_IMPORT": "匯入"
"MENU_IO_IMPORT": "匯入",
"APP_NOMODULE_1": "当前未加载任何模块。",
"APP_NOMODULE_2": "请重新配置您的加载顺序:"
}

View File

@@ -18,5 +18,7 @@
"MENU_OPTIONS_DITHER": "遞色",
"MENU_OPTIONS_BLUR": "模糊",
"MENU_OPTIONS_PARTICLES": "粒子数",
"MENU_IO_IMPORT": "Import"
"MENU_IO_IMPORT": "Import",
"APP_NOMODULE_1": "當前未加載任何模塊。",
"APP_NOMODULE_2": "請重新配置您的加載順序:"
}

View File

@@ -1,6 +0,0 @@
# Load Order
# Modules are loaded from top to bottom.
# You can disable basegame, but we don't recommend.
basegame
#dwarventech
1 # Load Order
2 # Modules are loaded from top to bottom.
3 # You can disable basegame, but we don't recommend.
4 basegame
5 #dwarventech

View File

@@ -46,6 +46,7 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack;
import net.torvald.util.DebugTimers;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.*;
@@ -1050,6 +1051,7 @@ public class App implements ApplicationListener {
public static String OSName = System.getProperty("os.name");
public static String OSVersion = System.getProperty("os.version");
private static String tempDir = System.getProperty("java.io.tmpdir");
public static String operationSystem;
/** %appdata%/Terrarum, without trailing slash */
public static String defaultDir;
@@ -1063,6 +1065,9 @@ public class App implements ApplicationListener {
public static String worldsDir;
/** defaultDir + "/config.json" */
public static String configDir;
/** defaultDir + "/LoadOrder.txt" */
public static String loadOrderDir;
public static RunningEnvironment environment;
private static void getDefaultDirectory() {
@@ -1093,6 +1098,7 @@ public class App implements ApplicationListener {
playersDir = defaultDir + "/Players";
worldsDir = defaultDir + "/Worlds";
configDir = defaultDir + "/config.json";
loadOrderDir = defaultDir + "/LoadOrder.txt";
System.out.println(String.format("os.name = %s (with identifier %s)", OSName, operationSystem));
System.out.println(String.format("os.version = %s", OSVersion));
@@ -1101,18 +1107,30 @@ public class App implements ApplicationListener {
}
private static void createDirs() {
File[] dirs = {new File(saveDir), new File(saveSharedDir), new File(playersDir), new File(worldsDir)};
File[] dirs = {
new File(saveDir),
new File(saveSharedDir),
new File(playersDir),
new File(worldsDir)
};
for (File it : dirs) {
if (!it.exists())
it.mkdirs();
}
try {
createLoadOrderFile();
}
catch (IOException e) {
e.printStackTrace();
}
//dirs.forEach { if (!it.exists()) it.mkdirs() }
}
public static File newTempFile(String filename) {
File tempfile = new File("./tmp_" + filename);
File tempfile = new File(tempDir, filename);
tempFilePool.add(tempfile);
return tempfile;
}
@@ -1127,6 +1145,16 @@ public class App implements ApplicationListener {
public static KVHashMap gameConfig = new KVHashMap();
private static void createLoadOrderFile() throws IOException {
File loadOrderFile = new File(loadOrderDir);
if (!loadOrderFile.exists() || loadOrderFile.length() == 0L) {
var writer = new FileWriter(loadOrderFile);
writer.write(TerrarumAppConfiguration.DEFAULT_LOADORDER_FILE);
writer.flush(); writer.close();
}
}
private static void createConfigJson() throws IOException {
File configFile = new File(configDir);

View File

@@ -34,7 +34,7 @@ import java.util.function.Consumer
* Although the game (as product) can have infinitely many stages/planets/etc., those stages must be manually managed by YOU;
* this instance only stores the stage that is currently being used.
*/
open class IngameInstance(val batch: SpriteBatch, val isMultiplayer: Boolean = false) : TerrarumGamescreen {
open class IngameInstance(val batch: FlippingSpriteBatch, val isMultiplayer: Boolean = false) : TerrarumGamescreen {
var WORLD_UPDATE_TIMER = Random().nextInt(1020) + 1; protected set

View File

@@ -17,8 +17,10 @@ import org.apache.commons.csv.CSVFormat
import org.apache.commons.csv.CSVParser
import org.apache.commons.csv.CSVRecord
import java.io.File
import java.io.FileFilter
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.FilenameFilter
import java.net.MalformedURLException
import java.net.URL
import java.net.URLClassLoader
@@ -79,7 +81,8 @@ object ModMgr {
NOT_EVEN_THERE
}
const val modDir = "./assets/mods"
const val modDirInternal = "./assets/mods"
val modDirExternal = "${App.defaultDir}/Modules"
/** Module name (directory name), ModuleMetadata */
val moduleInfo = HashMap<String, ModuleMetadata>()
@@ -99,7 +102,7 @@ object ModMgr {
/**
* Try to create an instance of a "titlescreen" from the current load order set.
*/
fun getTitleScreen(batch: SpriteBatch): IngameInstance? = entryPointClasses.getOrNull(0)?.getTitleScreen(batch)
fun getTitleScreen(batch: FlippingSpriteBatch): IngameInstance? = entryPointClasses.getOrNull(0)?.getTitleScreen(batch)
private fun List<String>.toVersionNumber() = 0L or
(this[0].replaceFirst('*','0').removeSuffix("+").toLong().shl(24)) or
@@ -108,7 +111,7 @@ object ModMgr {
init {
val loadOrderFile = FileSystems.getDefault().getPath("$modDir/LoadOrder.csv").toFile()
val loadOrderFile = FileSystems.getDefault().getPath("${App.defaultDir}/LoadOrder.txt").toFile()
if (loadOrderFile.exists()) {
// load modules
@@ -128,10 +131,10 @@ object ModMgr {
try {
val modMetadata = Properties()
modMetadata.load(FileInputStream("$modDir/$moduleName/$metaFilename"))
modMetadata.load(FileInputStream("$modDirInternal/$moduleName/$metaFilename"))
if (File("$modDir/$moduleName/$defaultConfigFilename").exists()) {
val defaultConfig = JsonFetcher("$modDir/$moduleName/$defaultConfigFilename")
if (File("$modDirInternal/$moduleName/$defaultConfigFilename").exists()) {
val defaultConfig = JsonFetcher("$modDirInternal/$moduleName/$defaultConfigFilename")
// read config and store it to the game
// write to user's config file
@@ -148,7 +151,7 @@ object ModMgr {
val version = modMetadata.getProperty("version")
val jar = modMetadata.getProperty("jar")
val dependency = modMetadata.getProperty("dependency").split(Regex(""";[ ]*""")).filter { it.isNotEmpty() }.toTypedArray()
val isDir = FileSystems.getDefault().getPath("$modDir/$moduleName").toFile().isDirectory
val isDir = FileSystems.getDefault().getPath("$modDirInternal/$moduleName").toFile().isDirectory
val versionNumeral = version.split('.')
@@ -170,10 +173,15 @@ object ModMgr {
}
moduleInfo[moduleName] = ModuleMetadata(index, isDir, Gdx.files.internal("$modDir/$moduleName/icon.png"), properName, description, author, packageName, entryPoint, releaseDate, version, jar, dependency)
moduleInfo[moduleName] = ModuleMetadata(index, isDir, Gdx.files.internal("$modDirInternal/$moduleName/icon.png"), properName, description, author, packageName, entryPoint, releaseDate, version, jar, dependency)
printdbg(this, moduleInfo[moduleName])
// do retexturing if retextures directory exists
if (hasFile(moduleName, "retextures")) {
printdbg(this, "Trying to load Retextures on ${moduleName}")
GameRetextureLoader(moduleName)
}
// run entry script in entry point
if (entryPoint.isNotBlank()) {
@@ -184,7 +192,7 @@ object ModMgr {
val urls = arrayOf<URL>()
val cl = JarFileLoader(urls)
cl.addFile("${File(modDir).absolutePath}/$moduleName/$jar")
cl.addFile("${File(modDirInternal).absolutePath}/$moduleName/$jar")
moduleClassloader[moduleName] = cl
newClass = cl.loadClass(entryPoint)
}
@@ -310,21 +318,31 @@ object ModMgr {
fun getPath(module: String, path: String): String {
/*fun getPath(module: String, path: String): String {
checkExistence(module)
return "$modDir/$module/${path.sanitisePath()}"
}
return "$modDirInternal/$module/${path.sanitisePath()}"
}*/
/** Returning files are read-only */
fun getGdxFile(module: String, path: String): FileHandle {
return Gdx.files.internal(getPath(module, path))
checkExistence(module)
return if (true) // TODO if module is internal...
Gdx.files.internal("$modDirInternal/$module/$path")
else
Gdx.files.absolute("$modDirExternal/$module/$path")
}
fun getFile(module: String, path: String): File {
checkExistence(module)
return FileSystems.getDefault().getPath(getPath(module, path)).toFile()
return if (true) // TODO if module is internal...
FileSystems.getDefault().getPath("$modDirInternal/$module/$path").toFile()
else
FileSystems.getDefault().getPath("$modDirExternal/$module/$path").toFile()
}
fun hasFile(module: String, path: String): Boolean {
return getFile(module, path).exists()
}
fun getFiles(module: String, path: String): Array<File> {
checkExistence(module)
val dir = FileSystems.getDefault().getPath(getPath(module, path)).toFile()
val dir = getFile(module, path)
if (!dir.isDirectory) {
throw FileNotFoundException("The path is not a directory")
}
@@ -344,8 +362,7 @@ object ModMgr {
val filesList = ArrayList<Pair<String, File>>()
moduleNames.forEach {
val file = File(getPath(it, path))
val file = getFile(it, path)
if (file.exists()) filesList.add(it to file)
}
@@ -364,8 +381,7 @@ object ModMgr {
val filesList = ArrayList<Pair<String, FileHandle>>()
moduleNames.forEach {
val file = Gdx.files.internal(getPath(it, path))
val file = getGdxFile(it, path)
if (file.exists()) filesList.add(it to file)
}
@@ -440,7 +456,7 @@ object ModMgr {
val langPath = "locales/"
@JvmStatic operator fun invoke(module: String) {
Lang.load(getPath(module, langPath))
Lang.load(getFile(module, langPath))
}
}
@@ -455,6 +471,58 @@ object ModMgr {
Terrarum.materialCodex.fromModule(module, matePath + "materials.csv")
}
}
/**
* A sugar-library for easy texture pack creation
*/
object GameRetextureLoader {
val retexturesPath = "retextures/"
val retexables = listOf("blocks","wires")
val altFilePaths = HashMap<String, FileHandle>()
val retexableCallbacks = HashMap<String, () -> Unit>()
init {
retexableCallbacks["blocks"] = {
App.tileMaker(true)
}
}
@JvmStatic operator fun invoke(module: String) {
val targetModNames = getFiles(module, retexturesPath).filter { it.isDirectory }
targetModNames.forEach { baseTargetModDir ->
// modules/<module>/retextures/basegame
// printdbg(this, "baseTargetModDir = $baseTargetModDir")
retexables.forEach { category ->
val dir = File(baseTargetModDir, category)
// modules/<module>/retextures/basegame/blocks
// printdbg(this, "cats: ${dir.path}")
if (dir.isDirectory && dir.exists()) {
dir.listFiles { it: File ->
it?.name?.contains('-') == true
}.forEach {
// <other modname>-<hopefully a number>.tga or .png
val tokens = it.name.split('-')
if (tokens.size > 1) {
val modname = tokens[0]
val filename = tokens.tail().joinToString("-")
altFilePaths["$modDirInternal/$modname/$category/$filename"] = getGdxFile(module, "$retexturesPath${baseTargetModDir.name}/$category/${it.name}")
}
}
}
// retexableCallbacks[category]?.invoke()
}
}
printdbg(this, "ALT FILE PATHS")
altFilePaths.forEach { (k, v) -> printdbg(this, "$k -> $v") }
}
}
}
private class JarFileLoader(urls: Array<URL>) : URLClassLoader(urls) {

View File

@@ -1,6 +1,5 @@
package net.torvald.terrarum
import com.badlogic.gdx.graphics.g2d.SpriteBatch
/**
* Created by minjaesong on 2018-06-21.
@@ -8,5 +7,5 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch
abstract class ModuleEntryPoint {
abstract fun invoke()
abstract fun dispose()
open fun getTitleScreen(batch: SpriteBatch): IngameInstance? = null
open fun getTitleScreen(batch: FlippingSpriteBatch): IngameInstance? = null
}

View File

@@ -4,44 +4,15 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.glutils.FrameBuffer
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarum.ui.Toolkit
/**
* Created by minjaesong on 2021-12-11.
*/
class NoModuleDefaultTitlescreen(batch: SpriteBatch) : IngameInstance(batch) {
class NoModuleDefaultTitlescreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
private val wot = """No Module is currently loaded.
Please reconfigure your Load Order on:
Derzeit ist kein Modul geladen.
Bitte konfigurieren Sie Ihren Ladeauftrag neu auf:
Actualmente no hay ningún módulo cargado.
Vuelva a configurar su orden de carga en:
Moduulia ei ole ladattu tällä hetkellä.
Määritä lataustilauksesi uudelleen:
Aucun module nest actuellement chargé.
Veuillez reconfigurer votre ordre de chargement sur :
現在ロードされたモジュールがありません。
次のファイルでロードオーダーを再設定してください。
현재 불러와진 모듈이 없습니다.
다음의 파일에서 불러오기 순서를 재설정하십시오.
В настоящее время модуль не загружен.
Измените конфигурацию вашего порядка загрузки на:
ไม่มีการโหลดโมดูลในขณะนี้
โปรดกำหนดค่าคำสั่งซื้อการโหลดของคุณใหม่เมื่อ:
当前未加载任何模块。请重新配置您的加载顺序:
當前未加載任何模塊。請重新配置您的加載順序:
\c\a assets/mods/LoadOrder.csv""".split('\n')
private val wot = "${Lang["APP_NOMODULE_1"]}\n${Lang["APP_NOMODULE_2"]}\n\u115F\n\u115F".split('\n')
private val maxtw = wot.maxOf { App.fontGameFBO.getWidth(it) }
@@ -49,11 +20,13 @@ Veuillez reconfigurer votre ordre de chargement sur :
private var init = false
private val pathText = App.loadOrderDir
override fun render(updateRate: Float) {
gdxClearAndSetBlend(0f, 0f, 0f, 0f)
if (!init) {
val lh = 20f
val lh = 28f
val pbreak = 8f
val th = lh * wot.size
@@ -72,19 +45,9 @@ Veuillez reconfigurer votre ordre de chargement sur :
batch.inUse {
batch.color = Color.WHITE
wot.reversed().forEachIndexed { index, s ->
if (s.startsWith('\\')) {
val tagsSplit = s.indexOfFirst { it == ' ' }
val tagsBulk = s.substring(0, tagsSplit)
val tags = tagsBulk.split('\\').filter { it.isNotBlank() }
val text = s.substring(tagsSplit + 1)
if (tags.contains("a")) batch.color = Toolkit.Theme.COL_HIGHLIGHT else batch.color = Color.WHITE
if (tags.contains("c"))
App.fontGameFBO.draw(batch, text, (Toolkit.drawWidth - App.fontGameFBO.getWidth(text)) / 2f, heights[index] + centering)
else
App.fontGameFBO.draw(batch, text, (Toolkit.drawWidth - maxtw) / 2f, heights[index] + centering)
if (index == 0) {
batch.color = Toolkit.Theme.COL_HIGHLIGHT
App.fontGameFBO.draw(batch, pathText, (Toolkit.drawWidth - App.fontGameFBO.getWidth(pathText)) / 2f, heights[index] + centering)
}
else {
batch.color = Color.WHITE

View File

@@ -28,6 +28,12 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
const val DEFAULT_LOADORDER_FILE = """# Load Order
# Modules are loaded from top to bottom.
# You can disable basegame, but we don't recommend.
basegame
"""
/**

View File

@@ -70,7 +70,7 @@ class WireCodex {
val wireid = id.split(':').last().toInt()
CommonResourcePool.addToLoadingList(id) {
val t = TextureRegionPack(ModMgr.getPath(module, "$path$wireid.tga"), TILE_SIZE, TILE_SIZE)
val t = TextureRegionPack(ModMgr.getGdxFile(module, "$path$wireid.tga"), TILE_SIZE, TILE_SIZE)
/*return*/t
}
}

View File

@@ -37,45 +37,46 @@ object CommandDict {
printdbg(this, ModMgr.loadOrder.reversed().map { ModMgr.moduleInfo[it]?.packageName })
((listOf("$" to "net.torvald.terrarum")) + ModMgr.loadOrder.reversed().map { it to ModMgr.moduleInfo[it]?.packageName }).forEach { (modName, packageRoot) ->
val commandsList = if (modName == "$") engineCommandList else ModMgr.getFile(modName, "commands.csv").readLines()
val packageConsole = "$packageRoot.console"
if (modName != "$" && ModMgr.hasFile(modName, "commands.csv")) {
val commandsList = if (modName == "$") engineCommandList else ModMgr.getFile(modName, "commands.csv").readLines()
val packageConsole = "$packageRoot.console"
printdbg(this, "Loading console commands from '${packageConsole}'")
printdbg(this, "Loading console commands from '${packageConsole}'")
// printdbg(this, commandsList.joinToString())
commandsList.forEach { commandName ->
val canonicalName = "$packageConsole.$commandName"
val it = Class.forName(canonicalName)
commandsList.forEach { commandName ->
val canonicalName = "$packageConsole.$commandName"
val it = Class.forName(canonicalName)
printdbg(this, "> Trying to instantiate ${it.canonicalName}")
printdbg(this, "> Trying to instantiate ${it.canonicalName}")
try {
val instance = it.kotlin.objectInstance ?: it.kotlin.java.newInstance()
try {
val instance = it.kotlin.objectInstance ?: it.kotlin.java.newInstance()
val aliases = instance.javaClass.getAnnotation(ConsoleAlias::class.java)?.aliasesCSV?.split(',')?.map { it.trim() }
val noexport = instance.javaClass.getAnnotation(ConsoleNoExport::class.java)
val aliases = instance.javaClass.getAnnotation(ConsoleAlias::class.java)?.aliasesCSV?.split(',')?.map { it.trim() }
val noexport = instance.javaClass.getAnnotation(ConsoleNoExport::class.java)
if (noexport == null) {
if (noexport == null) {
dict[instance.javaClass.simpleName.lowercase()] = instance as ConsoleCommand
aliases?.forEach {
dict[it] = instance as ConsoleCommand
dict[instance.javaClass.simpleName.lowercase()] = instance as ConsoleCommand
aliases?.forEach {
dict[it] = instance as ConsoleCommand
}
printdbg(this, "Class instantiated: ${instance.javaClass.simpleName}")
if (aliases != null)
printdbg(this, " Annotations: $aliases")
}
printdbg(this, "Class instantiated: ${instance.javaClass.simpleName}")
if (aliases != null)
printdbg(this, " Annotations: $aliases")
}
catch (e: ClassCastException) {
printdbgerr(this, "${it.canonicalName} is not a ConsoleCommand")
}
catch (e: InstantiationException) {
printdbgerr(this, "Could not instantiate ${it.canonicalName}")
e.printStackTrace(System.err)
}
}
catch (e: ClassCastException) {
printdbgerr(this, "${it.canonicalName} is not a ConsoleCommand")
}
catch (e: InstantiationException) {
printdbgerr(this, "Could not instantiate ${it.canonicalName}")
e.printStackTrace(System.err)
}
}
}

View File

@@ -44,17 +44,15 @@ object Lang {
init {
// load base langs
load("./assets/locales/")
load(File("./assets/locales/"))
}
@JvmStatic operator fun invoke() { /* dummy method for manual initialisation */ }
fun load(localesDir: String) {
fun load(localesDir: File) {
printdbg(this, "Loading languages from $localesDir")
val localesDir = File(localesDir)
// get all of the languages installed
localesDir.listFiles().filter { it.isDirectory }.forEach { languageList.add(it.name) }

View File

@@ -28,7 +28,7 @@ import net.torvald.util.CircularArray
/**
* Created by minjaesong on 2018-07-06.
*/
class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) {
private val menuYaml = Yaml("""
- File

View File

@@ -20,7 +20,7 @@ class EntryPoint : ModuleEntryPoint() {
private val moduleName = "basegame"
override fun getTitleScreen(batch: SpriteBatch): IngameInstance? {
override fun getTitleScreen(batch: FlippingSpriteBatch): IngameInstance? {
return TitleScreen(batch)
}

View File

@@ -61,7 +61,7 @@ import java.util.*
* Created by minjaesong on 2017-06-16.
*/
open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
var historicalFigureIDBucket: ArrayList<Int> = ArrayList<Int>()

View File

@@ -41,7 +41,7 @@ import kotlin.math.sin
/**
* Created by minjaesong on 2017-09-02.
*/
class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) {
// todo register titlescreen as the ingame, similar in a way that the buildingmaker did

View File

@@ -24,7 +24,7 @@ object InjectCreatureRaw {
* @param jsonFileName with extension
*/
operator fun invoke(actorValueRef: ActorValue, module: String, jsonFileName: String) {
val jsonObj = JsonFetcher(ModMgr.getPath(module, "creatures/$jsonFileName"))
val jsonObj = JsonFetcher(ModMgr.getFile(module, "creatures/$jsonFileName"))
JsonFetcher.forEach(jsonObj) { key, value -> if (!key.startsWith("_")) {

View File

@@ -10,8 +10,8 @@ import net.torvald.terrarum.gameactors.AVKey
object PlayerBuilderTestSubject1 {
operator fun invoke(): IngamePlayer {
val p: IngamePlayer = IngamePlayer(
ModMgr.getPath("basegame", "sprites/test_sprite.properties"),
ModMgr.getPath("basegame", "sprites/test_sprite_glow.properties"),
ModMgr.getGdxFile("basegame", "sprites/test_sprite.properties").path(),
ModMgr.getGdxFile("basegame", "sprites/test_sprite_glow.properties").path(),
-589141658L // random value thrown
)
InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json")

View File

@@ -11,8 +11,8 @@ import net.torvald.terrarum.gameactors.AVKey
object PlayerBuilderWerebeastTest {
operator fun invoke(): IngamePlayer {
val p: IngamePlayer = IngamePlayer(
ModMgr.getPath("basegame", "sprites/taimu.properties"),
ModMgr.getPath("basegame", "sprites/taimu_glow.properties"),
ModMgr.getGdxFile("basegame", "sprites/taimu.properties").path(),
ModMgr.getGdxFile("basegame", "sprites/taimu_glow.properties").path(),
-589141658L // random value thrown
)
InjectCreatureRaw(p.actorValue, "basegame", "CreatureWerebeastBase.json")

View File

@@ -29,7 +29,7 @@ class UIBasicInfo() : UICanvas() {
private var ELon = false
private var watchFont = WatchFont
private var atlas = TextureRegionPack(ModMgr.getPath("basegame", "gui/basic_info1.tga"), width, height)
private var atlas = TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/basic_info1.tga"), width, height)
private var font = Watch7SegSmall

View File

@@ -23,10 +23,10 @@ class UITierOneWatch() : UICanvas() {
private val ELuptime = 4f
private var ELon = false
private var atlas = TextureRegionPack(ModMgr.getPath("basegame", "gui/watchface_atlas.tga"), width, height)
private var atlas = TextureRegionPack(ModMgr.getGdxFile("basegame", "gui/watchface_atlas.tga"), width, height)
private var watchFont = WatchFont
private var moonDial = TextureRegionPack(ModMgr.getPath("basegame", "fonts/watch_17pxmoondial.tga"), 17, 17)
private var moonDial = TextureRegionPack(ModMgr.getGdxFile("basegame", "fonts/watch_17pxmoondial.tga"), 17, 17)
private var moonDialCount = moonDial.horizontalCount
private val drawCol = Color(1f, 1f, 1f, UIQuickslotBar.DISPLAY_OPACITY)

View File

@@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarum.App
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.ModMgr
@@ -28,7 +29,12 @@ class UIItemModuleInfoCell(
private val modErrored = (ModMgr.moduleInfo[modName] == null)
private val modIcon = TextureRegion(Texture(modProp.iconFile))
private val modIcon = try {
TextureRegion(Texture(modProp.iconFile))
}
catch (_: GdxRuntimeException) {
CommonResourcePool.getAsTextureRegion("itemplaceholder_48")
}
private val modVer = modProp.version
private val modDate = modProp.releaseDate
private val modAuthor = modProp.author

View File

@@ -36,7 +36,7 @@ object CSVFetcher {
return csvRecordList
}
fun readFromModule(module: String, path: String) = net.torvald.terrarum.utils.CSVFetcher.readFromFile(ModMgr.getPath(module, path))
fun readFromModule(module: String, path: String) = net.torvald.terrarum.utils.CSVFetcher.readFromFile(ModMgr.getGdxFile(module, path).path())
fun readFromString(csv: String): List<org.apache.commons.csv.CSVRecord> {
val csvParser = org.apache.commons.csv.CSVParser.parse(

View File

@@ -107,8 +107,11 @@ class CreateTileAtlas {
// filter files that do not exist on the blockcodex
dir.list().filter { tgaFile -> !tgaFile.isDirectory && (BlockCodex.getOrNull("$modname:${tgaFile.nameWithoutExtension()}") != null) }
.sortedBy { it.nameWithoutExtension().toInt() }.forEach { tgaFile -> // toInt() to sort by the number, not lexicographically
tgaList.add(modname to tgaFile)
.sortedBy { it.nameWithoutExtension().toInt() }.forEach { tgaFile: FileHandle -> // toInt() to sort by the number, not lexicographically
// tgaFile be like: ./assets/mods/basegame/blocks/32.tga (which is not always .tga)
val newFile = ModMgr.GameRetextureLoader.altFilePaths.getOrDefault(tgaFile.path(), tgaFile)
tgaList.add(modname to newFile)
// printdbg(this, "modname = $modname, file = $newFile")
}
}
@@ -225,7 +228,7 @@ class CreateTileAtlas {
private fun fileToAtlantes(modname: String, matte: FileHandle, glow: FileHandle?) {
val tilesPixmap = Pixmap(matte)
val tilesGlowPixmap = if (glow != null) Pixmap(glow) else nullTile
val blockName = matte.nameWithoutExtension().toInt() // basically a filename
val blockName = matte.nameWithoutExtension().split('-').last().toInt() // basically a filename
val blockID = "$modname:$blockName"
// determine the type of the block (populate tags list)