modular first test

This commit is contained in:
Song Minjae
2017-04-17 16:14:35 +09:00
parent 98d7548ce8
commit cec266d396
18 changed files with 128 additions and 56 deletions

View File

@@ -0,0 +1,9 @@
# Load order
# Modules are loaded from top to bottom.
# And yes, you can disable basegame, but we don't recommend.
# Acceptable formats:
# module_name,description_in_English_no_comma,
# module_name,description_in_English_no_comma,(external Jar 1);(external Jar 2); ...
basegame,The base game,
dwarventech,Logic gates and machines,
1 # Load order
2 # Modules are loaded from top to bottom.
3 # And yes, you can disable basegame, but we don't recommend.
4 # Acceptable formats:
5 # module_name,description_in_English_no_comma,
6 # module_name,description_in_English_no_comma,(external Jar 1);(external Jar 2); ...
7 basegame,The base game,
8 dwarventech,Logic gates and machines,

View File

@@ -1,2 +0,0 @@
"id";"filename"
"12345";"tty.lua"
1 id filename
2 12345 tty.lua

View File

@@ -1 +0,0 @@

View File

@@ -1,14 +1,3 @@
Modules may have following subdirectories:
## Register modules
- creatures
- factions
- items
- tiles
- weathers
Modules must be packed with Terrarum Virtual Disk format. The packer is located in
lib/TerranVirtualDisk.jar
For more information, please refer to [this link](https://github.com/minjaesong/TerranVirtualDisk)
Only the modules that enlisted in LoadOrder.csv will be loaded.

View File

@@ -5,13 +5,14 @@ import net.torvald.terrarum.weather.toColor
import org.newdawn.slick.Color
import org.newdawn.slick.Image
import net.torvald.colourutil.CIEXYZUtil.toColor
import net.torvald.terrarum.ModuleManager
/**
* RGB-modeled CCT calculator
* Created by minjaesong on 16-07-26.
*/
object ColourTemp {
private var envOverlayColourmap = Image("./assets/graphics/colourmap/black_body_col_1000_40000_K.tga")
private var envOverlayColourmap = Image(ModuleManager.getPath("basegame", "colourmap/black_body_col_1000_40000_K.tga"))
private fun colTempToImagePos(K: Int): Int {
if (K < 1000 || K >= 40000) throw IllegalArgumentException("K: out of range. ($K)")

View File

@@ -0,0 +1,77 @@
package net.torvald.terrarum
import org.apache.commons.csv.CSVFormat
import org.apache.commons.csv.CSVParser
import java.io.File
import java.io.FileNotFoundException
import java.nio.file.FileSystems
/**
* Modules Resource Manager
*
* Created by SKYHi14 on 2017-04-17.
*/
object ModuleManager {
data class ModuleMetadata(val order: Int, val isDir: Boolean, val desc: String, val libraries: Array<String>) {
override fun toString() =
"\tModule #$order -- $desc\n" +
"\tExternal libraries: ${libraries.joinToString(", ")}"
}
const val modDir = "./assets/modules"
val moduleInfo = HashMap<String, ModuleMetadata>()
init {
// load modules
val loadOrderCSVparser = CSVParser.parse(
FileSystems.getDefault().getPath("$modDir/LoadOrder.csv").toFile(),
Charsets.UTF_8,
CSVFormat.DEFAULT.withCommentMarker('#')
)
val loadOrder = loadOrderCSVparser.records
loadOrderCSVparser.close()
loadOrder.forEachIndexed { index, it ->
val moduleName = it[0]
println("[ModuleManager] Loading module $moduleName")
val description = it[1]
val libs = it[2].split(';').toTypedArray()
val isDir = FileSystems.getDefault().getPath("$modDir/$moduleName").toFile().isDirectory
moduleInfo[moduleName] = ModuleMetadata(index, isDir, description, libs)
println(moduleInfo[moduleName])
}
}
private fun checkExistence(module: String) {
if (!moduleInfo.containsKey(module))
throw FileNotFoundException("No such module: $module")
}
private fun String.sanitisePath() = if (this[0] == '/' || this[0] == '\\')
this.substring(1..this.lastIndex)
else this
fun getPath(module: String, path: String): String {
checkExistence(module)
return "$modDir/$module/${path.sanitisePath()}"
}
fun getFile(module: String, path: String): File {
checkExistence(module)
return FileSystems.getDefault().getPath(getPath(module, path)).toFile()
}
fun getFiles(module: String, path: String): Array<File> {
checkExistence(module)
val dir = FileSystems.getDefault().getPath(getPath(module, path)).toFile()
if (!dir.isDirectory) {
throw FileNotFoundException("The path is not a directory")
}
else {
return dir.listFiles()
}
}
}

View File

@@ -311,6 +311,11 @@ object Terrarum : StateBasedGame(GAME_NAME) {
}
}
// load modules
ModuleManager
gc.graphics.clear() // clean up any 'dust' in the buffer
//addState(StateVTTest())

View File

@@ -18,9 +18,9 @@ object CreatureBuilder {
* @Param jsonFileName with extension
*/
@Throws(IOException::class, SlickException::class)
operator fun invoke(jsonFileName: String): ActorWithSprite {
operator fun invoke(module: String, jsonFileName: String): ActorWithSprite {
val actor = ActorWithSprite(Actor.RenderOrder.MIDDLE)
InjectCreatureRaw(actor.actorValue, jsonFileName)
InjectCreatureRaw(actor.actorValue, module, jsonFileName)
return actor
}

View File

@@ -5,6 +5,7 @@ import net.torvald.random.Fudge3
import net.torvald.terrarum.langpack.Lang
import com.google.gson.JsonObject
import net.torvald.terrarum.ActorValue
import net.torvald.terrarum.ModuleManager
import net.torvald.terrarum.gameactors.ActorHumanoid
import org.newdawn.slick.SlickException
import java.io.IOException
@@ -15,7 +16,6 @@ import java.security.SecureRandom
*/
object InjectCreatureRaw {
const val JSONPATH = "./assets/raw/creatures/"
private const val JSONMULT = "mult" // one appears in JSON files
/**
@@ -24,8 +24,8 @@ object InjectCreatureRaw {
* @param actorValueRef ActorValue object to be injected.
* @param jsonFileName with extension
*/
operator fun invoke(actorValueRef: ActorValue, jsonFileName: String) {
val jsonObj = JsonFetcher(JSONPATH + jsonFileName)
operator fun invoke(actorValueRef: ActorValue, module: String, jsonFileName: String) {
val jsonObj = JsonFetcher(ModuleManager.getPath(module, "creatures/$jsonFileName"))
val elementsInt = arrayOf(AVKey.BASEHEIGHT, AVKey.TOOLSIZE, AVKey.ENCUMBRANCE)
val elementsString = arrayOf(AVKey.RACENAME, AVKey.RACENAMEPLURAL)

View File

@@ -13,7 +13,7 @@ object PlayerBuilder {
operator fun invoke(): Actor {
val p: Actor = Player(Terrarum.ingame!!.world.time.currentTimeAsGameDate)
InjectCreatureRaw(p.actorValue, "CreatureHuman.json")
InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json")
// attach sprite

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.gameactors
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.terrarum.ModuleManager
import net.torvald.terrarum.gameactors.ActorHumanoid
import net.torvald.terrarum.gameactors.ai.LuaAIWrapper
import net.torvald.terrarum.mapdrawer.FeaturesDrawer
@@ -15,14 +16,14 @@ object PlayerBuilderCynthia {
val p: HumanoidNPC = HumanoidNPC(
LuaAIWrapper("/net/torvald/terrarum/gameactors/ai/scripts/PokemonNPCAI.lua"),
GameDate(100, 143)) // random value thrown
InjectCreatureRaw(p.actorValue, "CreatureHuman.json")
InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json")
p.actorValue[AVKey.__PLAYER_QUICKSLOTSEL] = 0
p.actorValue[AVKey.NAME] = "Cynthia"
p.makeNewSprite(26, 42, "assets/graphics/sprites/test_player_2.tga")
p.makeNewSprite(26, 42, ModuleManager.getPath("basegame", "sprites/test_player_2.tga"))
p.sprite!!.delay = 200
p.sprite!!.setRowsAndFrames(1, 1)

View File

@@ -5,6 +5,7 @@ import net.torvald.terrarum.gameactors.faction.Faction
import net.torvald.spriteanimation.SpriteAnimation
import com.google.gson.JsonObject
import net.torvald.terrarum.ActorValue
import net.torvald.terrarum.ModuleManager
import net.torvald.terrarum.gameactors.ActorHumanoid
import net.torvald.terrarum.gameactors.faction.FactionFactory
import net.torvald.terrarum.itemproperties.ItemCodex
@@ -27,11 +28,11 @@ object PlayerBuilderSigrid {
p.referenceID = 0x51621D // the only constant of this procedural universe
p.makeNewSprite(28, 51, "assets/graphics/sprites/test_player.tga")
p.makeNewSprite(28, 51, ModuleManager.getPath("basegame", "sprites/test_player.tga"))
p.sprite!!.delay = 200
p.sprite!!.setRowsAndFrames(1, 1)
p.makeNewSpriteGlow(28, 51, "assets/graphics/sprites/test_player_glow.tga")
p.makeNewSpriteGlow(28, 51, ModuleManager.getPath("basegame", "sprites/test_player_glow.tga"))
p.spriteGlow!!.delay = 200
p.spriteGlow!!.setRowsAndFrames(1, 1)
@@ -72,7 +73,7 @@ object PlayerBuilderSigrid {
p.setPosition((4096 * FeaturesDrawer.TILE_SIZE).toDouble(), (300 * 16).toDouble())
p.faction.add(FactionFactory.create("FactionSigrid.json"))
p.faction.add(FactionFactory.create("basegame", "factions/FactionSigrid.json"))

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.gameactors
import net.torvald.terrarum.ModuleManager
import net.torvald.terrarum.gameactors.ai.LuaAIWrapper
import net.torvald.terrarum.mapdrawer.FeaturesDrawer
@@ -9,14 +10,14 @@ import net.torvald.terrarum.mapdrawer.FeaturesDrawer
object PlayerBuilderTestSubject1 {
operator fun invoke(): Player {
val p: Player = Player(GameDate(100, 143)) // random value thrown
InjectCreatureRaw(p.actorValue, "CreatureHuman.json")
InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json")
p.actorValue[AVKey.__PLAYER_QUICKSLOTSEL] = 0
p.actorValue[AVKey.NAME] = "Test Subject 1"
p.makeNewSprite(48, 52, "assets/graphics/sprites/npc_template_anim_prototype.tga")
p.makeNewSprite(48, 52, ModuleManager.getPath("basegame", "sprites/npc_template_anim_prototype.tga"))
p.sprite!!.delay = 200
p.sprite!!.setRowsAndFrames(2, 4)

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum.gameactors.faction
import net.torvald.JsonFetcher
import com.google.gson.JsonObject
import net.torvald.terrarum.ModuleManager
import java.io.IOException
@@ -10,14 +11,12 @@ import java.io.IOException
*/
object FactionFactory {
const val JSONPATH = "./assets/raw/factions/"
/**
* @param filename with extension
*/
@Throws(IOException::class)
fun create(filename: String): Faction {
val jsonObj = JsonFetcher(JSONPATH + filename)
fun create(module: String, path: String): Faction {
val jsonObj = JsonFetcher(ModuleManager.getPath(module, path))
val factionObj = Faction(jsonObj.get("factionname").asString)
jsonObj.get("factionamicable").asJsonArray.forEach { factionObj.addFactionAmicable(it.asString) }

View File

@@ -2,14 +2,11 @@ package net.torvald.terrarum.mapdrawer
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.gameworld.PairedMapLayer
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.tileproperties.Tile
import net.torvald.terrarum.tileproperties.TileCodex
import com.jme3.math.FastMath
import net.torvald.terrarum.blendAlphaMap
import net.torvald.terrarum.*
import net.torvald.terrarum.concurrent.ThreadParallel
import net.torvald.terrarum.blendMul
import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.mapdrawer.FeaturesDrawer.TILE_SIZE
import net.torvald.terrarum.mapdrawer.LightmapRenderer.normaliseToColour
import net.torvald.terrarum.mapdrawer.MapCamera.x
@@ -28,9 +25,9 @@ object TilesDrawer {
private val TILE_SIZE = FeaturesDrawer.TILE_SIZE
private val TILE_SIZEF = FeaturesDrawer.TILE_SIZE.toFloat()
var tilesTerrain: SpriteSheet = SpriteSheet("./assets/graphics/terrain/terrain.tga", TILE_SIZE, TILE_SIZE)
var tilesTerrain: SpriteSheet = SpriteSheet(ModuleManager.getPath("basegame", "tiles/terrain.tga"), TILE_SIZE, TILE_SIZE)
private set // Slick has some weird quirks with PNG's transparency. I'm using 32-bit targa here.
var tilesWire: SpriteSheet = SpriteSheet("./assets/graphics/terrain/wire.tga", TILE_SIZE, TILE_SIZE)
var tilesWire: SpriteSheet = SpriteSheet(ModuleManager.getPath("basegame", "tiles/wire.tga"), TILE_SIZE, TILE_SIZE)
private set
val WALL = GameWorld.WALL
@@ -52,7 +49,7 @@ object TilesDrawer {
* It holds different shading rule to discriminate with group 02, index 0 is single tile.
* These are the tiles that only connects to itself, will not connect to colour variants
*/
val TILES_CONNECT_SELF = arrayOf(
var TILES_CONNECT_SELF = arrayOf(
Tile.ICE_MAGICAL,
Tile.GLASS_CRUDE,
Tile.GLASS_CLEAN,
@@ -101,7 +98,7 @@ object TilesDrawer {
* Connectivity group 02 : natural tiles
* It holds different shading rule to discriminate with group 01, index 0 is middle tile.
*/
val TILES_CONNECT_MUTUAL = arrayOf(
var TILES_CONNECT_MUTUAL = arrayOf(
Tile.STONE,
Tile.STONE_QUARRIED,
Tile.STONE_TILE_WHITE,
@@ -166,7 +163,7 @@ object TilesDrawer {
/**
* Torches, levers, switches, ...
*/
val TILES_WALL_STICKER = arrayOf(
var TILES_WALL_STICKER = arrayOf(
Tile.TORCH,
Tile.TORCH_FROST,
Tile.TORCH_OFF,
@@ -176,7 +173,7 @@ object TilesDrawer {
/**
* platforms, ...
*/
val TILES_WALL_STICKER_CONNECT_SELF = arrayOf(
var TILES_WALL_STICKER_CONNECT_SELF = arrayOf(
Tile.PLATFORM_BIRCH,
Tile.PLATFORM_BLOODROSE,
Tile.PLATFORM_EBONY,
@@ -189,7 +186,7 @@ object TilesDrawer {
* will blend colour using colour multiplication
* i.e. red hues get lost if you dive into the water
*/
val TILES_BLEND_MUL = arrayOf(
var TILES_BLEND_MUL = arrayOf(
Tile.WATER,
Tile.WATER_1,
Tile.WATER_2,

View File

@@ -4,14 +4,11 @@ import com.jme3.math.FastMath
import net.torvald.JsonFetcher
import net.torvald.colourutil.*
import net.torvald.random.HQRNG
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blendMul
import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.*
import net.torvald.terrarum.gameactors.ParticleTestRain
import net.torvald.terrarum.gamecontroller.Key
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameworld.WorldTime
import net.torvald.terrarum.getPixel
import org.newdawn.slick.Color
import org.newdawn.slick.GameContainer
import org.newdawn.slick.Graphics
@@ -47,14 +44,12 @@ object WeatherMixer {
const val WEATHER_GENERIC_RAIN = "genericrain"
// TODO add weather classification indices manually
const val RAW_DIR = "./assets/raw/weathers"
init {
weatherList = HashMap<String, ArrayList<BaseModularWeather>>()
// read weather descriptions from assets/weather (modular weather)
val weatherRawValidList = ArrayList<File>()
val weatherRaws = File(RAW_DIR).listFiles()
val weatherRaws = ModuleManager.getFiles("basegame", "weathers")
weatherRaws.forEach {
if (!it.isDirectory && it.name.endsWith(".json"))
weatherRawValidList.add(it)
@@ -191,7 +186,7 @@ object WeatherMixer {
]
}
*/
val pathToImage = "./assets/graphics/weathers"
val pathToImage = "weathers"
val JSON = JsonFetcher(path)
@@ -212,7 +207,7 @@ object WeatherMixer {
// parse globalLight
if (globalLightInJson.isString)
globalLight = Image("$pathToImage/${globalLightInJson.asString}")
globalLight = Image(ModuleManager.getPath("basegame", "$pathToImage/${globalLightInJson.asString}"))
else if (globalLightInJson.isNumber) {
// make 1x1 image with specified colour
globalLight = Image(1, 1)
@@ -224,7 +219,7 @@ object WeatherMixer {
// parse skyboxGradColourMap
if (skyboxInJson.isString)
skybox = Image("$pathToImage/${skyboxInJson.asString}")
skybox = Image(ModuleManager.getPath("basegame", "$pathToImage/${skyboxInJson.asString}"))
else if (globalLightInJson.isNumber) {
// make 1x2 image with specified colour
skybox = Image(1, 2)
@@ -236,7 +231,7 @@ object WeatherMixer {
// get extra images
for (i in extraImagesPath)
extraImages.add(Image("$pathToImage/${i.asString}"))
extraImages.add(Image(ModuleManager.getPath("basegame", "$pathToImage/${i.asString}")))
// get mix from