From b84a0a770bb173d0cd457fb3cfac0d57397467bf Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 28 Aug 2021 16:31:06 +0900 Subject: [PATCH] loading player from json file --- src/net/torvald/gdx/graphics/Cvec.kt | 5 ++ .../spriteanimation/HasAssembledSprite.kt | 10 ++++ src/net/torvald/terrarum/AppLoader.java | 1 - src/net/torvald/terrarum/IngameInstance.kt | 13 +++-- src/net/torvald/terrarum/Point2d.kt | 27 ++++++++++- src/net/torvald/terrarum/Terrarum.kt | 1 + .../terrarum/TerrarumAppConfiguration.kt | 3 ++ src/net/torvald/terrarum/TitleScreen.kt | 4 +- .../torvald/terrarum/console/CommandDict.kt | 2 + src/net/torvald/terrarum/gameactors/Actor.kt | 20 +++++--- .../torvald/terrarum/gameactors/ActorValue.kt | 18 ++++--- .../terrarum/gameactors/ActorWithBody.kt | 10 +++- src/net/torvald/terrarum/gameactors/Hitbox.kt | 26 ++++++---- .../torvald/terrarum/gameworld/GameWorld.kt | 32 ++++--------- .../terrarum/modulebasegame/TerrarumIngame.kt | 43 +++++++++-------- .../modulebasegame/console/ExportMeta.kt | 9 ++-- .../modulebasegame/console/ImportWorld.kt | 30 ++++++++++-- .../gameactors/ActorHumanoid.kt | 26 ++++------ .../gameactors/ActorInventory.kt | 21 +++++---- .../gameactors/FixtureInventory.kt | 47 ++++++++++++++----- .../modulebasegame/gameactors/IngamePlayer.kt | 17 +++++-- .../gameactors/ThreadActorUpdate.kt | 6 +-- .../modulebasegame/ui/AmmoMeterProxy.kt | 2 +- .../ui/UIItemInventoryEquippedView.kt | 2 +- .../ui/UIItemInventoryItemGrid.kt | 16 +++---- .../modulebasegame/ui/UIQuickslotBar.kt | 2 +- .../modulebasegame/ui/UIQuickslotPie.kt | 2 +- .../torvald/terrarum/serialise/ReadActor.kt | 41 ++++++++++++++++ .../torvald/terrarum/serialise/WriteActor.kt | 5 +- src/net/torvald/terrarum/ui/ConsoleWindow.kt | 9 ++-- src/org/dyn4j/geometry/Vector2.kt | 3 ++ 31 files changed, 308 insertions(+), 145 deletions(-) create mode 100644 src/net/torvald/terrarum/serialise/ReadActor.kt diff --git a/src/net/torvald/gdx/graphics/Cvec.kt b/src/net/torvald/gdx/graphics/Cvec.kt index 8f5fb8efe..f71f4e567 100644 --- a/src/net/torvald/gdx/graphics/Cvec.kt +++ b/src/net/torvald/gdx/graphics/Cvec.kt @@ -77,6 +77,11 @@ class Cvec { set(color) } + operator fun component1() = r + operator fun component2() = g + operator fun component3() = b + operator fun component4() = a + /** * Get RGBA Element using index, of which: * - 0: R diff --git a/src/net/torvald/spriteanimation/HasAssembledSprite.kt b/src/net/torvald/spriteanimation/HasAssembledSprite.kt index 294eab559..cb37894d1 100644 --- a/src/net/torvald/spriteanimation/HasAssembledSprite.kt +++ b/src/net/torvald/spriteanimation/HasAssembledSprite.kt @@ -18,6 +18,16 @@ interface HasAssembledSprite { // FIXME sometimes the animmation is invisible (row and nFrames mismatch -- row is changed to 1 but it's drawing 3rd frame?) + /** + * Example usage: + * ``` + * this.animDescPath = "..." + * this.animDescPathGlow = "..." + * this.sprite = SpriteAnimation(actor) + * this.spriteGlow = SpriteAnimation(actor) + * reassembleSprite(this.sprite, this.spriteGlow) + * ``` + */ fun reassembleSprite(sprite: SpriteAnimation, spriteGlow: SpriteAnimation? = null) { _rebuild(ADProperties(Gdx.files.internal(animDescPath).read()), sprite) if (animDescPathGlow != null && spriteGlow != null) diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java index 0c6dafa70..78b81cb46 100644 --- a/src/net/torvald/terrarum/AppLoader.java +++ b/src/net/torvald/terrarum/AppLoader.java @@ -50,7 +50,6 @@ import static net.torvald.terrarum.TerrarumKt.printStackTrace; public class AppLoader implements ApplicationListener { public static final String GAME_NAME = TerrarumAppConfiguration.GAME_NAME; - public static final String COPYRIGHT_DATE_NAME = TerrarumAppConfiguration.COPYRIGHT_DATE_NAME; // is this jvm good? static { diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index f2ec32b13..b651b2f8a 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -225,9 +225,16 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { open fun removeActor(actor: Actor?) { if (actor == null) return - val indexToDelete = actorContainerActive.searchFor(actor.referenceID) { it.referenceID } - if (indexToDelete != null) { - actorContainerActive.remove(indexToDelete) + forceRemoveActor(actor) + } + + open fun forceRemoveActor(actor: Actor) { + arrayOf(actorContainerActive, actorContainerInactive).forEach { actorContainer -> + val indexToDelete = actorContainer.searchFor(actor.referenceID) { it.referenceID } + if (indexToDelete != null) { + actor.dispose() + actorContainer.remove(indexToDelete) + } } } diff --git a/src/net/torvald/terrarum/Point2d.kt b/src/net/torvald/terrarum/Point2d.kt index 41e4bec69..5642e794e 100644 --- a/src/net/torvald/terrarum/Point2d.kt +++ b/src/net/torvald/terrarum/Point2d.kt @@ -5,7 +5,15 @@ import org.dyn4j.geometry.Vector2 /** * Created by minjaesong on 2016-01-15. */ -data class Point2d(var x: Double, var y: Double) : Cloneable { +class Point2d() : Cloneable { + + var x: Double = 0.0 + var y: Double = 0.0 + + constructor(x: Double, y: Double) : this() { + this.x = x + this.y = y + } override fun toString(): String { return "($x, $y)" @@ -66,9 +74,21 @@ data class Point2d(var x: Double, var y: Double) : Cloneable { return this } + + operator fun component1() = x + operator fun component2() = y } -data class Point2i(var x: Int, var y: Int) { +class Point2i() { + + var x: Int = 0 + var y: Int = 0 + + constructor(x: Int, y: Int) : this() { + this.x = x + this.y = y + } + fun set(x: Int, y: Int) { this.x = x this.y = y @@ -94,4 +114,7 @@ data class Point2i(var x: Int, var y: Int) { return this } + + operator fun component1() = x + operator fun component2() = y } diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index d6544fcc8..7023deb58 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -494,6 +494,7 @@ val ccG = GameFontBase.toColorCode(0xF8F8) val ccV = GameFontBase.toColorCode(0xF080) val ccX = GameFontBase.toColorCode(0xF853) val ccK = GameFontBase.toColorCode(0xF888) +val ccE = GameFontBase.toColorCode(0xFBBB) typealias Second = Float diff --git a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt index cd65e80cb..8d69e107d 100644 --- a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt +++ b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt @@ -1,5 +1,7 @@ package net.torvald.terrarum +import net.torvald.terrarum.langpack.Lang + /** * You directly modify the source code to tune the engine to suit your needs. * @@ -11,6 +13,7 @@ object TerrarumAppConfiguration { ////////////////////////////////////// const val GAME_NAME = "Terrarum" const val COPYRIGHT_DATE_NAME = "Copyright 2013-2021 CuriousTorvald (minjaesong)" + val COPYRIGHT_LICENSE: String; get() = Lang["COPYRIGHT_GNU_GPL_3"] /** * diff --git a/src/net/torvald/terrarum/TitleScreen.kt b/src/net/torvald/terrarum/TitleScreen.kt index ea3cb4c0e..2e8672f1d 100644 --- a/src/net/torvald/terrarum/TitleScreen.kt +++ b/src/net/torvald/terrarum/TitleScreen.kt @@ -257,8 +257,8 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { batch.color = Color.LIGHT_GRAY val COPYTING = arrayOf( - AppLoader.COPYRIGHT_DATE_NAME, - Lang["COPYRIGHT_GNU_GPL_3"] + TerrarumAppConfiguration.COPYRIGHT_DATE_NAME, + TerrarumAppConfiguration.COPYRIGHT_LICENSE ) COPYTING.forEachIndexed { index, s -> diff --git a/src/net/torvald/terrarum/console/CommandDict.kt b/src/net/torvald/terrarum/console/CommandDict.kt index 1db00da02..56ee0ea28 100644 --- a/src/net/torvald/terrarum/console/CommandDict.kt +++ b/src/net/torvald/terrarum/console/CommandDict.kt @@ -8,6 +8,7 @@ import java.util.* */ object CommandDict { + // todo replace with reflection? internal val dict: HashMap = hashMapOf( "echo" to Echo, "error" to EchoError, @@ -63,6 +64,7 @@ object CommandDict { /* !! */"exportworld" to ExportWorld, /* !! */"exportactor" to ExportActor, /* !! */"importworld" to ImportWorld, + /* !! */"importactor" to ImportActor, /* !! */"exportfborgb" to ExportRendererFboRGB, /* !! */"printworld" to PrintWorld ) diff --git a/src/net/torvald/terrarum/gameactors/Actor.kt b/src/net/torvald/terrarum/gameactors/Actor.kt index 293189197..69bcab7d6 100644 --- a/src/net/torvald/terrarum/gameactors/Actor.kt +++ b/src/net/torvald/terrarum/gameactors/Actor.kt @@ -12,7 +12,20 @@ typealias ActorID = Int * * Created by minjaesong on 2015-12-31. */ -abstract class Actor(var renderOrder: RenderOrder, id: ActorID?) : Comparable, Runnable { +abstract class Actor() : Comparable, Runnable { + + /** + * Valid RefID is equal to or greater than 16777216. + * @return Reference ID. (16777216-0x7FFF_FFFF) + */ + open var referenceID: ActorID = 0 // in old time this was nullable without initialiser. If you're going to revert to that, add the reason why this should be nullable. + var renderOrder = RenderOrder.MIDDLE + + // needs zero-arg constructor for serialiser to work + constructor(renderOrder: RenderOrder, id: ActorID?) : this() { + referenceID = id ?: Terrarum.generateUniqueReferenceID(renderOrder) + } + enum class RenderOrder { BEHIND, // tapestries, some particles (obstructed by terrain) @@ -32,11 +45,6 @@ abstract class Actor(var renderOrder: RenderOrder, id: ActorID?) : Comparable): this(actor) { + @Transient lateinit var actor: Actor + internal set + + private constructor() + + constructor(actor: Actor) : this() { + this.actor = actor + } + + private constructor(actor: Actor, newMap: HashMap): this() { + this.actor = actor hashMap = newMap } override fun set(key: String, value: Any) { - /*if (key == AVKey.__PLAYER_QUICKSLOTSEL) { - printStackTrace(this) - }*/ - super.set(key, value) actor.onActorValueChange(key, value) // fire the event handler } diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index 41f289f9c..762dc5e15 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -36,9 +36,15 @@ import kotlin.math.roundToInt * * Created by minjaesong on 2016-01-13. */ -open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties, id: ActorID? = null) : - Actor(renderOrder, id) { +open class ActorWithBody() : Actor() { + var physProp = PhysProperties.HUMANOID_DEFAULT + + constructor(renderOrder: RenderOrder, physProp: PhysProperties, id: ActorID? = null) : this() { + this.physProp = physProp + this.renderOrder = renderOrder + id?.let { this.referenceID = id } + } @Transient val COLLISION_TEST_MODE = false diff --git a/src/net/torvald/terrarum/gameactors/Hitbox.kt b/src/net/torvald/terrarum/gameactors/Hitbox.kt index bb8690d05..db99d8aee 100644 --- a/src/net/torvald/terrarum/gameactors/Hitbox.kt +++ b/src/net/torvald/terrarum/gameactors/Hitbox.kt @@ -11,18 +11,15 @@ import org.dyn4j.geometry.Vector2 * * Created by minjaesong on 2016-01-15. */ -class Hitbox (x1: Double, y1: Double, width: Double, height: Double, var suppressWarning: Boolean = true) { +class Hitbox { - @Volatile var hitboxStart: Point2d - private set - inline val hitboxEnd: Point2d - get() = Point2d(hitboxStart.x + width, hitboxStart.y + height) - var width: Double = 0.0 - private set - var height: Double = 0.0 - private set + var suppressWarning = true + + private constructor() + + constructor(x1: Double, y1: Double, width: Double, height: Double, suppressWarning: Boolean = true) : this() { + this.suppressWarning = suppressWarning - init { hitboxStart = Point2d(x1, y1) this.width = width this.height = height @@ -33,6 +30,15 @@ class Hitbox (x1: Double, y1: Double, width: Double, height: Double, var suppres } } + @Volatile var hitboxStart: Point2d = Point2d(-1.0, -1.0) + private set + inline val hitboxEnd: Point2d + get() = Point2d(hitboxStart.x + width, hitboxStart.y + height) + var width: Double = 0.0 + private set + var height: Double = 0.0 + private set + val startX: Double get() = hitboxStart.x diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index 7ed622141..86f93dcf6 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -28,11 +28,11 @@ import kotlin.math.absoluteValue typealias BlockAddress = Long -class GameWorld : Disposable { +class GameWorld() : Disposable { var worldName: String = "New World" /** Index start at 1 */ - var worldIndex: Int + var worldIndex: Int = 1234567890 set(value) { if (value <= 0) throw Error("World index start at 1; you've entered $value") @@ -42,14 +42,14 @@ class GameWorld : Disposable { field = value } - val width: Int - val height: Int + var width: Int = 999; private set + var height: Int = 999; private set - var creationTime: Long + var creationTime: Long = AppLoader.getTIME_T() internal set - var lastPlayTime: Long + var lastPlayTime: Long = AppLoader.getTIME_T() internal set // there's a case of save-and-continue-playing - var totalPlayTime: Int + var totalPlayTime: Int = 0 internal set /** Used to calculate play time */ @@ -63,9 +63,9 @@ class GameWorld : Disposable { //val layerFluidPressure: MapLayerHalfFloat // (milibar - 1000) /** Tilewise spawn point */ - var spawnX: Int + var spawnX: Int = 0 /** Tilewise spawn point */ - var spawnY: Int + var spawnY: Int = 0 val wallDamages = HashArray() val terrainDamages = HashArray() @@ -119,7 +119,7 @@ class GameWorld : Disposable { /** * Create new world */ - constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) { + constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int): this() { if (width <= 0 || height <= 0) throw IllegalArgumentException("Non-positive width/height: ($width, $height)") this.worldIndex = worldIndex @@ -146,18 +146,6 @@ class GameWorld : Disposable { postLoad() } - constructor() { - worldIndex = 1234567890 - width = 999 - height = 999 - val time = AppLoader.getTIME_T() - creationTime = time - lastPlayTime = time - totalPlayTime = 0 - spawnX = 0 - spawnY = 0 - } - fun postLoad() { AppLoader.tileMaker.tags.forEach { printdbg(this, "tileNumber ${it.value.tileNumber} <-> tileName ${it.key}") diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 3dc60c95a..f91029881 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -32,7 +32,6 @@ import net.torvald.terrarum.gameworld.WorldSimulator import net.torvald.terrarum.modulebasegame.gameworld.GameEconomy import net.torvald.terrarum.modulebasegame.ui.* import net.torvald.terrarum.weather.WeatherMixer -import net.torvald.terrarum.modulebasegame.worldgenerator.RoguelikeRandomiser import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen import net.torvald.terrarum.modulebasegame.worldgenerator.WorldgenParams import net.torvald.terrarum.ui.UICanvas @@ -40,7 +39,6 @@ import net.torvald.terrarum.worlddrawer.BlocksDrawer import net.torvald.terrarum.worlddrawer.FeaturesDrawer import net.torvald.terrarum.worlddrawer.WorldCamera import net.torvald.util.CircularArray -import net.torvald.util.SortedArrayList import java.util.* import java.util.concurrent.locks.ReentrantLock import kotlin.math.roundToInt @@ -313,8 +311,8 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { /** Load rest of the game with GL context */ fun postInit() { //setTheRealGamerFirstTime(PlayerBuilderSigrid()) -// setTheRealGamerFirstTime(PlayerBuilderTestSubject1()) - setTheRealGamerFirstTime(PlayerBuilderWerebeastTest()) + setTheRealGamerFirstTime(PlayerBuilderTestSubject1()) +// setTheRealGamerFirstTime(PlayerBuilderWerebeastTest()) @@ -850,9 +848,9 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { if (it is Pocketed) { it.inventory.forEach { inventoryEntry -> - ItemCodex[inventoryEntry.item]!!.effectWhileInPocket(delta) - if (it.equipped(inventoryEntry.item)) { - ItemCodex[inventoryEntry.item]!!.effectWhenEquipped(delta) + ItemCodex[inventoryEntry.itm]!!.effectWhileInPocket(delta) + if (it.equipped(inventoryEntry.itm)) { + ItemCodex[inventoryEntry.itm]!!.effectWhenEquipped(delta) } } } @@ -920,17 +918,25 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { if (actor.referenceID == theRealGamer.referenceID || actor.referenceID == 0x51621D) // do not delete this magic throw RuntimeException("Attempted to remove player.") - val indexToDelete = actorContainerActive.searchForIndex(actor.referenceID) { it.referenceID } - if (indexToDelete != null) { - printdbg(this, "Removing actor $actor") - printStackTrace(this) - actorContainerActive.removeAt(indexToDelete) + forceRemoveActor(actor) + } - // indexToDelete >= 0 means that the actor certainly exists in the game - // which means we don't need to check if i >= 0 again - if (actor is ActorWithBody) { - actorToRenderQueue(actor).remove(actor) + override fun forceRemoveActor(actor: Actor) { + arrayOf(actorContainerActive, actorContainerInactive).forEach { actorContainer -> + val indexToDelete = actorContainer.searchForIndex(actor.referenceID) { it.referenceID } + if (indexToDelete != null) { + printdbg(this, "Removing actor $actor") + printStackTrace(this) + + actor.dispose() + actorContainer.removeAt(indexToDelete) + + // indexToDelete >= 0 means that the actor certainly exists in the game + // which means we don't need to check if i >= 0 again + if (actor is ActorWithBody) { + actorToRenderQueue(actor).remove(actor) + } } } } @@ -973,10 +979,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { } actorContainerActive.add(actor) - - if (actor is ActorWithBody) { - actorToRenderQueue(actor).add(actor) - } + if (actor is ActorWithBody) actorToRenderQueue(actor).add(actor) } } diff --git a/src/net/torvald/terrarum/modulebasegame/console/ExportMeta.kt b/src/net/torvald/terrarum/modulebasegame/console/ExportMeta.kt index dcba3e666..31d0364a2 100644 --- a/src/net/torvald/terrarum/modulebasegame/console/ExportMeta.kt +++ b/src/net/torvald/terrarum/modulebasegame/console/ExportMeta.kt @@ -6,6 +6,7 @@ import net.torvald.terrarum.Terrarum import net.torvald.terrarum.console.ConsoleCommand import net.torvald.terrarum.console.Echo import net.torvald.terrarum.modulebasegame.TerrarumIngame +import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.serialise.WriteActor import net.torvald.terrarum.serialise.WriteMeta import net.torvald.terrarum.serialise.WriteWorld @@ -40,10 +41,10 @@ object ExportWorld : ConsoleCommand { if (args.size == 2) { try { val str = WriteWorld(Terrarum.ingame!! as TerrarumIngame).invoke() - val writer = java.io.FileWriter(AppLoader.defaultDir + "/Exports/${args[1]}", false) + val writer = java.io.FileWriter(AppLoader.defaultDir + "/Exports/${args[1]}.json", false) writer.write(str) writer.close() - Echo("Exportworld: exported to ${args[1]}") + Echo("Exportworld: exported to ${args[1]}.json") } catch (e: IOException) { Echo("Exportworld: IOException raised.") @@ -56,7 +57,7 @@ object ExportWorld : ConsoleCommand { } override fun printUsage() { - Echo("Usage: Exportworld filename.json") + Echo("Usage: Exportworld filename-without-extension") } } @@ -67,7 +68,7 @@ object ExportActor : ConsoleCommand { val player = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying if (player == null) return - val str = WriteActor(player) + val str = WriteActor(player as IngamePlayer) val writer = java.io.FileWriter(AppLoader.defaultDir + "/Exports/${args[1]}.json", false) writer.write(str) writer.close() diff --git a/src/net/torvald/terrarum/modulebasegame/console/ImportWorld.kt b/src/net/torvald/terrarum/modulebasegame/console/ImportWorld.kt index af287310d..2fc6232d8 100644 --- a/src/net/torvald/terrarum/modulebasegame/console/ImportWorld.kt +++ b/src/net/torvald/terrarum/modulebasegame/console/ImportWorld.kt @@ -5,6 +5,7 @@ import net.torvald.terrarum.Terrarum import net.torvald.terrarum.console.ConsoleCommand import net.torvald.terrarum.console.Echo import net.torvald.terrarum.modulebasegame.TerrarumIngame +import net.torvald.terrarum.serialise.ReadActor import net.torvald.terrarum.serialise.ReadWorld import net.torvald.terrarum.serialise.WriteMeta import java.io.IOException @@ -16,9 +17,9 @@ object ImportWorld : ConsoleCommand { override fun execute(args: Array) { if (args.size == 2) { try { - val reader = java.io.FileReader(AppLoader.defaultDir + "/Exports/${args[1]}") + val reader = java.io.FileReader(AppLoader.defaultDir + "/Exports/${args[1]}.json") ReadWorld(Terrarum.ingame!! as TerrarumIngame).invoke(reader) - Echo("Importworld: imported a world from ${args[1]}") + Echo("Importworld: imported a world from ${args[1]}.json") } catch (e: IOException) { Echo("Importworld: IOException raised.") @@ -31,6 +32,29 @@ object ImportWorld : ConsoleCommand { } override fun printUsage() { - Echo("Usage: Importworld filename.json") + Echo("Usage: Importworld filename-without-extension") + } +} + +object ImportActor : ConsoleCommand { + override fun execute(args: Array) { + if (args.size == 2) { + try { + val reader = java.io.FileReader(AppLoader.defaultDir + "/Exports/${args[1]}.json") + ReadActor(Terrarum.ingame!! as TerrarumIngame).invoke(reader) + Echo("Importactor: imported an actor from ${args[1]}.json") + } + catch (e: IOException) { + Echo("Importactor: IOException raised.") + e.printStackTrace() + } + } + else { + printUsage() + } + } + + override fun printUsage() { + Echo("Usage: Importactor filename-without-extension") } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt index 9eee9a972..39e4332cf 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt @@ -9,11 +9,9 @@ import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gameactors.faction.Faction import net.torvald.terrarum.gameitem.GameItem -import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.itemproperties.ItemCodex import net.torvald.terrarum.itemproperties.Material import net.torvald.terrarum.realestate.LandUtil -import net.torvald.terrarum.worlddrawer.LightmapRenderer import org.dyn4j.geometry.Vector2 import java.util.* @@ -28,12 +26,13 @@ import java.util.* * * Created by minjaesong on 2016-10-24. */ -open class ActorHumanoid( - birth: Long, - death: Long? = null, - physProp: PhysProperties = PhysProperties.HUMANOID_DEFAULT -) : ActorWithBody(RenderOrder.MIDDLE, physProp = physProp), Controllable, Pocketed, Factionable, Luminous, LandHolder, HistoricalFigure { +open class ActorHumanoid() : ActorWithBody(), Controllable, Pocketed, Factionable, Luminous, LandHolder, HistoricalFigure { + constructor(birth: Long, death: Long? = null, physProp: PhysProperties = PhysProperties.HUMANOID_DEFAULT) : this() { + actorValue[AVKey.__HISTORICAL_BORNTIME] = birth + death?.let { actorValue[AVKey.__HISTORICAL_DEADTIME] = death } + this.physProp = physProp + } var vehicleRiding: Controllable? = null // usually player only @@ -176,11 +175,6 @@ open class ActorHumanoid( override val material = Material() } - init { - actorValue[AVKey.__HISTORICAL_BORNTIME] = birth - death?.let { actorValue[AVKey.__HISTORICAL_DEADTIME] = death } - } - override fun update(delta: Float) { super.update(delta) @@ -217,11 +211,11 @@ open class ActorHumanoid( // update inventory items inventory.forEach { - if (!inventory.itemEquipped.contains(it.item)) { // unequipped - ItemCodex[it.item]!!.effectWhileInPocket(delta) + if (!inventory.itemEquipped.contains(it.itm)) { // unequipped + ItemCodex[it.itm]!!.effectWhileInPocket(delta) } else { // equipped - ItemCodex[it.item]!!.effectWhenEquipped(delta) + ItemCodex[it.itm]!!.effectWhenEquipped(delta) } } } @@ -640,7 +634,7 @@ open class ActorHumanoid( // make quickslot work if (key == AVKey.__PLAYER_QUICKSLOTSEL && value != null) { // ONLY FOR HAND_GRIPs!! - val quickBarItem = ItemCodex[inventory.getQuickslot(actorValue.getAsInt(key)!!)?.item] + val quickBarItem = ItemCodex[inventory.getQuickslot(actorValue.getAsInt(key)!!)?.itm] if (quickBarItem != null && quickBarItem.equipPosition == GameItem.EquipPosition.HAND_GRIP) { equipItem(quickBarItem) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt index 5775afe40..a5062f21b 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt @@ -1,29 +1,30 @@ package net.torvald.terrarum.modulebasegame.gameactors import net.torvald.terrarum.AppLoader -import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.blockproperties.BlockCodex import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.Actor import net.torvald.terrarum.gameitem.GameItem import net.torvald.terrarum.itemproperties.ItemCodex import net.torvald.terrarum.gameitem.ItemID -import net.torvald.terrarum.lock -import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.ui.UIQuickslotBar -import java.math.BigInteger -import java.util.* -import java.util.concurrent.locks.ReentrantLock /** * Created by minjaesong on 2016-03-15. */ -class ActorInventory(@Transient val actor: Pocketed, maxCapacity: Int, capacityMode: Int): - FixtureInventory(maxCapacity, capacityMode) { +class ActorInventory() : FixtureInventory() { // FIXME unless absolutely necessary, don't store full item object; only store its dynamicID + @Transient lateinit var actor: Pocketed + internal set + + constructor(actor: Pocketed, maxCapacity: Int, capacityMode: Int) : this() { + this.actor = actor + this.maxCapacity = maxCapacity + this.capacityMode = capacityMode + } + /** * List of all equipped items (tools, armours, rings, necklaces, etc.) */ @@ -38,7 +39,7 @@ class ActorInventory(@Transient val actor: Pocketed, maxCapacity: Int, capacityM override fun remove(item: GameItem, count: Int) { super.remove(item, count) { existingItem -> // unequip, if applicable - actor.unequipItem(existingItem.item) + actor.unequipItem(existingItem.itm) // also unequip on the quickslot actor.actorValue.getAsInt(AVKey.__PLAYER_QUICKSLOTSEL)?.let { setQuickBar(it, null) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureInventory.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureInventory.kt index b68b71b17..76ef224d1 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureInventory.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureInventory.kt @@ -13,8 +13,16 @@ import java.util.concurrent.locks.ReentrantLock * Created by minjaesong on 2021-03-16. */ -open class FixtureInventory(var maxCapacity: Int, var capacityMode: Int) { - +open class FixtureInventory() { + + var maxCapacity = 100 + var capacityMode = CAPACITY_MODE_COUNT + + constructor(maxCapacity: Int, capacityMode: Int) : this() { + this.maxCapacity = maxCapacity + this.capacityMode = capacityMode + } + companion object { val CAPACITY_MODE_NO_ENCUMBER = 0 val CAPACITY_MODE_COUNT = 1 @@ -60,7 +68,7 @@ open class FixtureInventory(var maxCapacity: Int, var capacityMode: Int) { // if the item already exists if (existingItem != null) { // increment count - existingItem.amount += count + existingItem.qty += count } // new item else { @@ -90,14 +98,14 @@ open class FixtureInventory(var maxCapacity: Int, var capacityMode: Int) { val existingItem = invSearchByDynamicID(item.dynamicID) if (existingItem != null) { // if the item already exists - val newCount = existingItem.amount - count + val newCount = existingItem.qty - count if (newCount < 0) { - throw Error("Tried to remove $count of $item, but the inventory only contains ${existingItem.amount} of them.") + throw Error("Tried to remove $count of $item, but the inventory only contains ${existingItem.qty} of them.") } else if (newCount > 0) { // decrement count - existingItem.amount = newCount + existingItem.qty = newCount } else { // depleted item; remove entry from inventory @@ -128,12 +136,12 @@ open class FixtureInventory(var maxCapacity: Int, var capacityMode: Int) { else getTotalCount().toDouble() - fun getTotalWeight(): Double = itemList.map { ItemCodex[it.item]!!.mass * it.amount }.sum() + fun getTotalWeight(): Double = itemList.map { ItemCodex[it.itm]!!.mass * it.qty }.sum() /** * Real amount */ - fun getTotalCount(): Int = itemList.map { it.amount }.sum() + fun getTotalCount(): Int = itemList.map { it.qty }.sum() /** * Unique amount, multiple items are calculated as one @@ -182,7 +190,7 @@ open class FixtureInventory(var maxCapacity: Int, var capacityMode: Int) { ReentrantLock().lock { var j = arr.lastIndex - 1 val x = arr.last() - while (j >= 0 && arr[j].item > x.item) { + while (j >= 0 && arr[j].itm > x.itm) { arr[j + 1] = arr[j] j -= 1 } @@ -200,9 +208,9 @@ open class FixtureInventory(var maxCapacity: Int, var capacityMode: Int) { val mid = (low + high).ushr(1) // safe from overflows val midVal = if (searchMode == STATIC_ID) - ItemCodex[this[mid].item]!!.originalID + ItemCodex[this[mid].itm]!!.originalID else - ItemCodex[this[mid].item]!!.dynamicID + ItemCodex[this[mid].itm]!!.dynamicID if (ID > midVal) low = mid + 1 @@ -215,4 +223,19 @@ open class FixtureInventory(var maxCapacity: Int, var capacityMode: Int) { } } -data class InventoryPair(val item: ItemID, var amount: Int) \ No newline at end of file +class InventoryPair { + + var itm: ItemID = ""; private set + var qty: Int = 0 + + private constructor() + + constructor(item: ItemID, quantity: Int) : this() { + itm = item + qty = quantity + } + + operator fun component1() = itm + operator fun component2() = qty + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt index 60c81d456..6fad625e3 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.gameactors import net.torvald.spriteanimation.HasAssembledSprite import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.gameactors.AVKey /** @@ -10,11 +11,17 @@ import net.torvald.terrarum.Terrarum * Created by minjaesong on 2015-12-31. */ -class IngamePlayer( - override var animDescPath: String, - override var animDescPathGlow: String? = null, - born: Long -) : ActorHumanoid(born), HasAssembledSprite { +class IngamePlayer() : ActorHumanoid(), HasAssembledSprite { + + override var animDescPath = "invalid" + override var animDescPathGlow: String? = null + + + constructor(animDescPath: String, animDescPathGlow: String?, born: Long) : this() { + this.animDescPath = animDescPath + this.animDescPathGlow = animDescPathGlow + actorValue[AVKey.__HISTORICAL_BORNTIME] = born + } /** * Creates new Player instance with empty elements (sprites, actorvalue, etc.). diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ThreadActorUpdate.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ThreadActorUpdate.kt index 03c399d65..0a927b052 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ThreadActorUpdate.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ThreadActorUpdate.kt @@ -16,9 +16,9 @@ class ThreadActorUpdate(val startIndex: Int, val endIndex: Int) : Callable if (it is Pocketed) { it.inventory.forEach { inventoryEntry -> - ItemCodex[inventoryEntry.item]?.effectWhileInPocket(AppLoader.UPDATE_RATE) - if (it.equipped(inventoryEntry.item)) { - ItemCodex[inventoryEntry.item]?.effectWhenEquipped(AppLoader.UPDATE_RATE) + ItemCodex[inventoryEntry.itm]?.effectWhileInPocket(AppLoader.UPDATE_RATE) + if (it.equipped(inventoryEntry.itm)) { + ItemCodex[inventoryEntry.itm]?.effectWhenEquipped(AppLoader.UPDATE_RATE) } } } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/AmmoMeterProxy.kt b/src/net/torvald/terrarum/modulebasegame/ui/AmmoMeterProxy.kt index 755a52c50..a3d42c71e 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/AmmoMeterProxy.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/AmmoMeterProxy.kt @@ -19,7 +19,7 @@ object AmmoMeterProxy { else { meter.vitalGetterVal = { if (currentItem.stackable && currentItem.maxDurability == GameItem.DURABILITY_NA) { - actor.inventory.invSearchByDynamicID(currentItem.dynamicID)!!.amount.toFloat() + actor.inventory.invSearchByDynamicID(currentItem.dynamicID)!!.qty.toFloat() } else currentItem.durability diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryEquippedView.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryEquippedView.kt index d7e5758bb..533083037 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryEquippedView.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryEquippedView.kt @@ -139,7 +139,7 @@ class UIItemInventoryEquippedView( val itemRecord = inventory.invSearchByDynamicID(item)!! itemGrid[k].item = ItemCodex[item] - itemGrid[k].amount = itemRecord.amount + itemGrid[k].amount = itemRecord.qty itemGrid[k].itemImage = ItemCodex.getItemImage(item) itemGrid[k].quickslot = null // don't need to be displayed itemGrid[k].equippedSlot = null // don't need to be displayed diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryItemGrid.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryItemGrid.kt index 422a07457..8cf0b45a5 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryItemGrid.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryItemGrid.kt @@ -120,7 +120,7 @@ class UIItemInventoryItemGrid( inventory.setQuickBar( slot, - if (currentSlotItem?.item != item.dynamicID) + if (currentSlotItem?.itm != item.dynamicID) item.dynamicID // register else null // drop registration @@ -129,7 +129,7 @@ class UIItemInventoryItemGrid( // search for duplicates in the quickbar, except mine // if there is, unregister the other (0..9).minus(slot).forEach { - if (inventory.getQuickslot(it)?.item == item.dynamicID) { + if (inventory.getQuickslot(it)?.itm == item.dynamicID) { inventory.setQuickBar(it, null) } } @@ -412,27 +412,27 @@ class UIItemInventoryItemGrid( // filter items inventory.forEach { - if ((filter.contains(ItemCodex[it.item]!!.inventoryCategory) || filter[0] == CAT_ALL)) + if ((filter.contains(ItemCodex[it.itm]!!.inventoryCategory) || filter[0] == CAT_ALL)) inventorySortList.add(it) } // sort if needed // test sort by name - inventorySortList.sortBy { ItemCodex[it.item]!!.name } + inventorySortList.sortBy { ItemCodex[it.itm]!!.name } // map sortList to item list for (k in items.indices) { // we have an item try { val sortListItem = inventorySortList[k + itemPage * items.size] - items[k].item = ItemCodex[sortListItem.item] - items[k].amount = sortListItem.amount - items[k].itemImage = ItemCodex.getItemImage(sortListItem.item) + items[k].item = ItemCodex[sortListItem.itm] + items[k].amount = sortListItem.qty + items[k].itemImage = ItemCodex.getItemImage(sortListItem.itm) // set quickslot number if (inventory is ActorInventory) { for (qs in 1..UIQuickslotBar.SLOT_COUNT) { - if (sortListItem.item == inventory.getQuickslot(qs - 1)?.item) { + if (sortListItem.itm == inventory.getQuickslot(qs - 1)?.itm) { items[k].quickslot = qs % 10 // 10 -> 0, 1..9 -> 1..9 break } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotBar.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotBar.kt index 92f837341..7b0b9b029 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotBar.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotBar.kt @@ -48,7 +48,7 @@ class UIQuickslotBar : UICanvas() { override fun renderUI(batch: SpriteBatch, camera: Camera) { for (i in 0..SLOT_COUNT - 1) { - val item = ItemCodex[(Terrarum.ingame!! as TerrarumIngame).actorNowPlaying?.inventory?.getQuickslot(i)?.item] + val item = ItemCodex[(Terrarum.ingame!! as TerrarumIngame).actorNowPlaying?.inventory?.getQuickslot(i)?.itm] val image = if (i == selection) ItemSlotImageFactory.produceLarge(false, (i + 1) % SLOT_COUNT, item) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt index 6131b9efd..611fee583 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIQuickslotPie.kt @@ -64,7 +64,7 @@ class UIQuickslotPie : UICanvas() { override fun renderUI(batch: SpriteBatch, camera: Camera) { // draw radial thingies for (i in 0..slotCount - 1) { - val item = ItemCodex[(Terrarum.ingame!! as TerrarumIngame).actorNowPlaying?.inventory?.getQuickslot(i)?.item] + val item = ItemCodex[(Terrarum.ingame!! as TerrarumIngame).actorNowPlaying?.inventory?.getQuickslot(i)?.itm] // set position val angle = Math.PI * 2.0 * (i.toDouble() / slotCount) + Math.PI // 180 deg monitor-wise diff --git a/src/net/torvald/terrarum/serialise/ReadActor.kt b/src/net/torvald/terrarum/serialise/ReadActor.kt new file mode 100644 index 000000000..7955e2f47 --- /dev/null +++ b/src/net/torvald/terrarum/serialise/ReadActor.kt @@ -0,0 +1,41 @@ +package net.torvald.terrarum.serialise + +import net.torvald.spriteanimation.HasAssembledSprite +import net.torvald.spriteanimation.SpriteAnimation +import net.torvald.terrarum.gameactors.Actor +import net.torvald.terrarum.gameactors.ActorWithBody +import net.torvald.terrarum.modulebasegame.TerrarumIngame +import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid +import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer +import java.io.InputStream +import java.io.Reader + +/** + * Created by minjaesong on 2021-08-27. + */ +class ReadActor(val ingame: TerrarumIngame) { + + open fun invoke(worldDataStream: InputStream) { + postRead(Common.jsoner.fromJson(IngamePlayer::class.java, worldDataStream)) + } + + open fun invoke(worldDataStream: Reader) { + IngamePlayer() + + postRead(Common.jsoner.fromJson(IngamePlayer::class.java, worldDataStream)) + } + + private fun postRead(actor: IngamePlayer) { + // filling in Transients + actor.actorValue.actor = actor + actor.inventory.actor = actor + actor.sprite = SpriteAnimation(actor) + if (actor.animDescPathGlow != null) actor.spriteGlow = SpriteAnimation(actor) + actor.reassembleSprite(actor.sprite!!, actor.spriteGlow) + // replace existing player + ingame.forceRemoveActor(ingame.actorNowPlaying!!) + ingame.addNewActor(actor) + ingame.actorNowPlaying = actor + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/serialise/WriteActor.kt b/src/net/torvald/terrarum/serialise/WriteActor.kt index 90ada814a..8085f4fa3 100644 --- a/src/net/torvald/terrarum/serialise/WriteActor.kt +++ b/src/net/torvald/terrarum/serialise/WriteActor.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.utils.Json import com.badlogic.gdx.utils.JsonValue import com.badlogic.gdx.utils.JsonWriter import net.torvald.terrarum.gameactors.Actor +import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64 import java.math.BigInteger @@ -12,11 +13,11 @@ import java.math.BigInteger */ object WriteActor { - operator fun invoke(actor: Actor): String { + operator fun invoke(actor: IngamePlayer): String { return Common.jsoner.toJson(actor) } - fun encodeToByteArray64(actor: Actor): ByteArray64 { + fun encodeToByteArray64(actor: IngamePlayer): ByteArray64 { val ba = ByteArray64() this.invoke(actor).toByteArray().forEach { ba.add(it) } return ba diff --git a/src/net/torvald/terrarum/ui/ConsoleWindow.kt b/src/net/torvald/terrarum/ui/ConsoleWindow.kt index 2671c95e2..8116479fc 100644 --- a/src/net/torvald/terrarum/ui/ConsoleWindow.kt +++ b/src/net/torvald/terrarum/ui/ConsoleWindow.kt @@ -4,12 +4,12 @@ import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch -import net.torvald.terrarum.AppLoader -import net.torvald.terrarum.Terrarum +import net.torvald.EMDASH +import net.torvald.terrarum.* import net.torvald.terrarum.console.Authenticator import net.torvald.terrarum.console.CommandInterpreter -import net.torvald.terrarum.fillRect import net.torvald.terrarum.langpack.Lang +import net.torvald.terrarumsansbitmap.gdx.GameFontBase import net.torvald.util.CircularArray @@ -183,7 +183,8 @@ class ConsoleWindow : UICanvas() { commandInputPool = StringBuilder() if (Authenticator.b()) { - sendMessage("${AppLoader.GAME_NAME} ${AppLoader.getVERSION_STRING()}") + sendMessage("$ccE${TerrarumAppConfiguration.GAME_NAME} ${AppLoader.getVERSION_STRING()} $EMDASH ${TerrarumAppConfiguration.COPYRIGHT_DATE_NAME}") + sendMessage("$ccE${TerrarumAppConfiguration.COPYRIGHT_LICENSE}") sendMessage(Lang["DEV_MESSAGE_CONSOLE_CODEX"]) } } diff --git a/src/org/dyn4j/geometry/Vector2.kt b/src/org/dyn4j/geometry/Vector2.kt index eb79cc542..8f180c181 100644 --- a/src/org/dyn4j/geometry/Vector2.kt +++ b/src/org/dyn4j/geometry/Vector2.kt @@ -132,6 +132,9 @@ class Vector2 { this.y = Math.sin(direction) } + operator fun component1() = x + operator fun component2() = y + /** * Returns a copy of this [Vector2]. * @return [Vector2]