From f1686e4cdd54999a417753279337b17875d578dd Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Thu, 24 Mar 2016 23:41:56 +0900 Subject: [PATCH] more Kotlin (Everything is now Kotlin except for RNGs and FastMath), more sunlight tinkering, a lantern Former-commit-id: b284424580831956f8383b97ccfc1bdd1e03feeb Former-commit-id: ec788cf7ef74f91fb54b905817febd22b6da6d54 --- res/graphics/sky_colour.png | Bin 17007 -> 17510 bytes res/graphics/sprites/test_player.png | Bin 17983 -> 18100 bytes res/graphics/terrain/terrain.png | Bin 354806 -> 355402 bytes src/com/Torvald/JsonWriter.kt | 12 + src/com/Torvald/Point/Point2f.java | 28 -- src/com/Torvald/Point/Point2f.kt | 22 + src/com/Torvald/Terrarum/Actors/Hitbox.java | 130 ------ src/com/Torvald/Terrarum/Actors/Hitbox.kt | 115 +++++ src/com/Torvald/Terrarum/Actors/PFSigrid.kt | 2 - .../Torvald/Terrarum/Actors/PhysTestBall.kt | 8 +- .../Terrarum/ConsoleCommand/CatStdout.java | 34 -- .../Terrarum/ConsoleCommand/CatStdout.kt | 32 ++ .../Torvald/Terrarum/ConsoleCommand/Echo.java | 32 -- .../Torvald/Terrarum/ConsoleCommand/Echo.kt | 26 ++ .../Terrarum/ConsoleCommand/ExportAV.java | 39 -- .../Terrarum/ConsoleCommand/ExportAV.kt | 38 ++ .../{ExportMap.java => ExportMap.kt} | 150 +++++++ .../Terrarum/ConsoleCommand/ForceGC.java | 17 - .../Terrarum/ConsoleCommand/ForceGC.kt | 15 + .../Terrarum/ConsoleCommand/GetAV.java | 65 --- .../Torvald/Terrarum/ConsoleCommand/GetAV.kt | 57 +++ .../ConsoleCommand/GetFactioning.java | 60 --- .../Terrarum/ConsoleCommand/GetFactioning.kt | 51 +++ .../Terrarum/ConsoleCommand/GetLocale.java | 27 -- .../Terrarum/ConsoleCommand/GetLocale.kt | 24 ++ .../Terrarum/ConsoleCommand/GsonTest.java | 48 --- .../Terrarum/ConsoleCommand/GsonTest.kt | 47 ++ .../Torvald/Terrarum/ConsoleCommand/Help.kt | 2 +- .../Terrarum/ConsoleCommand/QuitApp.java | 17 - .../Terrarum/ConsoleCommand/QuitApp.kt | 15 + .../Terrarum/ConsoleCommand/SetAV.java | 59 --- .../Torvald/Terrarum/ConsoleCommand/SetAV.kt | 61 +++ .../Terrarum/ConsoleCommand/SetBulletin.java | 35 -- .../Terrarum/ConsoleCommand/SetBulletin.kt | 31 ++ .../Terrarum/ConsoleCommand/SetLocale.java | 45 -- .../Terrarum/ConsoleCommand/SetLocale.kt | 43 ++ .../ConsoleCommand/SpawnPhysTestBall.java | 37 -- .../ConsoleCommand/SpawnPhysTestBall.kt | 38 ++ .../ConsoleCommand/TeleportPlayer.java | 37 -- .../Terrarum/ConsoleCommand/TeleportPlayer.kt | 36 ++ .../Terrarum/ConsoleCommand/ToggleNoClip.java | 22 - .../Terrarum/ConsoleCommand/ToggleNoClip.kt | 20 + src/com/Torvald/Terrarum/Game | 403 ------------------ src/com/Torvald/Terrarum/Game.kt | 6 +- .../Terrarum/GameControl/GameController.kt | 4 +- src/com/Torvald/Terrarum/GameMap/GameMap.java | 247 ----------- src/com/Torvald/Terrarum/GameMap/GameMap.kt | 178 ++++++++ .../Torvald/Terrarum/GameMap/MapLayer.java | 126 ------ src/com/Torvald/Terrarum/GameMap/MapLayer.kt | 58 +++ .../Torvald/Terrarum/GameMap/MapPoint.java | 41 -- src/com/Torvald/Terrarum/GameMap/MapPoint.kt | 35 ++ .../Terrarum/GameMap/PairedMapLayer.java | 136 ------ .../Terrarum/GameMap/PairedMapLayer.kt | 82 ++++ src/com/Torvald/Terrarum/LangPack/Lang.java | 179 -------- src/com/Torvald/Terrarum/LangPack/Lang.kt | 190 +++++++++ .../Terrarum/MapDrawer/LightmapRenderer.kt | 6 +- .../Torvald/Terrarum/MapDrawer/MapCamera.kt | 91 +--- .../Torvald/Terrarum/MapDrawer/MapDrawer.kt | 7 +- src/com/Torvald/Terrarum/Terrarum | 305 ------------- src/com/Torvald/Terrarum/Terrarum.kt | 7 - .../Terrarum/TileProperties/tileprop.csv | 3 +- .../UserInterface/BasicDebugInfoWindow.kt | 24 +- .../Terrarum/UserInterface/UIHandler.kt | 5 +- .../spriteAnimation/SpriteAnimation.java | 281 ------------ .../spriteAnimation/SpriteAnimation.kt | 261 ++++++++++++ 65 files changed, 1692 insertions(+), 2560 deletions(-) delete mode 100644 src/com/Torvald/Point/Point2f.java create mode 100644 src/com/Torvald/Point/Point2f.kt delete mode 100644 src/com/Torvald/Terrarum/Actors/Hitbox.java create mode 100644 src/com/Torvald/Terrarum/Actors/Hitbox.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/Echo.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/Echo.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/ExportAV.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/ExportAV.kt rename src/com/Torvald/Terrarum/ConsoleCommand/{ExportMap.java => ExportMap.kt} (51%) delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/ForceGC.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/ForceGC.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/GetAV.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/GetAV.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/GetFactioning.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/GetFactioning.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/GetLocale.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/GetLocale.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/GsonTest.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/GsonTest.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/QuitApp.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/QuitApp.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/SetAV.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/SetAV.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/SetBulletin.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/SetBulletin.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/SetLocale.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/SetLocale.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/SpawnPhysTestBall.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/SpawnPhysTestBall.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/TeleportPlayer.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/TeleportPlayer.kt delete mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/ToggleNoClip.java create mode 100644 src/com/Torvald/Terrarum/ConsoleCommand/ToggleNoClip.kt delete mode 100644 src/com/Torvald/Terrarum/Game delete mode 100644 src/com/Torvald/Terrarum/GameMap/GameMap.java create mode 100644 src/com/Torvald/Terrarum/GameMap/GameMap.kt delete mode 100644 src/com/Torvald/Terrarum/GameMap/MapLayer.java create mode 100644 src/com/Torvald/Terrarum/GameMap/MapLayer.kt delete mode 100644 src/com/Torvald/Terrarum/GameMap/MapPoint.java create mode 100644 src/com/Torvald/Terrarum/GameMap/MapPoint.kt delete mode 100644 src/com/Torvald/Terrarum/GameMap/PairedMapLayer.java create mode 100644 src/com/Torvald/Terrarum/GameMap/PairedMapLayer.kt delete mode 100644 src/com/Torvald/Terrarum/LangPack/Lang.java create mode 100644 src/com/Torvald/Terrarum/LangPack/Lang.kt delete mode 100644 src/com/Torvald/Terrarum/Terrarum delete mode 100644 src/com/Torvald/spriteAnimation/SpriteAnimation.java create mode 100644 src/com/Torvald/spriteAnimation/SpriteAnimation.kt diff --git a/res/graphics/sky_colour.png b/res/graphics/sky_colour.png index 9c5574f32ed4cb2c069689e8f48940e902520b10..240210244349b0bd6d41e270f5e76bf97b2a3a66 100644 GIT binary patch delta 2758 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 diff --git a/res/graphics/sprites/test_player.png b/res/graphics/sprites/test_player.png index 99a21e8e1c0e472651d7b269238d89b82058a6dd..d9a1c32de9b3d2f24dde387e9603e8393e6fe29b 100644 GIT binary patch delta 3299 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 delta 3181 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 diff --git a/res/graphics/terrain/terrain.png b/res/graphics/terrain/terrain.png index d4a10ca529404ef082c440a2281ad6c197af78d3..e847fef6ab38bcc02878524f6b5c59a71d1e27c8 100644 GIT binary patch delta 95301 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

