diff --git a/README.md b/README.md
index f19b49adc..9c3145865 100644
--- a/README.md
+++ b/README.md
@@ -21,24 +21,7 @@ Any contribution in this project must be made sorely in English, Korean part is
## The Engine ##
-The Engine is custom built to suit the needs most. Following list is our aims:
-
-* Reasonable performance on vast world, on JVM
- - At least better than Notch's codes...
-
-* Thread scalability
- - Multithreaded environments are commonplace in this era; even in the Intel Pentium G. We aim to introduce performance boost by supporting multithreads, without the limitation of threads count (hopefully).
-
-* Lightweight physics solver, as light as we need
- - This game is not exactly a physics toy, albeit some could add the fun.
- - Currently implemented: gravity (NOT artificial), friction, buoyancy (WIP), air/fluid density and termination velocity
- - Planned: artificial gravitation, wind, joints
-
-* Cellular Automata fluid simulation
- - It should be enough — period.
-
-
-Because of this, we just couldn't use solutions out there. For example, Tiled is too slow[citation needed] and has large memory footprint[citation needed] for our vast world; we can't use JBox2d nor Dyn4j as we don't need any sophisticated physics simulation, and can't use them anyway as we have literally _millions_ of rigid bodies (tiles) and actors. (Trivia: we _do_ use Dyn4j's Vector2 class)
+Please refer to [```THE_ENGINE.md```](THE_ENGINE.md).
## Contribution guidelines ##
diff --git a/THE_ENGINE.md b/THE_ENGINE.md
new file mode 100644
index 000000000..503a08417
--- /dev/null
+++ b/THE_ENGINE.md
@@ -0,0 +1,58 @@
+DISCLAIMER: this is marketing-team stuffs. Features are still in-development and may not be available.
+
+### TODO: cleanup
+
+The Engine is custom built to suit the needs most. Following list is our aims:
+
+* Reasonable performance on vast world, on JVM
+ - At least better than Notch's codes...
+
+* Thread scalability
+ - Multithreaded environments are commonplace in this era; even in the Intel Pentium G. We aim to introduce performance boost by supporting multithreads, without the limitation of threads count (hopefully).
+
+* Lightweight physics solver, as light as we need
+ - This game is not exactly a physics toy, albeit some could add the fun.
+ - Currently implemented: gravity (NOT artificial), friction, buoyancy (WIP), air/fluid density and termination velocity
+ - Planned: artificial gravitation, wind, joints
+
+* Cellular Automata fluid simulation
+ - It should be enough — period.
+
+
+Because of this, we just couldn't use solutions out there. For example, Tiled is too slow[citation needed] and has large memory footprint[citation needed] for our vast world; we can't use JBox2d nor Dyn4j as we don't need any sophisticated physics simulation, and can't use them anyway as we have literally _millions_ of rigid bodies (tiles) and actors. (Trivia: we _do_ use Dyn4j's Vector2 class)
+
+
+
+## General-Purpose Side-Scroller Game Maker
+
+The Engines is specialised in side-scrolling platformers with controls specific to
+
+The Engine is designed with modularity in mind — every game runs upon the Engine is individual module(s), and you can write your own module to alter the original game (module), essentially a game "mod" (put intended).
+
+
+### Actors
+
+The Engine allows Actors (NPCs) to have AIs
+
+
+### Sprites
+
+The Engine allows up to 64 sprite layers that are either software- or hardware-blended
+
+
+### Multilingual Support
+
+The Engine can support any arbitrary language, as long as there is fonts for them. A default font is shipped with the Engine, and it already supports 20+ languages.
+
+
+
+### Utilities
+
+The Engine also comes with various utilities to help the game making bit easier. They include:
+
+- Savegame generator/loader
+- Password system (old games used password system to load/save the gameplay)
+- CSV loader (e.g. Item properties)
+- Json loader/saver
+- Text cipher
+
diff --git a/Terrarum_renewed.iml b/Terrarum_renewed.iml
index ed975cde6..369566090 100644
--- a/Terrarum_renewed.iml
+++ b/Terrarum_renewed.iml
@@ -1,21 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/net/torvald/JsonFetcher.kt b/src/net/torvald/JsonFetcher.kt
deleted file mode 100644
index abfd54774..000000000
--- a/src/net/torvald/JsonFetcher.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-package net.torvald
-
-import com.google.gson.JsonObject
-import com.google.gson.JsonParser
-import java.io.File
-
-import java.io.IOException
-import java.nio.file.FileSystems
-import java.nio.file.Files
-import java.util.ArrayList
-import java.util.function.Consumer
-
-/**
- * Created by minjaesong on 16-02-15.
- */
-object JsonFetcher {
-
- private var jsonString: StringBuffer? = null
-
- @Throws(IOException::class)
- operator fun invoke(jsonFilePath: String): JsonObject {
- jsonString = StringBuffer() // reset buffer every time it called
- readJsonFileAsString(jsonFilePath)
-
- println("[JsonFetcher] Reading JSON $jsonFilePath")
-
- val jsonParser = JsonParser()
- val jsonObj = jsonParser.parse(jsonString!!.toString()).asJsonObject
-
- return jsonObj
- }
-
- @Throws(IOException::class)
- operator fun invoke(jsonFile: File): JsonObject {
- jsonString = StringBuffer() // reset buffer every time it called
- readJsonFileAsString(jsonFile.canonicalPath)
-
- println("[JsonFetcher] Reading JSON ${jsonFile.path}")
-
- val jsonParser = JsonParser()
- val jsonObj = jsonParser.parse(jsonString!!.toString()).asJsonObject
-
- return jsonObj
- }
-
- @Throws(IOException::class)
- private fun readJsonFileAsString(path: String) {
- Files.lines(FileSystems.getDefault().getPath(path)).forEach(
- { jsonString!!.append(it) }
- ) // JSON does not require line break
- }
-}
diff --git a/src/net/torvald/RasterWriter.kt b/src/net/torvald/RasterWriter.kt
deleted file mode 100644
index 65b375485..000000000
--- a/src/net/torvald/RasterWriter.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package net.torvald
-
-import javax.imageio.ImageIO
-import java.awt.*
-import java.awt.color.ColorSpace
-import java.awt.image.*
-import java.io.File
-import java.io.IOException
-
-/**
- * Created by minjaesong on 16-03-04.
- */
-object RasterWriter {
-
- val BANDOFFSET_RGB = intArrayOf(0, 1, 2)
- val BANDOFFSET_RGBA = intArrayOf(0, 1, 2, 3)
- val BANDOFFSET_ARGB = intArrayOf(3, 0, 1, 2)
- val BANDOFFSET_MONO = intArrayOf(0)
-
- val COLORSPACE_SRGB = ColorSpace.CS_sRGB
- val COLORSPACE_GRAY = ColorSpace.CS_GRAY
- val COLORSPACE_GREY = COLORSPACE_GRAY
- val COLORSPACE_CIEXYZ = ColorSpace.CS_CIEXYZ
- val COLORSPACE_RGB_LINEAR_GAMMA = ColorSpace.CS_LINEAR_RGB
-
- @Throws(IOException::class)
- fun writePNG_RGB(w: Int, h: Int, rasterData: ByteArray, path: String) {
- writePNG(w, h, rasterData, BANDOFFSET_RGB, COLORSPACE_SRGB, path)
- }
-
- @Throws(IOException::class)
- fun writePNG_Mono(w: Int, h: Int, rasterData: ByteArray, path: String) {
- writePNG(w, h, rasterData, BANDOFFSET_MONO, COLORSPACE_GREY, path)
- }
-
- @Throws(IOException::class)
- fun writePNG(w: Int, h: Int, rasterData: ByteArray, bandOffsets: IntArray, awt_colorspace: Int, path: String) {
- val buffer = DataBufferByte(rasterData, rasterData.size)
- val raster = Raster.createInterleavedRaster(
- buffer, w, h, bandOffsets.size * w, bandOffsets.size, bandOffsets, null)
-
- val colorModel = ComponentColorModel(ColorSpace.getInstance(awt_colorspace), false, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE)
-
- val image = BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied, null)
-
- ImageIO.write(image, "PNG", File(path))
- }
-
-}
diff --git a/src/net/torvald/terrarum/ModMgr.kt b/src/net/torvald/terrarum/ModMgr.kt
index 59171eec4..793dceb76 100644
--- a/src/net/torvald/terrarum/ModMgr.kt
+++ b/src/net/torvald/terrarum/ModMgr.kt
@@ -1,6 +1,6 @@
package net.torvald.terrarum
-import net.torvald.CSVFetcher
+import net.torvald.terrarum.utils.CSVFetcher
import net.torvald.terrarum.itemproperties.GameItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.blockproperties.BlockCodex
@@ -99,12 +99,6 @@ object ModMgr {
println("extension:" + f.extensions)
println("-----------------------------------------------")
}*/
-
-
- /*val engine = ScriptEngineManager().getEngineByExtension("groovy")!!
- engine.eval(FileReader(getFile("basegame", "/items/testpick.groovy")))
- val newPick = (engine as Invocable).invokeFunction("invoke", 8449) as GameItem
- ItemCodex[8449] = newPick*/
}
private fun checkExistence(module: String) {
diff --git a/src/net/torvald/terrarum/StateUITest.kt b/src/net/torvald/terrarum/StateUITest.kt
index 13816faf0..6be124572 100644
--- a/src/net/torvald/terrarum/StateUITest.kt
+++ b/src/net/torvald/terrarum/StateUITest.kt
@@ -27,7 +27,7 @@ class StateUITest : BasicGameState() {
TODO("not implemented")
}
- override fun actorValueChanged(key: String, value: Any?) {
+ override fun onActorValueChange(key: String, value: Any?) {
}
override var inventory: ActorInventory = ActorInventory(this, 100, ActorInventory.CAPACITY_MODE_WEIGHT)
diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt
index 639582b9e..d829bed23 100644
--- a/src/net/torvald/terrarum/Terrarum.kt
+++ b/src/net/torvald/terrarum/Terrarum.kt
@@ -1,11 +1,10 @@
package net.torvald.terrarum
import com.google.gson.JsonArray
-import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import net.torvald.imagefont.GameFontImpl
-import net.torvald.JsonFetcher
-import net.torvald.JsonWriter
+import net.torvald.terrarum.utils.JsonFetcher
+import net.torvald.terrarum.utils.JsonWriter
import net.torvald.imagefont.TinyAlphNum
import net.torvald.terrarum.gamecontroller.mouseTileX
import net.torvald.terrarum.gamecontroller.mouseTileY
@@ -18,7 +17,6 @@ import org.newdawn.slick.opengl.Texture
import org.newdawn.slick.state.StateBasedGame
import java.io.File
import java.io.IOException
-import java.lang.management.ManagementFactory
import java.nio.ByteOrder
import java.text.SimpleDateFormat
import java.util.*
@@ -351,23 +349,23 @@ object Terrarum : StateBasedGame(GAME_NAME) {
val OS = System.getProperty("os.name").toUpperCase()
if (OS.contains("WIN")) {
OperationSystem = "WINDOWS"
- defaultDir = System.getenv("APPDATA") + "/terrarum"
+ defaultDir = System.getenv("APPDATA") + "/Terrarum"
}
else if (OS.contains("OS X")) {
OperationSystem = "OSX"
- defaultDir = System.getProperty("user.home") + "/Library/Application Support/terrarum"
+ defaultDir = System.getProperty("user.home") + "/Library/Application Support/Terrarum"
}
else if (OS.contains("NUX") || OS.contains("NIX")) {
OperationSystem = "LINUX"
- defaultDir = System.getProperty("user.home") + "/.terrarum"
+ defaultDir = System.getProperty("user.home") + "/.Terrarum"
}
else if (OS.contains("SUNOS")) {
OperationSystem = "SOLARIS"
- defaultDir = System.getProperty("user.home") + "/.terrarum"
+ defaultDir = System.getProperty("user.home") + "/.Terrarum"
}
else {
OperationSystem = "UNKNOWN"
- defaultDir = System.getProperty("user.home") + "/.terrarum"
+ defaultDir = System.getProperty("user.home") + "/.Terrarum"
}
defaultSaveDir = defaultDir + "/Saves"
diff --git a/src/net/torvald/terrarum/blockproperties/BlockCodex.kt b/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
index dc223ad63..b9848fc5e 100644
--- a/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
+++ b/src/net/torvald/terrarum/blockproperties/BlockCodex.kt
@@ -1,6 +1,6 @@
package net.torvald.terrarum.blockproperties
-import net.torvald.CSVFetcher
+import net.torvald.terrarum.utils.CSVFetcher
import net.torvald.terrarum.gameworld.MapLayer
import net.torvald.terrarum.gameworld.PairedMapLayer
import org.apache.commons.csv.CSVRecord
diff --git a/src/net/torvald/terrarum/console/ExportAV.kt b/src/net/torvald/terrarum/console/ExportAV.kt
index 351afb6fb..995d822ec 100644
--- a/src/net/torvald/terrarum/console/ExportAV.kt
+++ b/src/net/torvald/terrarum/console/ExportAV.kt
@@ -1,6 +1,6 @@
package net.torvald.terrarum.console
-import net.torvald.JsonWriter
+import net.torvald.terrarum.utils.JsonWriter
import net.torvald.terrarum.Terrarum
import java.io.IOException
diff --git a/src/net/torvald/terrarum/console/ExportMap.kt b/src/net/torvald/terrarum/console/ExportMap.kt
index 763d1fdc3..9d0577d22 100644
--- a/src/net/torvald/terrarum/console/ExportMap.kt
+++ b/src/net/torvald/terrarum/console/ExportMap.kt
@@ -1,7 +1,7 @@
package net.torvald.terrarum.console
import net.torvald.colourutil.Col4096
-import net.torvald.RasterWriter
+import net.torvald.terrarum.utils.RasterWriter
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blockproperties.Block
diff --git a/src/net/torvald/terrarum/gameactors/Actor.kt b/src/net/torvald/terrarum/gameactors/Actor.kt
index 032763bdd..f7d37f3c1 100644
--- a/src/net/torvald/terrarum/gameactors/Actor.kt
+++ b/src/net/torvald/terrarum/gameactors/Actor.kt
@@ -84,5 +84,7 @@ abstract class Actor(val renderOrder: RenderOrder) : Comparable, Runnable
*
* @param value null if the key is deleted
*/
- abstract fun actorValueChanged(key: String, value: Any?)
-}
\ No newline at end of file
+ abstract @Event fun onActorValueChange(key: String, value: Any?)
+}
+
+annotation class Event
diff --git a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt
index 6489a3a93..4dad3bf27 100644
--- a/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt
+++ b/src/net/torvald/terrarum/gameactors/ActorHumanoid.kt
@@ -335,8 +335,10 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
}
override fun keyPressed(key: Int, c: Char) {
- if (key in Key.NUM_1..Key.NUM_0) {
- actorValue[AVKey.__PLAYER_QUICKSLOTSEL] = key - Key.NUM_1
+ // quickslot (quickbar)
+ val quickbarKeys = Terrarum.getConfigIntArray("keyquickbars")
+ if (key in quickbarKeys) {
+ actorValue[AVKey.__PLAYER_QUICKSLOTSEL] = quickbarKeys.indexOf(key)
}
}
@@ -474,7 +476,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
}
}
- override fun actorValueChanged(key: String, value: Any?) {
+ override fun onActorValueChange(key: String, value: Any?) {
// quickslot implementation
if (key == AVKey.__PLAYER_QUICKSLOTSEL && value != null) {
// ONLY FOR HAND_GRIPs!!
diff --git a/src/net/torvald/terrarum/gameactors/ActorValue.kt b/src/net/torvald/terrarum/gameactors/ActorValue.kt
index 36b1f11fb..ada9da23e 100644
--- a/src/net/torvald/terrarum/gameactors/ActorValue.kt
+++ b/src/net/torvald/terrarum/gameactors/ActorValue.kt
@@ -13,13 +13,13 @@ class ActorValue(val actor: Actor) : KVHashMap() {
override fun set(key: String, value: Any) {
super.set(key, value)
- actor.actorValueChanged(key, value) // fire the event handler
+ actor.onActorValueChange(key, value) // fire the event handler
}
override fun remove(key: String) {
if (hashMap[key] != null) {
hashMap.remove(key, hashMap[key]!!)
- actor.actorValueChanged(key, null)
+ actor.onActorValueChange(key, null)
}
}
diff --git a/src/net/torvald/terrarum/gameactors/ActorWithPhysics.kt b/src/net/torvald/terrarum/gameactors/ActorWithPhysics.kt
index 8b8ec4a77..3136b1ce6 100644
--- a/src/net/torvald/terrarum/gameactors/ActorWithPhysics.kt
+++ b/src/net/torvald/terrarum/gameactors/ActorWithPhysics.kt
@@ -1135,7 +1135,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
}
}
- override fun actorValueChanged(key: String, value: Any?) {
+ override fun onActorValueChange(key: String, value: Any?) {
// do nothing
}
diff --git a/src/net/torvald/terrarum/gameactors/CreatureBuilder.kt b/src/net/torvald/terrarum/gameactors/CreatureBuilder.kt
index 4e27d0d1a..a67eaf19e 100644
--- a/src/net/torvald/terrarum/gameactors/CreatureBuilder.kt
+++ b/src/net/torvald/terrarum/gameactors/CreatureBuilder.kt
@@ -1,10 +1,5 @@
package net.torvald.terrarum.gameactors
-import net.torvald.JsonFetcher
-import net.torvald.random.Fudge3
-import net.torvald.random.HQRNG
-import net.torvald.terrarum.langpack.Lang
-import com.google.gson.JsonObject
import org.newdawn.slick.SlickException
import java.io.IOException
diff --git a/src/net/torvald/terrarum/gameactors/InjectCreatureRaw.kt b/src/net/torvald/terrarum/gameactors/InjectCreatureRaw.kt
index 719025125..b060fc7b6 100644
--- a/src/net/torvald/terrarum/gameactors/InjectCreatureRaw.kt
+++ b/src/net/torvald/terrarum/gameactors/InjectCreatureRaw.kt
@@ -1,14 +1,10 @@
package net.torvald.terrarum.gameactors
-import net.torvald.JsonFetcher
+import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.random.Fudge3
import net.torvald.terrarum.langpack.Lang
import com.google.gson.JsonObject
-import net.torvald.terrarum.gameactors.ActorValue
import net.torvald.terrarum.ModMgr
-import net.torvald.terrarum.gameactors.ActorHumanoid
-import org.newdawn.slick.SlickException
-import java.io.IOException
import java.security.SecureRandom
/**
diff --git a/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt b/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt
index ddf4805a2..51c366a64 100644
--- a/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt
+++ b/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt
@@ -1,7 +1,6 @@
package net.torvald.terrarum.gameactors.faction
-import net.torvald.JsonFetcher
-import com.google.gson.JsonObject
+import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarum.ModMgr
import java.io.IOException
diff --git a/src/net/torvald/terrarum/gamecontroller/KeyLayout.kt b/src/net/torvald/terrarum/gamecontroller/KeyLayout.kt
index e13875c85..4a4c78bd4 100644
--- a/src/net/torvald/terrarum/gamecontroller/KeyLayout.kt
+++ b/src/net/torvald/terrarum/gamecontroller/KeyLayout.kt
@@ -1,6 +1,6 @@
package net.torvald.terrarum.gamecontroller
-import net.torvald.JsonFetcher
+import net.torvald.terrarum.utils.JsonFetcher
import java.util.*
/**
diff --git a/src/net/torvald/terrarum/langpack/Lang.kt b/src/net/torvald/terrarum/langpack/Lang.kt
index feaf43029..016c6abab 100644
--- a/src/net/torvald/terrarum/langpack/Lang.kt
+++ b/src/net/torvald/terrarum/langpack/Lang.kt
@@ -1,6 +1,6 @@
package net.torvald.terrarum.langpack
-import net.torvald.JsonFetcher
+import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.terrarum.Terrarum
import java.io.*
import java.util.*
diff --git a/src/net/torvald/CSVFetcher.kt b/src/net/torvald/terrarum/utils/CSVFetcher.kt
similarity index 51%
rename from src/net/torvald/CSVFetcher.kt
rename to src/net/torvald/terrarum/utils/CSVFetcher.kt
index 9da24802e..0ebe5de55 100644
--- a/src/net/torvald/CSVFetcher.kt
+++ b/src/net/torvald/terrarum/utils/CSVFetcher.kt
@@ -1,4 +1,4 @@
-package net.torvald
+package net.torvald.terrarum.utils
import net.torvald.terrarum.ModMgr
import org.apache.commons.csv.CSVFormat
@@ -17,15 +17,15 @@ object CSVFetcher {
private var csvString: StringBuffer? = null
- fun readFromFile(csvFilePath: String): List {
- csvString = StringBuffer() // reset buffer every time it called
- readCSVasString(csvFilePath)
+ fun readFromFile(csvFilePath: String): List {
+ net.torvald.terrarum.utils.CSVFetcher.csvString = StringBuffer() // reset buffer every time it called
+ net.torvald.terrarum.utils.CSVFetcher.readCSVasString(csvFilePath)
println("[CSVFetcher] Reading CSV $csvFilePath")
- val csvParser = CSVParser.parse(
- csvString!!.toString(),
- CSVFormat.DEFAULT.withIgnoreSurroundingSpaces()
+ val csvParser = org.apache.commons.csv.CSVParser.parse(
+ net.torvald.terrarum.utils.CSVFetcher.csvString!!.toString(),
+ org.apache.commons.csv.CSVFormat.DEFAULT.withIgnoreSurroundingSpaces()
.withHeader()
.withIgnoreEmptyLines()
.withDelimiter(';')
@@ -40,12 +40,12 @@ object CSVFetcher {
return csvRecordList
}
- fun readFromModule(module: String, path: String) = readFromFile(ModMgr.getPath(module, path))
+ fun readFromModule(module: String, path: String) = net.torvald.terrarum.utils.CSVFetcher.readFromFile(ModMgr.getPath(module, path))
- fun readFromString(csv: String): List {
- val csvParser = CSVParser.parse(
+ fun readFromString(csv: String): List {
+ val csvParser = org.apache.commons.csv.CSVParser.parse(
csv,
- CSVFormat.DEFAULT.withIgnoreSurroundingSpaces()
+ org.apache.commons.csv.CSVFormat.DEFAULT.withIgnoreSurroundingSpaces()
.withHeader()
.withIgnoreEmptyLines()
.withDelimiter(';')
@@ -60,12 +60,12 @@ object CSVFetcher {
return csvRecordList
}
- @Throws(IOException::class)
+ @Throws(java.io.IOException::class)
fun readCSVasString(path: String): String {
- csvString = StringBuffer()
- Files.lines(FileSystems.getDefault().getPath(path)).forEach(
- { s -> csvString!!.append("$s\n") }
+ net.torvald.terrarum.utils.CSVFetcher.csvString = StringBuffer()
+ java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(
+ { s -> net.torvald.terrarum.utils.CSVFetcher.csvString!!.append("$s\n") }
)
- return csvString!!.toString()
+ return net.torvald.terrarum.utils.CSVFetcher.csvString!!.toString()
}
}
diff --git a/src/net/torvald/simplecipher/ROTUtil.kt b/src/net/torvald/terrarum/utils/CipherROT.kt
similarity index 76%
rename from src/net/torvald/simplecipher/ROTUtil.kt
rename to src/net/torvald/terrarum/utils/CipherROT.kt
index 429995afb..49444eb52 100644
--- a/src/net/torvald/simplecipher/ROTUtil.kt
+++ b/src/net/torvald/terrarum/utils/CipherROT.kt
@@ -1,9 +1,9 @@
-package net.torvald.simplecipher
+package net.torvald.terrarum.utils
/**
* Created by minjaesong on 16-03-20.
*/
-object ROTUtil {
+object CipherROT {
const val CODE_CAP_A = 'A'.toInt()
const val CODE_LOW_A = 'a'.toInt()
@@ -14,18 +14,6 @@ object ROTUtil {
* * Latin alph: removes diacritics and do ROT13, string reverse, capitalised.
* Ligatures are disassembled. Even if the target language does not have
* certain alphabet (e.g. C in Icelandic), such alphabet will be printed anyway.
- *
- * * Cyrillic: removes diacritics and do ROTnn, string reverse, capitalised.
- *
- * * Kana: raise Sutegana, ROT3 on vowels (a i u e o -> e o a i u), string reverse
- * (Wa Wo -> Wo Wa), Nn will remain untouched, forced Katakana.
- *
- * * Hangul: ROT3 on initials\*, lower double initials to single
- * (ㄱ ㄲ ㄴ ㄷ ㄸ ㄹ ㅁ ㅂ ㅃ ㅅ ㅆ ㅇ ㅈ ㅉ ㅊ ㅋ ㅌ ㅍ ㅎ -> ㄹ ㄹ ㅁ ㅂ ㅂ ㅅ ㅇ ㅇ ㅈ ㅈ ㅊ ㅋ ㅋ ㅌ ㅍ ㅎ ㄱ ㄴ ㄷ),
- * string reverse
- *
- * * Chinese: NOT SUPPORTED
- *
* * Numeric: no encrypt
*/
fun encrypt(plaintext: String): String {
diff --git a/src/net/torvald/Clipboard.kt b/src/net/torvald/terrarum/utils/Clipboard.kt
similarity index 93%
rename from src/net/torvald/Clipboard.kt
rename to src/net/torvald/terrarum/utils/Clipboard.kt
index 1e82ea209..aff3c4ef3 100644
--- a/src/net/torvald/Clipboard.kt
+++ b/src/net/torvald/terrarum/utils/Clipboard.kt
@@ -1,4 +1,4 @@
-package net.torvald
+package net.torvald.terrarum.utils
import java.awt.Toolkit
import java.awt.datatransfer.DataFlavor
diff --git a/src/net/torvald/terrarum/utils/JsonFetcher.kt b/src/net/torvald/terrarum/utils/JsonFetcher.kt
new file mode 100644
index 000000000..8ad531148
--- /dev/null
+++ b/src/net/torvald/terrarum/utils/JsonFetcher.kt
@@ -0,0 +1,52 @@
+package net.torvald.terrarum.utils
+
+import com.google.gson.JsonObject
+import com.google.gson.JsonParser
+import java.io.File
+
+import java.io.IOException
+import java.nio.file.FileSystems
+import java.nio.file.Files
+import java.util.ArrayList
+import java.util.function.Consumer
+
+/**
+ * Created by minjaesong on 16-02-15.
+ */
+object JsonFetcher {
+
+ private var jsonString: StringBuffer? = null
+
+ @Throws(java.io.IOException::class)
+ operator fun invoke(jsonFilePath: String): com.google.gson.JsonObject {
+ net.torvald.terrarum.utils.JsonFetcher.jsonString = StringBuffer() // reset buffer every time it called
+ net.torvald.terrarum.utils.JsonFetcher.readJsonFileAsString(jsonFilePath)
+
+ println("[JsonFetcher] Reading JSON $jsonFilePath")
+
+ val jsonParser = com.google.gson.JsonParser()
+ val jsonObj = jsonParser.parse(net.torvald.terrarum.utils.JsonFetcher.jsonString!!.toString()).asJsonObject
+
+ return jsonObj
+ }
+
+ @Throws(java.io.IOException::class)
+ operator fun invoke(jsonFile: java.io.File): com.google.gson.JsonObject {
+ net.torvald.terrarum.utils.JsonFetcher.jsonString = StringBuffer() // reset buffer every time it called
+ net.torvald.terrarum.utils.JsonFetcher.readJsonFileAsString(jsonFile.canonicalPath)
+
+ println("[JsonFetcher] Reading JSON ${jsonFile.path}")
+
+ val jsonParser = com.google.gson.JsonParser()
+ val jsonObj = jsonParser.parse(net.torvald.terrarum.utils.JsonFetcher.jsonString!!.toString()).asJsonObject
+
+ return jsonObj
+ }
+
+ @Throws(java.io.IOException::class)
+ private fun readJsonFileAsString(path: String) {
+ java.nio.file.Files.lines(java.nio.file.FileSystems.getDefault().getPath(path)).forEach(
+ { net.torvald.terrarum.utils.JsonFetcher.jsonString!!.append(it) }
+ ) // JSON does not require line break
+ }
+}
diff --git a/src/net/torvald/JsonWriter.kt b/src/net/torvald/terrarum/utils/JsonWriter.kt
similarity index 68%
rename from src/net/torvald/JsonWriter.kt
rename to src/net/torvald/terrarum/utils/JsonWriter.kt
index 51bfe8dc5..c874f2926 100644
--- a/src/net/torvald/JsonWriter.kt
+++ b/src/net/torvald/terrarum/utils/JsonWriter.kt
@@ -1,4 +1,4 @@
-package net.torvald
+package net.torvald.terrarum.utils
import com.google.gson.Gson
import com.google.gson.JsonElement
@@ -18,11 +18,11 @@ object JsonWriter {
* @param c: a class
* @param path: path to write a file
*/
- @Throws(IOException::class)
+ @Throws(java.io.IOException::class)
fun writeToFile(c: Any, path: String) {
- val classElem = Gson().toJsonTree(c)
+ val classElem = com.google.gson.Gson().toJsonTree(c)
val jsonString = classElem.toString()
- val writer = FileWriter(path)
+ val writer = java.io.FileWriter(path)
writer.write(jsonString)
writer.close()
}
@@ -33,9 +33,9 @@ object JsonWriter {
* @param jsonObject
* @param path: path to write a file
*/
- @Throws(IOException::class)
- fun writeToFile(jsonObject: JsonObject, path: String) {
- val writer = FileWriter(path)
+ @Throws(java.io.IOException::class)
+ fun writeToFile(jsonObject: com.google.gson.JsonObject, path: String) {
+ val writer = java.io.FileWriter(path)
writer.write(jsonObject.toString())
writer.close()
}
diff --git a/src/net/torvald/terrarum/utils/PasswordBase32.kt b/src/net/torvald/terrarum/utils/PasswordBase32.kt
new file mode 100644
index 000000000..004247d2f
--- /dev/null
+++ b/src/net/torvald/terrarum/utils/PasswordBase32.kt
@@ -0,0 +1,150 @@
+package net.torvald.terrarum.utils
+
+import kotlin.experimental.xor
+
+
+/**
+ * Old-school passworld system using Base32
+ *
+ * Created by minjaesong on 2017-05-02.
+ */
+object PasswordBase32 {
+
+ private val stringSet = "YBNDRFG8EJKMCPQXOT+VWIS2A345H769="
+
+ private val substituteSet = hashMapOf(
+ Pair('0', 'O'),
+ Pair('1', 'I'),
+ Pair('Z', '2')
+ )
+
+ /*
+ 0 x
+ 1 6
+ 2 4
+ 3 3
+ 4 1
+ */
+ val padLen = arrayOf(0, 6, 4, 3, 1)
+ private val nullPw = byteArrayOf(0.toByte())
+
+
+ private fun encodeToLetters(byteArray: ByteArray, password: ByteArray): IntArray {
+ val out = ArrayList()
+
+ fun get(i: Int) = byteArray[i] xor (password[i % password.size])
+
+
+ /*
+ 5 Bytes -> 8 Letters
+
+ 0000 0000 | 1111 1111 | 2222 2222 | 3333 3333 | 4444 4444
+ AAAA ABBB | BBCC CCCD | DDDD EEEE | EFFF FFGG | GGGH HHHH
+ */
+
+ // non-pads
+ (0..byteArray.lastIndex - 5 step 5).forEach {
+ /* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
+ /* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
+ /* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
+ /* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
+ /* E */ out.add(get(it+2).toInt().and(0xF).shl(1) or get(it+3).toInt().and(0x80).ushr(7))
+ /* F */ out.add(get(it+3).toInt().and(0x7C).ushr(2))
+ /* G */ out.add(get(it+3).toInt().and(3).shl(3) or get(it+4).toInt().and(0xE0).ushr(5))
+ /* H */ out.add(get(it+4).toInt().and(0x1F))
+ }
+ // pads
+ val residue = byteArray.size % 5
+ if (residue != 0){
+
+ val it = (byteArray.size / 5) * 5 // dark magic of integer division, let's hope the compiler won't "optimise" this...
+
+ when (residue) {
+ 1 -> {
+ /* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
+ /* B */ out.add(get(it).toInt().and(7).shl(2))
+ }
+ 2 -> {
+ /* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
+ /* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
+ /* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
+ /* D */ out.add(get(it+1).toInt().and(1).shl(4))
+ }
+ 3 -> {
+ /* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
+ /* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
+ /* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
+ /* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
+ /* E */ out.add(get(it+2).toInt().and(0xF).shl(1))
+ }
+ 4 -> {
+ /* A */ out.add(get(it).toInt().and(0xF8).ushr(3))
+ /* B */ out.add(get(it).toInt().and(7).shl(2) or get(it+1).toInt().and(0xC0).ushr(6))
+ /* C */ out.add(get(it+1).toInt().and(0x3E).ushr(1))
+ /* D */ out.add(get(it+1).toInt().and(1).shl(4) or get(it+2).toInt().and(0xF0).ushr(4))
+ /* E */ out.add(get(it+2).toInt().and(0xF).shl(1) or get(it+3).toInt().and(0x80).ushr(7))
+ /* F */ out.add(get(it+3).toInt().and(0x7C).ushr(2))
+ /* G */ out.add(get(it+3).toInt().and(3).shl(3))
+ }
+ }
+
+ // append padding
+ kotlin.repeat(padLen[residue], { out.add(32) })
+ }
+
+ return out.toIntArray()
+ }
+
+ /**
+ *
+ * @param bytes size of multiple of five (5, 10, 15, 20, ...) is highly recommended to prevent
+ * lengthy padding
+ * @param password to encode resulting string using XOR Cipher to prevent unexperienced kids
+ * from doing naughty things. Longer, the better.
+ */
+ fun encode(bytes: ByteArray, password: ByteArray = nullPw): String {
+ val plaintext = encodeToLetters(bytes, password)
+ val sb = StringBuilder()
+ plaintext.forEach { sb.append(stringSet[it]) }
+
+ return sb.toString()
+ }
+
+ /**
+ * @param outByteLength expected length of your decoded password. It is always a good idea to
+ * suspect user inputs and sanitise them.
+ */
+ fun decode(input: String, outByteLength: Int, password: ByteArray = nullPw): ByteArray {
+ val buffer = ByteArray(outByteLength)
+ var appendCount = 0
+ var input = input.toUpperCase()
+ substituteSet.forEach { from, to ->
+ input = input.replace(from, to)
+ }
+
+ fun append(byte: Int) {
+ buffer[appendCount] = byte.toByte() xor (password[appendCount % password.size])
+ appendCount++
+ }
+ fun sbyteOf(i: Int) = stringSet.indexOf(input[i]).and(0x1F)
+
+ try {
+ /*
+ 8 Letters -> 5 Bytes
+
+ 0000 0000 | 1111 1111 | 2222 2222 | 3333 3333 | 4444 4444
+ AAAA ABBB | BBCC CCCD | DDDD EEEE | EFFF FFGG | GGGH HHHH
+ */
+ (0..input.lastIndex.plus(8) step 8).forEach {
+ /* 0 */ append(sbyteOf(it+0).shl(3) or sbyteOf(it+1).ushr(2))
+ /* 1 */ append(sbyteOf(it+1).shl(6) or sbyteOf(it+2).shl(1) or sbyteOf(it+3).ushr(4))
+ /* 2 */ append(sbyteOf(it+3).shl(4) or sbyteOf(it+4).ushr(1))
+ /* 3 */ append(sbyteOf(it+4).shl(7) or sbyteOf(it+5).shl(2) or sbyteOf(it+6).ushr(3))
+ /* 4 */ append(sbyteOf(it+6).shl(5) or sbyteOf(it+7))
+ }
+ }
+ catch (endOfStream: ArrayIndexOutOfBoundsException) { }
+
+ return buffer
+ }
+}
diff --git a/src/net/torvald/terrarum/utils/RasterWriter.kt b/src/net/torvald/terrarum/utils/RasterWriter.kt
new file mode 100644
index 000000000..7d60ec339
--- /dev/null
+++ b/src/net/torvald/terrarum/utils/RasterWriter.kt
@@ -0,0 +1,49 @@
+package net.torvald.terrarum.utils
+
+import javax.imageio.ImageIO
+import java.awt.*
+import java.awt.color.ColorSpace
+import java.awt.image.*
+import java.io.File
+import java.io.IOException
+
+/**
+ * Created by minjaesong on 16-03-04.
+ */
+object RasterWriter {
+
+ val BANDOFFSET_RGB = intArrayOf(0, 1, 2)
+ val BANDOFFSET_RGBA = intArrayOf(0, 1, 2, 3)
+ val BANDOFFSET_ARGB = intArrayOf(3, 0, 1, 2)
+ val BANDOFFSET_MONO = intArrayOf(0)
+
+ val COLORSPACE_SRGB = java.awt.color.ColorSpace.CS_sRGB
+ val COLORSPACE_GRAY = java.awt.color.ColorSpace.CS_GRAY
+ val COLORSPACE_GREY = net.torvald.terrarum.utils.RasterWriter.COLORSPACE_GRAY
+ val COLORSPACE_CIEXYZ = java.awt.color.ColorSpace.CS_CIEXYZ
+ val COLORSPACE_RGB_LINEAR_GAMMA = java.awt.color.ColorSpace.CS_LINEAR_RGB
+
+ @Throws(java.io.IOException::class)
+ fun writePNG_RGB(w: Int, h: Int, rasterData: ByteArray, path: String) {
+ net.torvald.terrarum.utils.RasterWriter.writePNG(w, h, rasterData, BANDOFFSET_RGB, COLORSPACE_SRGB, path)
+ }
+
+ @Throws(java.io.IOException::class)
+ fun writePNG_Mono(w: Int, h: Int, rasterData: ByteArray, path: String) {
+ net.torvald.terrarum.utils.RasterWriter.writePNG(w, h, rasterData, BANDOFFSET_MONO, COLORSPACE_GREY, path)
+ }
+
+ @Throws(java.io.IOException::class)
+ fun writePNG(w: Int, h: Int, rasterData: ByteArray, bandOffsets: IntArray, awt_colorspace: Int, path: String) {
+ val buffer = java.awt.image.DataBufferByte(rasterData, rasterData.size)
+ val raster = java.awt.image.Raster.createInterleavedRaster(
+ buffer, w, h, bandOffsets.size * w, bandOffsets.size, bandOffsets, null)
+
+ val colorModel = java.awt.image.ComponentColorModel(java.awt.color.ColorSpace.getInstance(awt_colorspace), false, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE)
+
+ val image = java.awt.image.BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied, null)
+
+ javax.imageio.ImageIO.write(image, "PNG", java.io.File(path))
+ }
+
+}
diff --git a/src/net/torvald/terrarum/weather/WeatherMixer.kt b/src/net/torvald/terrarum/weather/WeatherMixer.kt
index 75159eaac..b66046668 100644
--- a/src/net/torvald/terrarum/weather/WeatherMixer.kt
+++ b/src/net/torvald/terrarum/weather/WeatherMixer.kt
@@ -1,7 +1,6 @@
package net.torvald.terrarum.weather
-import com.jme3.math.FastMath
-import net.torvald.JsonFetcher
+import net.torvald.terrarum.utils.JsonFetcher
import net.torvald.colourutil.*
import net.torvald.random.HQRNG
import net.torvald.terrarum.*
diff --git a/work_files/GameDesign/BACKEND_DESIGN.md b/work_files/GameDesign/BACKEND_DESIGN.md
index ffc6ec98a..f28352e12 100644
--- a/work_files/GameDesign/BACKEND_DESIGN.md
+++ b/work_files/GameDesign/BACKEND_DESIGN.md
@@ -1,3 +1,5 @@
+The extension of [```THE_ENGINE.md```](THE_ENGINE.md)
+
The game has elements that are:
- Actors