diff --git a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureHomeComputer.kt b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureHomeComputer.kt index fae458b86..1f2a44fe9 100644 --- a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureHomeComputer.kt +++ b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameactors/FixtureHomeComputer.kt @@ -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()) } diff --git a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/ItemWearableWorldRadar.kt b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/ItemWearableWorldRadar.kt index 533be6b73..da7eb9442 100644 --- a/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/ItemWearableWorldRadar.kt +++ b/ModuleComputers/src/net/torvald/terrarum/modulecomputers/gameitems/ItemWearableWorldRadar.kt @@ -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()) } diff --git a/assets/locales/de/terrarum.json b/assets/locales/de/terrarum.json index 6d73c3a0a..f3474ce24 100644 --- a/assets/locales/de/terrarum.json +++ b/assets/locales/de/terrarum.json @@ -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:" } \ No newline at end of file diff --git a/assets/locales/en/terrarum.json b/assets/locales/en/terrarum.json index 04e3b34ce..e77178eba 100644 --- a/assets/locales/en/terrarum.json +++ b/assets/locales/en/terrarum.json @@ -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:" } \ No newline at end of file diff --git a/assets/locales/es/terrarum.json b/assets/locales/es/terrarum.json index 21af9cfcb..8e4417c45 100644 --- a/assets/locales/es/terrarum.json +++ b/assets/locales/es/terrarum.json @@ -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:" } \ No newline at end of file diff --git a/assets/locales/fiFI/terrarum.json b/assets/locales/fiFI/terrarum.json index f282c6d08..494f1880f 100644 --- a/assets/locales/fiFI/terrarum.json +++ b/assets/locales/fiFI/terrarum.json @@ -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:" } \ No newline at end of file diff --git a/assets/locales/frFR/terrarum.json b/assets/locales/frFR/terrarum.json index 7458f9440..3805a95bb 100644 --- a/assets/locales/frFR/terrarum.json +++ b/assets/locales/frFR/terrarum.json @@ -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 n’est actuellement chargé.", + "APP_NOMODULE_2": "Veuillez reconfigurer votre ordre de chargement sur :" } \ No newline at end of file diff --git a/assets/locales/hiIN/Polyglot-100_hi.json b/assets/locales/hiIN/Polyglot-100_hi.json new file mode 100644 index 000000000..32835e9fa --- /dev/null +++ b/assets/locales/hiIN/Polyglot-100_hi.json @@ -0,0 +1,2568 @@ +{ + "resources": { + "polyglot": { + "LANG": "Hindi", + "DIRECTION": "ltr", + "VERSION": "100", + "DATE": "2022-02-16" + }, + "data": [ + { + "n": "CONTEXT_CHARACTER_CLASS", + "s": "Class" + }, + { + "n": "CONTEXT_CHARACTER_DELETE", + "s": "Delete Character" + }, + { + "n": "CONTEXT_CHARACTER_NEW", + "s": "नया अवतार" + }, + { + "n": "CONTEXT_CLASS_AI", + "s": "Artificial Intelligence" + }, + { + "n": "CONTEXT_CLASS_ALIEN", + "s": "Alien" + }, + { + "n": "CONTEXT_CLASS_CLONE", + "s": "Clone" + }, + { + "n": "CONTEXT_CLASS_CYBORG", + "s": "Cyborg" + }, + { + "n": "CONTEXT_CLASS_DEITY", + "s": "Deity" + }, + { + "n": "CONTEXT_CLASS_DEMON", + "s": "Demon" + }, + { + "n": "CONTEXT_CLASS_DEMONNESS", + "s": "Demonness" + }, + { + "n": "CONTEXT_CLASS_DRAGON", + "s": "Dragon" + }, + { + "n": "CONTEXT_CLASS_DRAGON_PLURAL", + "s": "Dragons" + }, + { + "n": "CONTEXT_CLASS_GHOST", + "s": "Ghost" + }, + { + "n": "CONTEXT_CLASS_GOD", + "s": "God" + }, + { + "n": "CONTEXT_CLASS_GOD_PLURAL", + "s": "Gods" + }, + { + "n": "CONTEXT_CLASS_GODDESS", + "s": "Goddess" + }, + { + "n": "CONTEXT_CLASS_MAGE", + "s": "Mage" + }, + { + "n": "CONTEXT_CLASS_MEDIC", + "s": "Medic" + }, + { + "n": "CONTEXT_CLASS_MONSTER", + "s": "Monster" + }, + { + "n": "CONTEXT_CLASS_NINJA", + "s": "Ninja" + }, + { + "n": "CONTEXT_CLASS_PIRATE", + "s": "Pirate" + }, + { + "n": "CONTEXT_CLASS_PRIEST", + "s": "Priest" + }, + { + "n": "CONTEXT_CLASS_PRINCE", + "s": "Prince" + }, + { + "n": "CONTEXT_CLASS_PRINCESS", + "s": "Princess" + }, + { + "n": "CONTEXT_CLASS_ROBOT", + "s": "Robot" + }, + { + "n": "CONTEXT_CLASS_SKELETON", + "s": "Skeleton" + }, + { + "n": "CONTEXT_CLASS_SNIPER", + "s": "Sniper" + }, + { + "n": "CONTEXT_CLASS_SOLDIER", + "s": "Soldier" + }, + { + "n": "CONTEXT_CLASS_THIEF", + "s": "Thief" + }, + { + "n": "CONTEXT_CLASS_WARRIOR", + "s": "Warrior" + }, + { + "n": "CONTEXT_CLASS_WIZARD", + "s": "Wizard" + }, + { + "n": "CONTEXT_CLASS_ZOMBIE", + "s": "Zombie" + }, + { + "n": "CONTEXT_CLASS_ZOMBIE_PLURAL", + "s": "Zombies" + }, + { + "n": "CONTEXT_COMPETITION_FIRST", + "s": "First place" + }, + { + "n": "CONTEXT_COMPETITION_PLACE_NOUN", + "s": "Place" + }, + { + "n": "CONTEXT_COMPETITION_SECOND", + "s": "Second place" + }, + { + "n": "CONTEXT_COMPETITION_THIRD", + "s": "Third place" + }, + { + "n": "CONTEXT_CONDITION_BURNING", + "s": "Burning" + }, + { + "n": "CONTEXT_CONDITION_CRITICAL", + "s": "Critical" + }, + { + "n": "CONTEXT_CONDITION_DEAD", + "s": "Dead" + }, + { + "n": "CONTEXT_CONDITION_FROZEN", + "s": "Frozen" + }, + { + "n": "CONTEXT_CONDITION_POISONED", + "s": "Poisoned" + }, + { + "n": "CONTEXT_CONDITION_SLOWED", + "s": "Slowed" + }, + { + "n": "CONTEXT_CONDITION_STUNNED", + "s": "Stunned" + }, + { + "n": "CONTEXT_CONDITION_UNCONSCIOUS", + "s": "Unconscious" + }, + { + "n": "CONTEXT_CONDITION_UNHURT", + "s": "Unhurt" + }, + { + "n": "CONTEXT_CONDITION_WET", + "s": "Wet" + }, + { + "n": "CONTEXT_CONDITION_WOUNDED", + "s": "Wounded" + }, + { + "n": "CONTEXT_DESCRIPTION_BIG", + "s": "Big" + }, + { + "n": "CONTEXT_DESCRIPTION_HUGE", + "s": "Huge" + }, + { + "n": "CONTEXT_DESCRIPTION_SMALL", + "s": "Small" + }, + { + "n": "CONTEXT_DESCRIPTION_TINY", + "s": "Tiny" + }, + { + "n": "CONTEXT_ELEMENT_AIR", + "s": "Air" + }, + { + "n": "CONTEXT_ELEMENT_EARTH", + "s": "Earth" + }, + { + "n": "CONTEXT_ELEMENT_FIRE", + "s": "Fire" + }, + { + "n": "CONTEXT_ELEMENT_METAL", + "s": "Metal" + }, + { + "n": "CONTEXT_ELEMENT_WATER", + "s": "Water" + }, + { + "n": "CONTEXT_GAMBLING_BET", + "s": "Bet" + }, + { + "n": "CONTEXT_GAMBLING_DISCARD", + "s": "Discard" + }, + { + "n": "CONTEXT_GAMBLING_JACKPOT", + "s": "Jackpot" + }, + { + "n": "CONTEXT_GAMBLING_MAX", + "s": "Max" + }, + { + "n": "CONTEXT_GAMBLING_MIN", + "s": "Min" + }, + { + "n": "CONTEXT_ITEM_ARMOR", + "s": "Armor" + }, + { + "n": "CONTEXT_ITEM_ARROW", + "s": "Arrow" + }, + { + "n": "CONTEXT_ITEM_ARROWS", + "s": "Arrows" + }, + { + "n": "CONTEXT_ITEM_BOARD", + "s": "Board" + }, + { + "n": "CONTEXT_ITEM_BOMB", + "s": "Bomb" + }, + { + "n": "CONTEXT_ITEM_BOOK", + "s": "Book" + }, + { + "n": "CONTEXT_ITEM_BOOTS", + "s": "Boots" + }, + { + "n": "CONTEXT_ITEM_BOW", + "s": "Bow" + }, + { + "n": "CONTEXT_ITEM_CARD", + "s": "Card" + }, + { + "n": "CONTEXT_ITEM_CARD_PLURAL", + "s": "Cards" + }, + { + "n": "CONTEXT_ITEM_CHEST", + "s": "Chest" + }, + { + "n": "CONTEXT_ITEM_COND_MAGICAL", + "s": "Magic" + }, + { + "n": "CONTEXT_ITEM_COND_RUSTY", + "s": "Rusty" + }, + { + "n": "CONTEXT_ITEM_DAGGER", + "s": "Dagger" + }, + { + "n": "CONTEXT_ITEM_DIE_NOUN", + "s": "Die" + }, + { + "n": "CONTEXT_ITEM_DIE_PLURAL", + "s": "Dice" + }, + { + "n": "CONTEXT_ITEM_DOOR", + "s": "Door" + }, + { + "n": "CONTEXT_ITEM_GAUNTLETS", + "s": "Gauntlets" + }, + { + "n": "CONTEXT_ITEM_GEM", + "s": "Gem" + }, + { + "n": "CONTEXT_ITEM_GIFT_NOUN", + "s": "Gift" + }, + { + "n": "CONTEXT_ITEM_GIFT_PLURAL", + "s": "Gifts" + }, + { + "n": "CONTEXT_ITEM_GLOVE", + "s": "Gloves" + }, + { + "n": "CONTEXT_ITEM_GUN", + "s": "Gun" + }, + { + "n": "CONTEXT_ITEM_HAMMER", + "s": "Hammer" + }, + { + "n": "CONTEXT_ITEM_HELMET", + "s": "Helmet" + }, + { + "n": "CONTEXT_ITEM_KEY", + "s": "Key" + }, + { + "n": "CONTEXT_ITEM_KNIFE", + "s": "Knife" + }, + { + "n": "CONTEXT_ITEM_LOCK", + "s": "Lock" + }, + { + "n": "CONTEXT_ITEM_LOVE", + "s": "Love" + }, + { + "n": "CONTEXT_ITEM_MACHINE_ITEM_GUN", + "s": "Machine Gun" + }, + { + "n": "CONTEXT_ITEM_MAGIC", + "s": "Magic" + }, + { + "n": "CONTEXT_ITEM_PISTOL", + "s": "Pistol" + }, + { + "n": "CONTEXT_ITEM_QUEST_NOUN", + "s": "Quest" + }, + { + "n": "CONTEXT_ITEM_RANK_NOUN", + "s": "Rank" + }, + { + "n": "CONTEXT_ITEM_RIFLE", + "s": "Rifle" + }, + { + "n": "CONTEXT_ITEM_ROCKET_ITEM_LAUNCHER", + "s": "Rocket Launcher" + }, + { + "n": "CONTEXT_ITEM_RPG", + "s": "RPG" + }, + { + "n": "CONTEXT_ITEM_SCROLL", + "s": "Scroll" + }, + { + "n": "CONTEXT_ITEM_SHIELD", + "s": "Shield" + }, + { + "n": "CONTEXT_ITEM_SHIELD_PLURAL", + "s": "Shields" + }, + { + "n": "CONTEXT_ITEM_SHIELD_SCIFI", + "s": "Energy shield" + }, + { + "n": "CONTEXT_ITEM_SHIELD_SCIFI_PLURAL", + "s": "Energy shields" + }, + { + "n": "CONTEXT_ITEM_SHOTGUN", + "s": "Shotgun" + }, + { + "n": "CONTEXT_ITEM_SNIPER_ITEM_RIFLE", + "s": "Sniper rifle" + }, + { + "n": "CONTEXT_ITEM_SPELL", + "s": "Spell" + }, + { + "n": "CONTEXT_ITEM_STAFF", + "s": "Staff" + }, + { + "n": "CONTEXT_ITEM_SWORD", + "s": "Sword" + }, + { + "n": "CONTEXT_ITEM_TREASURE", + "s": "Treasure" + }, + { + "n": "CONTEXT_ITEM_TYPE_EPIC", + "s": "Epic" + }, + { + "n": "CONTEXT_ITEM_TYPE_JUNK", + "s": "Junk" + }, + { + "n": "CONTEXT_ITEM_WAND", + "s": "Wand" + }, + { + "n": "CONTEXT_ITEM_WOOD", + "s": "Wood" + }, + { + "n": "CONTEXT_MACHINE_ALTITUDE", + "s": "Altitude" + }, + { + "n": "CONTEXT_MACHINE_BRAKES", + "s": "Brakes" + }, + { + "n": "CONTEXT_MACHINE_CHASSIS", + "s": "Chassis" + }, + { + "n": "CONTEXT_MACHINE_DEPTH", + "s": "Depth" + }, + { + "n": "CONTEXT_MACHINE_FUEL", + "s": "Fuel" + }, + { + "n": "CONTEXT_MACHINE_GEAR", + "s": "Gear" + }, + { + "n": "CONTEXT_MACHINE_HANDLING", + "s": "Handling" + }, + { + "n": "CONTEXT_MACHINE_SPEED", + "s": "Speed" + }, + { + "n": "CONTEXT_MACHINE_STEERING", + "s": "Steering" + }, + { + "n": "CONTEXT_MACHINE_SUSPENSION", + "s": "Suspension" + }, + { + "n": "CONTEXT_MACHINE_WHEELS", + "s": "Wheels" + }, + { + "n": "CONTEXT_MACHINE_WINGS", + "s": "Wings" + }, + { + "n": "CONTEXT_MEDAL", + "s": "Medal" + }, + { + "n": "CONTEXT_MEDAL_BRONZE", + "s": "Bronze medal" + }, + { + "n": "CONTEXT_MEDAL_GOLD", + "s": "Gold medal" + }, + { + "n": "CONTEXT_MEDAL_SILVER", + "s": "Silver medal" + }, + { + "n": "CONTEXT_METAL_BRONZE", + "s": "Bronze" + }, + { + "n": "CONTEXT_METAL_COIN", + "s": "Coin" + }, + { + "n": "CONTEXT_METAL_GOLD", + "s": "Gold" + }, + { + "n": "CONTEXT_METAL_INGOT", + "s": "Ingot" + }, + { + "n": "CONTEXT_METAL_PLATINUM", + "s": "Platinum" + }, + { + "n": "CONTEXT_METAL_SILVER", + "s": "Silver" + }, + { + "n": "CONTEXT_PLACE_CASTLE", + "s": "Castle" + }, + { + "n": "CONTEXT_PLACE_CAVE", + "s": "Cave" + }, + { + "n": "CONTEXT_PLACE_DUNGEON", + "s": "Dungeon" + }, + { + "n": "CONTEXT_PLACE_INN", + "s": "Inn" + }, + { + "n": "CONTEXT_PLACE_PLANET", + "s": "Planet" + }, + { + "n": "CONTEXT_PLACE_PLANET_EARTH", + "s": "Earth" + }, + { + "n": "CONTEXT_PLACE_SPACE", + "s": "Space" + }, + { + "n": "CONTEXT_PLACE_SPACESHIP", + "s": "Spaceship" + }, + { + "n": "CONTEXT_STORY", + "s": "Story" + }, + { + "n": "CONTEXT_STORY_ADVENTURE", + "s": "Adventure" + }, + { + "n": "CONTEXT_STORY_CHAPTER", + "s": "Chapter" + }, + { + "n": "CONTEXT_STORY_PAGE", + "s": "Page" + }, + { + "n": "CREDITS_3D_MODELING", + "s": "3D Modeling" + }, + { + "n": "CREDITS_ANIMATION", + "s": "Animation" + }, + { + "n": "CREDITS_ANIMATION_DIRECTOR", + "s": "Animation Director" + }, + { + "n": "CREDITS_ANIMATOR", + "s": "Animator" + }, + { + "n": "CREDITS_ART", + "s": "Art" + }, + { + "n": "CREDITS_ART_DIRECTOR", + "s": "Art Director" + }, + { + "n": "CREDITS_ARTIST", + "s": "Artist" + }, + { + "n": "CREDITS_ARTIST_PLURAL", + "s": "Artists" + }, + { + "n": "CREDITS_ASSISTANT", + "s": "Assistant" + }, + { + "n": "CREDITS_ASSOCIATE", + "s": "Associate" + }, + { + "n": "CREDITS_AUDIO_DIRECTOR", + "s": "Audio Director" + }, + { + "n": "CREDITS_CHARACTER_DESIGNER", + "s": "Character Designer" + }, + { + "n": "CREDITS_CHIEF_TECH_OFFICER", + "s": "Chief Technical Officer" + }, + { + "n": "CREDITS_CINEMATIC_ANIMATOR", + "s": "Cinematic Animator" + }, + { + "n": "CREDITS_CINEMATICS_DIRECTOR", + "s": "Cinematics Director" + }, + { + "n": "CREDITS_CODE", + "s": "Code" + }, + { + "n": "CREDITS_COMPOSER", + "s": "Composer" + }, + { + "n": "CREDITS_CONCEPT_ARTIST", + "s": "Concept artist" + }, + { + "n": "CREDITS_CREATIVE_DIRECTOR", + "s": "Creative Director" + }, + { + "n": "CREDITS_DATABASE_ADMIN", + "s": "Database Admin" + }, + { + "n": "CREDITS_DESIGN DIRECTOR", + "s": "Design Director" + }, + { + "n": "CREDITS_DEVELOPED_BY", + "s": "Developed by" + }, + { + "n": "CREDITS_DIRECTOR", + "s": "Director" + }, + { + "n": "CREDITS_FOLEY_ARTIST", + "s": "Foley artist" + }, + { + "n": "CREDITS_FONT", + "s": "Font" + }, + { + "n": "CREDITS_FONT_PLURAL", + "s": "Fonts" + }, + { + "n": "CREDITS_GAME", + "s": "Game" + }, + { + "n": "CREDITS_GAME_DESIGN", + "s": "Game design" + }, + { + "n": "CREDITS_GAME_DESIGNER", + "s": "Game designer" + }, + { + "n": "CREDITS_GAME_DEVELOPER", + "s": "Game developer" + }, + { + "n": "CREDITS_GAME_DEVELOPMENT", + "s": "Game development" + }, + { + "n": "CREDITS_GRAPHIC_DESIGNER", + "s": "Graphic designer" + }, + { + "n": "CREDITS_IMAGE", + "s": "Image" + }, + { + "n": "CREDITS_IMAGE_PLURAL", + "s": "Images" + }, + { + "n": "CREDITS_INTERFACE_ARTIST", + "s": "Interface Artist" + }, + { + "n": "CREDITS_JUNIOR", + "s": "Junior" + }, + { + "n": "CREDITS_LEAD", + "s": "Lead" + }, + { + "n": "CREDITS_LEAD_PROGRAMMER", + "s": "Lead programmer" + }, + { + "n": "CREDITS_LEVEL_DESIGN", + "s": "Level design" + }, + { + "n": "CREDITS_LEVEL_DESIGNER", + "s": "Level designer" + }, + { + "n": "CREDITS_LOCALIZATION", + "s": "Localization" + }, + { + "n": "CREDITS_MANUSCRIPT", + "s": "Manuscript" + }, + { + "n": "CREDITS_MODELS", + "s": "Models" + }, + { + "n": "CREDITS_MUSICIAN", + "s": "Musician" + }, + { + "n": "CREDITS_POLYGLOT", + "s": "Translated by the Polyglot Project" + }, + { + "n": "CREDITS_PRODUCER", + "s": "Producer" + }, + { + "n": "CREDITS_PRODUCTION", + "s": "Production" + }, + { + "n": "CREDITS_PROGRAM_MANAGER", + "s": "Program Manager" + }, + { + "n": "CREDITS_PROGRAMMER", + "s": "Programmer" + }, + { + "n": "CREDITS_PROGRAMMER_PLURAL", + "s": "Programmers" + }, + { + "n": "CREDITS_PROGRAMMING", + "s": "Programming" + }, + { + "n": "CREDITS_PROJECT_MANAGER", + "s": "Project Manager" + }, + { + "n": "CREDITS_PUBLISHER", + "s": "Publisher" + }, + { + "n": "CREDITS_RECORDIST", + "s": "Recordist" + }, + { + "n": "CREDITS_SCRIPT_WRITER", + "s": "Script writer" + }, + { + "n": "CREDITS_SENIOR", + "s": "Senior" + }, + { + "n": "CREDITS_SFX", + "s": "Sound Effects" + }, + { + "n": "CREDITS_SOUND_DESIGNER", + "s": "Sound designer" + }, + { + "n": "CREDITS_SOUND_ENGINEER", + "s": "Sound engineer" + }, + { + "n": "CREDITS_SOUNDTRACK", + "s": "Soundtrack" + }, + { + "n": "CREDITS_SPECIAL_THANKS", + "s": "Special thanks" + }, + { + "n": "CREDITS_SPECIAL_THANKS_TO", + "s": "Special thanks to" + }, + { + "n": "CREDITS_TECHNICAL_ARTIST", + "s": "Technical artist" + }, + { + "n": "CREDITS_TECHNICAL_DIRECTOR", + "s": "Technical Director" + }, + { + "n": "CREDITS_TEST_LEAD", + "s": "Test Lead" + }, + { + "n": "CREDITS_TEST_MANAGER", + "s": "Test Manager" + }, + { + "n": "CREDITS_TESTER", + "s": "Tester" + }, + { + "n": "CREDITS_TRANSLATION", + "s": "Translation" + }, + { + "n": "CREDITS_VFX", + "s": "Visual Effects" + }, + { + "n": "CREDITS_VOICE_ACTING", + "s": "Voice acting" + }, + { + "n": "CREDITS_VOICE_ACTOR", + "s": "Voice actor" + }, + { + "n": "CREDITS_WRITER", + "s": "Writer" + }, + { + "n": "ERROR_DEVICE_NOT_FOUND", + "s": "No {0} detected" + }, + { + "n": "ERROR_DEVICE_VR_LEAVING_TRACKAREA", + "s": "Leaving tracking area" + }, + { + "n": "ERROR_DEVICE_VR_NO_HMD", + "s": "No HMD detected" + }, + { + "n": "ERROR_GENERIC_CHEATING", + "s": "Cheats detected!" + }, + { + "n": "ERROR_GENERIC_ERRCODE", + "s": "Error code:" + }, + { + "n": "ERROR_GENERIC_INVALID_KEY", + "s": "Invalid CD Key." + }, + { + "n": "ERROR_GENERIC_INVALID_NAME", + "s": "Invalid name!" + }, + { + "n": "ERROR_GENERIC_TEXT", + "s": "An error has occured." + }, + { + "n": "ERROR_NETWORK_CONNECTION_LOST", + "s": "Connection lost." + }, + { + "n": "ERROR_NETWORK_DISCONNECTED_YOUR_OPPONENT", + "s": "Your opponent has disconnected." + }, + { + "n": "ERROR_NETWORK_DISCONNECTED_YOUR_PLAYER", + "s": "The other player has disconnected." + }, + { + "n": "ERROR_NETWORK_DISCONNECTED_YOUR_TEAMMATE", + "s": "Your teammate has disconnected." + }, + { + "n": "ERROR_NETWORK_SERVER", + "s": "Cannot connect to server." + }, + { + "n": "ERROR_SAVE_CORRUPTED", + "s": "Save file corrupted." + }, + { + "n": "ERROR_SAVE_NO_GAMES_FOUND", + "s": "No games found." + }, + { + "n": "ERROR_SAVE_NO_OPEN_GAMES", + "s": "No open games." + }, + { + "n": "GAME_ACTION_ATTACK", + "s": "Attack" + }, + { + "n": "GAME_ACTION_BOOST", + "s": "Boost" + }, + { + "n": "GAME_ACTION_BUILD", + "s": "Build" + }, + { + "n": "GAME_ACTION_CAST_FISHING", + "s": "Cast" + }, + { + "n": "GAME_ACTION_CAST_SPELL", + "s": "Cast" + }, + { + "n": "GAME_ACTION_CLAIM", + "s": "Claim" + }, + { + "n": "GAME_ACTION_CLIMB", + "s": "Climb" + }, + { + "n": "GAME_ACTION_CLOSE", + "s": "Close" + }, + { + "n": "GAME_ACTION_COLLECT", + "s": "Collect" + }, + { + "n": "GAME_ACTION_COOK", + "s": "Cook" + }, + { + "n": "GAME_ACTION_CRAFT", + "s": "Craft" + }, + { + "n": "GAME_ACTION_CROUCH", + "s": "Crouch" + }, + { + "n": "GAME_ACTION_DODGE", + "s": "Dodge" + }, + { + "n": "GAME_ACTION_DRIVE", + "s": "Drive" + }, + { + "n": "GAME_ACTION_FLY", + "s": "Fly" + }, + { + "n": "GAME_ACTION_FULL_SPEED", + "s": "Full Speed" + }, + { + "n": "GAME_ACTION_GO", + "s": "Go" + }, + { + "n": "GAME_ACTION_GO_TO_PLACE", + "s": "Go to" + }, + { + "n": "GAME_ACTION_HALF_SPEED", + "s": "Half Speed" + }, + { + "n": "GAME_ACTION_HEAL", + "s": "Heal" + }, + { + "n": "GAME_ACTION_JUMP", + "s": "कूदना" + }, + { + "n": "GAME_ACTION_LAND", + "s": "Landing" + }, + { + "n": "GAME_ACTION_LOOK", + "s": "Look" + }, + { + "n": "GAME_ACTION_MIX", + "s": "Mix" + }, + { + "n": "GAME_ACTION_OPEN", + "s": "Open" + }, + { + "n": "GAME_ACTION_PICK_UP", + "s": "Pick up" + }, + { + "n": "GAME_ACTION_RACE", + "s": "Race" + }, + { + "n": "GAME_ACTION_READ", + "s": "Read" + }, + { + "n": "GAME_ACTION_REPLACE", + "s": "Replace" + }, + { + "n": "GAME_ACTION_RUN", + "s": "Run" + }, + { + "n": "GAME_ACTION_RUN_AWAY", + "s": "Run away" + }, + { + "n": "GAME_ACTION_SHOOT", + "s": "Shoot" + }, + { + "n": "GAME_ACTION_SNEAK", + "s": "Sneak" + }, + { + "n": "GAME_ACTION_SPIN", + "s": "Spin" + }, + { + "n": "GAME_ACTION_SPRINT", + "s": "Sprint" + }, + { + "n": "GAME_ACTION_STEER", + "s": "Steer" + }, + { + "n": "GAME_ACTION_TAKE_OFF", + "s": "Takeoff" + }, + { + "n": "GAME_ACTION_TALK", + "s": "Talk" + }, + { + "n": "GAME_ACTION_THROW", + "s": "Throw" + }, + { + "n": "GAME_ACTION_WALK", + "s": "Walk" + }, + { + "n": "GAME_CHARACTER_ENDURANCE", + "s": "Endurance" + }, + { + "n": "GAME_CHARACTER_EXP", + "s": "Experience points" + }, + { + "n": "GAME_CHARACTER_FEMALE", + "s": "Female" + }, + { + "n": "GAME_CHARACTER_HEALTH", + "s": "Health" + }, + { + "n": "GAME_CHARACTER_HEART", + "s": "Heart" + }, + { + "n": "GAME_CHARACTER_HEART_PLURAL", + "s": "Hearts" + }, + { + "n": "GAME_CHARACTER_LEVEL", + "s": "Level" + }, + { + "n": "GAME_CHARACTER_LEVEL_UP", + "s": "Level up!" + }, + { + "n": "GAME_CHARACTER_LIVES", + "s": "Lives" + }, + { + "n": "GAME_CHARACTER_MALE", + "s": "Male" + }, + { + "n": "GAME_CHARACTER_MAN", + "s": "Man" + }, + { + "n": "GAME_CHARACTER_MAN_PLURAL", + "s": "Men" + }, + { + "n": "GAME_CHARACTER_RESPAWN", + "s": "Respawn" + }, + { + "n": "GAME_CHARACTER_RESPAWN_IN", + "s": "Respawn in:" + }, + { + "n": "GAME_CHARACTER_RESPAWN_QUESTION", + "s": "Respawn?" + }, + { + "n": "GAME_CHARACTER_RESPAWNING", + "s": "Respawning" + }, + { + "n": "GAME_CHARACTER_SKILL", + "s": "Skill" + }, + { + "n": "GAME_CHARACTER_SPAWN_POINT", + "s": "Spawn Point" + }, + { + "n": "GAME_CHARACTER_TRANSGENDER", + "s": "Transgender" + }, + { + "n": "GAME_CHARACTER_WOMAN", + "s": "Woman" + }, + { + "n": "GAME_CHARACTER_WOMAN_PLURAL", + "s": "Women" + }, + { + "n": "GAME_DAMAGE", + "s": "Damage" + }, + { + "n": "GAME_DAMAGE_CRITICAL_HIT", + "s": "Critical Hit" + }, + { + "n": "GAME_DAMAGE_CRITICAL_MISS", + "s": "Critical Miss" + }, + { + "n": "GAME_DAMAGE_HIT_NOUN", + "s": "Hit" + }, + { + "n": "GAME_DAMAGE_HIT_POINTS_PLURAL", + "s": "Hit points" + }, + { + "n": "GAME_DAMAGE_MISS_NOUN", + "s": "Miss" + }, + { + "n": "GAME_DAMAGE_UNIT", + "s": "Damage" + }, + { + "n": "GAME_DAMAGE_UNIT_PLURAL", + "s": "Damage" + }, + { + "n": "GAME_ENEMY", + "s": "Enemy" + }, + { + "n": "GAME_ENEMY_FEMALE", + "s": "Enemy" + }, + { + "n": "GAME_ENEMY_FEMALE_PLURAL", + "s": "Enemies" + }, + { + "n": "GAME_ENEMY_PLURAL", + "s": "Enemies" + }, + { + "n": "GAME_GENRE_ACTION", + "s": "Action game" + }, + { + "n": "GAME_GENRE_ADVENTURE", + "s": "Adventure game" + }, + { + "n": "GAME_GENRE_CARD", + "s": "Card" + }, + { + "n": "GAME_GENRE_CASUAL", + "s": "Casual game" + }, + { + "n": "GAME_GENRE_FANTASY", + "s": "Fantasy game" + }, + { + "n": "GAME_GENRE_HARDCORE", + "s": "Hardcore game" + }, + { + "n": "GAME_GENRE_INDIE", + "s": "Indie" + }, + { + "n": "GAME_GENRE_MEDIEVAL", + "s": "Medieval game" + }, + { + "n": "GAME_GENRE_MISC", + "s": "Misc." + }, + { + "n": "GAME_GENRE_MULTIPLAYER", + "s": "Multiplayer" + }, + { + "n": "GAME_GENRE_NAME", + "s": "Genre" + }, + { + "n": "GAME_GENRE_PLATFORMER", + "s": "Platformer game" + }, + { + "n": "GAME_GENRE_PUZZLE", + "s": "Puzzle game" + }, + { + "n": "GAME_GENRE_QUIZ", + "s": "Quiz game" + }, + { + "n": "GAME_GENRE_RACING", + "s": "Racing" + }, + { + "n": "GAME_GENRE_RETRO", + "s": "Retro game" + }, + { + "n": "GAME_GENRE_RPG", + "s": "Roleplaying game" + }, + { + "n": "GAME_GENRE_RTS", + "s": "Real-time strategy" + }, + { + "n": "GAME_GENRE_SCIFI", + "s": "Science fiction game" + }, + { + "n": "GAME_GENRE_SHOOTER", + "s": "Shooter game" + }, + { + "n": "GAME_GENRE_SIMULATION", + "s": "Simulation game" + }, + { + "n": "GAME_GENRE_SINGLEPLAYER", + "s": "Singleplayer" + }, + { + "n": "GAME_GENRE_SPORTS", + "s": "Sports game" + }, + { + "n": "GAME_GENRE_STRATEGY", + "s": "Strategy game" + }, + { + "n": "GAME_GENRE_TBS", + "s": "Turn-based strategy" + }, + { + "n": "GAME_GENRE_TOWER_DEFENSE", + "s": "Tower defence game" + }, + { + "n": "GAME_INVENTORY", + "s": "सूची" + }, + { + "n": "GAME_INVENTORY_AMMO", + "s": "Ammo" + }, + { + "n": "GAME_INVENTORY_AMMUNITION", + "s": "Ammunition" + }, + { + "n": "GAME_INVENTORY_BULLET", + "s": "Bullet" + }, + { + "n": "GAME_INVENTORY_BULLET_PLURAL", + "s": "Bullets" + }, + { + "n": "GAME_INVENTORY_BUY", + "s": "Buy" + }, + { + "n": "GAME_INVENTORY_CAPACITY", + "s": "Inventory Capacity" + }, + { + "n": "GAME_INVENTORY_DROP", + "s": "Drop" + }, + { + "n": "GAME_INVENTORY_ENCUMBRANCE", + "s": "Encumbrance" + }, + { + "n": "GAME_INVENTORY_FULL", + "s": "Inventory Full" + }, + { + "n": "GAME_INVENTORY_ITEM", + "s": "Item" + }, + { + "n": "GAME_INVENTORY_KEY", + "s": "Key" + }, + { + "n": "GAME_INVENTORY_POWERUP", + "s": "Power-up" + }, + { + "n": "GAME_INVENTORY_SELL", + "s": "Sell" + }, + { + "n": "GAME_INVENTORY_USE", + "s": "Use" + }, + { + "n": "GAME_INVENTORY_WEAPON", + "s": "Weapon" + }, + { + "n": "GAME_INVENTORY_WEAPONS", + "s": "Weapons" + }, + { + "n": "GAME_INVENTORY_YOU_CANNOT_CARRY", + "s": "You cannot carry any more." + }, + { + "n": "GAME_LABEL_BE_CAREFUL", + "s": "Be careful!" + }, + { + "n": "GAME_LABEL_PLEASE_BE_CAREFUL", + "s": "Please be careful." + }, + { + "n": "GAME_LABEL_TACTICS", + "s": "Tactics" + }, + { + "n": "GAME_OBJECTIVE", + "s": "Objective" + }, + { + "n": "GAME_OBJECTIVE_ASSIST", + "s": "Assist" + }, + { + "n": "GAME_OBJECTIVE_ASSIST_PLURAL", + "s": "Assists" + }, + { + "n": "GAME_OBJECTIVE_ATTACK", + "s": "Attack" + }, + { + "n": "GAME_OBJECTIVE_BONUS", + "s": "Bonus" + }, + { + "n": "GAME_OBJECTIVE_CAPTURE", + "s": "Capture" + }, + { + "n": "GAME_OBJECTIVE_COMPLETE", + "s": "Complete" + }, + { + "n": "GAME_OBJECTIVE_DEATH", + "s": "Death" + }, + { + "n": "GAME_OBJECTIVE_DEATH_PLURAL", + "s": "Deaths" + }, + { + "n": "GAME_OBJECTIVE_DEFEND", + "s": "Defend" + }, + { + "n": "GAME_OBJECTIVE_DESTROY", + "s": "Destroy" + }, + { + "n": "GAME_OBJECTIVE_ESCAPE", + "s": "Escape" + }, + { + "n": "GAME_OBJECTIVE_GAME_FINISHED", + "s": "The End" + }, + { + "n": "GAME_OBJECTIVE_GAMEOVER", + "s": "Game over!" + }, + { + "n": "GAME_OBJECTIVE_GAMEOVER_CAPS", + "s": "GAME OVER!" + }, + { + "n": "GAME_OBJECTIVE_HIGH_SCORE", + "s": "High score" + }, + { + "n": "GAME_OBJECTIVE_INCOMPLETE", + "s": "Incomplete" + }, + { + "n": "GAME_OBJECTIVE_KILL", + "s": "Kill" + }, + { + "n": "GAME_OBJECTIVE_KILL_ASSIST", + "s": "Kill Assist" + }, + { + "n": "GAME_OBJECTIVE_KILL_NOUN", + "s": "Kill" + }, + { + "n": "GAME_OBJECTIVE_KILL_PLURAL", + "s": "Kills" + }, + { + "n": "GAME_OBJECTIVE_LOCKED", + "s": "Locked" + }, + { + "n": "GAME_OBJECTIVE_LOSSES", + "s": "Losses" + }, + { + "n": "GAME_OBJECTIVE_MATCH", + "s": "Match" + }, + { + "n": "GAME_OBJECTIVE_MISSION", + "s": "Mission" + }, + { + "n": "GAME_OBJECTIVE_MISSION_OBJECTIVE", + "s": "Mission Objective" + }, + { + "n": "GAME_OBJECTIVE_MISSION_OBJECTIVE_PLURAL", + "s": "Mission Objectives" + }, + { + "n": "GAME_OBJECTIVE_MULTIPLIER", + "s": "Multiplier" + }, + { + "n": "GAME_OBJECTIVE_PLURAL", + "s": "Objectives" + }, + { + "n": "GAME_OBJECTIVE_POSITION", + "s": "Position" + }, + { + "n": "GAME_OBJECTIVE_RACE_LAP", + "s": "Lap" + }, + { + "n": "GAME_OBJECTIVE_RACE_LAP_PLURAL", + "s": "Laps" + }, + { + "n": "GAME_OBJECTIVE_ROUND", + "s": "Round" + }, + { + "n": "GAME_OBJECTIVE_SCORE", + "s": "Score" + }, + { + "n": "GAME_OBJECTIVE_TIME", + "s": "Time" + }, + { + "n": "GAME_OBJECTIVE_TIME_LEFT", + "s": "Time left" + }, + { + "n": "GAME_OBJECTIVE_TOURNAMENT", + "s": "Tournament" + }, + { + "n": "GAME_OBJECTIVE_TOURNAMENT_PLURAL", + "s": "Tournaments" + }, + { + "n": "GAME_OBJECTIVE_WINS", + "s": "Wins" + }, + { + "n": "GAME_STATUS_DEFEAT", + "s": "Defeat" + }, + { + "n": "GAME_STATUS_DEFEATED", + "s": "You have been defeated." + }, + { + "n": "GAME_STATUS_LOSER", + "s": "Loser" + }, + { + "n": "GAME_STATUS_TEAM_LOST", + "s": "Your team lost!" + }, + { + "n": "GAME_STATUS_TEAM_WON", + "s": "Your team won!" + }, + { + "n": "GAME_STATUS_VICTORY", + "s": "Victory" + }, + { + "n": "GAME_STATUS_WINNER", + "s": "Winner" + }, + { + "n": "GAME_STATUS_YOU_ARE_DEAD", + "s": "You are dead." + }, + { + "n": "GAME_STATUS_YOU_DIED", + "s": "You died." + }, + { + "n": "GAME_STATUS_YOU_LOSE", + "s": "You lose!" + }, + { + "n": "GAME_STATUS_YOU_LOST", + "s": "You lost!" + }, + { + "n": "GAME_STATUS_YOU_WIN", + "s": "You win!" + }, + { + "n": "GAME_STATUS_YOU_WON", + "s": "You won!" + }, + { + "n": "MENU_CAMERA", + "s": "Camera" + }, + { + "n": "MENU_CAMERA_INVERTED", + "s": "Inverted" + }, + { + "n": "MENU_CAMERA_NORMAL", + "s": "Normal" + }, + { + "n": "MENU_CAMERA_XAXIS", + "s": "Camera X-Axis" + }, + { + "n": "MENU_CAMERA_YAXIS", + "s": "Camera Y-Axis" + }, + { + "n": "MENU_CONTROLS_BUTTON", + "s": "Button" + }, + { + "n": "MENU_CONTROLS_CLICK", + "s": "Click" + }, + { + "n": "MENU_CONTROLS_DEADZONE", + "s": "Dead zone" + }, + { + "n": "MENU_CONTROLS_DOUBLE_CLICK", + "s": "Double-click" + }, + { + "n": "MENU_CONTROLS_DRAG", + "s": "Drag" + }, + { + "n": "MENU_CONTROLS_DRAG_DROP", + "s": "Drag and drop" + }, + { + "n": "MENU_CONTROLS_FINGER", + "s": "Finger" + }, + { + "n": "MENU_CONTROLS_GAMEPAD", + "s": "Gamepad" + }, + { + "n": "MENU_CONTROLS_GYROSCOPE", + "s": "Gyroscope" + }, + { + "n": "MENU_CONTROLS_KEY", + "s": "Key" + }, + { + "n": "MENU_CONTROLS_KEYBOARD", + "s": "कीबोर्ड" + }, + { + "n": "MENU_CONTROLS_MOUSE", + "s": "Mouse" + }, + { + "n": "MENU_CONTROLS_MOUSE_SENSITIVITY", + "s": "Mouse sensitivity" + }, + { + "n": "MENU_CONTROLS_PINCH", + "s": "Pinch" + }, + { + "n": "MENU_CONTROLS_ROTATE", + "s": "Rotate" + }, + { + "n": "MENU_CONTROLS_SCROLL", + "s": "Scroll" + }, + { + "n": "MENU_CONTROLS_SHAKE", + "s": "Shake" + }, + { + "n": "MENU_CONTROLS_SPREAD", + "s": "Spread" + }, + { + "n": "MENU_CONTROLS_SWIPE", + "s": "Swipe" + }, + { + "n": "MENU_CONTROLS_TAP", + "s": "Tap" + }, + { + "n": "MENU_CONTROLS_THE_BUTTON", + "s": "The button" + }, + { + "n": "MENU_CONTROLS_THE_KEY", + "s": "The key" + }, + { + "n": "MENU_CONTROLS_TILT", + "s": "Tilt" + }, + { + "n": "MENU_CUSTOMIZE_ARM", + "s": "Arm" + }, + { + "n": "MENU_CUSTOMIZE_ARM_PLURAL", + "s": "Arms" + }, + { + "n": "MENU_CUSTOMIZE_CHEST", + "s": "Chest" + }, + { + "n": "MENU_CUSTOMIZE_CHIN", + "s": "Chin" + }, + { + "n": "MENU_CUSTOMIZE_COLOR", + "s": "Color" + }, + { + "n": "MENU_CUSTOMIZE_EAR", + "s": "Ear" + }, + { + "n": "MENU_CUSTOMIZE_EAR_PLURAL", + "s": "Ears" + }, + { + "n": "MENU_CUSTOMIZE_EYE", + "s": "Eye" + }, + { + "n": "MENU_CUSTOMIZE_EYE_PLURAL", + "s": "Eyes" + }, + { + "n": "MENU_CUSTOMIZE_FEET", + "s": "Feet" + }, + { + "n": "MENU_CUSTOMIZE_FOOT", + "s": "Foot" + }, + { + "n": "MENU_CUSTOMIZE_HAIR", + "s": "Hair" + }, + { + "n": "MENU_CUSTOMIZE_HAIR_BEARD", + "s": "Beard" + }, + { + "n": "MENU_CUSTOMIZE_HAIR_FUR", + "s": "Fur" + }, + { + "n": "MENU_CUSTOMIZE_HAIR_HEAD", + "s": "Hair" + }, + { + "n": "MENU_CUSTOMIZE_HAND", + "s": "Hand" + }, + { + "n": "MENU_CUSTOMIZE_HAND_PLURAL", + "s": "Hands" + }, + { + "n": "MENU_CUSTOMIZE_HEAD", + "s": "Head" + }, + { + "n": "MENU_CUSTOMIZE_HIPS", + "s": "Hips" + }, + { + "n": "MENU_CUSTOMIZE_LEG", + "s": "Leg" + }, + { + "n": "MENU_CUSTOMIZE_LEG_PLURAL", + "s": "Legs" + }, + { + "n": "MENU_CUSTOMIZE_MOUTH", + "s": "Mouth" + }, + { + "n": "MENU_CUSTOMIZE_NECK", + "s": "Neck" + }, + { + "n": "MENU_CUSTOMIZE_NOSE", + "s": "Nose" + }, + { + "n": "MENU_CUSTOMIZE_SKIN", + "s": "Skin" + }, + { + "n": "MENU_CUSTOMIZE_THORAX", + "s": "Thorax" + }, + { + "n": "MENU_DIFFICULTY", + "s": "Difficulty" + }, + { + "n": "MENU_DIFFICULTY_EASY", + "s": "Easy" + }, + { + "n": "MENU_DIFFICULTY_HARD", + "s": "Hard" + }, + { + "n": "MENU_DIFFICULTY_IMPOSSIBLE", + "s": "Impossible" + }, + { + "n": "MENU_DIFFICULTY_INSANE", + "s": "Insane" + }, + { + "n": "MENU_DIFFICULTY_MEDIUM", + "s": "Medium" + }, + { + "n": "MENU_DIFFICULTY_VERY_EASY", + "s": "Very Easy" + }, + { + "n": "MENU_DIFFICULTY_VERY_HARD", + "s": "Very Hard" + }, + { + "n": "MENU_DIR_DOWN", + "s": "Down" + }, + { + "n": "MENU_DIR_LEFT", + "s": "Left" + }, + { + "n": "MENU_DIR_RIGHT", + "s": "Right" + }, + { + "n": "MENU_DIR_UP", + "s": "Up" + }, + { + "n": "MENU_IO_LOAD", + "s": "Load" + }, + { + "n": "MENU_IO_LOAD_GAME", + "s": "Load Game" + }, + { + "n": "MENU_IO_LOADING", + "s": "Loading..." + }, + { + "n": "MENU_IO_PLEASE_WAIT", + "s": "Please wait..." + }, + { + "n": "MENU_IO_RESET_SAVE_DATA", + "s": "Reset save data?" + }, + { + "n": "MENU_IO_SAVE", + "s": "Save" + }, + { + "n": "MENU_IO_SAVE_DATA", + "s": "Save data" + }, + { + "n": "MENU_IO_SAVE_GAME", + "s": "Save Game" + }, + { + "n": "MENU_IO_SAVING", + "s": "Saving..." + }, + { + "n": "MENU_LABEL_AGE", + "s": "Age" + }, + { + "n": "MENU_LABEL_ALL", + "s": "All" + }, + { + "n": "MENU_LABEL_ARE_YOU_REALLY_SURE", + "s": "Are you really sure?" + }, + { + "n": "MENU_LABEL_ARE_YOU_SURE", + "s": "Are you sure?" + }, + { + "n": "MENU_LABEL_BACK", + "s": "Back" + }, + { + "n": "MENU_LABEL_BACKGROUND_MUSIC", + "s": "Background music" + }, + { + "n": "MENU_LABEL_CANCEL", + "s": "रद्द करें" + }, + { + "n": "MENU_LABEL_CLOSE", + "s": "Close" + }, + { + "n": "MENU_LABEL_CONFIRM_BUTTON", + "s": "Confirm" + }, + { + "n": "MENU_LABEL_CONTINUE", + "s": "Continue" + }, + { + "n": "MENU_LABEL_CONTINUE_QUESTION", + "s": "Continue?" + }, + { + "n": "MENU_LABEL_CREDITS", + "s": "क्रेडिट" + }, + { + "n": "MENU_LABEL_DESKTOP", + "s": "डेस्कटॉप से बाहर निकलें " + }, + { + "n": "MENU_LABEL_DESKTOP_QUESTION", + "s": "डेस्कटॉप से बाहर निकलें?" + }, + { + "n": "MENU_LABEL_DLC", + "s": "DLC" + }, + { + "n": "MENU_LABEL_DOWNLOAD", + "s": "Download" + }, + { + "n": "MENU_LABEL_DOWNLOADABLE", + "s": "Downloadable content" + }, + { + "n": "MENU_LABEL_EXIT", + "s": "Exit" + }, + { + "n": "MENU_LABEL_EXIT_QUESTION", + "s": "Exit?" + }, + { + "n": "MENU_LABEL_EXTRAS", + "s": "Extras" + }, + { + "n": "MENU_LABEL_FRAMESPERSEC", + "s": "FPS" + }, + { + "n": "MENU_LABEL_GALLERY", + "s": "Art gallery" + }, + { + "n": "MENU_LABEL_GOODBYE", + "s": "Goodbye!" + }, + { + "n": "MENU_LABEL_GRAPHICS", + "s": "ग्राफिक्स" + }, + { + "n": "MENU_LABEL_IAP", + "s": "In-app purchase" + }, + { + "n": "MENU_LABEL_LANGUAGE", + "s": "भाषा" + }, + { + "n": "MENU_LABEL_LEVEL", + "s": "Level" + }, + { + "n": "MENU_LABEL_MAIL", + "s": "Mail" + }, + { + "n": "MENU_LABEL_MAINMENU", + "s": "Main Menu" + }, + { + "n": "MENU_LABEL_MORE", + "s": "More" + }, + { + "n": "MENU_LABEL_MUSIC", + "s": "Music" + }, + { + "n": "MENU_LABEL_MUSIC_PLAYER", + "s": "Music Player" + }, + { + "n": "MENU_LABEL_NEW_GAME", + "s": "New Game" + }, + { + "n": "MENU_LABEL_NEXT", + "s": "Next" + }, + { + "n": "MENU_LABEL_NEXT_TRACK", + "s": "Next track" + }, + { + "n": "MENU_LABEL_NO", + "s": "नहीं" + }, + { + "n": "MENU_LABEL_NO_CAPS", + "s": "नहीं" + }, + { + "n": "MENU_LABEL_NOPE", + "s": "Nope" + }, + { + "n": "MENU_LABEL_OK", + "s": "OK" + }, + { + "n": "MENU_LABEL_PAUSE", + "s": "Pause" + }, + { + "n": "MENU_LABEL_PAUSED", + "s": "Paused" + }, + { + "n": "MENU_LABEL_PLAY", + "s": "Play" + }, + { + "n": "MENU_LABEL_PLAY_AGAIN", + "s": "Play again" + }, + { + "n": "MENU_LABEL_PRESS_ANYKEY", + "s": "Press any key" + }, + { + "n": "MENU_LABEL_PRESS_ANYKEY_CONTINUE", + "s": "Press any key to continue" + }, + { + "n": "MENU_LABEL_PRESS_START", + "s": "Press Start" + }, + { + "n": "MENU_LABEL_PRESS_START_CONTINUE", + "s": "Press Start to continue" + }, + { + "n": "MENU_LABEL_PREVIOUS", + "s": "Previous" + }, + { + "n": "MENU_LABEL_PREVIOUS_TRACK", + "s": "Previous track" + }, + { + "n": "MENU_LABEL_PRICE", + "s": "Price" + }, + { + "n": "MENU_LABEL_PRICE_FREE", + "s": "Free" + }, + { + "n": "MENU_LABEL_PURCHASE", + "s": "Purchase" + }, + { + "n": "MENU_LABEL_QUIT", + "s": "छोड़ना" + }, + { + "n": "MENU_LABEL_QUIT_CONFIRM", + "s": "क्या आप वाकई छोड़ना चाहते हैं? " + }, + { + "n": "MENU_LABEL_QUIT_QUESTION", + "s": "छोड़ना?" + }, + { + "n": "MENU_LABEL_REPLAY", + "s": "Replay" + }, + { + "n": "MENU_LABEL_RETURN", + "s": "लौटना" + }, + { + "n": "MENU_LABEL_RETURN_MAIN", + "s": "मुख्य मेनू पर लौटें" + }, + { + "n": "MENU_LABEL_RETURN_MAIN_QUESTION", + "s": "मुख्य मेनू पर वापस जाएँ? " + }, + { + "n": "MENU_LABEL_SHARE", + "s": "Share" + }, + { + "n": "MENU_LABEL_SKIP", + "s": "Skip" + }, + { + "n": "MENU_LABEL_SOUND", + "s": "Sound" + }, + { + "n": "MENU_LABEL_THANK_YOU", + "s": "Thank you!" + }, + { + "n": "MENU_LABEL_UNLOCK", + "s": "Unlock" + }, + { + "n": "MENU_LABEL_VIDEO", + "s": "Video" + }, + { + "n": "MENU_LABEL_VOICES", + "s": "Voices" + }, + { + "n": "MENU_LABEL_WARNING", + "s": "Warning" + }, + { + "n": "MENU_LABEL_WELCOME", + "s": "Welcome" + }, + { + "n": "MENU_LABEL_WORLD", + "s": "दुनिया" + }, + { + "n": "MENU_LABEL_YEAH", + "s": "Yeah" + }, + { + "n": "MENU_LABEL_YES", + "s": "हां" + }, + { + "n": "MENU_LABEL_YES_CAPS", + "s": "हां" + }, + { + "n": "MENU_LANGUAGE_DIRECTION", + "s": "ltr" + }, + { + "n": "MENU_LANGUAGE_THIS", + "s": "हिन्दी" + }, + { + "n": "MENU_LANGUAGE_THIS_EN", + "s": "Hindi" + }, + { + "n": "MENU_LOGIN", + "s": "Login" + }, + { + "n": "MENU_LOGIN_EMAIL", + "s": "E-mail" + }, + { + "n": "MENU_LOGIN_FORGOT", + "s": "Forgot password" + }, + { + "n": "MENU_LOGIN_PASSWORD", + "s": "Password" + }, + { + "n": "MENU_LOGIN_REGISTER", + "s": "Register" + }, + { + "n": "MENU_LOGIN_REMEMBER", + "s": "Remember?" + }, + { + "n": "MENU_MODE_CHALLENGE", + "s": "Challenge" + }, + { + "n": "MENU_MODE_CHALLENGE_MODE", + "s": "Challenge mode" + }, + { + "n": "MENU_MODE_COOP", + "s": "Co-op" + }, + { + "n": "MENU_MODE_COOPERATIVE", + "s": "Cooperative" + }, + { + "n": "MENU_MODE_DEATHMATCH", + "s": "Deathmatch" + }, + { + "n": "MENU_MODE_HELP", + "s": "Help" + }, + { + "n": "MENU_MODE_INSTRUCTIONS", + "s": "Instructions" + }, + { + "n": "MENU_MODE_MULTIPLAYER", + "s": "Multiplayer" + }, + { + "n": "MENU_MODE_MULTIPLAYER_LOCAL", + "s": "Local Multiplayer" + }, + { + "n": "MENU_MODE_MULTIPLAYER_ONLINE", + "s": "Online Multiplayer" + }, + { + "n": "MENU_MODE_PLAY_ONLINE", + "s": "Play Online" + }, + { + "n": "MENU_MODE_SINGLEPLAYER", + "s": "एकल खिलाड़ी" + }, + { + "n": "MENU_MODE_TRAINING", + "s": "Training" + }, + { + "n": "MENU_MODE_TUTORIAL", + "s": "Tutorial" + }, + { + "n": "MENU_MODE_VERSUS", + "s": "Versus" + }, + { + "n": "MENU_NAME", + "s": "Name" + }, + { + "n": "MENU_NAME_FIRST", + "s": "First Name" + }, + { + "n": "MENU_NAME_LAST", + "s": "Last Name" + }, + { + "n": "MENU_NAME_USER", + "s": "Username" + }, + { + "n": "MENU_OPTIONS", + "s": "विन्यास" + }, + { + "n": "MENU_OPTIONS_ADVANCEDGRAPHICS", + "s": "Advanced Graphics" + }, + { + "n": "MENU_OPTIONS_ANTIALIASING", + "s": "Anti-aliasing" + }, + { + "n": "MENU_OPTIONS_BLOOM", + "s": "Bloom" + }, + { + "n": "MENU_OPTIONS_CONTROLS", + "s": "नियंत्रण" + }, + { + "n": "MENU_OPTIONS_DIFFICULTY", + "s": "Difficulty Options" + }, + { + "n": "MENU_OPTIONS_DISPLAY", + "s": "Display" + }, + { + "n": "MENU_OPTIONS_EFFECT_DETAIL", + "s": "Effect detail" + }, + { + "n": "MENU_OPTIONS_FILTERING_ANISOTROPIC", + "s": "Anisotropic" + }, + { + "n": "MENU_OPTIONS_FILTERING_BILINEAR", + "s": "Bilinear" + }, + { + "n": "MENU_OPTIONS_FILTERING_MODE", + "s": "Filtering mode" + }, + { + "n": "MENU_OPTIONS_FILTERING_TRILINEAR", + "s": "Trilinear" + }, + { + "n": "MENU_OPTIONS_FIRST_PERSON_VIEW", + "s": "First Person View" + }, + { + "n": "MENU_OPTIONS_FOV", + "s": "FOV" + }, + { + "n": "MENU_OPTIONS_FULLSCREEN", + "s": "Fullscreen" + }, + { + "n": "MENU_OPTIONS_GAMEPLAY", + "s": "Gameplay Options" + }, + { + "n": "MENU_OPTIONS_GRAPHICS", + "s": "Graphics Options" + }, + { + "n": "MENU_OPTIONS_HUD", + "s": "HUD" + }, + { + "n": "MENU_OPTIONS_MODEL_DETAIL", + "s": "Model detail" + }, + { + "n": "MENU_OPTIONS_MULTICORE_RENDERING", + "s": "Multicore rendering" + }, + { + "n": "MENU_OPTIONS_MUSIC_VOLUME", + "s": "Music volume" + }, + { + "n": "MENU_OPTIONS_NETWORK", + "s": "Network Options" + }, + { + "n": "MENU_OPTIONS_QUALITY", + "s": "Quality" + }, + { + "n": "MENU_OPTIONS_RESOLUTION", + "s": "Resolution" + }, + { + "n": "MENU_OPTIONS_SFX_VOLUME", + "s": "Sound effect volume" + }, + { + "n": "MENU_OPTIONS_SHADER_DETAIL", + "s": "Shader detail" + }, + { + "n": "MENU_OPTIONS_SHADOW", + "s": "Shadow" + }, + { + "n": "MENU_OPTIONS_SHADOW_PLURAL", + "s": "Shadows" + }, + { + "n": "MENU_OPTIONS_SIZE", + "s": "Size" + }, + { + "n": "MENU_OPTIONS_SOUND", + "s": "Sound Options" + }, + { + "n": "MENU_OPTIONS_SOUND_VOLUME", + "s": "Volume" + }, + { + "n": "MENU_OPTIONS_SPLITSCREEN", + "s": "Splitscreen" + }, + { + "n": "MENU_OPTIONS_TEXTURE_DETAIL", + "s": "Texture detail" + }, + { + "n": "MENU_OPTIONS_THIRD_PERSON_VIEW", + "s": "Third Person View" + }, + { + "n": "MENU_OPTIONS_VIDEO", + "s": "Video Options" + }, + { + "n": "MENU_OPTIONS_VIDEO_QUALITY", + "s": "Video Quality" + }, + { + "n": "MENU_OPTIONS_VOICE_VOLUME", + "s": "Voice volume" + }, + { + "n": "MENU_OPTIONS_VSYNC", + "s": "V-sync" + }, + { + "n": "MENU_OPTIONS_WIDESCREEN", + "s": "Widescreen" + }, + { + "n": "MENU_OPTIONS_WINDOWED", + "s": "Windowed" + }, + { + "n": "MENU_SETTING_HIGH", + "s": "High" + }, + { + "n": "MENU_SETTING_LOW", + "s": "Low" + }, + { + "n": "MENU_SETTING_MEDIUM", + "s": "Medium" + }, + { + "n": "MENU_SETTING_ULTRA", + "s": "Ultra" + }, + { + "n": "MENU_SETTING_VERY_HIGH", + "s": "Very High" + }, + { + "n": "MENU_VERSION", + "s": "Version" + }, + { + "n": "MENU_VERSION_DEMO", + "s": "Demo" + }, + { + "n": "MENU_VERSION_FREE", + "s": "Free" + }, + { + "n": "MENU_VERSION_FULL", + "s": "Full" + }, + { + "n": "MENU_VERSION_LITE", + "s": "Lite" + }, + { + "n": "MENU_VERSION_PREMIUM", + "s": "Premium" + }, + { + "n": "MENU_VERSION_SHAREWARE", + "s": "Shareware" + }, + { + "n": "MENU_VERSION_TRIAL", + "s": "Trial" + }, + { + "n": "MENU_VR_COMFORT_MODE", + "s": "VR comfort mode" + }, + { + "n": "MENU_VR_HMD_ORIENT_RESET", + "s": "HMD orientation reset" + }, + { + "n": "MENU_VR_VIRTUAL_REALITY", + "s": "Virtual Reality" + } + ] + } +} diff --git a/assets/locales/hiIN/terrarum.json b/assets/locales/hiIN/terrarum.json new file mode 100644 index 000000000..16d58ace5 --- /dev/null +++ b/assets/locales/hiIN/terrarum.json @@ -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": "कृपया निम्न फ़ाइल पर अपना लोड ऑर्डर पुन: कॉन्फ़िगर करें:" +} diff --git a/assets/locales/jaJP/terrarum.json b/assets/locales/jaJP/terrarum.json index 23fc76057..ab27fdc15 100644 --- a/assets/locales/jaJP/terrarum.json +++ b/assets/locales/jaJP/terrarum.json @@ -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": "次のファイルでロードオーダーを再設定してください。" } \ No newline at end of file diff --git a/assets/locales/koKR/terrarum.json b/assets/locales/koKR/terrarum.json index 3609d2c2c..0a8ebe85e 100644 --- a/assets/locales/koKR/terrarum.json +++ b/assets/locales/koKR/terrarum.json @@ -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": "다음의 파일에서 불러오기 순서를 재설정하십시오." } diff --git a/assets/locales/ruRU/terrarum.json b/assets/locales/ruRU/terrarum.json index 2a9193b26..6b5ca1f4a 100644 --- a/assets/locales/ruRU/terrarum.json +++ b/assets/locales/ruRU/terrarum.json @@ -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": "Измените конфигурацию вашего порядка загрузки на:" } \ No newline at end of file diff --git a/assets/locales/zhCN/terrarum.json b/assets/locales/zhCN/terrarum.json index a2f88099c..8b20d99d6 100644 --- a/assets/locales/zhCN/terrarum.json +++ b/assets/locales/zhCN/terrarum.json @@ -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": "请重新配置您的加载顺序:" } \ No newline at end of file diff --git a/assets/locales/zhTW/terrarum.json b/assets/locales/zhTW/terrarum.json index 394032488..847d23484 100644 --- a/assets/locales/zhTW/terrarum.json +++ b/assets/locales/zhTW/terrarum.json @@ -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": "請重新配置您的加載順序:" } \ No newline at end of file diff --git a/assets/mods/LoadOrder.csv b/assets/mods/LoadOrder.csv deleted file mode 100644 index 1d47f6ac0..000000000 --- a/assets/mods/LoadOrder.csv +++ /dev/null @@ -1,6 +0,0 @@ -# Load Order -# Modules are loaded from top to bottom. -# You can disable basegame, but we don't recommend. - -basegame -#dwarventech diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index bea9a5254..75bc662e6 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -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); diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index f01745500..531113114 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -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 diff --git a/src/net/torvald/terrarum/ModMgr.kt b/src/net/torvald/terrarum/ModMgr.kt index cdf779f46..3b8726e46 100644 --- a/src/net/torvald/terrarum/ModMgr.kt +++ b/src/net/torvald/terrarum/ModMgr.kt @@ -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() @@ -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.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() 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 { 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>() 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>() 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() + val retexableCallbacks = HashMap 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//retextures/basegame +// printdbg(this, "baseTargetModDir = $baseTargetModDir") + + retexables.forEach { category -> + val dir = File(baseTargetModDir, category) + // modules//retextures/basegame/blocks + +// printdbg(this, "cats: ${dir.path}") + + if (dir.isDirectory && dir.exists()) { + dir.listFiles { it: File -> + it?.name?.contains('-') == true + }.forEach { + // -.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) : URLClassLoader(urls) { diff --git a/src/net/torvald/terrarum/ModuleEntryPoint.kt b/src/net/torvald/terrarum/ModuleEntryPoint.kt index 38837ba16..59e1cf1b9 100644 --- a/src/net/torvald/terrarum/ModuleEntryPoint.kt +++ b/src/net/torvald/terrarum/ModuleEntryPoint.kt @@ -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 } \ No newline at end of file diff --git a/src/net/torvald/terrarum/NoModuleDefaultTitlescreen.kt b/src/net/torvald/terrarum/NoModuleDefaultTitlescreen.kt index e31aa908d..89d9f0c8c 100644 --- a/src/net/torvald/terrarum/NoModuleDefaultTitlescreen.kt +++ b/src/net/torvald/terrarum/NoModuleDefaultTitlescreen.kt @@ -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 n’est 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 diff --git a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt index 0cac5ab5e..b0bcd8feb 100644 --- a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt +++ b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt @@ -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 . +""" + const val DEFAULT_LOADORDER_FILE = """# Load Order +# Modules are loaded from top to bottom. +# You can disable basegame, but we don't recommend. + +basegame """ /** diff --git a/src/net/torvald/terrarum/blockproperties/WireCodex.kt b/src/net/torvald/terrarum/blockproperties/WireCodex.kt index 5a0c07668..40b141cb5 100644 --- a/src/net/torvald/terrarum/blockproperties/WireCodex.kt +++ b/src/net/torvald/terrarum/blockproperties/WireCodex.kt @@ -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 } } diff --git a/src/net/torvald/terrarum/console/CommandDict.kt b/src/net/torvald/terrarum/console/CommandDict.kt index 7bc820969..03d2b295e 100644 --- a/src/net/torvald/terrarum/console/CommandDict.kt +++ b/src/net/torvald/terrarum/console/CommandDict.kt @@ -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) - } } - } diff --git a/src/net/torvald/terrarum/langpack/Lang.kt b/src/net/torvald/terrarum/langpack/Lang.kt index 64c33dfaa..76b8e92d6 100644 --- a/src/net/torvald/terrarum/langpack/Lang.kt +++ b/src/net/torvald/terrarum/langpack/Lang.kt @@ -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) } diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index 6336eca6c..bb445dca5 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -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 diff --git a/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt b/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt index 9b426f9d5..37c6b0ffb 100644 --- a/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt +++ b/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt @@ -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) } diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 88fc3a99f..ca7810e67 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -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 = ArrayList() diff --git a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt index 1d8e7c1e0..381369e4f 100644 --- a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt +++ b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt @@ -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 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt index 96b1b05ed..ef6ab50fb 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt @@ -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("_")) { diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt index e7ad4df8d..7e5baebeb 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt @@ -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") diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt index 441dd4f81..8c06d5f3a 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt @@ -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") diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIBasicInfo.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIBasicInfo.kt index 6efd96ecf..514de6334 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIBasicInfo.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIBasicInfo.kt @@ -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 diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UITierOneWatch.kt b/src/net/torvald/terrarum/modulebasegame/ui/UITierOneWatch.kt index ce974bbec..b6889891f 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UITierOneWatch.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UITierOneWatch.kt @@ -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) diff --git a/src/net/torvald/terrarum/ui/UIItemModuleInfoCell.kt b/src/net/torvald/terrarum/ui/UIItemModuleInfoCell.kt index c61673b91..d231705fe 100644 --- a/src/net/torvald/terrarum/ui/UIItemModuleInfoCell.kt +++ b/src/net/torvald/terrarum/ui/UIItemModuleInfoCell.kt @@ -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 diff --git a/src/net/torvald/terrarum/utils/CSVFetcher.kt b/src/net/torvald/terrarum/utils/CSVFetcher.kt index ab58907f2..26f454f6b 100644 --- a/src/net/torvald/terrarum/utils/CSVFetcher.kt +++ b/src/net/torvald/terrarum/utils/CSVFetcher.kt @@ -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 { val csvParser = org.apache.commons.csv.CSVParser.parse( diff --git a/src/net/torvald/terrarum/worlddrawer/CreateTileAtlas.kt b/src/net/torvald/terrarum/worlddrawer/CreateTileAtlas.kt index 7c96b6ba2..c45278382 100644 --- a/src/net/torvald/terrarum/worlddrawer/CreateTileAtlas.kt +++ b/src/net/torvald/terrarum/worlddrawer/CreateTileAtlas.kt @@ -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)