#N|v$ 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 diff --git a/src/com/Torvald/JsonWriter.kt b/src/com/Torvald/JsonWriter.kt index 52563b523..c32f970a0 100644 --- a/src/com/Torvald/JsonWriter.kt +++ b/src/com/Torvald/JsonWriter.kt @@ -12,6 +12,12 @@ import java.io.IOException */ object JsonWriter { + /** + * Serialise a class to the file as JSON, using Google GSON. + * + * @param c: a class + * @param path: path to write a file + */ @Throws(IOException::class) fun writeToFile(c: Any, path: String) { val classElem = Gson().toJsonTree(c) @@ -21,6 +27,12 @@ object JsonWriter { writer.close() } + /** + * Serialise JsonObject to the file as JSON, using Google GSON. + * + * @param jsonObject + * @param path: path to write a file + */ @Throws(IOException::class) fun writeToFile(jsonObject: JsonObject, path: String) { val writer = FileWriter(path) diff --git a/src/com/Torvald/Point/Point2f.java b/src/com/Torvald/Point/Point2f.java deleted file mode 100644 index ad29004b0..000000000 --- a/src/com/Torvald/Point/Point2f.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.Torvald.Point; - -/** - * Created by minjaesong on 16-01-15. - */ -public class Point2f { - - private float x; - private float y; - - public Point2f(float x, float y) { - this.x = x; - this.y = y; - } - - public void set(float x, float y) { - this.x = x; - this.y = y; - } - - public float getX() { - return x; - } - - public float getY() { - return y; - } -} diff --git a/src/com/Torvald/Point/Point2f.kt b/src/com/Torvald/Point/Point2f.kt new file mode 100644 index 000000000..da5fb376c --- /dev/null +++ b/src/com/Torvald/Point/Point2f.kt @@ -0,0 +1,22 @@ +package com.Torvald.Point + +/** + * Created by minjaesong on 16-01-15. + */ +class Point2f(x: Float, y: Float) { + + var x: Float = 0.toFloat() + private set + var y: Float = 0.toFloat() + private set + + init { + this.x = x + this.y = y + } + + operator fun set(x: Float, y: Float) { + this.x = x + this.y = y + } +} diff --git a/src/com/Torvald/Terrarum/Actors/Hitbox.java b/src/com/Torvald/Terrarum/Actors/Hitbox.java deleted file mode 100644 index 6729accf4..000000000 --- a/src/com/Torvald/Terrarum/Actors/Hitbox.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.Torvald.Terrarum.Actors; - -import com.Torvald.Point.Point2f; - -/** - * Created by minjaesong on 16-01-15. - */ -public class Hitbox { - - private Point2f hitboxStart; - private Point2f hitboxEnd; - private float width; - private float height; - - public Hitbox(float x1, float y1, float width, float height) { - hitboxStart = new Point2f(x1, y1); - hitboxEnd = new Point2f(x1 + width, y1 + height); - this.width = width; - this.height = height; - } - - public Point2f getHitboxStart() { - return hitboxStart; - } - - public Point2f getHitboxEnd() { - return hitboxEnd; - } - - public float getWidth() { - return width; - } - - public float getHeight() { - return height; - } - - /** - * Returns bottom-centered point of hitbox. - * @return pointX - */ - public float getPointedX() { - return hitboxStart.getX() + (width / 2); - } - - /** - * Returns bottom-centered point of hitbox. - * @return pointY - */ - public float getPointedY() { - return hitboxEnd.getY(); - } - - /** - * Set to the point top left - * @param x1 - * @param y1 - * @param width - * @param height - */ - public void set(float x1, float y1, float width, float height) { - hitboxStart = new Point2f(x1, y1); - hitboxEnd = new Point2f(x1 + width, y1 + height); - this.width = width; - this.height = height; - } - - public void setPosition(float x1, float y1) { - hitboxStart = new Point2f(x1, y1); - hitboxEnd = new Point2f(x1 + width, y1 + height); - } - - public void setPositionX(float x) { - setPosition(x, getPosY()); - } - - public void setPositionY(float y) { - setPosition(getPosX(), y); - } - - public void setPositionFromPoint(float x1, float y1) { - hitboxStart = new Point2f(x1 - (width / 2), y1 - height); - hitboxEnd = new Point2f(hitboxStart.getX() + width, hitboxStart.getY() + height); - } - - public void setPositionXFromPoint(float x) { - setPositionFromPoint(x, getPointedY()); - } - - public void setPositionYFromPoint(float y) { - setPositionFromPoint(getPointedX(), y); - } - - public void translatePosX(float d) { - setPositionX(getPosX() + d); - } - - public void translatePosY(float d) { - setPositionY(getPosY() + d); - } - - public void setDimension(float w, float h) { - width = w; - height = h; - } - - /** - * Returns x value of start point - * @return top-left point posX - */ - public float getPosX() { - return hitboxStart.getX(); - } - - /** - * Returns y value of start point - * @return top-left point posY - */ - public float getPosY() { - return hitboxStart.getY(); - } - - public float getCenteredX() { - return (hitboxStart.getX() + hitboxEnd.getX()) * 0.5f; - } - - public float getCenteredY() { - return (hitboxStart.getY() + hitboxEnd.getY()) * 0.5f; - } -} diff --git a/src/com/Torvald/Terrarum/Actors/Hitbox.kt b/src/com/Torvald/Terrarum/Actors/Hitbox.kt new file mode 100644 index 000000000..8631ac807 --- /dev/null +++ b/src/com/Torvald/Terrarum/Actors/Hitbox.kt @@ -0,0 +1,115 @@ +package com.Torvald.Terrarum.Actors + +import com.Torvald.Point.Point2f + +/** + * Created by minjaesong on 16-01-15. + */ +class Hitbox(x1: Float, y1: Float, width: Float, height: Float) { + + var hitboxStart: Point2f + private set + var hitboxEnd: Point2f + private set + var width: Float = 0.toFloat() + private set + var height: Float = 0.toFloat() + private set + + init { + hitboxStart = Point2f(x1, y1) + hitboxEnd = Point2f(x1 + width, y1 + height) + this.width = width + this.height = height + } + + /** + * Returns bottom-centered point of hitbox. + * @return pointX + */ + val pointedX: Float + get() = hitboxStart.x + width / 2 + + /** + * Returns bottom-centered point of hitbox. + * @return pointY + */ + val pointedY: Float + get() = hitboxEnd.y + + /** + * Set to the point top left + * @param x1 + * * + * @param y1 + * * + * @param width + * * + * @param height + */ + operator fun set(x1: Float, y1: Float, width: Float, height: Float) { + hitboxStart = Point2f(x1, y1) + hitboxEnd = Point2f(x1 + width, y1 + height) + this.width = width + this.height = height + } + + fun setPosition(x1: Float, y1: Float) { + hitboxStart = Point2f(x1, y1) + hitboxEnd = Point2f(x1 + width, y1 + height) + } + + fun setPositionX(x: Float) { + setPosition(x, posY) + } + + fun setPositionY(y: Float) { + setPosition(posX, y) + } + + fun setPositionFromPoint(x1: Float, y1: Float) { + hitboxStart = Point2f(x1 - width / 2, y1 - height) + hitboxEnd = Point2f(hitboxStart.x + width, hitboxStart.y + height) + } + + fun setPositionXFromPoint(x: Float) { + setPositionFromPoint(x, pointedY) + } + + fun setPositionYFromPoint(y: Float) { + setPositionFromPoint(pointedX, y) + } + + fun translatePosX(d: Float) { + setPositionX(posX + d) + } + + fun translatePosY(d: Float) { + setPositionY(posY + d) + } + + fun setDimension(w: Float, h: Float) { + width = w + height = h + } + + /** + * Returns x value of start point + * @return top-left point posX + */ + val posX: Float + get() = hitboxStart.x + + /** + * Returns y value of start point + * @return top-left point posY + */ + val posY: Float + get() = hitboxStart.y + + val centeredX: Float + get() = (hitboxStart.x + hitboxEnd.x) * 0.5f + + val centeredY: Float + get() = (hitboxStart.y + hitboxEnd.y) * 0.5f +} diff --git a/src/com/Torvald/Terrarum/Actors/PFSigrid.kt b/src/com/Torvald/Terrarum/Actors/PFSigrid.kt index 5c363f051..282d86c57 100644 --- a/src/com/Torvald/Terrarum/Actors/PFSigrid.kt +++ b/src/com/Torvald/Terrarum/Actors/PFSigrid.kt @@ -26,7 +26,6 @@ object PFSigrid { p.sprite!!.setDelay(200) p.sprite!!.setRowsAndFrames(1, 1) p.sprite!!.setAsVisible() - p.sprite!!.composeSprite() p.spriteGlow = SpriteAnimation() p.spriteGlow!!.setDimension(28, 51) @@ -34,7 +33,6 @@ object PFSigrid { p.spriteGlow!!.setDelay(200) p.spriteGlow!!.setRowsAndFrames(1, 1) p.spriteGlow!!.setAsVisible() - p.spriteGlow!!.composeSprite() p.actorValue = ActorValue() p.actorValue.set("scale", 1.0f) diff --git a/src/com/Torvald/Terrarum/Actors/PhysTestBall.kt b/src/com/Torvald/Terrarum/Actors/PhysTestBall.kt index d4c009258..17c808645 100644 --- a/src/com/Torvald/Terrarum/Actors/PhysTestBall.kt +++ b/src/com/Torvald/Terrarum/Actors/PhysTestBall.kt @@ -17,9 +17,9 @@ class PhysTestBall : ActorWithBody { override fun drawBody(gc: GameContainer, g: Graphics) { g.color = Color.orange g.fillOval( - hitbox!!.getPosX(), - hitbox!!.getPosY(), - hitbox!!.getWidth(), - hitbox!!.getHeight()) + hitbox!!.posX, + hitbox!!.posY, + hitbox!!.width, + hitbox!!.height) } } \ No newline at end of file diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.java b/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.java deleted file mode 100644 index 418348a68..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Files; - -/** - * Created by minjaesong on 16-02-10. - */ -public class CatStdout implements ConsoleCommand { - @Override - public void execute(String[] args) { - - Echo echo = new Echo(); - - if (args.length == 1) { - printUsage(); - return; - } - - try { - Files.lines(FileSystems.getDefault().getPath(args[1])).forEach(echo::execute); - } - catch (IOException e) { - echo.execute("CatStdout: could not read file -- IOException"); - } - - } - - @Override - public void printUsage() { - new Echo().execute("usage: cat 'path/to/text/file"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.kt b/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.kt new file mode 100644 index 000000000..6ee8e12c7 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/CatStdout.kt @@ -0,0 +1,32 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import java.io.IOException +import java.nio.file.FileSystems +import java.nio.file.Files + +/** + * Created by minjaesong on 16-02-10. + */ +class CatStdout : ConsoleCommand { + override fun execute(args: Array) { + + val echo = Echo() + + if (args.size == 1) { + printUsage() + return + } + + try { + Files.lines(FileSystems.getDefault().getPath(args[1])).forEach({ echo.execute(it) }) + } + catch (e: IOException) { + echo.execute("CatStdout: could not read file -- IOException") + } + + } + + override fun printUsage() { + Echo().execute("usage: cat 'path/to/text/file") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/Echo.java b/src/com/Torvald/Terrarum/ConsoleCommand/Echo.java deleted file mode 100644 index d90cabb7f..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/Echo.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.Terrarum; -import com.Torvald.Terrarum.UserInterface.ConsoleWindow; - -import java.util.Arrays; - -/** - * Created by minjaesong on 16-01-16. - */ -class Echo implements ConsoleCommand { - @Override - public void execute(String[] args) { - String[] argsWoHeader = new String[args.length - 1]; - for (int i = 0; i < argsWoHeader.length; i++) - argsWoHeader[i] = args[i + 1]; - - Arrays.asList(argsWoHeader).forEach( - ((ConsoleWindow) Terrarum.game.consoleHandler.getUI())::sendMessage - ); - } - - public void execute(String single_line) { - ((ConsoleWindow) Terrarum.game.consoleHandler.getUI()) - .sendMessage(single_line); - } - - @Override - public void printUsage() { - - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/Echo.kt b/src/com/Torvald/Terrarum/ConsoleCommand/Echo.kt new file mode 100644 index 000000000..5b5d39b8f --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/Echo.kt @@ -0,0 +1,26 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.Terrarum +import com.Torvald.Terrarum.UserInterface.ConsoleWindow + +import java.util.Arrays + +/** + * Created by minjaesong on 16-01-16. + */ +internal class Echo : ConsoleCommand { + override fun execute(args: Array) { + val argsWoHeader = Array(args.size - 1, {it -> args[it + 1]}) + + argsWoHeader.forEach( + { (Terrarum.game.consoleHandler.UI as ConsoleWindow).sendMessage(it) }) + } + + fun execute(single_line: String) { + (Terrarum.game.consoleHandler.UI as ConsoleWindow).sendMessage(single_line) + } + + override fun printUsage() { + + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/ExportAV.java b/src/com/Torvald/Terrarum/ConsoleCommand/ExportAV.java deleted file mode 100644 index d625c5cb5..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/ExportAV.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.JsonWriter; -import com.Torvald.Terrarum.Terrarum; - -import java.io.IOException; - -/** - * Created by minjaesong on 16-02-10. - */ -public class ExportAV implements ConsoleCommand { - @Override - public void execute(String[] args) { - if (args.length == 2) { - try { - JsonWriter.INSTANCE.writeToFile(Terrarum.game.player.getActorValue() - , Terrarum.defaultDir + "/Exports/" + args[1] + ".json" - ); - - new Echo().execute("ExportAV: exported to " + args[1] + ".json"); - } - catch (IOException e) { - new Echo().execute("ExportAV: IOException raised."); - e.printStackTrace(); - } - } - else { - printUsage(); - } - } - - @Override - public void printUsage() { - Echo echo = new Echo(); - echo.execute("Export ActorValue as JSON format."); - echo.execute("Usage: exportav (id) filename-without-extension"); - echo.execute("blank ID for player"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/ExportAV.kt b/src/com/Torvald/Terrarum/ConsoleCommand/ExportAV.kt new file mode 100644 index 000000000..c37fe6828 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/ExportAV.kt @@ -0,0 +1,38 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.JsonWriter +import com.Torvald.Terrarum.Terrarum + +import java.io.IOException + +/** + * Created by minjaesong on 16-02-10. + */ +class ExportAV : ConsoleCommand { + override fun execute(args: Array) { + if (args.size == 2) { + try { + JsonWriter.writeToFile( + Terrarum.game.player.getActorValue(), + Terrarum.defaultDir + "/Exports/" + args[1] + ".json") + + Echo().execute("ExportAV: exported to " + args[1] + ".json") + } + catch (e: IOException) { + Echo().execute("ExportAV: IOException raised.") + e.printStackTrace() + } + + } + else { + printUsage() + } + } + + override fun printUsage() { + val echo = Echo() + echo.execute("Export ActorValue as JSON format.") + echo.execute("Usage: exportav (id) filename-without-extension") + echo.execute("blank ID for player") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.java b/src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.kt similarity index 51% rename from src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.java rename to src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.kt index 5df05bf63..79d84cbb2 100644 --- a/src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.java +++ b/src/com/Torvald/Terrarum/ConsoleCommand/ExportMap.kt @@ -1,3 +1,151 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.ColourUtil.Col4096 +import com.Torvald.RasterWriter +import com.Torvald.Terrarum.Terrarum + +import javax.imageio.ImageIO +import java.awt.* +import java.awt.color.ColorSpace +import java.awt.image.* +import java.io.* +import java.util.Hashtable + +/** + * Created by minjaesong on 16-01-17. + */ +class ExportMap : ConsoleCommand { + + //private var mapData: ByteArray? = null + // private var mapDataPointer = 0 + + private val colorTable = Hashtable() + + override fun execute(args: Array) { + if (args.size == 2) { + buildColorTable() + + var mapData = ByteArray(Terrarum.game.map.width * Terrarum.game.map.height * 3) + var mapDataPointer = 0 + + for (tile in Terrarum.game.map.layerTerrain) { + val colArray = (colorTable as java.util.Map) + .getOrDefault(tile, Col4096(0xFFF)).toByteArray() + + for (i in 0..2) { + mapData[mapDataPointer + i] = colArray[i] + } + + mapDataPointer += 3 + } + + val dir = Terrarum.defaultDir + "/Exports/" + val dirAsFile = File(dir) + if (!dirAsFile.exists()) { + dirAsFile.mkdir() + } + + try { + RasterWriter.writePNG_RGB( + Terrarum.game.map.width, Terrarum.game.map.height, mapData, dir + args[1] + ".png") + Echo().execute("ExportMap: exported to " + args[1] + ".png") + + } + catch (e: IOException) { + Echo().execute("ExportMap: IOException raised.") + e.printStackTrace() + } + + // mapData = null + // mapDataPointer = 0 + + // Free up some memory + System.gc() + } + else { + printUsage() + } + } + + override fun printUsage() { + val echo = Echo() + echo.execute("Usage: export ") + echo.execute("Exports current map into visible image.") + echo.execute("The image can be found at %adddata%/Terrarum/Exports") + } + + private fun buildColorTable() { + colorTable.put(AIR, Col4096(0xCEF)) + colorTable.put(STONE, Col4096(0x887)) + colorTable.put(DIRT, Col4096(0x763)) + colorTable.put(GRASS, Col4096(0x251)) + + colorTable.put(COPPER, Col4096(0x6A8)) + colorTable.put(IRON, Col4096(0xC75)) + colorTable.put(GOLD, Col4096(0xCB6)) + colorTable.put(ILMENITE, Col4096(0x8AB)) + colorTable.put(AURICHALCUM, Col4096(0xD92)) + colorTable.put(SILVER, Col4096(0xDDD)) + + colorTable.put(DIAMOND, Col4096(0x9CE)) + colorTable.put(RUBY, Col4096(0xB10)) + colorTable.put(EMERALD, Col4096(0x0B1)) + colorTable.put(SAPPHIRE, Col4096(0x01B)) + colorTable.put(TOPAZ, Col4096(0xC70)) + colorTable.put(AMETHYST, Col4096(0x70C)) + + colorTable.put(WATER, Col4096(0x038)) + colorTable.put(LAVA, Col4096(0xF50)) + + colorTable.put(SAND, Col4096(0xDCA)) + colorTable.put(GRAVEL, Col4096(0x664)) + + colorTable.put(ICE_NATURAL, Col4096(0x9AB)) + colorTable.put(ICE_MAGICAL, Col4096(0x7AC)) + colorTable.put(ICE_FRAGILE, Col4096(0x6AF)) + colorTable.put(SNOW, Col4096(0xCDE)) + + + } + + companion object { + + private val AIR: Byte = 0 + + private val STONE: Byte = 1 + private val DIRT: Byte = 2 + private val GRASS: Byte = 3 + + private val SAND: Byte = 13 + private val GRAVEL: Byte = 14 + + private val COPPER: Byte = 15 + private val IRON: Byte = 16 + private val GOLD: Byte = 17 + private val SILVER: Byte = 18 + private val ILMENITE: Byte = 19 + private val AURICHALCUM: Byte = 20 + + private val DIAMOND: Byte = 25 + private val RUBY: Byte = 21 + private val EMERALD: Byte = 22 + private val SAPPHIRE: Byte = 23 + private val TOPAZ: Byte = 24 + private val AMETHYST: Byte = 26 + + private val SNOW: Byte = 27 + private val ICE_FRAGILE: Byte = 28 + private val ICE_NATURAL: Byte = 29 + private val ICE_MAGICAL: Byte = 30 + + private val WATER = 239.toByte() + private val LAVA = 255.toByte() + } + +} + + +/* package com.Torvald.Terrarum.ConsoleCommand; import com.Torvald.ColourUtil.Col4096; @@ -144,3 +292,5 @@ public class ExportMap implements ConsoleCommand { } } + + */ \ No newline at end of file diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/ForceGC.java b/src/com/Torvald/Terrarum/ConsoleCommand/ForceGC.java deleted file mode 100644 index 4b0121491..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/ForceGC.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -/** - * Created by minjaesong on 16-01-18. - */ -public class ForceGC implements ConsoleCommand { - @Override - public void execute(String[] args) { - System.gc(); - new Echo().execute("Invoked System.gc"); - } - - @Override - public void printUsage() { - new Echo().execute("Invoke garbage collection of JVM."); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/ForceGC.kt b/src/com/Torvald/Terrarum/ConsoleCommand/ForceGC.kt new file mode 100644 index 000000000..b3d41afc6 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/ForceGC.kt @@ -0,0 +1,15 @@ +package com.Torvald.Terrarum.ConsoleCommand + +/** + * Created by minjaesong on 16-01-18. + */ +class ForceGC : ConsoleCommand { + override fun execute(args: Array) { + System.gc() + Echo().execute("Invoked System.gc") + } + + override fun printUsage() { + Echo().execute("Invoke garbage collection of JVM.") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/GetAV.java b/src/com/Torvald/Terrarum/ConsoleCommand/GetAV.java deleted file mode 100644 index 6902b8feb..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/GetAV.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.Actors.ActorValue; -import com.Torvald.Terrarum.Game; -import com.Torvald.Terrarum.Terrarum; - -import java.util.Iterator; -import java.util.Set; - -/** - * Created by minjaesong on 16-01-19. - */ -public class GetAV implements ConsoleCommand { - @Override - public void execute(String[] args) { - Echo echo = new Echo(); - - try { - if (args.length == 1) { - // print all actorvalue of player - ActorValue av = Terrarum.game.player.getActorValue(); - Set keyset = av.getKeySet(); - - keyset.forEach( - elem -> echo.execute(elem + " = " + av.get((String) elem)) - ); - - } - else if (args.length != 3 && args.length != 2) { - printUsage(); - } - else if (args.length == 2) { - echo.execute("player." + args[1] + " = " - + Terrarum.game.player.getActorValue().get(args[1]) - + " (" - + Terrarum.game.player.getActorValue().get(args[1]).getClass() - .getSimpleName() - + ")" - ); - } - else if (args.length == 3) { - - } - } - catch (NullPointerException e) { - if (args.length == 2) { - echo.execute(args[1] + ": actor value does not exist."); - } - else if (args.length == 3) { - echo.execute(args[2] + ": actor value does not exist."); - } - else { - throw new NullPointerException(); - } - } - } - - @Override - public void printUsage() { - Echo echo = new Echo(); - echo.execute("Get desired actor value of specific target."); - echo.execute("Usage: getav (id) "); - echo.execute("blank ID for player"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/GetAV.kt b/src/com/Torvald/Terrarum/ConsoleCommand/GetAV.kt new file mode 100644 index 000000000..51d96e7f1 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/GetAV.kt @@ -0,0 +1,57 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.Actors.ActorValue +import com.Torvald.Terrarum.Game +import com.Torvald.Terrarum.Terrarum + +/** + * Created by minjaesong on 16-01-19. + */ +class GetAV : ConsoleCommand { + override fun execute(args: Array) { + val echo = Echo() + + try { + if (args.size == 1) { + // print all actorvalue of player + val av = Terrarum.game.player.getActorValue() + val keyset = av.keySet + + keyset.forEach { elem -> echo.execute("$elem = ${av[elem as String]}") } + + } + else if (args.size != 3 && args.size != 2) { + printUsage() + } + else if (args.size == 2) { + echo.execute("player." + args[1] + " = " + + Terrarum.game.player.getActorValue()[args[1]] + + " (" + + Terrarum.game.player.getActorValue()[args[1]]!!.javaClass.simpleName + + ")") + } + else if (args.size == 3) { + + } + } + catch (e: NullPointerException) { + if (args.size == 2) { + echo.execute(args[1] + ": actor value does not exist.") + } + else if (args.size == 3) { + echo.execute(args[2] + ": actor value does not exist.") + } + else { + throw NullPointerException() + } + } + + } + + override fun printUsage() { + val echo = Echo() + echo.execute("Get desired actor value of specific target.") + echo.execute("Usage: getav (id) ") + echo.execute("blank ID for player") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/GetFactioning.java b/src/com/Torvald/Terrarum/ConsoleCommand/GetFactioning.java deleted file mode 100644 index e58532f85..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/GetFactioning.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.Actors.Faction.Faction; -import com.Torvald.Terrarum.LangPack.Lang; -import com.Torvald.Terrarum.Terrarum; - -import java.util.HashSet; - -/** - * Created by minjaesong on 16-02-17. - */ -public class GetFactioning implements ConsoleCommand { - - private final String PRINT_INDENTATION = " --> "; - - @Override - public void execute(String[] args) { - Echo echo = new Echo(); - - if (args.length == 1) { // get all factioning data of player - HashSet factionSet = Terrarum.game.player.getFaction(); - - if (factionSet == null) { - echo.execute("The actor has null faction set."); - return; - } - - int count = factionSet.size(); - echo.execute(String.valueOf(count) + Lang.pluralise(" faction", count) + " assigned."); - - for (Faction faction : factionSet) { - echo.execute("Faction \"" + faction.getFactionName() + "\""); - echo.execute(" Amicable"); - faction.getFactionAmicable().forEach( - s -> echo.execute(PRINT_INDENTATION + s) - ); - - echo.execute(" Explicit neutral"); - faction.getFactionNeutral().forEach( - s -> echo.execute(PRINT_INDENTATION + s) - ); - - echo.execute(" Hostile"); - faction.getFactionHostile().forEach( - s -> echo.execute(PRINT_INDENTATION + s) - ); - - echo.execute(" Fearful"); - faction.getFactionFearful().forEach( - s -> echo.execute(PRINT_INDENTATION + s) - ); - } - } - } - - @Override - public void printUsage() { - - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/GetFactioning.kt b/src/com/Torvald/Terrarum/ConsoleCommand/GetFactioning.kt new file mode 100644 index 000000000..7a2a7fd18 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/GetFactioning.kt @@ -0,0 +1,51 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.Actors.Faction.Faction +import com.Torvald.Terrarum.LangPack.Lang +import com.Torvald.Terrarum.Terrarum + +import java.util.HashSet + +/** + * Created by minjaesong on 16-02-17. + */ +class GetFactioning : ConsoleCommand { + + private val PRINT_INDENTATION = " --> " + + override fun execute(args: Array) { + val echo = Echo() + + if (args.size == 1) { + // get all factioning data of player + val factionSet = Terrarum.game.player.faction + + if (factionSet == null) { + echo.execute("The actor has null faction set.") + return + } + + val count = factionSet.size + echo.execute(count.toString() + Lang.pluralise(" faction", count) + " assigned.") + + for (faction in factionSet) { + echo.execute("Faction \"" + faction.factionName + "\"") + echo.execute(" Amicable") + faction.factionAmicable.forEach { s -> echo.execute(PRINT_INDENTATION + s) } + + echo.execute(" Explicit neutral") + faction.factionNeutral.forEach { s -> echo.execute(PRINT_INDENTATION + s) } + + echo.execute(" Hostile") + faction.factionHostile.forEach { s -> echo.execute(PRINT_INDENTATION + s) } + + echo.execute(" Fearful") + faction.factionFearful.forEach { s -> echo.execute(PRINT_INDENTATION + s) } + } + } + } + + override fun printUsage() { + + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/GetLocale.java b/src/com/Torvald/Terrarum/ConsoleCommand/GetLocale.java deleted file mode 100644 index bd1696c9d..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/GetLocale.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.LangPack.Lang; -import com.Torvald.Terrarum.Terrarum; - -/** - * Created by minjaesong on 16-01-22. - */ -public class GetLocale implements ConsoleCommand { - @Override - public void execute(String[] args) { - new Echo().execute( - "Locale: " - + Lang.get("LANGUAGE_THIS") - + " (" - + Lang.get("LANGUAGE_EN") - + ")" - ); - } - - @Override - public void printUsage() { - Echo echo = new Echo(); - echo.execute("Usage: getlocale"); - echo.execute("Get name of locale currently using."); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/GetLocale.kt b/src/com/Torvald/Terrarum/ConsoleCommand/GetLocale.kt new file mode 100644 index 000000000..eb3f8b908 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/GetLocale.kt @@ -0,0 +1,24 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.LangPack.Lang +import com.Torvald.Terrarum.Terrarum + +/** + * Created by minjaesong on 16-01-22. + */ +class GetLocale : ConsoleCommand { + override fun execute(args: Array) { + Echo().execute( + "Locale: " + + Lang.get("LANGUAGE_THIS") + + " (" + + Lang.get("LANGUAGE_EN") + + ")") + } + + override fun printUsage() { + val echo = Echo() + echo.execute("Usage: getlocale") + echo.execute("Get name of locale currently using.") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/GsonTest.java b/src/com/Torvald/Terrarum/ConsoleCommand/GsonTest.java deleted file mode 100644 index 2d23740d9..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/GsonTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.Terrarum; -import com.google.gson.Gson; -import com.google.gson.JsonElement; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; - -/** - * Created by minjaesong on 16-02-10. - */ -public class GsonTest implements ConsoleCommand { - @Override - public void execute(String[] args) { - if (args.length == 2) { - JsonElement avelem = new Gson().toJsonTree(Terrarum.game.player); - - String jsonString = avelem.toString(); - - BufferedWriter bufferedWriter; - FileWriter writer; - try { - writer = new FileWriter(Terrarum.defaultDir + "/Exports/" + args[1] + ".json"); - bufferedWriter = new BufferedWriter(writer); - - bufferedWriter.write(jsonString); - bufferedWriter.close(); - - new Echo().execute("GsonTest: exported to " + args[1] + ".json"); - } - catch (IOException e) { - new Echo().execute("GsonTest: IOException raised."); - e.printStackTrace(); - } - } - else { - printUsage(); - } - } - - @Override - public void printUsage() { - Echo echo = new Echo(); - echo.execute("Usage: gsontest filename-without-extension"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/GsonTest.kt b/src/com/Torvald/Terrarum/ConsoleCommand/GsonTest.kt new file mode 100644 index 000000000..13ed6898f --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/GsonTest.kt @@ -0,0 +1,47 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.Terrarum +import com.google.gson.Gson +import com.google.gson.JsonElement + +import java.io.BufferedWriter +import java.io.FileWriter +import java.io.IOException + +/** + * Created by minjaesong on 16-02-10. + */ +class GsonTest : ConsoleCommand { + override fun execute(args: Array) { + if (args.size == 2) { + val avelem = Gson().toJsonTree(Terrarum.game.player) + + val jsonString = avelem.toString() + + val bufferedWriter: BufferedWriter + val writer: FileWriter + try { + writer = FileWriter(Terrarum.defaultDir + "/Exports/" + args[1] + ".json") + bufferedWriter = BufferedWriter(writer) + + bufferedWriter.write(jsonString) + bufferedWriter.close() + + Echo().execute("GsonTest: exported to " + args[1] + ".json") + } + catch (e: IOException) { + Echo().execute("GsonTest: IOException raised.") + e.printStackTrace() + } + + } + else { + printUsage() + } + } + + override fun printUsage() { + val echo = Echo() + echo.execute("Usage: gsontest filename-without-extension") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/Help.kt b/src/com/Torvald/Terrarum/ConsoleCommand/Help.kt index 9f5f2d015..e042e38bc 100644 --- a/src/com/Torvald/Terrarum/ConsoleCommand/Help.kt +++ b/src/com/Torvald/Terrarum/ConsoleCommand/Help.kt @@ -15,6 +15,6 @@ class Help : ConsoleCommand { } override fun printUsage() { - Echo().execute("Prints some utility functions assigned to runction row of the keyboard.") + Echo().execute("Prints some utility functions assigned to function row of the keyboard.") } } \ No newline at end of file diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/QuitApp.java b/src/com/Torvald/Terrarum/ConsoleCommand/QuitApp.java deleted file mode 100644 index 11f25ef60..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/QuitApp.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -/** - * Created by minjaesong on 16-01-15. - */ -public class QuitApp implements ConsoleCommand { - - @Override - public void execute(String[] args) { - System.exit(1); - } - - @Override - public void printUsage() { - - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/QuitApp.kt b/src/com/Torvald/Terrarum/ConsoleCommand/QuitApp.kt new file mode 100644 index 000000000..ae1fe3013 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/QuitApp.kt @@ -0,0 +1,15 @@ +package com.Torvald.Terrarum.ConsoleCommand + +/** + * Created by minjaesong on 16-01-15. + */ +class QuitApp : ConsoleCommand { + + override fun execute(args: Array) { + System.exit(1) + } + + override fun printUsage() { + + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/SetAV.java b/src/com/Torvald/Terrarum/ConsoleCommand/SetAV.java deleted file mode 100644 index a73f5f2e4..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/SetAV.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.Game; -import com.Torvald.Terrarum.Terrarum; - -/** - * Created by minjaesong on 16-01-15. - */ -class SetAV implements ConsoleCommand { - - @Override - public void printUsage() { - Echo echo = new Echo(); - echo.execute("Set actor value of specific target to desired value."); - echo.execute("Usage: setav (id) "); - echo.execute("blank ID for player"); - } - - @Override - public void execute(String[] args) { - Echo echo = new Echo(); - - // setav - if (args.length != 4 && args.length != 3) { - printUsage(); - } - else if (args.length == 3) { - Object val; - - try { - val = new Integer(args[2]); // try for integer - } - catch (NumberFormatException e) { - - try { - val = new Float(args[2]); // try for float - } - catch (NumberFormatException ee) { - if (args[2].equalsIgnoreCase("__true")) { - val = new Boolean(true); - } - else if (args[2].equalsIgnoreCase("__false")) { - val = new Boolean(false); - } - else { - val = new String(args[2]); // string if not number - } - } - } - - Terrarum.game.player.getActorValue().set(args[1], val); - echo.execute("Set " + args[1] + " to " + val); - } - else if (args.length == 4) { - - } - - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/SetAV.kt b/src/com/Torvald/Terrarum/ConsoleCommand/SetAV.kt new file mode 100644 index 000000000..c542405ca --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/SetAV.kt @@ -0,0 +1,61 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.Game +import com.Torvald.Terrarum.Terrarum + +/** + * Created by minjaesong on 16-01-15. + */ +internal class SetAV : ConsoleCommand { + + override fun printUsage() { + val echo = Echo() + echo.execute("Set actor value of specific target to desired value.") + echo.execute("Usage: setav (id) ") + echo.execute("blank ID for player") + echo.execute("Contaminated (float -> string) actor value will crash the game,") + echo.execute(" so make it sure before you issue the command.") + echo.execute("Use '__true' and '__false' for boolean value.") + } + + override fun execute(args: Array) { + val echo = Echo() + + // setav + if (args.size != 4 && args.size != 3) { + printUsage() + } + else if (args.size == 3) { + val `val`: Any + + try { + `val` = Integer(args[2]) // try for integer + } + catch (e: NumberFormatException) { + + try { + `val` = args[2].toFloat() // try for float + } + catch (ee: NumberFormatException) { + if (args[2].equals("__true", ignoreCase = true)) { + `val` = true + } + else if (args[2].equals("__false", ignoreCase = true)) { + `val` = false + } + else { + `val` = args[2] // string if not number + } + } + + } + + Terrarum.game.player.getActorValue()[args[1]] = `val` + echo.execute("Set " + args[1] + " to " + `val`) + } + else if (args.size == 4) { + + } + + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/SetBulletin.java b/src/com/Torvald/Terrarum/ConsoleCommand/SetBulletin.java deleted file mode 100644 index b4368a6be..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/SetBulletin.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.LangPack.Lang; -import com.Torvald.Terrarum.Terrarum; -import com.Torvald.Terrarum.UserInterface.Notification; - -/** - * Created by minjaesong on 16-01-23. - */ -public class SetBulletin implements ConsoleCommand { - @Override - public void execute(String[] args) { - String[] testMsg = { - //Lang.get("ERROR_SAVE_CORRUPTED") - //, Lang.get("MENU_LABEL_CONTINUE_QUESTION") - "Bulletin test “Hello, world!”", - "世界一みんなの人気者 それは彼女のこと アシュリー 달이 차오른다 가자" - }; - send(testMsg); - } - - @Override - public void printUsage() { - - } - - /** - * Actually send notifinator - * @param message real message - */ - public void send(String[] message) { - Terrarum.game.sendNotification(message); - System.out.println("sent notifinator"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/SetBulletin.kt b/src/com/Torvald/Terrarum/ConsoleCommand/SetBulletin.kt new file mode 100644 index 000000000..a78054b6a --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/SetBulletin.kt @@ -0,0 +1,31 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.LangPack.Lang +import com.Torvald.Terrarum.Terrarum +import com.Torvald.Terrarum.UserInterface.Notification + +/** + * Created by minjaesong on 16-01-23. + */ +class SetBulletin : ConsoleCommand { + override fun execute(args: Array) { + val testMsg = arrayOf( + Lang["ERROR_SAVE_CORRUPTED"], + Lang["MENU_LABEL_CONTINUE_QUESTION"] + ) + send(testMsg) + } + + override fun printUsage() { + + } + + /** + * Actually send notifinator + * @param message real message + */ + fun send(message: Array) { + Terrarum.game.sendNotification(message) + println("sent notifinator") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/SetLocale.java b/src/com/Torvald/Terrarum/ConsoleCommand/SetLocale.java deleted file mode 100644 index 7c2b7220f..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/SetLocale.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.ImageFont.GameFontBase; -import com.Torvald.Terrarum.LangPack.Lang; -import com.Torvald.Terrarum.Terrarum; -import org.apache.commons.csv.CSVRecord; -import org.newdawn.slick.SlickException; - -import java.io.IOException; - -/** - * Created by minjaesong on 16-01-25. - */ -public class SetLocale implements ConsoleCommand { - @Override - public void execute(String[] args) { - if (args.length == 2) { - String prevLocale = Terrarum.Companion.getGameLocale(); - Terrarum.Companion.setGameLocale(args[1]); - try { - new Lang(); - new Echo().execute("Set locale to '" + Terrarum.Companion.getGameLocale() + "'."); - } - catch (IOException e) { - new Echo().execute("could not read lang file."); - Terrarum.Companion.setGameLocale(prevLocale); - } - } - else if (args.length == 1) { - Echo echo = new Echo(); - echo.execute("Locales:"); - - CSVRecord record = Lang.getRecord("LANGUAGE_ID"); - record.forEach(field -> echo.execute("] " + field)); - } - else { - printUsage(); - } - } - - @Override - public void printUsage() { - new Echo().execute("Usage: setlocale [locale]"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/SetLocale.kt b/src/com/Torvald/Terrarum/ConsoleCommand/SetLocale.kt new file mode 100644 index 000000000..08acbe7e2 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/SetLocale.kt @@ -0,0 +1,43 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.ImageFont.GameFontBase +import com.Torvald.Terrarum.LangPack.Lang +import com.Torvald.Terrarum.Terrarum +import org.apache.commons.csv.CSVRecord +import org.newdawn.slick.SlickException + +import java.io.IOException + +/** + * Created by minjaesong on 16-01-25. + */ +class SetLocale : ConsoleCommand { + override fun execute(args: Array) { + if (args.size == 2) { + val prevLocale = Terrarum.gameLocale + Terrarum.gameLocale = args[1] + try { + Echo().execute("Set locale to '" + Terrarum.gameLocale + "'.") + } + catch (e: IOException) { + Echo().execute("could not read lang file.") + Terrarum.gameLocale = prevLocale + } + + } + else if (args.size == 1) { + val echo = Echo() + echo.execute("Locales:") + + val record = Lang.getRecord("LANGUAGE_ID") + record.forEach { field -> echo.execute("] " + field) } + } + else { + printUsage() + } + } + + override fun printUsage() { + Echo().execute("Usage: setlocale [locale]") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/SpawnPhysTestBall.java b/src/com/Torvald/Terrarum/ConsoleCommand/SpawnPhysTestBall.java deleted file mode 100644 index d40b136c0..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/SpawnPhysTestBall.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.Actors.Actor; -import com.Torvald.Terrarum.Actors.ActorWithBody; -import com.Torvald.Terrarum.Actors.PhysTestBall; -import com.Torvald.Terrarum.MapDrawer.MapCamera; -import com.Torvald.Terrarum.Terrarum; - -/** - * Created by minjaesong on 16-03-05. - */ -public class SpawnPhysTestBall implements ConsoleCommand { - @Override - public void execute(String[] args) throws Exception { - if (args.length == 2) { - int mouseX = Terrarum.appgc.getInput().getMouseX(); - int mouseY = Terrarum.appgc.getInput().getMouseY(); - - float elasticity = new Float(args[1]); - - ActorWithBody ball = new PhysTestBall(); - ball.setPosition(mouseX + MapCamera.getCameraX() - , mouseY + MapCamera.getCameraY()); - ball.setElasticity(elasticity); - - Terrarum.game.addActor(ball); - } - else { - printUsage(); - } - } - - @Override - public void printUsage() { - new Echo().execute("usage: spawnball [elasticity]"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/SpawnPhysTestBall.kt b/src/com/Torvald/Terrarum/ConsoleCommand/SpawnPhysTestBall.kt new file mode 100644 index 000000000..b9669748a --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/SpawnPhysTestBall.kt @@ -0,0 +1,38 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.Actors.Actor +import com.Torvald.Terrarum.Actors.ActorWithBody +import com.Torvald.Terrarum.Actors.PhysTestBall +import com.Torvald.Terrarum.MapDrawer.MapCamera +import com.Torvald.Terrarum.Terrarum + +/** + * Created by minjaesong on 16-03-05. + */ +class SpawnPhysTestBall : ConsoleCommand { + @Throws(Exception::class) + override fun execute(args: Array) { + if (args.size == 2) { + val mouseX = Terrarum.appgc.input.mouseX + val mouseY = Terrarum.appgc.input.mouseY + + val elasticity = args[1].toFloat() + + val ball = PhysTestBall() + ball.setPosition( + (mouseX + MapCamera.cameraX).toFloat(), + (mouseY + MapCamera.cameraY).toFloat() + ) + ball.elasticity = elasticity + + Terrarum.game.addActor(ball) + } + else { + printUsage() + } + } + + override fun printUsage() { + Echo().execute("usage: spawnball [elasticity]") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/TeleportPlayer.java b/src/com/Torvald/Terrarum/ConsoleCommand/TeleportPlayer.java deleted file mode 100644 index cc4e8ccce..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/TeleportPlayer.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.Game; -import com.Torvald.Terrarum.MapDrawer.MapDrawer; -import com.Torvald.Terrarum.Terrarum; - -/** - * Created by minjaesong on 16-01-24. - */ -public class TeleportPlayer implements ConsoleCommand { - - @Override - public void execute(String[] args) { - if (args.length != 3) { - printUsage(); - } - else { - - int x, y; - try { - x = new Integer((args[1])) * MapDrawer.getTILE_SIZE() + (MapDrawer.getTILE_SIZE() / 2); - y = new Integer((args[2])) * MapDrawer.getTILE_SIZE() + (MapDrawer.getTILE_SIZE() / 2); - } - catch (NumberFormatException e) { - new Echo().execute("Wrong number input."); - return; - } - - Terrarum.game.player.setPosition(x, y); - } - } - - @Override - public void printUsage() { - new Echo().execute("Usage: teleport [x-tile] [y-tile]"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/TeleportPlayer.kt b/src/com/Torvald/Terrarum/ConsoleCommand/TeleportPlayer.kt new file mode 100644 index 000000000..d244eee5c --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/TeleportPlayer.kt @@ -0,0 +1,36 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.Game +import com.Torvald.Terrarum.MapDrawer.MapDrawer +import com.Torvald.Terrarum.Terrarum + +/** + * Created by minjaesong on 16-01-24. + */ +class TeleportPlayer : ConsoleCommand { + + override fun execute(args: Array) { + if (args.size != 3) { + printUsage() + } + else { + + val x: Int + val y: Int + try { + x = args[1].toInt() * MapDrawer.TILE_SIZE + MapDrawer.TILE_SIZE / 2 + y = args[2].toInt() * MapDrawer.TILE_SIZE + MapDrawer.TILE_SIZE / 2 + } + catch (e: NumberFormatException) { + Echo().execute("Wrong number input.") + return + } + + Terrarum.game.player.setPosition(x.toFloat(), y.toFloat()) + } + } + + override fun printUsage() { + Echo().execute("Usage: teleport [x-tile] [y-tile]") + } +} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/ToggleNoClip.java b/src/com/Torvald/Terrarum/ConsoleCommand/ToggleNoClip.java deleted file mode 100644 index 4d6efb387..000000000 --- a/src/com/Torvald/Terrarum/ConsoleCommand/ToggleNoClip.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.Torvald.Terrarum.ConsoleCommand; - -import com.Torvald.Terrarum.Game; -import com.Torvald.Terrarum.Terrarum; - -/** - * Created by minjaesong on 16-01-19. - */ -public class ToggleNoClip implements ConsoleCommand { - @Override - public void execute(String[] args) { - boolean status = Terrarum.game.player.isNoClip(); - - Terrarum.game.player.setNoClip(!status); - new Echo().execute("Set no-clip status to " + String.valueOf(!status)); - } - - @Override - public void printUsage() { - new Echo().execute("toggle no-clip status of player"); - } -} diff --git a/src/com/Torvald/Terrarum/ConsoleCommand/ToggleNoClip.kt b/src/com/Torvald/Terrarum/ConsoleCommand/ToggleNoClip.kt new file mode 100644 index 000000000..24dc5fb44 --- /dev/null +++ b/src/com/Torvald/Terrarum/ConsoleCommand/ToggleNoClip.kt @@ -0,0 +1,20 @@ +package com.Torvald.Terrarum.ConsoleCommand + +import com.Torvald.Terrarum.Game +import com.Torvald.Terrarum.Terrarum + +/** + * Created by minjaesong on 16-01-19. + */ +class ToggleNoClip : ConsoleCommand { + override fun execute(args: Array) { + val status = Terrarum.game.player.isNoClip() + + Terrarum.game.player.setNoClip(!status) + Echo().execute("Set no-clip status to " + (!status).toString()) + } + + override fun printUsage() { + Echo().execute("toggle no-clip status of player") + } +} diff --git a/src/com/Torvald/Terrarum/Game b/src/com/Torvald/Terrarum/Game deleted file mode 100644 index 34aec2639..000000000 --- a/src/com/Torvald/Terrarum/Game +++ /dev/null @@ -1,403 +0,0 @@ -package com.Torvald.Terrarum; - -import com.Torvald.Rand.HQRNG; -import com.Torvald.Terrarum.Actors.*; -import com.Torvald.Terrarum.ConsoleCommand.Authenticator; -import com.Torvald.Terrarum.ConsoleCommand.CommandDict; -import com.Torvald.Terrarum.GameControl.GameController; -import com.Torvald.Terrarum.GameControl.KeyMap; -import com.Torvald.Terrarum.GameMap.GameMap; -import com.Torvald.Terrarum.GameMap.WorldTime; -import com.Torvald.Terrarum.MapDrawer.LightmapRenderer; -import com.Torvald.Terrarum.MapDrawer.MapCamera; -import com.Torvald.Terrarum.MapDrawer.MapDrawer; -import com.Torvald.Terrarum.MapGenerator.MapGenerator; -import com.Torvald.Terrarum.MapGenerator.RoguelikeRandomiser; -import com.Torvald.Terrarum.TileProperties.TilePropCodex; -import com.Torvald.Terrarum.TileStat.TileStat; -import com.Torvald.Terrarum.UserInterface.*; -import com.jme3.math.FastMath; -import org.lwjgl.opengl.ARBShaderObjects; -import org.lwjgl.opengl.GL11; -import org.newdawn.slick.*; -import org.newdawn.slick.Graphics; -import org.newdawn.slick.fills.GradientFill; -import org.newdawn.slick.geom.Rectangle; -import org.newdawn.slick.state.BasicGameState; -import org.newdawn.slick.state.StateBasedGame; -import shader.Shader; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.InputStreamReader; -import java.lang.management.ManagementFactory; -import java.util.HashSet; - -/** - * Created by minjaesong on 15-12-30. - */ -public class Game extends BasicGameState { - - public static long memInUse; - public static long totalVMMem; - int game_mode = 0; - - public GameMap map; - - public HashSet actorContainer = new HashSet<>(); - public HashSet uiContainer = new HashSet<>(); - - public UIHandler consoleHandler; - public UIHandler debugWindow; - public UIHandler notifinator; - - Player player; - - private Image GRADIENT_IMAGE; - private Rectangle skyBox; - - public float screenZoom = 1.0f; - public final float ZOOM_MAX = 2.0f; - public final float ZOOM_MIN = 0.25f; - - private Shader shader12BitCol; - private Shader shaderBlurH; - private Shader shaderBlurV; - - public static Authenticator auth = new Authenticator(); - - public Game() throws SlickException { } - - - private boolean useShader; - private int shaderProgram = 0; - - - private final int ENV_COLTEMP_SUNRISE = 2500; - private final int ENV_SUNLIGHT_DELTA = MapDrawer.getENV_COLTEMP_NOON() - ENV_COLTEMP_SUNRISE; - - - @Override - public void init(GameContainer gameContainer, StateBasedGame stateBasedGame) throws - SlickException { - new GameController(); - KeyMap.build(); - GameController.setKeyMap(new KeyMap()); - - - shader12BitCol = Shader.makeShader("./res/4096.vrt", "./res/4096.frg"); - shaderBlurH = Shader.makeShader("./res/blurH.vrt", "./res/blur.frg"); - shaderBlurV = Shader.makeShader("./res/blurV.vrt", "./res/blur.frg"); - - - GRADIENT_IMAGE = new Image("res/graphics/sky_colour.png"); - skyBox = new Rectangle(0, 0, Terrarum.WIDTH, Terrarum.HEIGHT); - - new WorldTime(); - new TilePropCodex(); - // new ItemPropCodex() -- This is kotlin object and already initialised. - - map = new GameMap(8192, 2048); - map.setGravitation(9.8f); - - MapGenerator.attachMap(map); - MapGenerator.setSeed(0x51621D2); - //MapGenerator.setSeed(new HQRNG().nextLong()); - MapGenerator.generateMap(); - - RoguelikeRandomiser.setSeed(0x540198); - //RoguelikeRandomiser.setSeed(new HQRNG().nextLong()); - - - new CommandDict(); - - // add new player and put it to actorContainer - //player = new Player(); - player = PFSigrid.build(); - //player.setNoClip(true); - actorContainer.add(player); - - consoleHandler = new UIHandler(new ConsoleWindow()); - consoleHandler.setPosition(0, 0); - - debugWindow = new UIHandler(new BasicDebugInfoWindow()); - debugWindow.setPosition(0, 0); - - notifinator = new UIHandler(new Notification()); - notifinator.setPosition( - (Terrarum.WIDTH - notifinator.getUI().getWidth()) - / 2 - , Terrarum.HEIGHT - notifinator.getUI().getHeight() - ); - notifinator.setVisibility(true); - } - - public Player getPlayer() { - return player; - } - - @Override - public void update(GameContainer gc, StateBasedGame sbg, int delta_t) { - setAppTitle(); - - // GL at after_sunrise-noon_before_sunset - //map.setGlobalLight(); - - GameController.processInput(gc.getInput()); - - TileStat.update(); - - MapDrawer.update(gc, delta_t); - MapCamera.update(gc, delta_t); - - actorContainer.forEach(actor -> actor.update(gc, delta_t)); - actorContainer.forEach( - actor -> { - if (actor instanceof Visible) { - ((Visible) actor).updateBodySprite(gc, delta_t); - } - if (actor instanceof Glowing) { - ((Glowing) actor).updateGlowSprite(gc, delta_t); - } - } - ); - - uiContainer.forEach(ui -> ui.update(gc, delta_t)); - - notifinator.update(gc, delta_t); - - Terrarum.appgc.setVSync(Terrarum.appgc.getFPS() >= Terrarum.VSYNC_TRIGGER_THRESHOLD); - } - - private void setAppTitle() { - Runtime runtime = Runtime.getRuntime(); - memInUse = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage().getUsed() >> 20; - totalVMMem = runtime.maxMemory() >> 20; - - Terrarum.appgc.setTitle( - "Simple Slick Game — FPS: " - + Terrarum.appgc.getFPS() + " (" - + String.valueOf(Terrarum.TARGET_INTERNAL_FPS) - + ") — " - + String.valueOf(memInUse) + "M / " - + String.valueOf(totalVMMem) + "M" - ); - } - - @Override - public void render(GameContainer gc, StateBasedGame sbg, Graphics g) { - - drawSkybox(g); - - // compensate for zoom. UIs have to be treated specially! (see UIHandler) - g.translate( - -MapCamera.getCameraX() * screenZoom - , -MapCamera.getCameraY() * screenZoom - ); - - MapCamera.renderBehind(gc, g); - - actorContainer.forEach( - actor -> { if (actor instanceof Visible) ((Visible) actor).drawBody(gc, g); } - ); - actorContainer.forEach( - actor -> { if (actor instanceof Glowing) ((Glowing) actor).drawGlow(gc, g); } - ); - - LightmapRenderer.renderLightMap(); - - MapCamera.renderFront(gc, g); - MapDrawer.render(gc, g); - - setBlendModeMul(); - MapDrawer.drawEnvOverlay(g); - LightmapRenderer.draw(g); - setBlendModeNormal(); - - uiContainer.forEach(ui -> ui.render(gc, g)); - debugWindow.render(gc, g); - consoleHandler.render(gc, g); - notifinator.render(gc, g); - } - - public boolean addActor(Actor e) { - return actorContainer.add(e); - } - - public boolean removeActor(Actor e) { - return actorContainer.remove(e); - } - - private Color[] getGradientColour(int timeSec) { - Color[] colourTable = new Color[2]; - - int gradMapWidth = GRADIENT_IMAGE.getWidth(); - int phase = Math.round((timeSec / WorldTime.DAY_LENGTH) * gradMapWidth); - - //update in every INTERNAL_FRAME frames - colourTable[0] = GRADIENT_IMAGE.getColor(phase, 0); - colourTable[1] = GRADIENT_IMAGE.getColor(phase, 1); - - return colourTable; - } - - public void keyPressed(int key, char c) { - GameController.keyPressed(key, c); - } - - public void keyReleased(int key, char c) { - GameController.keyReleased(key, c); - } - - public void mouseMoved(int oldx, int oldy, int newx, int newy) { - GameController.mouseMoved(oldx, oldy, newx, newy); - } - - public void mouseDragged(int oldx, int oldy, int newx, int newy) { - GameController.mouseDragged(oldx, oldy, newx, newy); - } - - public void mousePressed(int button, int x, int y) { - GameController.mousePressed(button, x, y); - } - - public void mouseReleased(int button, int x, int y) { - GameController.mouseReleased(button, x, y); - } - - public void mouseWheelMoved(int change) { - GameController.mouseWheelMoved(change); - } - - public void controllerButtonPressed(int controller, int button) { - GameController.controllerButtonPressed(controller, button); - } - - public void controllerButtonReleased(int controller, int button) { - GameController.controllerButtonReleased(controller, button); - } - - @Override - public int getID() { - return Terrarum.SCENE_ID_GAME; - } - - private void drawSkybox(Graphics g) { - Color[] colourTable = getGradientColour(Terrarum.game.map.getWorldTime().elapsedSeconds()); - GradientFill skyColourFill = new GradientFill(0, 0, colourTable[0], 0, Terrarum.HEIGHT, colourTable[1]); - g.fill(skyBox, skyColourFill); - } - - private void setBlendModeMul() { - GL11.glEnable(GL11.GL_BLEND); - GL11.glBlendFunc(GL11.GL_DST_COLOR, GL11.GL_ONE_MINUS_SRC_ALPHA); - } - - private void setBlendModeNormal() { - GL11.glDisable(GL11.GL_BLEND); - Terrarum.appgc.getGraphics().setDrawMode(Graphics.MODE_NORMAL); - } - - public void sendNotification(String[] msg) { - ((Notification) notifinator.getUI()).sendNotification(msg); - } - - private int createShader(String filename, int shaderType) throws Exception { - int shader = 0; - try { - shader = ARBShaderObjects.glCreateShaderObjectARB(shaderType); - - if(shader == 0) - return 0; - - ARBShaderObjects.glShaderSourceARB(shader, readFileAsString(filename)); - ARBShaderObjects.glCompileShaderARB(shader); - - if (ARBShaderObjects.glGetObjectParameteriARB(shader, ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB) == GL11.GL_FALSE) - throw new RuntimeException("Error creating shader: " + getLogInfo(shader)); - - return shader; - } - catch(Exception exc) { - ARBShaderObjects.glDeleteObjectARB(shader); - throw exc; - } - } - - private static String getLogInfo(int obj) { - return ARBShaderObjects.glGetInfoLogARB(obj, ARBShaderObjects.glGetObjectParameteriARB(obj, ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB)); - } - - private String readFileAsString(String filename) throws Exception { - StringBuilder source = new StringBuilder(); - - FileInputStream in = new FileInputStream(filename); - - Exception exception = null; - - BufferedReader reader; - try{ - reader = new BufferedReader(new InputStreamReader(in,"UTF-8")); - - Exception innerExc= null; - try { - String line; - while((line = reader.readLine()) != null) - source.append(line).append('\n'); - } - catch(Exception exc) { - exception = exc; - } - finally { - try { - reader.close(); - } - catch(Exception exc) { - if(innerExc == null) - innerExc = exc; - else - exc.printStackTrace(); - } - } - - if(innerExc != null) - throw innerExc; - } - catch(Exception exc) { - exception = exc; - } - finally { - try { - in.close(); - } - catch(Exception exc) { - if(exception == null) - exception = exc; - else - exc.printStackTrace(); - } - - if(exception != null) - throw exception; - } - - return source.toString(); - } - - public long getMemInUse() { - return memInUse; - } - - public long getTotalVMMem() { - return totalVMMem; - } - - private int getSunlightColtemp() { - int half_today = WorldTime.DAY_LENGTH / 2; - int timeToday = WorldTime.elapsedSeconds(); - float sunAlt = (timeToday < half_today) ? - timeToday / half_today * FastMath.PI - : 0f; - return Math.round(ENV_COLTEMP_SUNRISE + (ENV_SUNLIGHT_DELTA * FastMath.sin(sunAlt))); - } -} diff --git a/src/com/Torvald/Terrarum/Game.kt b/src/com/Torvald/Terrarum/Game.kt index 2466e9246..3d5c3e631 100644 --- a/src/com/Torvald/Terrarum/Game.kt +++ b/src/com/Torvald/Terrarum/Game.kt @@ -185,7 +185,7 @@ constructor() : BasicGameState() { // compensate for zoom. UIs have to be treated specially! (see UIHandler) g.translate( - -MapCamera.getCameraX() * screenZoom, -MapCamera.getCameraY() * screenZoom) + -MapCamera.cameraX * screenZoom, -MapCamera.cameraY * screenZoom) MapCamera.renderBehind(gc, g) @@ -305,7 +305,5 @@ constructor() : BasicGameState() { /** * extension function for org.newdawn.slick.Color */ - fun Color.getRGB24(): Int = (this.redByte shl 16) or - (this.greenByte shl 8) or - (this.blueByte) + fun Color.getRGB24(): Int = (this.redByte shl 16) or (this.greenByte shl 8) or (this.blueByte) } diff --git a/src/com/Torvald/Terrarum/GameControl/GameController.kt b/src/com/Torvald/Terrarum/GameControl/GameController.kt index 05dca0526..b3e44d330 100644 --- a/src/com/Torvald/Terrarum/GameControl/GameController.kt +++ b/src/com/Torvald/Terrarum/GameControl/GameController.kt @@ -16,8 +16,8 @@ import org.newdawn.slick.Input object GameController { fun processInput(input: Input) { - val mouseTileX = ((MapCamera.getCameraX() + input.mouseX / Terrarum.game.screenZoom) / MapDrawer.TILE_SIZE).toInt() - val mouseTileY = ((MapCamera.getCameraY() + input.mouseY / Terrarum.game.screenZoom) / MapDrawer.TILE_SIZE).toInt() + val mouseTileX = ((MapCamera.cameraX + input.mouseX / Terrarum.game.screenZoom) / MapDrawer.TILE_SIZE).toInt() + val mouseTileY = ((MapCamera.cameraY + input.mouseY / Terrarum.game.screenZoom) / MapDrawer.TILE_SIZE).toInt() KeyToggler.update(input) diff --git a/src/com/Torvald/Terrarum/GameMap/GameMap.java b/src/com/Torvald/Terrarum/GameMap/GameMap.java deleted file mode 100644 index 7125ff7ce..000000000 --- a/src/com/Torvald/Terrarum/GameMap/GameMap.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * MapLoader version 1.2 - * Release date 2013-05-20 - * Copyright 2013 SKYHi14 - * - * The program is distributed in GNU GPL Licence version 3. - * See http://www.gnu.org/licenses/gpl.html for information. - */ - -package com.Torvald.Terrarum.GameMap; - -import org.newdawn.slick.SlickException; - -public class GameMap { - - //layers - private volatile MapLayer layerWall; - private volatile MapLayer layerTerrain; - private volatile MapLayer layerWire; - private volatile PairedMapLayer wallDamage; - private volatile PairedMapLayer terrainDamage; - - //properties - private int width; - private int height; - private int spawnX; - private int spawnY; - - public static transient final int WALL = 0; - public static transient final int TERRAIN = 1; - public static transient final int WIRE = 2; - - //public World physWorld = new World( new Vec2(0, -TerrarumMain.game.gravitationalAccel) ); - //physics - private float gravitation; - private int globalLight; - private WorldTime worldTime; - - public static transient final int TILES_SUPPORTED = MapLayer.RANGE * PairedMapLayer.RANGE; - public static transient final byte BITS = 1; // 1 for Byte, 2 for Char, 4 for Int, 8 for Long - public static transient final byte LAYERS = 4; // terrain, wall (terrainDamage + wallDamage), wire - - /** - * @param width - * @param height - * @throws SlickException - */ - public GameMap(int width, int height) throws SlickException { - this.width = width; - this.height = height; - this.spawnX = width / 2; - this.spawnY = 200; - - layerTerrain = new MapLayer(width, height); - layerWall = new MapLayer(width, height); - layerWire = new MapLayer(width, height); - terrainDamage = new PairedMapLayer(width, height); - wallDamage = new PairedMapLayer(width, height); - - globalLight = (char) 0; - worldTime = new WorldTime(); - } - - public void setGravitation(float g) { - gravitation = g; - } - - /** - * Get 2d array data of terrain - * - * @return byte[][] terrain layer - */ - public byte[][] getTerrainArray() { - return layerTerrain.data; - } - - /** - * Get 2d array data of wall - * - * @return byte[][] wall layer - */ - public byte[][] getWallArray() { - return layerWall.data; - } - - /** - * Get 2d array data of wire - * - * @return byte[][] wire layer - */ - public byte[][] getWireArray() { - return layerWire.data; - } - - /** - * Get paired array data of damage codes. - * Format: 0baaaabbbb, aaaa for x = 0, 2, 4, ..., bbbb for x = 1, 3, 5, ... - * @return byte[][] damage code pair - */ - public byte[][] getDamageDataArray() { - return terrainDamage.dataPair; - } - - /** - * Get MapLayer object of terrain - * - * @return MapLayer terrain layer - */ - public MapLayer getLayerTerrain() { - return layerTerrain; - } - - public MapLayer getLayerWall() { - return layerWall; - } - - public MapLayer getLayerWire() { - return layerWire; - } - - public PairedMapLayer getTerrainDamage() { - return terrainDamage; - } - - public PairedMapLayer getWallDamage() { - return wallDamage; - } - - public int getTileFromWall(int x, int y) { - return layerWall.getTile(x, y) * PairedMapLayer.RANGE + getWallDamage(x, y); - } - - public int getTileFromTerrain(int x, int y) { - return layerTerrain.getTile(x, y) * PairedMapLayer.RANGE + getTerrainDamage(x, y); - } - - public int getTileFromWire(int x, int y) { - return layerWire.getTile(x, y); - } - - public int getWallDamage(int x, int y) { - return wallDamage.getData(x, y); - } - - public int getTerrainDamage(int x, int y) { - return terrainDamage.getData(x, y); - } - - /** - * Set the tile of wall as specified, with damage value of zero. - * @param x - * @param y - * @param combinedTilenum (tilenum * 16) + damage - */ - public void setTileWall(int x, int y, int combinedTilenum) { - setTileWall(x, y - , (byte) (combinedTilenum / PairedMapLayer.RANGE) - , combinedTilenum % PairedMapLayer.RANGE); - } - - /** - * Set the tile of wall as specified, with damage value of zero. - * @param x - * @param y - * @param combinedTilenum (tilenum * 16) + damage - */ - public void setTileTerrain(int x, int y, int combinedTilenum) { - setTileTerrain(x, y - , (byte) (combinedTilenum / PairedMapLayer.RANGE) - , combinedTilenum % PairedMapLayer.RANGE); - } - - public void setTileWall(int x, int y, byte tile, int damage) { - layerWall.setTile(x, y, tile); - wallDamage.setData(x, y, damage); - } - - public void setTileTerrain(int x, int y, byte tile, int damage) { - layerTerrain.setTile(x, y, tile); - terrainDamage.setData(x, y, damage); - } - - public void setTileWire(int x, int y, byte tile) { - layerWire.data[y][x] = tile; - } - - public int getTileFrom(int mode, int x, int y) { - if (mode == TERRAIN) { return getTileFromTerrain(x, y); } - else if (mode == WALL) { return getTileFromWall(x, y); } - else if (mode == WIRE) { return getTileFromWire(x, y); } - else throw new IllegalArgumentException("illegal mode input: " + String.valueOf(mode)); - } - - public void overwriteLayerWall(MapLayer layerData) { - layerWall = layerData; - } - - public void overwriteLayerTerrain(MapLayer layerData) { - layerTerrain = layerData; - } - - private int uint8ToInt32(byte x) { - int ret; - if ((x & 0b1000_0000) != 0) { - ret = x & 0b1111_1111; - } else { - ret = x; - } - return ret; - } - - public float getGravitation() { - return gravitation; - } - - public int getGlobalLight() { - return globalLight; - } - - public void setGlobalLight(int globalLight) { - this.globalLight = globalLight; - } - - public WorldTime getWorldTime() { - return worldTime; - } - - public void updateWorldTime(int delta) { - worldTime.update(delta); - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public int getSpawnX() { - return spawnX; - } - - public int getSpawnY() { - return spawnY; - } -} \ No newline at end of file diff --git a/src/com/Torvald/Terrarum/GameMap/GameMap.kt b/src/com/Torvald/Terrarum/GameMap/GameMap.kt new file mode 100644 index 000000000..44a529569 --- /dev/null +++ b/src/com/Torvald/Terrarum/GameMap/GameMap.kt @@ -0,0 +1,178 @@ +/* + * MapLoader version 1.2 + * Release date 2013-05-20 + * Copyright 2013 SKYHi14 + * + * The program is distributed in GNU GPL Licence version 3. + * See http://www.gnu.org/licenses/gpl.html for information. + */ + +package com.Torvald.Terrarum.GameMap + +import org.newdawn.slick.SlickException + +class GameMap +/** + * @param width + * * + * @param height + * * + * @throws SlickException + */ +@Throws(SlickException::class) +constructor(//properties + val width: Int, val height: Int) { + + //layers + val layerWall: MapLayer + /** + * Get MapLayer object of terrain + + * @return MapLayer terrain layer + */ + val layerTerrain: MapLayer + val layerWire: MapLayer + val wallDamage: PairedMapLayer + val terrainDamage: PairedMapLayer + val spawnX: Int + val spawnY: Int + + //public World physWorld = new World( new Vec2(0, -TerrarumMain.game.gravitationalAccel) ); + //physics + var gravitation: Float = 0.toFloat() + var globalLight: Int = 0 + val worldTime: WorldTime + + init { + this.spawnX = width / 2 + this.spawnY = 200 + + layerTerrain = MapLayer(width, height) + layerWall = MapLayer(width, height) + layerWire = MapLayer(width, height) + terrainDamage = PairedMapLayer(width, height) + wallDamage = PairedMapLayer(width, height) + + globalLight = 0.toChar().toInt() + worldTime = WorldTime() + } + + /** + * Get 2d array data of terrain + + * @return byte[][] terrain layer + */ + val terrainArray: Array + get() = layerTerrain.data + + /** + * Get 2d array data of wall + + * @return byte[][] wall layer + */ + val wallArray: Array + get() = layerWall.data + + /** + * Get 2d array data of wire + + * @return byte[][] wire layer + */ + val wireArray: Array + get() = layerWire.data + + /** + * Get paired array data of damage codes. + * Format: 0baaaabbbb, aaaa for x = 0, 2, 4, ..., bbbb for x = 1, 3, 5, ... + * @return byte[][] damage code pair + */ + val damageDataArray: Array + get() = terrainDamage.dataPair + + fun getTileFromWall(x: Int, y: Int): Int { + return layerWall.getTile(x, y) * PairedMapLayer.RANGE + getWallDamage(x, y) + } + + fun getTileFromTerrain(x: Int, y: Int): Int { + return layerTerrain.getTile(x, y) * PairedMapLayer.RANGE + getTerrainDamage(x, y) + } + + fun getTileFromWire(x: Int, y: Int): Int { + return layerWire.getTile(x, y) + } + + fun getWallDamage(x: Int, y: Int): Int { + return wallDamage.getData(x, y) + } + + fun getTerrainDamage(x: Int, y: Int): Int { + return terrainDamage.getData(x, y) + } + + /** + * Set the tile of wall as specified, with damage value of zero. + * @param x + * * + * @param y + * * + * @param combinedTilenum (tilenum * 16) + damage + */ + fun setTileWall(x: Int, y: Int, combinedTilenum: Int) { + setTileWall(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) + } + + /** + * Set the tile of wall as specified, with damage value of zero. + * @param x + * * + * @param y + * * + * @param combinedTilenum (tilenum * 16) + damage + */ + fun setTileTerrain(x: Int, y: Int, combinedTilenum: Int) { + setTileTerrain(x, y, (combinedTilenum / PairedMapLayer.RANGE).toByte(), combinedTilenum % PairedMapLayer.RANGE) + } + + fun setTileWall(x: Int, y: Int, tile: Byte, damage: Int) { + layerWall.setTile(x, y, tile) + wallDamage.setData(x, y, damage) + } + + fun setTileTerrain(x: Int, y: Int, tile: Byte, damage: Int) { + layerTerrain.setTile(x, y, tile) + terrainDamage.setData(x, y, damage) + } + + fun setTileWire(x: Int, y: Int, tile: Byte) { + layerWire.data[y][x] = tile + } + + fun getTileFrom(mode: Int, x: Int, y: Int): Int { + if (mode == TERRAIN) { + return getTileFromTerrain(x, y) + } + else if (mode == WALL) { + return getTileFromWall(x, y) + } + else if (mode == WIRE) { + return getTileFromWire(x, y) + } + else + throw IllegalArgumentException("illegal mode input: " + mode.toString()) + } + + fun updateWorldTime(delta: Int) { + worldTime.update(delta) + } + + companion object { + + @Transient val WALL = 0 + @Transient val TERRAIN = 1 + @Transient val WIRE = 2 + + @Transient val TILES_SUPPORTED = MapLayer.RANGE * PairedMapLayer.RANGE + @Transient val BITS: Byte = 1 // 1 for Byte, 2 for Char, 4 for Int, 8 for Long + @Transient val LAYERS: Byte = 4 // terrain, wall (terrainDamage + wallDamage), wire + } +} \ No newline at end of file diff --git a/src/com/Torvald/Terrarum/GameMap/MapLayer.java b/src/com/Torvald/Terrarum/GameMap/MapLayer.java deleted file mode 100644 index 203abc6ac..000000000 --- a/src/com/Torvald/Terrarum/GameMap/MapLayer.java +++ /dev/null @@ -1,126 +0,0 @@ -package com.Torvald.Terrarum.GameMap; - -import java.io.Serializable; -import java.util.Iterator; -import java.util.Spliterator; -import java.util.function.Consumer; - -/** - * Created by minjaesong on 16-01-17. - */ -public class MapLayer implements Iterable { - - byte[][] data; - - public int width; - public int height; - - public static transient final int RANGE = 256; - - public MapLayer(int width, int height) { - this.width = width; - this.height = height; - - data = new byte[height][width]; - - for (int i = 0; i < height; i++) { - for (int j = 0; j < width; j++) { - data[i][j] = 0; - } - } - } - - /** - * Returns an iterator over elements of type {@code T}. - * - * @return an Iterator. - */ - @Override - public Iterator iterator() { - return new Iterator() { - - private int iteratorCount = 0; - - @Override - public boolean hasNext() { - return iteratorCount < width * height; - } - - @Override - public Byte next() { - int y = iteratorCount / width; - int x = iteratorCount % width; - // advance counter - iteratorCount += 1; - - return data[y][x]; - } - }; - } - - /** - * Performs the given action for each element of the {@code Iterable} - * until all elements have been processed or the action throws an - * exception. Unless otherwise specified by the implementing class, - * actions are performed in the order of iteration (if an iteration order - * is specified). Exceptions thrown by the action are relayed to the - * caller. - * - * @param action The action to be performed for each element - * @throws NullPointerException if the specified action is null - * @implSpec

The default implementation behaves as if: - *

{@code
-     *     for (T t : this)
-     *         action.accept(t);
-     * }
- * @since 1.8 - */ - @Override - public void forEach(Consumer action) { - for (Byte b : this) { - action.accept(b); - } - } - - /** - * Creates a {@link java.util.Spliterator} over the elements described by this - * {@code Iterable}. - * - * @return a {@code Spliterator} over the elements described by this - * {@code Iterable}. - * @implSpec The default implementation creates an - *
early-binding - * spliterator from the iterable's {@code Iterator}. The spliterator - * inherits the fail-fast properties of the iterable's iterator. - * @implNote The default implementation should usually be overridden. The - * spliterator returned by the default implementation has poor splitting - * capabilities, is unsized, and does not report any spliterator - * characteristics. Implementing classes can nearly always provide a - * better implementation. - * @since 1.8 - */ - @Override - public Spliterator spliterator() { - throw new UnsupportedOperationException(); - } - - int getTile(int x, int y) { - return uint8ToInt32(data[y][x]); - } - - void setTile(int x, int y, byte tile) { - data[y][x] = tile; - } - - private int uint8ToInt32(byte x) { - int ret; - if ((x & 0b1000_0000) != 0) { - ret = (x & 0b0111_1111) | (x & 0b1000_0000); - } - else { - ret = x; - } - return ret; - } -} - diff --git a/src/com/Torvald/Terrarum/GameMap/MapLayer.kt b/src/com/Torvald/Terrarum/GameMap/MapLayer.kt new file mode 100644 index 000000000..2c89c3942 --- /dev/null +++ b/src/com/Torvald/Terrarum/GameMap/MapLayer.kt @@ -0,0 +1,58 @@ +package com.Torvald.Terrarum.GameMap + +import java.io.Serializable +import java.util.Spliterator +import java.util.function.Consumer + +/** + * Created by minjaesong on 16-01-17. + */ +class MapLayer(var width: Int, var height: Int) : Iterable { + + internal var data: Array + + init { + data = Array(height) { ByteArray(width) } + } + + /** + * Returns an iterator over elements of type `T`. + + * @return an Iterator. + */ + override fun iterator(): Iterator { + return object : Iterator { + + private var iteratorCount = 0 + + override fun hasNext(): Boolean { + return iteratorCount < width * height + } + + override fun next(): Byte { + val y = iteratorCount / width + val x = iteratorCount % width + // advance counter + iteratorCount += 1 + + return data[y][x] + } + } + } + + internal fun getTile(x: Int, y: Int): Int { + return uint8ToInt32(data[y][x]) + } + + internal fun setTile(x: Int, y: Int, tile: Byte) { + data[y][x] = tile + } + + private fun uint8ToInt32(x: Byte): Int = java.lang.Byte.toUnsignedInt(x) + + companion object { + + @Transient @JvmStatic val RANGE = 256 + } +} + diff --git a/src/com/Torvald/Terrarum/GameMap/MapPoint.java b/src/com/Torvald/Terrarum/GameMap/MapPoint.java deleted file mode 100644 index 8b1a134dd..000000000 --- a/src/com/Torvald/Terrarum/GameMap/MapPoint.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.Torvald.Terrarum.GameMap; - -import com.Torvald.Point.Point2f; - -import java.io.Serializable; - - -public class MapPoint { - private Point2f startPoint; - private Point2f endPoint; - - public MapPoint(){ - - } - - public MapPoint(Point2f p1, Point2f p2){ - setPoint(p1, p2); - } - - public MapPoint(int x1, int y1, int x2, int y2){ - setPoint(x1, y1, x2, y2); - } - - public void setPoint(Point2f p1, Point2f p2){ - startPoint = p1; - endPoint = p2; - } - - public void setPoint(int x1, int y1, int x2, int y2){ - startPoint = new Point2f(x1, y1); - endPoint = new Point2f(x2, y2); - } - - public Point2f getStartPoint(){ - return startPoint; - } - - public Point2f getEndPoint(){ - return endPoint; - } -} diff --git a/src/com/Torvald/Terrarum/GameMap/MapPoint.kt b/src/com/Torvald/Terrarum/GameMap/MapPoint.kt new file mode 100644 index 000000000..a449e2370 --- /dev/null +++ b/src/com/Torvald/Terrarum/GameMap/MapPoint.kt @@ -0,0 +1,35 @@ +package com.Torvald.Terrarum.GameMap + +import com.Torvald.Point.Point2f + +import java.io.Serializable + + +class MapPoint { + var startPoint: Point2f? = null + private set + var endPoint: Point2f? = null + private set + + constructor() { + + } + + constructor(p1: Point2f, p2: Point2f) { + setPoint(p1, p2) + } + + constructor(x1: Int, y1: Int, x2: Int, y2: Int) { + setPoint(x1, y1, x2, y2) + } + + fun setPoint(p1: Point2f, p2: Point2f) { + startPoint = p1 + endPoint = p2 + } + + fun setPoint(x1: Int, y1: Int, x2: Int, y2: Int) { + startPoint = Point2f(x1.toFloat(), y1.toFloat()) + endPoint = Point2f(x2.toFloat(), y2.toFloat()) + } +} diff --git a/src/com/Torvald/Terrarum/GameMap/PairedMapLayer.java b/src/com/Torvald/Terrarum/GameMap/PairedMapLayer.java deleted file mode 100644 index 23e003d45..000000000 --- a/src/com/Torvald/Terrarum/GameMap/PairedMapLayer.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.Torvald.Terrarum.GameMap; - -import java.io.Serializable; -import java.util.Iterator; -import java.util.Spliterator; -import java.util.function.Consumer; - -/** - * Created by minjaesong on 16-02-15. - */ -public class PairedMapLayer implements Iterable { - - /** - * 0b_xxxx_yyyy, x for lower index, y for higher index - * - * e.g. - * - * 0110 1101 is interpreted as - * 6 for tile 0, 13 for tile 1. - */ - byte[][] dataPair; - - public int width; - public int height; - - public static transient final int RANGE = 16; - - public PairedMapLayer(int width, int height) { - this.width = width / 2; - this.height = height; - - dataPair = new byte[height][width / 2]; - - for (int i = 0; i < height; i++) { - for (int j = 0; j < width / 2; j++) { - dataPair[i][j] = 0; - } - } - } - - /** - * Returns an iterator over elements of type {@code T}. - * Note: this iterator will return combined damage, that is 0bxxxx_yyyy as whole. - * - * @return an Iterator. - */ - @Override - public Iterator iterator() { - return new Iterator() { - - private int iteratorCount = 0; - - @Override - public boolean hasNext() { - return iteratorCount < width * height; - } - - @Override - public Byte next() { - int y = iteratorCount / width; - int x = iteratorCount % width; - // advance counter - iteratorCount += 1; - - return dataPair[y][x]; - } - }; - } - - /** - * Performs the given action for each element of the {@code Iterable} - * until all elements have been processed or the action throws an - * exception. Unless otherwise specified by the implementing class, - * actions are performed in the order of iteration (if an iteration order - * is specified). Exceptions thrown by the action are relayed to the - * caller. - * - * Note: this iterator will return combined damage, that is 0bxxxx_yyyy as whole. - * - * @param action The action to be performed for each element - * @throws NullPointerException if the specified action is null - * @implSpec

The default implementation behaves as if: - *

{@code
-     *     for (T t : this)
-     *         action.accept(t);
-     * }
- * @since 1.8 - */ - @Override - public void forEach(Consumer action) { - for (Byte b : this) { - action.accept(b); - } - } - - /** - * Creates a {@link Spliterator} over the elements described by this - * {@code Iterable}. - * - * @return a {@code Spliterator} over the elements described by this - * {@code Iterable}. - * @implSpec The default implementation creates an - * early-binding - * spliterator from the iterable's {@code Iterator}. The spliterator - * inherits the fail-fast properties of the iterable's iterator. - * @implNote The default implementation should usually be overridden. The - * spliterator returned by the default implementation has poor splitting - * capabilities, is unsized, and does not report any spliterator - * characteristics. Implementing classes can nearly always provide a - * better implementation. - * @since 1.8 - */ - @Override - public Spliterator spliterator() { - throw new UnsupportedOperationException(); - } - - int getData(int x, int y) { - if ((x & 0x1) == 0) - // higher four bits for i = 0, 2, 4, ... - return (dataPair[y][x / 2] & 0xF0) >>> 4; - else - // lower four bits for i = 1, 3, 5, ... - return dataPair[y][x / 2] & 0x0F; - } - - void setData(int x, int y, int data) { - if (data < 0 || data >= 16) throw new IllegalArgumentException("[PairedMapLayer] " + data + ": invalid data value."); - if ((x & 0x1) == 0) - // higher four bits for i = 0, 2, 4, ... - dataPair[y][x / 2] = (byte) (dataPair[y][x / 2] & 0x0F | (data & 0xF) << 4); - else - // lower four bits for i = 1, 3, 5, ... - dataPair[y][x / 2] = (byte) (dataPair[y][x / 2] & 0xF0 | (data & 0xF)); - } -} diff --git a/src/com/Torvald/Terrarum/GameMap/PairedMapLayer.kt b/src/com/Torvald/Terrarum/GameMap/PairedMapLayer.kt new file mode 100644 index 000000000..a4fd75fa0 --- /dev/null +++ b/src/com/Torvald/Terrarum/GameMap/PairedMapLayer.kt @@ -0,0 +1,82 @@ +package com.Torvald.Terrarum.GameMap + +import java.io.Serializable +import java.util.Spliterator +import java.util.function.Consumer + +/** + * Created by minjaesong on 16-02-15. + */ +class PairedMapLayer(width: Int, var height: Int) : Iterable { + + /** + * 0b_xxxx_yyyy, x for lower index, y for higher index + + * e.g. + + * 0110 1101 is interpreted as + * 6 for tile 0, 13 for tile 1. + */ + internal var dataPair: Array + + var width: Int = 0 + + init { + this.width = width / 2 + + dataPair = Array(height) { ByteArray(width / 2) } + } + + /** + * Returns an iterator over elements of type `T`. + * Note: this iterator will return combined damage, that is 0bxxxx_yyyy as whole. + + * @return an Iterator. + */ + override fun iterator(): Iterator { + return object : Iterator { + + private var iteratorCount = 0 + + override fun hasNext(): Boolean { + return iteratorCount < width * height + } + + override fun next(): Byte { + val y = iteratorCount / width + val x = iteratorCount % width + // advance counter + iteratorCount += 1 + + return dataPair[y][x] + } + } + } + + internal fun getData(x: Int, y: Int): Int { + if (x and 0x1 == 0) + // higher four bits for i = 0, 2, 4, ... + return (java.lang.Byte.toUnsignedInt(dataPair[y][x / 2]) and 0xF0) ushr 4 + else + // lower four bits for i = 1, 3, 5, ... + return java.lang.Byte.toUnsignedInt(dataPair[y][x / 2]) and 0x0F + } + + internal fun setData(x: Int, y: Int, data: Int) { + if (data < 0 || data >= 16) throw IllegalArgumentException("[PairedMapLayer] $data: invalid data value.") + if (x and 0x1 == 0) + // higher four bits for i = 0, 2, 4, ... + dataPair[y][x / 2] = + (java.lang.Byte.toUnsignedInt(dataPair[y][x / 2]) and 0x0F + or (data and 0xF shl 4)).toByte() + else + // lower four bits for i = 1, 3, 5, ... + dataPair[y][x / 2] = (java.lang.Byte.toUnsignedInt(dataPair[y][x / 2]) and 0xF0 + or (data and 0xF)).toByte() + } + + companion object { + + @Transient val RANGE = 16 + } +} diff --git a/src/com/Torvald/Terrarum/LangPack/Lang.java b/src/com/Torvald/Terrarum/LangPack/Lang.java deleted file mode 100644 index 442671266..000000000 --- a/src/com/Torvald/Terrarum/LangPack/Lang.java +++ /dev/null @@ -1,179 +0,0 @@ -package com.Torvald.Terrarum.LangPack; - -import com.Torvald.CSVFetcher; -import com.Torvald.ImageFont.GameFontWhite; -import com.Torvald.Terrarum.Terrarum; -import org.apache.commons.csv.CSVRecord; -import org.newdawn.slick.SlickException; - -import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Hashtable; -import java.util.List; -import java.util.Properties; - -/** - * Created by minjaesong on 16-01-22. - */ -public class Lang { - - private static final String CSV_COLUMN_FIRST = "STRING_ID"; - /** - * Get record by its STRING_ID - */ - private static Hashtable lang; - private static final String FALLBACK_LANG_CODE = "enUS"; - - private static final int HANGUL_SYL_START = 0xAC00; - - private static final String PATH_TO_CSV = "./res/locales/"; - private static final String CSV_MAIN = "polyglot.csv"; - private static final String NAMESET_PREFIX = "nameset_"; - - private static final int[] HANGUL_POST_INDEX_ALPH = { // 0: 는, 가, ... 1: 은, 이, ... - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - private static final int[] HANGUL_POST_RO_INDEX_ALPH = { // 0: 로 1: 으로 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - private static String[] ENGLISH_WORD_NORMAL_PLURAL = { - "photo" - }; - - private static String[] FRENCH_WORD_NORMAL_PLURAL = { - "bal" - , "banal" - , "fatal" - , "final" - }; - - public Lang() throws IOException { - lang = new Hashtable<>(); - - List langPackCSV = CSVFetcher.INSTANCE.readCSV(PATH_TO_CSV + CSV_MAIN); - - File file = new File(PATH_TO_CSV); - FilenameFilter filter = new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.contains(".csv") && !name.contains(CSV_MAIN) && !name.contains(NAMESET_PREFIX); - } - }; - for (String csvfilename : file.list(filter)) { - List csv = CSVFetcher.INSTANCE.readCSV(PATH_TO_CSV + csvfilename); - csv.forEach(langPackCSV::add); - } - - // Fill lang table - langPackCSV.forEach(this::appendToLangByStringID); - - - Arrays.sort(ENGLISH_WORD_NORMAL_PLURAL); - Arrays.sort(FRENCH_WORD_NORMAL_PLURAL); - - try { ((GameFontWhite)Terrarum.gameFontWhite).reloadUnihan(); } - catch (SlickException e) {} - } - - private void appendToLangByStringID(CSVRecord record) { - lang.put(record.get(CSV_COLUMN_FIRST), record); - } - - public static CSVRecord getRecord(String key) { - CSVRecord record = lang.get(key); - if (record == null) { - System.out.println("[Lang] No such record."); - throw new NullPointerException(); - } - return record; - } - - public static String get(String key) { - String value = null; - try { value = lang.get(key).get(Terrarum.Companion.getGameLocale()); } - catch (IllegalArgumentException e) { value = key; } - return value; - } - - public static String pluraliseLang(String key, int count) { - return (count > 1) ? get(key + "_PLURAL") : get(key); - } - - public static String pluralise(String word, int count) { - if (count < 2) return word; - - switch (Terrarum.Companion.getGameLocale()) { - case ("fr"): - if (Arrays.binarySearch(FRENCH_WORD_NORMAL_PLURAL, word) >= 0) { - return word + "s"; - } - if (word.endsWith("al") || word.endsWith("au") || word.endsWith("eu") || word - .endsWith("eau")) { - return word.substring(0, word.length() - 2) + "ux"; - } - else if (word.endsWith("ail")) { - return word.substring(0, word.length() - 3) + "ux"; - } - else { - return word + "s"; - } - case ("en"): default: - if (Arrays.binarySearch(ENGLISH_WORD_NORMAL_PLURAL, word) >= 0) { - return word + "s"; - } - else if (word.endsWith("f")) { // f -> ves - return word.substring(0, word.length() - 2) + "ves"; - } - else if (word.endsWith("o") || word.endsWith("z")) { // o -> oes - return word + "es"; - } - else { - return word + "s"; - } - } - } - - public static String postEunNeun(String word) { - char lastChar = getLastChar(word); - - if (isHangul(lastChar)) { - int index = lastChar - HANGUL_SYL_START; - return (index % 28 == 0) ? word + "는" : word + "은"; - } - else if ((lastChar >= 'A' && lastChar <= 'Z') - || (lastChar >= 'a' && lastChar <= 'z')) { - int index = (lastChar - 0x41) % 0x20; - return (HANGUL_POST_INDEX_ALPH[index] == 0) ? word + "는" : word + "은"; - } - else { - return "은(는)"; - } - } - - public static String postIiGa(String word) { - char lastChar = getLastChar(word); - - if (isHangul(lastChar)) { - int index = lastChar - HANGUL_SYL_START; - return (index % 28 == 0) ? word + "가" : word + "이"; - } - else if ((lastChar >= 'A' && lastChar <= 'Z') - || (lastChar >= 'a' && lastChar <= 'z')) { - int index = (lastChar - 0x41) % 0x20; - return (HANGUL_POST_INDEX_ALPH[index] == 0) ? word + "가" : word + "이"; - } - else { - return "이(가)"; - } - } - - private static boolean isHangul(char c) { - return (c >= 0xAC00 && c <= 0xD7A3); - } - - private static char getLastChar(String s) { - return s.charAt(s.length() - 1); - } -} diff --git a/src/com/Torvald/Terrarum/LangPack/Lang.kt b/src/com/Torvald/Terrarum/LangPack/Lang.kt new file mode 100644 index 000000000..965d925b6 --- /dev/null +++ b/src/com/Torvald/Terrarum/LangPack/Lang.kt @@ -0,0 +1,190 @@ +package com.Torvald.Terrarum.LangPack + +import com.Torvald.CSVFetcher +import com.Torvald.ImageFont.GameFontWhite +import com.Torvald.Terrarum.Terrarum +import org.apache.commons.csv.CSVRecord +import org.newdawn.slick.SlickException + +import java.io.* +import java.util.* + +/** + * Created by minjaesong on 16-01-22. + */ +object Lang { + + private val CSV_COLUMN_FIRST = "STRING_ID" + /** + * Get record by its STRING_ID + */ + private var lang: HashMap + private val FALLBACK_LANG_CODE = "enUS" + + private val HANGUL_SYL_START = 0xAC00 + + private val PATH_TO_CSV = "./res/locales/" + private val CSV_MAIN = "polyglot.csv" + private val NAMESET_PREFIX = "nameset_" + + private val HANGUL_POST_INDEX_ALPH = intArrayOf(// 0: 는, 가, ... 1: 은, 이, ... + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + private val HANGUL_POST_RO_INDEX_ALPH = intArrayOf(// 0: 로 1: 으로 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + + private val ENGLISH_WORD_NORMAL_PLURAL = arrayOf("photo") + + private val FRENCH_WORD_NORMAL_PLURAL = arrayOf("bal", "banal", "fatal", "final") + + init { + lang = HashMap() + + // read polyglot.csv first and use this list as a pivot + var langPackCSV: List = CSVFetcher.readCSV(PATH_TO_CSV + CSV_MAIN) + + // append CSV records to the main langpack + val file = File(PATH_TO_CSV) + val filter = FilenameFilter { dir, name -> name.contains(".csv") && !name.contains(NAMESET_PREFIX) } + for (csvfilename in file.list(filter)) { + val csv = CSVFetcher.readCSV(PATH_TO_CSV + csvfilename) + //csv.forEach({ langPackCSV. }) + csv.forEach { it -> lang.put(it.get(CSV_COLUMN_FIRST), it) } + } + + // lang.put(record.get(CSV_COLUMN_FIRST), record) + + // Fill lang table + // langPackCSV.forEach({ this.appendToLangByStringID(it) }) + + + Arrays.sort(ENGLISH_WORD_NORMAL_PLURAL) + Arrays.sort(FRENCH_WORD_NORMAL_PLURAL) + + try { + (Terrarum.gameFontWhite as GameFontWhite).reloadUnihan() + } + catch (e: SlickException) { + } + + } + + fun getRecord(key: String): CSVRecord { + val record = lang[key] + if (record == null) { + println("[Lang] No such record: $key") + throw NullPointerException() + } + return record + } + + operator fun get(key: String): String { + var value: String + try { + value = lang[key]!!.get(Terrarum.gameLocale) + } + catch (e: IllegalArgumentException) { + value = key + } + + return value + } + + fun pluraliseLang(key: String, count: Int): String { + return if (count > 1) get(key + "_PLURAL") else get(key) + } + + fun pluralise(word: String, count: Int): String { + if (count < 2) return word + + when (Terrarum.gameLocale) { + "fr" -> { + if (Arrays.binarySearch(FRENCH_WORD_NORMAL_PLURAL, word) >= 0) { + return word + "s" + } + if (word.endsWith("al") || word.endsWith("au") || word.endsWith("eu") || word.endsWith("eau")) { + return word.substring(0, word.length - 2) + "ux" + } + else if (word.endsWith("ail")) { + return word.substring(0, word.length - 3) + "ux" + } + else { + return word + "s" + } + } + "en" -> { + if (Arrays.binarySearch(ENGLISH_WORD_NORMAL_PLURAL, word) >= 0) { + return word + "s" + } + else if (word.endsWith("f")) { + // f -> ves + return word.substring(0, word.length - 2) + "ves" + } + else if (word.endsWith("o") || word.endsWith("z")) { + // o -> oes + return word + "es" + } + else { + return word + "s" + } + } + else -> { + if (Arrays.binarySearch(ENGLISH_WORD_NORMAL_PLURAL, word) >= 0) { + return word + "s" + } + else if (word.endsWith("f")) { + return word.substring(0, word.length - 2) + "ves" + } + else if (word.endsWith("o") || word.endsWith("z")) { + return word + "es" + } + else { + return word + "s" + } + } + } + } + + fun postEunNeun(word: String): String { + val lastChar = getLastChar(word) + + if (isHangul(lastChar)) { + val index = lastChar.toInt() - HANGUL_SYL_START + return if (index % 28 == 0) word + "는" else word + "은" + } + else if (lastChar >= 'A' && lastChar <= 'Z' || lastChar >= 'a' && lastChar <= 'z') { + val index = (lastChar.toInt() - 0x41) % 0x20 + return if (HANGUL_POST_INDEX_ALPH[index] == 0) word + "는" else word + "은" + } + else { + return "은(는)" + } + } + + fun postIiGa(word: String): String { + val lastChar = getLastChar(word) + + if (isHangul(lastChar)) { + val index = lastChar.toInt() - HANGUL_SYL_START + return if (index % 28 == 0) word + "가" else word + "이" + } + else if (lastChar >= 'A' && lastChar <= 'Z' || lastChar >= 'a' && lastChar <= 'z') { + val index = (lastChar.toInt() - 0x41) % 0x20 + return if (HANGUL_POST_INDEX_ALPH[index] == 0) word + "가" else word + "이" + } + else { + return "이(가)" + } + } + + private fun isHangul(c: Char): Boolean { + return c.toInt() >= 0xAC00 && c.toInt() <= 0xD7A3 + } + + private fun getLastChar(s: String): Char { + return s[s.length - 1] + } + + private fun appendToLangByStringID(record: CSVRecord) { + lang.put(record.get(CSV_COLUMN_FIRST), record) + } +} diff --git a/src/com/Torvald/Terrarum/MapDrawer/LightmapRenderer.kt b/src/com/Torvald/Terrarum/MapDrawer/LightmapRenderer.kt index 01c1771b3..b27de7e43 100644 --- a/src/com/Torvald/Terrarum/MapDrawer/LightmapRenderer.kt +++ b/src/com/Torvald/Terrarum/MapDrawer/LightmapRenderer.kt @@ -96,11 +96,11 @@ object LightmapRenderer { } - val for_y_start = div16(MapCamera.getCameraY()) - 1 // fix for premature lightmap rendering - val for_x_start = div16(MapCamera.getCameraX()) - 1 // on topmost/leftmost side + val for_x_start = div16(MapCamera.cameraX) - 1 // fix for premature lightmap rendering + val for_y_start = div16(MapCamera.cameraY) - 1 // on topmost/leftmost side - val for_y_end = clampHTile(for_y_start + div16(MapCamera.getRenderHeight()) + 2) + 1 // same fix as above val for_x_end = clampWTile(for_x_start + div16(MapCamera.getRenderWidth()) + 2) + 1 + val for_y_end = clampHTile(for_y_start + div16(MapCamera.getRenderHeight()) + 2) + 1 // same fix as above /** * Updating order: diff --git a/src/com/Torvald/Terrarum/MapDrawer/MapCamera.kt b/src/com/Torvald/Terrarum/MapDrawer/MapCamera.kt index aa43771e9..88282bf13 100644 --- a/src/com/Torvald/Terrarum/MapDrawer/MapCamera.kt +++ b/src/com/Torvald/Terrarum/MapDrawer/MapCamera.kt @@ -19,8 +19,10 @@ import java.util.* object MapCamera { private val map: GameMap = Terrarum.game.map; - internal var cameraX = 0 - internal var cameraY = 0 + var cameraX = 0 + private set + var cameraY = 0 + private set private val TSIZE = MapDrawer.TILE_SIZE @@ -122,6 +124,7 @@ object MapCamera { , TileNameCode.ORE_ILMENITE , TileNameCode.ORE_AURICHALCUM + , TileNameCode.WATER , TileNameCode.WATER_1 , TileNameCode.WATER_2 , TileNameCode.WATER_3 @@ -153,7 +156,6 @@ object MapCamera { , TileNameCode.LAVA_13 , TileNameCode.LAVA_14 , TileNameCode.LAVA_15 - , TileNameCode.LAVA ) /** @@ -444,18 +446,9 @@ object MapCamera { } } - @JvmStatic - fun div16(x: Int): Int { - return x and 0x7FFFFFFF shr 4 - } - - fun mod16(x: Int): Int { - return x and 15 - } - - fun quantise16(x: Int): Int { - return x and 0xFFFFFFF0.toInt() - } + fun div16(x: Int): Int = x and 0x7FFFFFFF shr 4 + fun mod16(x: Int): Int = x and 15 + fun quantise16(x: Int): Int = x and 0xFFFFFFF0.toInt() fun clampW(x: Int): Int { if (x < 0) { @@ -477,7 +470,6 @@ object MapCamera { } } - @JvmStatic fun clampWTile(x: Int): Int { if (x < 0) { return 0 @@ -488,7 +480,6 @@ object MapCamera { } } - @JvmStatic fun clampHTile(x: Int): Int { if (x < 0) { return 0 @@ -499,55 +490,21 @@ object MapCamera { } } - @JvmStatic - fun getRenderWidth(): Int { - return renderWidth - } + fun getRenderWidth(): Int = renderWidth + fun getRenderHeight(): Int = renderHeight - @JvmStatic - fun getRenderHeight(): Int { - return renderHeight - } + fun getRenderStartX(): Int = div16(cameraX) + fun getRenderStartY(): Int = div16(cameraY) - @JvmStatic - fun getRenderStartX(): Int { - return div16(cameraX) - } + fun getRenderEndX(): Int = clampWTile(getRenderStartX() + div16(renderWidth) + 2) + fun getRenderEndY(): Int = clampHTile(getRenderStartY() + div16(renderHeight) + 2) - @JvmStatic - fun getRenderStartY(): Int { - return div16(cameraY) - } + private fun isConnectSelf(b: Int): Boolean = TILES_CONNECT_SELF.contains(b) + private fun isConnectMutual(b: Int): Boolean = TILES_CONNECT_MUTUAL.contains(b) + private fun isWallSticker(b: Int): Boolean = TILES_WALL_STICKER.contains(b) + private fun isPlatform(b: Int): Boolean = TILES_WALL_STICKER_CONNECT_SELF.contains(b) - @JvmStatic - fun getRenderEndX(): Int { - return clampWTile(getRenderStartX() + div16(renderWidth) + 2) - } - - @JvmStatic - fun getRenderEndY(): Int { - return clampHTile(getRenderStartY() + div16(renderHeight) + 2) - } - - private fun isConnectSelf(b: Int): Boolean { - return Arrays.asList(*TILES_CONNECT_SELF).contains(b) - } - - private fun isConnectMutual(b: Int): Boolean { - return Arrays.asList(*TILES_CONNECT_MUTUAL).contains(b) - } - - private fun isWallSticker(b: Int): Boolean { - return Arrays.asList(*TILES_WALL_STICKER).contains(b) - } - - private fun isPlatform(b: Int): Boolean { - return Arrays.asList(*TILES_WALL_STICKER_CONNECT_SELF).contains(b) - } - - private fun isBlendMul(b: Int): Boolean { - return Arrays.asList(*TILES_BLEND_MUL).contains(b) - } + private fun isBlendMul(b: Int): Boolean = TILES_BLEND_MUL.contains(b) private fun setBlendModeMul() { GL11.glEnable(GL11.GL_BLEND) @@ -558,14 +515,4 @@ object MapCamera { GL11.glDisable(GL11.GL_BLEND) Terrarum.appgc.graphics.setDrawMode(Graphics.MODE_NORMAL) } - - @JvmStatic - fun getCameraX(): Int { - return cameraX - } - - @JvmStatic - fun getCameraY(): Int { - return cameraY - } } \ No newline at end of file diff --git a/src/com/Torvald/Terrarum/MapDrawer/MapDrawer.kt b/src/com/Torvald/Terrarum/MapDrawer/MapDrawer.kt index 878c680cb..475fd26dc 100644 --- a/src/com/Torvald/Terrarum/MapDrawer/MapDrawer.kt +++ b/src/com/Torvald/Terrarum/MapDrawer/MapDrawer.kt @@ -54,7 +54,12 @@ object MapDrawer { g.color = getColourFromMap(colTemp) //g.color = getColourFromMap(3022) - g.fillRect(MapCamera.getCameraX() * zoom, MapCamera.getCameraY() * zoom, Terrarum.WIDTH * if (zoom < 1) 1f / zoom else zoom, Terrarum.HEIGHT * if (zoom < 1) 1f / zoom else zoom) + g.fillRect( + MapCamera.cameraX * zoom, + MapCamera.cameraY * zoom, + Terrarum.WIDTH * if (zoom < 1) 1f / zoom else zoom, + Terrarum.HEIGHT * if (zoom < 1) 1f / zoom else zoom + ) } /** diff --git a/src/com/Torvald/Terrarum/Terrarum b/src/com/Torvald/Terrarum/Terrarum deleted file mode 100644 index 45be528a9..000000000 --- a/src/com/Torvald/Terrarum/Terrarum +++ /dev/null @@ -1,305 +0,0 @@ -package com.Torvald.Terrarum; - -import java.io.File; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.Torvald.ImageFont.GameFontWhite; -import com.Torvald.JsonFetcher; -import com.Torvald.JsonWriter; -import com.Torvald.Terrarum.LangPack.Lang; -import com.google.gson.JsonObject; -import org.lwjgl.input.Controllers; -import org.newdawn.slick.*; -import org.newdawn.slick.state.StateBasedGame; - -/** - * Created by minjaesong on 15-12-30. - */ -public class Terrarum extends StateBasedGame { - - /** - * To be used with physics simulator - */ - public static final int TARGET_FPS = 50; - - /** - * To be used with render, to achieve smooth frame drawing - * - * TARGET_INTERNAL_FPS > TARGET_FPS for smooth frame drawing - * - * Must choose a value so that (1000 / VAL) is still integer - */ - public static final int TARGET_INTERNAL_FPS = 100; - - public static AppGameContainer appgc; - - public static final int WIDTH = 1060; - public static final int HEIGHT = 742; // IMAX ratio - public static boolean VSYNC = true; - public static final int VSYNC_TRIGGER_THRESHOLD = 56; - - public static Game game; - public static GameConfig gameConfig; - - public static String OSName; - public static String OSVersion; - public static String OperationSystem; - public static String defaultDir; - public static String defaultSaveDir; - - public static String gameLocale = ""; // locale override - - public static Font gameFontWhite; - - public static final int SCENE_ID_HOME = 1; - public static final int SCENE_ID_GAME = 3; - - public static boolean hasController = false; - public static final float CONTROLLER_DEADZONE = 0.1f; - - private static String configDir; - - public Terrarum(String gamename) throws SlickException { - super(gamename); - - gameConfig = new GameConfig(); - - getDefaultDirectory(); - createDirs(); - - boolean readFromDisk = readConfigJson(); - if (!readFromDisk) readConfigJson(); - - // get locale from config - gameLocale = gameConfig.getAsString("language"); - - // if game locale were not set, use system locale - if (gameLocale.length() < 4) - gameLocale = getSysLang(); - - System.out.println("[Terrarum] Locale: " + gameLocale); - } - - @Override - public void initStatesList(GameContainer gc) throws SlickException { - gameFontWhite = new GameFontWhite(); - - try { new Lang(); } - catch (IOException e) { e.printStackTrace(); } - - hasController = (gc.getInput().getControllerCount() > 0); - if (hasController) { - for (int c = 0; c < Controllers.getController(0).getAxisCount(); c++) { - Controllers.getController(0).setDeadZone(c, CONTROLLER_DEADZONE); - } - } - - appgc.getInput().enableKeyRepeat(); - - game = new Game(); - addState(game); - } - - public static void main(String[] args) - { - try - { - appgc = new AppGameContainer(new Terrarum("Terrarum")); - appgc.setDisplayMode(WIDTH, HEIGHT, false); - - appgc.setTargetFrameRate(TARGET_INTERNAL_FPS); - appgc.setVSync(VSYNC); - appgc.setMaximumLogicUpdateInterval(1000 / TARGET_INTERNAL_FPS); - appgc.setMinimumLogicUpdateInterval(1000 / TARGET_INTERNAL_FPS - 1); - - appgc.setShowFPS(false); - appgc.setUpdateOnlyWhenVisible(false); - - appgc.start(); - } - catch (SlickException ex) - { - Logger.getLogger(Terrarum.class.getName()).log(Level.SEVERE, null, ex); - } - } - - private static void getDefaultDirectory(){ - OSName = System.getProperty("os.name"); - OSVersion = System.getProperty("os.version"); - - String OS = System.getProperty("os.name").toUpperCase(); - if (OS.contains("WIN")){ - OperationSystem = "WINDOWS"; - defaultDir = System.getenv("APPDATA") + "/Terrarum"; - } - else if (OS.contains("OS X")){ - OperationSystem = "OSX"; - 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"; - } - else if (OS.contains("SUNOS")){ - OperationSystem = "SOLARIS"; - defaultDir = System.getProperty("user.home") + "/.terrarum"; - } - else{ - OperationSystem = "UNKNOWN"; - defaultDir = System.getProperty("user.home") + "/.terrarum"; - } - - defaultSaveDir = defaultDir + "/Saves"; - configDir = defaultDir + "/config.json"; - } - - private static void createDirs(){ - File[] dirs = { - new File(defaultSaveDir), - }; - - for (File d : dirs){ - if (!d.exists()){ - d.mkdirs(); - } - } - } - - private static void createConfigJson() throws IOException { - File configFile = new File(configDir); - - if (!configFile.exists() || configFile.length() == 0) { - JsonWriter.writeToFile(DefaultConfig.fetch(), configDir); - } - } - - private static boolean readConfigJson() { - try { - // read from disk and build config from it - JsonObject jsonObject = JsonFetcher.readJson(configDir); - - // make config - jsonObject.entrySet().forEach( - entry -> gameConfig.set(entry.getKey(), entry.getValue()) - ); - - return true; - } - catch (IOException e) { - // write default config to game dir. Call this method again to read config from it. - try { - createConfigJson(); - } - catch (IOException e1) { - e.printStackTrace(); - } - - return false; - } - } - - public static String getSysLang() { - String lan = System.getProperty("user.language"); - String country = System.getProperty("user.country"); - - // exception handling - if (lan.equals("en")) country = "US"; - else if (lan.equals("fr")) country = "FR"; - else if (lan.equals("de")) country = "DE"; - else if (lan.equals("ko")) country = "KR"; - - return lan + country; - } - - - /** - * Return config from config set. If the config does not exist, default value will be returned. - * @param key - * @return Config from config set or default config if it does not exist. - * @throws NullPointerException if the specified config simply does not exist. - */ - public static int getConfigInt(String key) { - int cfg = 0; - try { - cfg = gameConfig.getAsInt(key); - } - catch (NullPointerException e) { - try { - cfg = DefaultConfig.fetch().get(key).getAsInt(); - } - catch (NullPointerException e1) { - e.printStackTrace(); - } - } - return cfg; - } - - /** - * Return config from config set. If the config does not exist, default value will be returned. - * @param key - * @return Config from config set or default config if it does not exist. - * @throws NullPointerException if the specified config simply does not exist. - */ - public static float getConfigFloat(String key) { - float cfg = 0; - try { - cfg = gameConfig.getAsFloat(key); - } - catch (NullPointerException e) { - try { - cfg = DefaultConfig.fetch().get(key).getAsFloat(); - } - catch (NullPointerException e1) { - e.printStackTrace(); - } - } - return cfg; - } - - /** - * Return config from config set. If the config does not exist, default value will be returned. - * @param key - * @return Config from config set or default config if it does not exist. - * @throws NullPointerException if the specified config simply does not exist. - */ - public static String getConfigString(String key) { - String cfg = ""; - try { - cfg = gameConfig.getAsString(key); - } - catch (NullPointerException e) { - try { - cfg = DefaultConfig.fetch().get(key).getAsString(); - } - catch (NullPointerException e1) { - e.printStackTrace(); - } - } - return cfg; - } - - /** - * Return config from config set. If the config does not exist, default value will be returned. - * @param key - * @return Config from config set or default config if it does not exist. - * @throws NullPointerException if the specified config simply does not exist. - */ - public static boolean getConfigBoolean(String key) { - boolean cfg = false; - try { - cfg = gameConfig.getAsBoolean(key); - } - catch (NullPointerException e) { - try { - cfg = DefaultConfig.fetch().get(key).getAsBoolean(); - } - catch (NullPointerException e1) { - e.printStackTrace(); - } - } - return cfg; - } -} diff --git a/src/com/Torvald/Terrarum/Terrarum.kt b/src/com/Torvald/Terrarum/Terrarum.kt index 36bde460e..2466ecb8b 100644 --- a/src/com/Torvald/Terrarum/Terrarum.kt +++ b/src/com/Torvald/Terrarum/Terrarum.kt @@ -46,13 +46,6 @@ constructor(gamename: String) : StateBasedGame(gamename) { override fun initStatesList(gc: GameContainer) { gameFontWhite = GameFontWhite() - try { - Lang() - } - catch (e: IOException) { - e.printStackTrace() - } - hasController = gc.input.controllerCount > 0 if (hasController) { for (c in 0..Controllers.getController(0).axisCount - 1) { diff --git a/src/com/Torvald/Terrarum/TileProperties/tileprop.csv b/src/com/Torvald/Terrarum/TileProperties/tileprop.csv index 221d2f08e..2d29ad39b 100644 --- a/src/com/Torvald/Terrarum/TileProperties/tileprop.csv +++ b/src/com/Torvald/Terrarum/TileProperties/tileprop.csv @@ -41,7 +41,7 @@ "10"; "2";"TILE_PLATFORM_EBONY" ; "394758"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "2"; "0";"16" "10"; "3";"TILE_PLATFORM_BIRCH" ; "394758"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "3"; "0";"16" "10"; "4";"TILE_PLATFORM_BLOODROSE" ; "394758"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "4"; "0";"16" - "11"; "0";"TILE_TORCH" ; "0"; "0"; "N/A"; "0"; "0"; "0"; "0";"16750673"; "11"; "0"; "0";"16" + "11"; "0";"TILE_TORCH" ; "0"; "0"; "N/A"; "0"; "0"; "0"; "0";"15304000"; "11"; "0"; "0";"16" "11"; "1";"TILE_TORCH_FROST" ; "0"; "0"; "N/A"; "0"; "0"; "0"; "0"; "5143807"; "11"; "1"; "0";"16" "12"; "0";"TILE_TORCH" ; "394758"; "0"; "N/A"; "0"; "0"; "0"; "0"; "0"; "11"; "0"; "0";"16" "12"; "1";"TILE_TORCH_FROST" ; "394758"; "0"; "N/A"; "0"; "0"; "0"; "0"; "0"; "11"; "1"; "0";"16" @@ -83,6 +83,7 @@ "15"; "3";"TILE_SANDSTONE_DESERT" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "3"; "0";"16" "15"; "4";"TILE_SANDSTONE_BLACK" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "4"; "0";"16" "15"; "5";"TILE_SANDSTONE_BLACK" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "5"; "0";"16" + "16"; "0";"TILE_LANTERN_IRON_REGULAR"; "0"; "0"; "N/A"; "0"; "0"; "0"; "0";"16769944"; "16"; "0"; "0";"16" "254"; "0";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16" "254"; "1";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16" "254"; "2";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16" diff --git a/src/com/Torvald/Terrarum/UserInterface/BasicDebugInfoWindow.kt b/src/com/Torvald/Terrarum/UserInterface/BasicDebugInfoWindow.kt index d988e62e6..95d275285 100644 --- a/src/com/Torvald/Terrarum/UserInterface/BasicDebugInfoWindow.kt +++ b/src/com/Torvald/Terrarum/UserInterface/BasicDebugInfoWindow.kt @@ -137,14 +137,14 @@ class BasicDebugInfoWindow : UICanvas { // Hitbox val zoom = Terrarum.game.screenZoom g.setColor(Color(0x007f00)) - g.drawRect(hitbox.getHitboxStart().getX() * zoom - MapCamera.cameraX * zoom - , hitbox.getHitboxStart().getY() * zoom - MapCamera.cameraY * zoom - , hitbox.getWidth() * zoom - , hitbox.getHeight() * zoom) + g.drawRect(hitbox.hitboxStart.x * zoom - MapCamera.cameraX * zoom + , hitbox.hitboxStart.y * zoom - MapCamera.cameraY * zoom + , hitbox.width * zoom + , hitbox.height * zoom) // ...and its point g.fillRect( - (hitbox.getPointedX() - 1) * zoom - MapCamera.cameraX * zoom - , (hitbox.getPointedY() - 1) * zoom - MapCamera.cameraY * zoom + (hitbox.pointedX - 1) * zoom - MapCamera.cameraX * zoom + , (hitbox.pointedY - 1) * zoom - MapCamera.cameraY * zoom , 3f, 3f) g.drawString( Lang.get("DEV_COLOUR_LEGEND_GREEN") + " : hitbox", (Terrarum.WIDTH - 200).toFloat() @@ -152,14 +152,14 @@ class BasicDebugInfoWindow : UICanvas { // Next hitbox g.setColor(Color.blue) - g.drawRect(nextHitbox!!.getHitboxStart().getX() * zoom - MapCamera.cameraX * zoom - , nextHitbox.getHitboxStart().getY() * zoom - MapCamera.cameraY * zoom - , nextHitbox.getWidth() * zoom - , nextHitbox.getHeight() * zoom) + g.drawRect(nextHitbox!!.hitboxStart.x * zoom - MapCamera.cameraX * zoom + , nextHitbox.hitboxStart.y * zoom - MapCamera.cameraY * zoom + , nextHitbox.width * zoom + , nextHitbox.height * zoom) // ...and its point g.fillRect( - (nextHitbox.getPointedX() - 1) * zoom - MapCamera.cameraX * zoom - , (nextHitbox.getPointedY() - 1) * zoom - MapCamera.cameraY * zoom + (nextHitbox.pointedX - 1) * zoom - MapCamera.cameraX * zoom + , (nextHitbox.pointedY - 1) * zoom - MapCamera.cameraY * zoom , 3f, 3f) g.drawString( Lang.get("DEV_COLOUR_LEGEND_BLUE") + " : nextHitbox", (Terrarum.WIDTH - 200).toFloat() diff --git a/src/com/Torvald/Terrarum/UserInterface/UIHandler.kt b/src/com/Torvald/Terrarum/UserInterface/UIHandler.kt index d8eba8b2a..c01488b03 100644 --- a/src/com/Torvald/Terrarum/UserInterface/UIHandler.kt +++ b/src/com/Torvald/Terrarum/UserInterface/UIHandler.kt @@ -96,7 +96,10 @@ constructor(val UI: UICanvas) { UIGraphicInstance.font = Terrarum.gameFontWhite UI.render(gc, UIGraphicInstance) - gameGraphicInstance.drawImage(UIDrawnCanvas, posX + MapCamera.getCameraX() * Terrarum.game.screenZoom, posY + MapCamera.getCameraY() * Terrarum.game.screenZoom)// compensate for screenZoom AND camera translation + gameGraphicInstance.drawImage(UIDrawnCanvas, + posX + MapCamera.cameraX * Terrarum.game.screenZoom, + posY + MapCamera.cameraY * Terrarum.game.screenZoom + )// compensate for screenZoom AND camera translation // (see Game.render -> g.translate()) } } diff --git a/src/com/Torvald/spriteAnimation/SpriteAnimation.java b/src/com/Torvald/spriteAnimation/SpriteAnimation.java deleted file mode 100644 index b5080d7ec..000000000 --- a/src/com/Torvald/spriteAnimation/SpriteAnimation.java +++ /dev/null @@ -1,281 +0,0 @@ - -/* Original code author: Sean Laurvick - * This code is based on the original author's code written in Lua. - */ - -package com.Torvald.spriteAnimation; - -import com.Torvald.Terrarum.Game; -import com.Torvald.Terrarum.Terrarum; -import com.jme3.math.FastMath; -import org.newdawn.slick.Graphics; -import org.newdawn.slick.Image; -import org.newdawn.slick.SlickException; -import org.newdawn.slick.SpriteSheet; - -public class SpriteAnimation { - - private SpriteSheet spriteImage; - private Image[][] sprites; - private int height; - private int width; - private int currentFrame = 1; - private int currentRow = 1; - private int nFrames; - private int nRows; - private int delay = 200; - private int delta = 0; - private boolean looping = true; - private boolean animationRunning = true; - private boolean flipHorizontal = false; - private boolean flipVertical = false; - private boolean visible = false; - - private int offsetX = 0; - private int offsetY = 0; - - private float prevScale = 1f; - private Image currentImage; - - public SpriteAnimation() throws SlickException{ - - } - - /** - * Sets spritesheet. - * MUST be called AFTER setDimension. - * @param imagePath path to the sprite sheet image. - * @throws SlickException - */ - public void setSpriteImage(String imagePath) throws SlickException { - spriteImage = new SpriteSheet(imagePath, this.width, this.height); - } - - /** - * Sets animation delay. Will default to 200 if not called. - * @param delay in milliseconds - */ - public void setDelay(int delay) { - this.delay = delay; - } - - /** - * Sets sprite dimension. This is necessary. - * @param w - * @param h - */ - public void setDimension(int w, int h) { - width = w; - height = h; - } - - /** - * Sets sheet rows and animation frames. Will default to - * 1, 1 (still image of top left from the sheet) if not called. - * @param rows - * @param frames - */ - public void setRowsAndFrames(int rows, int frames) { - nRows = rows; - nFrames = frames; - } - - /** - * Compose (load from spritesheet) as attributes defined. - * If attributes were not defined, will throw exception of - * SlickException or ArraySizeException. - * @throws SlickException - */ - public void composeSprite() throws SlickException { - this.sprites = new Image[this.nRows][this.nFrames]; - - for (int i=0; i= ( this.delay ) ){ - //if set to not loop, keep the frame at the last frame - if ( this.currentFrame == this.nFrames && !(this.looping) ){ - this.currentFrame = this.nFrames - 1; - } - - //advance one frame, then reset delta counter - this.currentFrame = (this.currentFrame % this.nFrames) + 1; - this.delta = 0; - } - } - } - - /** - * Render to specific coordinates. Will assume bottom-center point as image position. - * Will round to integer. - * @param g - * @param posX bottom-center point - * @param posY bottom-center point - * @param scale - */ - public void render(Graphics g, float posX, float posY, float scale){ - scale *= Terrarum.game.getScreenZoom(); - - // Null checking - if (currentImage == null) { - currentImage = getScaledSprite(scale); - } - - if (visible) { - // re-scale image if scale has been changed - if (prevScale != scale) { - currentImage = getScaledSprite(scale); - prevScale = scale; - } - - Image flippedImage = currentImage.getFlippedCopy(flipHorizontal, flipVertical); - - flippedImage.startUse(); - flippedImage.drawEmbedded( - Math.round(posX * Terrarum.game.getScreenZoom()) - , Math.round(posY * Terrarum.game.getScreenZoom()) - , FastMath.floor(width * scale) - , FastMath.floor(height * scale) - ); - flippedImage.endUse(); - } - } - - public void render(Graphics g, float posX, float posY){ - render(g, posX, posY, 1); - } - - public void switchSprite(int newRow){ - currentRow = newRow; - - //if beyond the frame index then reset - if (currentFrame > nFrames){ - reset(); - } - } - - public void switchSprite(int newRow, int newMax){ - if (newMax > 0){ - nFrames = newMax; - } - - currentRow = newRow; - - //if beyond the frame index then reset - if (currentFrame > nFrames){ - reset(); - } - } - - public void switchSpriteDelay(int newDelay){ - if (newDelay > 0){ - delay = newDelay; - } - } - - public void switchSprite(int newRow, int newMax, int newDelay){ - if (newMax > 0){ - nFrames = newMax; - } - - if (newDelay > 0){ - delay = newDelay; - } - - currentRow = newRow; - - //if beyond the frame index then reset - if (currentFrame > nFrames){ - reset(); - } - } - - public void reset(){ - currentFrame = 1; - } - - public void start(){ //starts the animation - animationRunning = true; - } - - public void start(int selectFrame){ //starts the animation - animationRunning = true; - - //optional: seleft the frame no which to start the animation - currentFrame = selectFrame; - } - - public void stop(){ - animationRunning = false; - } - - public void stop(int selectFrame){ - animationRunning = false; - - currentFrame = selectFrame; - } - - public void flip(boolean horizontal, boolean vertical){ - flipHorizontal = horizontal; - flipVertical = vertical; - } - - public boolean flippedHorizontal() { - return flipHorizontal; - } - - public boolean flippedVertical() { - return flipVertical; - } - - public int getWidth(){ - return width; - } - - public int getHeight(){ - return height; - } - - private Image getScaledSprite(float scale) { - Image selectedImage = sprites[currentRow - 1][currentFrame - 1]; - - // resample - /*float nearestResampleScale = (scale > 1) ? Math.round(scale) : 1; - float linearResampleScale = scale / nearestResampleScale; - - // scale 1.8 -> resample in 2(nearest), then resample in 0.9(linear) - // scale by nearestResampleScale (2, 3, ...) - selectedImage.setFilter(Image.FILTER_NEAREST); - Image selImgNearestScaled = selectedImage.getScaledCopy(nearestResampleScale); - // scale by linearResampleScale (.x) - Image selImgLinearScaled; - if (scale % 1 > 0) { - selImgNearestScaled.setFilter(Image.FILTER_LINEAR); - selImgLinearScaled = selImgNearestScaled.getScaledCopy(linearResampleScale); - return selImgLinearScaled; - } - else { - return selImgNearestScaled; - }*/ - selectedImage.setFilter(Image.FILTER_NEAREST); - return selectedImage.getScaledCopy(scale); - } -} diff --git a/src/com/Torvald/spriteAnimation/SpriteAnimation.kt b/src/com/Torvald/spriteAnimation/SpriteAnimation.kt new file mode 100644 index 000000000..a8347eac7 --- /dev/null +++ b/src/com/Torvald/spriteAnimation/SpriteAnimation.kt @@ -0,0 +1,261 @@ +/* Original code author: Sean Laurvick + * This code is based on the original author's code written in Lua. + */ + +package com.Torvald.spriteAnimation + +import com.Torvald.Terrarum.Game +import com.Torvald.Terrarum.Terrarum +import com.jme3.math.FastMath +import org.newdawn.slick.Graphics +import org.newdawn.slick.Image +import org.newdawn.slick.SlickException +import org.newdawn.slick.SpriteSheet + +class SpriteAnimation @Throws(SlickException::class) +constructor() { + + private var spriteImage: SpriteSheet? = null + var height: Int = 0 + private set + var width: Int = 0 + private set + private var currentFrame = 1 + private var currentRow = 1 + private var nFrames: Int = 0 + private var nRows: Int = 0 + private var delay = 200 + private var delta = 0 + private val looping = true + private var animationRunning = true + private var flipHorizontal = false + private var flipVertical = false + private var visible = false + + private val offsetX = 0 + private val offsetY = 0 + + private var prevScale = 1f + private var currentImage: Image? = null + + /** + * Sets spritesheet. + * MUST be called AFTER setDimension. + * @param imagePath path to the sprite sheet image. + * * + * @throws SlickException + */ + @Throws(SlickException::class) + fun setSpriteImage(imagePath: String) { + spriteImage = SpriteSheet(imagePath, this.width, this.height) + } + + /** + * Sets animation delay. Will default to 200 if not called. + * @param delay in milliseconds + */ + fun setDelay(delay: Int) { + this.delay = delay + } + + /** + * Sets sprite dimension. This is necessary. + * @param w + * * + * @param h + */ + fun setDimension(w: Int, h: Int) { + width = w + height = h + } + + /** + * Sets sheet rows and animation frames. Will default to + * 1, 1 (still image of top left from the sheet) if not called. + * @param rows + * * + * @param frames + */ + fun setRowsAndFrames(rows: Int, frames: Int) { + nRows = rows + nFrames = frames + } + + fun setAsVisible() { + visible = true + } + + fun setAsInvisible() { + visible = false + } + + fun update(delta: Int) { + if (animationRunning) { + //skip this if animation is stopped + this.delta += delta + + //check if it's time to advance the frame + if (this.delta >= this.delay) { + //if set to not loop, keep the frame at the last frame + if (this.currentFrame == this.nFrames && !this.looping) { + this.currentFrame = this.nFrames - 1 + } + + //advance one frame, then reset delta counter + this.currentFrame = this.currentFrame % this.nFrames + 1 + this.delta = 0 + } + } + } + + /** + * Render to specific coordinates. Will assume bottom-center point as image position. + * Will round to integer. + * @param g + * * + * @param posX bottom-center point + * * + * @param posY bottom-center point + * * + * @param scale + */ + @JvmOverloads fun render(g: Graphics, posX: Float, posY: Float, scale: Float = 1f) { + var scale = scale + scale *= Terrarum.game.screenZoom + + // Null checking + if (currentImage == null) { + currentImage = getScaledSprite(scale) + } + + if (visible) { + // re-scale image if scale has been changed + if (prevScale != scale) { + currentImage = getScaledSprite(scale) + prevScale = scale + } + + val flippedImage = currentImage!!.getFlippedCopy(flipHorizontal, flipVertical) + + flippedImage.startUse() + flippedImage.drawEmbedded( + Math.round(posX * Terrarum.game.screenZoom).toFloat(), + Math.round(posY * Terrarum.game.screenZoom).toFloat(), + FastMath.floor(width * scale).toFloat(), + FastMath.floor(height * scale).toFloat() + ) + flippedImage.endUse() + } + } + + fun switchSprite(newRow: Int) { + currentRow = newRow + + //if beyond the frame index then reset + if (currentFrame > nFrames) { + reset() + } + } + + fun switchSprite(newRow: Int, newMax: Int) { + if (newMax > 0) { + nFrames = newMax + } + + currentRow = newRow + + //if beyond the frame index then reset + if (currentFrame > nFrames) { + reset() + } + } + + fun switchSpriteDelay(newDelay: Int) { + if (newDelay > 0) { + delay = newDelay + } + } + + fun switchSprite(newRow: Int, newMax: Int, newDelay: Int) { + if (newMax > 0) { + nFrames = newMax + } + + if (newDelay > 0) { + delay = newDelay + } + + currentRow = newRow + + //if beyond the frame index then reset + if (currentFrame > nFrames) { + reset() + } + } + + fun reset() { + currentFrame = 1 + } + + fun start() { + //starts the animation + animationRunning = true + } + + fun start(selectFrame: Int) { + //starts the animation + animationRunning = true + + //optional: seleft the frame no which to start the animation + currentFrame = selectFrame + } + + fun stop() { + animationRunning = false + } + + fun stop(selectFrame: Int) { + animationRunning = false + + currentFrame = selectFrame + } + + fun flip(horizontal: Boolean, vertical: Boolean) { + flipHorizontal = horizontal + flipVertical = vertical + } + + fun flippedHorizontal(): Boolean { + return flipHorizontal + } + + fun flippedVertical(): Boolean { + return flipVertical + } + + private fun getScaledSprite(scale: Float): Image { + val selectedImage = spriteImage!!.getSprite(currentFrame - 1, currentRow - 1) + //Image selectedImage = sprites[currentRow - 1][currentFrame - 1]; + + // resample + /*float nearestResampleScale = (scale > 1) ? Math.round(scale) : 1; + float linearResampleScale = scale / nearestResampleScale; + + // scale 1.8 -> resample in 2(nearest), then resample in 0.9(linear) + // scale by nearestResampleScale (2, 3, ...) + selectedImage.setFilter(Image.FILTER_NEAREST); + Image selImgNearestScaled = selectedImage.getScaledCopy(nearestResampleScale); + // scale by linearResampleScale (.x) + Image selImgLinearScaled; + if (scale % 1 > 0) { + selImgNearestScaled.setFilter(Image.FILTER_LINEAR); + selImgLinearScaled = selImgNearestScaled.getScaledCopy(linearResampleScale); + return selImgLinearScaled; + } + else { + return selImgNearestScaled; + }*/ + selectedImage.filter = Image.FILTER_NEAREST + return selectedImage.getScaledCopy(scale) + } +}