mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-08 04:41:51 +09:00
save/load kinda mostly working but fixtures are not getting their sprites back
This commit is contained in:
@@ -1139,6 +1139,9 @@ public class AppLoader implements ApplicationListener {
|
||||
|
||||
// //
|
||||
|
||||
public static String csiR = "\u001B[31m";
|
||||
public static String csi0 = "\u001B[m";
|
||||
|
||||
public static void printdbg(Object obj, Object message) {
|
||||
if (IS_DEVELOPMENT_BUILD) {
|
||||
String out = (obj instanceof String) ? (String) obj : obj.getClass().getSimpleName();
|
||||
@@ -1153,9 +1156,9 @@ public class AppLoader implements ApplicationListener {
|
||||
if (IS_DEVELOPMENT_BUILD) {
|
||||
String out = (obj instanceof String) ? (String) obj : obj.getClass().getSimpleName();
|
||||
if (message == null)
|
||||
System.err.println("[" + out + "] null");
|
||||
System.out.println(csiR + "[" + out + "] null" + csi0);
|
||||
else
|
||||
System.err.println("[" + out + "] " + message.toString());
|
||||
System.out.println(csiR + "[" + out + "] " + message.toString() + csi0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import net.torvald.util.CircularArray
|
||||
|
||||
open class LoadScreenBase : ScreenAdapter(), Disposable {
|
||||
|
||||
open var preLoadJob: (LoadScreenBase) -> Unit = {}
|
||||
open var screenToLoad: IngameInstance? = null
|
||||
open lateinit var screenLoadingThread: Thread
|
||||
|
||||
@@ -33,6 +34,7 @@ open class LoadScreenBase : ScreenAdapter(), Disposable {
|
||||
else {
|
||||
val runnable = {
|
||||
try {
|
||||
preLoadJob(this)
|
||||
screenToLoad!!.show()
|
||||
}
|
||||
catch (e: Exception) {
|
||||
|
||||
@@ -123,7 +123,7 @@ object ModMgr {
|
||||
}
|
||||
|
||||
newClass?.let {
|
||||
val newClassConstructor = newClass.getConstructor(/* no args defined */)
|
||||
val newClassConstructor = newClass!!.getConstructor(/* no args defined */)
|
||||
val newClassInstance = newClassConstructor.newInstance(/* no args defined */)
|
||||
|
||||
entryPointClasses.add(newClassInstance as ModuleEntryPoint)
|
||||
@@ -141,29 +141,63 @@ object ModMgr {
|
||||
catch (e: Throwable) {
|
||||
printdbgerr(this, "There was an error while loading module $moduleName")
|
||||
printdbgerr(this, "\t$e")
|
||||
e.printStackTrace(System.err)
|
||||
print(AppLoader.csiR); e.printStackTrace(System.out); print(AppLoader.csi0)
|
||||
moduleInfo.remove(moduleName)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// lists available engines
|
||||
/*val manager = ScriptEngineManager()
|
||||
val factories = manager.engineFactories
|
||||
for (f in factories) {
|
||||
println("engine name:" + f.engineName)
|
||||
println("engine version:" + f.engineVersion)
|
||||
println("language name:" + f.languageName)
|
||||
println("language version:" + f.languageVersion)
|
||||
println("names:" + f.names)
|
||||
println("mime:" + f.mimeTypes)
|
||||
println("extension:" + f.extensions)
|
||||
println("-----------------------------------------------")
|
||||
}*/
|
||||
}
|
||||
|
||||
operator fun invoke() { }
|
||||
|
||||
fun reloadModules() {
|
||||
loadOrder.forEach {
|
||||
val moduleName = it
|
||||
|
||||
printmsg(this, "Reloading module $moduleName")
|
||||
|
||||
try {
|
||||
checkExistence(moduleName)
|
||||
val modMetadata = moduleInfo[it]!!
|
||||
val entryPoint = modMetadata.entryPoint
|
||||
|
||||
|
||||
// run entry script in entry point
|
||||
if (entryPoint.isNotBlank()) {
|
||||
var newClass: Class<*>? = null
|
||||
try {
|
||||
newClass = Class.forName(entryPoint)
|
||||
}
|
||||
catch (e: ClassNotFoundException) {
|
||||
printdbgerr(this, "$moduleName has nonexisting entry point, skipping...")
|
||||
printdbgerr(this, "\t$e")
|
||||
moduleInfo.remove(moduleName)
|
||||
}
|
||||
|
||||
newClass?.let {
|
||||
val newClassConstructor = newClass!!.getConstructor(/* no args defined */)
|
||||
val newClassInstance = newClassConstructor.newInstance(/* no args defined */)
|
||||
|
||||
entryPointClasses.add(newClassInstance as ModuleEntryPoint)
|
||||
(newClassInstance as ModuleEntryPoint).invoke()
|
||||
}
|
||||
}
|
||||
|
||||
printdbg(this, "$moduleName reloaded successfully")
|
||||
}
|
||||
catch (noSuchModule: FileNotFoundException) {
|
||||
printdbgerr(this, "No such module: $moduleName, skipping...")
|
||||
moduleInfo.remove(moduleName)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
printdbgerr(this, "There was an error while loading module $moduleName")
|
||||
printdbgerr(this, "\t$e")
|
||||
print(AppLoader.csiR); e.printStackTrace(System.out); print(AppLoader.csi0)
|
||||
moduleInfo.remove(moduleName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkExistence(module: String) {
|
||||
if (!moduleInfo.containsKey(module))
|
||||
throw FileNotFoundException("No such module: $module")
|
||||
|
||||
@@ -36,7 +36,7 @@ object PostProcessor : Disposable {
|
||||
private val defaultResCol = Color(0x66ffff66)
|
||||
private val safeAreaCol = Color(0xffffff66.toInt())
|
||||
private val safeAreaCol2 = Color(0xffffff44.toInt())
|
||||
private val currentResCol = Color(0xff00ff44.toInt())
|
||||
private val currentResCol = Color(0xffffee44.toInt())
|
||||
|
||||
private val debugUI = BasicDebugInfoWindow()
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ object SanicLoadScreen : LoadScreenBase() {
|
||||
|
||||
// log messages
|
||||
it.color = messageForegroundColour
|
||||
messages.forEachIndexed { i, s ->
|
||||
messages.reversed().forEachIndexed { i, s ->
|
||||
AppLoader.fontGame.draw(it,
|
||||
s,
|
||||
AppLoader.screenSize.tvSafeGraphicsWidth + 16f,
|
||||
@@ -213,7 +213,7 @@ object SanicLoadScreen : LoadScreenBase() {
|
||||
|
||||
// log messages
|
||||
it.color = messageForegroundColour
|
||||
messages.forEachIndexed { i, s ->
|
||||
messages.reversed().forEachIndexed { i, s ->
|
||||
AppLoader.fontGame.draw(it,
|
||||
s,
|
||||
AppLoader.screenSize.tvSafeGraphicsWidth + 16f,
|
||||
|
||||
@@ -20,31 +20,31 @@ import java.io.IOException
|
||||
*/
|
||||
class BlockCodex {
|
||||
|
||||
val blockProps = HashMap<ItemID, BlockProp>()
|
||||
@Transient val blockProps = HashMap<ItemID, BlockProp>()
|
||||
|
||||
val dynamicLights = SortedArrayList<ItemID>() // does not include virtual ones
|
||||
@Transient val dynamicLights = SortedArrayList<ItemID>() // does not include virtual ones
|
||||
|
||||
/** 65536 */
|
||||
//val MAX_TERRAIN_TILES = GameWorld.TILES_SUPPORTED
|
||||
|
||||
@Transient private val nullProp = BlockProp()
|
||||
|
||||
var highestNumber = -1 // does not include virtual ones
|
||||
@Transient var highestNumber = -1 // does not include virtual ones
|
||||
private set
|
||||
|
||||
// fake props for "randomised" dynamic lights
|
||||
@Transient val DYNAMIC_RANDOM_CASES = 64
|
||||
private var virtualTileCursor = 1
|
||||
@Transient private var virtualTileCursor = 1
|
||||
|
||||
/**
|
||||
* One-to-Many
|
||||
*/
|
||||
val tileToVirtual = HashMap<ItemID, List<ItemID>>()
|
||||
@Transient val tileToVirtual = HashMap<ItemID, List<ItemID>>()
|
||||
|
||||
/**
|
||||
* Many-to-One
|
||||
*/
|
||||
val virtualToTile = HashMap<ItemID, ItemID>()
|
||||
@Transient val virtualToTile = HashMap<ItemID, ItemID>()
|
||||
|
||||
fun clear() {
|
||||
blockProps.clear()
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.io.IOException
|
||||
*/
|
||||
class WireCodex {
|
||||
|
||||
val wireProps = HashMap<ItemID, WireProp>()
|
||||
@Transient val wireProps = HashMap<ItemID, WireProp>()
|
||||
|
||||
@Transient private val nullProp = WireProp()
|
||||
|
||||
|
||||
@@ -3,9 +3,11 @@ package net.torvald.terrarum.gameactors
|
||||
import com.badlogic.gdx.Input
|
||||
import com.badlogic.gdx.graphics.Color
|
||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||
import net.torvald.spriteanimation.HasAssembledSprite
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.AppLoader.printdbg
|
||||
import net.torvald.terrarum.AppLoader.printdbgerr
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
||||
@@ -40,7 +42,7 @@ open class ActorWithBody : Actor {
|
||||
|
||||
var physProp = PhysProperties.HUMANOID_DEFAULT
|
||||
|
||||
protected constructor()
|
||||
protected constructor() : super()
|
||||
|
||||
constructor(renderOrder: RenderOrder, physProp: PhysProperties, id: ActorID? = null) : super(renderOrder, id) {
|
||||
this.physProp = physProp
|
||||
@@ -1644,11 +1646,19 @@ open class ActorWithBody : Actor {
|
||||
)
|
||||
}
|
||||
else {
|
||||
sprite.render(batch,
|
||||
(hitbox.startX - offsetX).toFloat(),
|
||||
(hitbox.startY - offsetY).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
try {
|
||||
sprite.render(batch,
|
||||
(hitbox.startX - offsetX).toFloat(),
|
||||
(hitbox.startY - offsetY).toFloat(),
|
||||
(scale).toFloat()
|
||||
)
|
||||
}
|
||||
catch (e: UninitializedPropertyAccessException) {
|
||||
printdbgerr(this, this.javaClass.simpleName)
|
||||
printdbgerr(this, actorValue.getAsString(AVKey.NAME))
|
||||
printdbgerr(this, if (this is HasAssembledSprite) this.animDescPath else "(not HasAssembledSprite)")
|
||||
printdbgerr(this, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package net.torvald.terrarum.gameactors
|
||||
|
||||
data class PhysProperties(
|
||||
val immobileBody: Boolean,
|
||||
var usePhysics: Boolean,
|
||||
val useStairs: Boolean
|
||||
val immobileBody: Boolean = false,
|
||||
var usePhysics: Boolean = true,
|
||||
val useStairs: Boolean = false
|
||||
) {
|
||||
companion object {
|
||||
val HUMANOID_DEFAULT = PhysProperties(
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.util.*
|
||||
* Created by minjaesong on 2016-05-09.
|
||||
*/
|
||||
class FactionCodex {
|
||||
val factionContainer = ArrayList<Faction>()
|
||||
@Transient val factionContainer = ArrayList<Faction>()
|
||||
|
||||
fun clear() = factionContainer.clear()
|
||||
|
||||
|
||||
@@ -133,10 +133,7 @@ class GameWorld() : Disposable {
|
||||
lastPlayTime = lastPlayTIME_T
|
||||
this.totalPlayTime = totalPlayTime
|
||||
|
||||
postLoad()
|
||||
}
|
||||
|
||||
fun postLoad() {
|
||||
AppLoader.tileMaker.tags.forEach {
|
||||
printdbg(this, "tileNumber ${it.value.tileNumber} <-> tileName ${it.key}")
|
||||
|
||||
@@ -148,6 +145,8 @@ class GameWorld() : Disposable {
|
||||
tileNumberToNameMap[0] = Block.AIR
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Load existing world
|
||||
*/
|
||||
@@ -271,7 +270,7 @@ class GameWorld() : Disposable {
|
||||
*/
|
||||
fun setTileTerrain(x: Int, y: Int, itemID: ItemID, bypassEvent: Boolean) {
|
||||
val (x, y) = coerceXY(x, y)
|
||||
val tilenum = tileNameToNumberMap[itemID]!!
|
||||
val tilenum = tileNameToNumberMap[itemID] ?: throw NullPointerException("Unknown tile name $itemID")
|
||||
|
||||
val oldTerrain = getTileFromTerrain(x, y)
|
||||
layerTerrain.unsafeSetTile(x, y, tilenum)
|
||||
|
||||
@@ -26,9 +26,9 @@ class ItemCodex {
|
||||
* <ItemID or RefID for Actor, TheItem>
|
||||
* Will return corresponding Actor if ID >= ACTORID_MIN
|
||||
*/
|
||||
val itemCodex = HashMap<ItemID, GameItem>()
|
||||
val dynamicItemDescription = HashMap<ItemID, GameItem>()
|
||||
val dynamicToStaticTable = HashMap<ItemID, ItemID>()
|
||||
@Transient val itemCodex = HashMap<ItemID, GameItem>()
|
||||
@Transient var dynamicItemDescription = HashMap<ItemID, GameItem>(); private set
|
||||
var dynamicToStaticTable = HashMap<ItemID, ItemID>(); private set
|
||||
|
||||
@Transient val ACTORID_MIN = ReferencingRanges.ACTORS.first
|
||||
|
||||
@@ -40,6 +40,17 @@ class ItemCodex {
|
||||
dynamicToStaticTable.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does not alter already-been-loaded itemCodex; only filles up dynamicitem-related fields
|
||||
*/
|
||||
fun loadFromSave(other: ItemCodex) {
|
||||
this.dynamicToStaticTable = other.dynamicToStaticTable
|
||||
dynamicToStaticTable.forEach { dynid, itemid ->
|
||||
printdbg(this, "Loadfromsave dynid $dynid ->> $itemid")
|
||||
dynamicItemDescription[dynid] = itemCodex[itemid]!!
|
||||
}
|
||||
}
|
||||
|
||||
private val itemImagePlaceholder: TextureRegion
|
||||
get() = CommonResourcePool.getAsTextureRegion("itemplaceholder_24") // copper pickaxe
|
||||
|
||||
@@ -62,7 +73,7 @@ class ItemCodex {
|
||||
if (code == null) return null
|
||||
|
||||
if (code.startsWith("$PREFIX_DYNAMICITEM:"))
|
||||
return dynamicItemDescription[code]!!
|
||||
return dynamicItemDescription[code] ?: throw NullPointerException("No ItemProp with id $code")
|
||||
else if (code.startsWith("$PREFIX_ACTORITEM:")) {
|
||||
val a = (Terrarum.ingame!! as TerrarumIngame).getActorByID(code.substring(6).toInt()) // actor item
|
||||
if (a is CanBeAnItem) return a.itemData
|
||||
|
||||
@@ -34,7 +34,7 @@ class Material {
|
||||
|
||||
class MaterialCodex {
|
||||
|
||||
val materialProps = HashMap<String, Material>()
|
||||
@Transient val materialProps = HashMap<String, Material>()
|
||||
@Transient private val nullMaterial = Material()
|
||||
|
||||
internal constructor()
|
||||
|
||||
@@ -177,6 +177,7 @@ object IngameRenderer : Disposable {
|
||||
|
||||
operator fun invoke(
|
||||
gamePaused: Boolean,
|
||||
zoom: Float = 1f,
|
||||
actorsRenderBehind : List<ActorWithBody>? = null,
|
||||
actorsRenderMiddle : List<ActorWithBody>? = null,
|
||||
actorsRenderMidTop : List<ActorWithBody>? = null,
|
||||
@@ -194,7 +195,6 @@ object IngameRenderer : Disposable {
|
||||
//renderingParticleCount = particlesContainer?.size ?: 0
|
||||
//renderingParticleCount = (particlesContainer?.buffer?.map { (!it.flagDespawn).toInt() } ?: listOf(0)).sum()
|
||||
renderingUIsCount = uiContainer?.countVisible() ?: 0
|
||||
val zoom = Terrarum.ingame?.screenZoom ?: 1f
|
||||
|
||||
invokeInit()
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
IngameRenderer.setRenderedWorld(world)
|
||||
|
||||
|
||||
super.show() // gameInitialised = true
|
||||
super.show() // this function sets gameInitialised = true
|
||||
}
|
||||
|
||||
data class NewWorldParameters(
|
||||
@@ -245,11 +245,11 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
data class Codices(
|
||||
val meta: WriteMeta.WorldMeta,
|
||||
val block: BlockCodex,
|
||||
// val block: BlockCodex,
|
||||
val item: ItemCodex,
|
||||
val wire: WireCodex,
|
||||
val material: MaterialCodex,
|
||||
val faction: FactionCodex,
|
||||
// val wire: WireCodex,
|
||||
// val material: MaterialCodex,
|
||||
// val faction: FactionCodex,
|
||||
val apocryphas: Map<String, Any>
|
||||
)
|
||||
|
||||
@@ -270,18 +270,13 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
printdbg(this, "loaded successfully.")
|
||||
}
|
||||
else {
|
||||
printdbg(this, "Ingame setting things up from the savegame")
|
||||
|
||||
RoguelikeRandomiser.loadFromSave(codices.meta.randseed0, codices.meta.randseed1)
|
||||
WeatherMixer.loadFromSave(codices.meta.weatseed0, codices.meta.weatseed1)
|
||||
|
||||
// Load BlockCodex //
|
||||
|
||||
// Load WireCodex //
|
||||
|
||||
// Load ItemCodex //
|
||||
Terrarum.itemCodex = codices.item
|
||||
|
||||
// Load MaterialCodex //
|
||||
|
||||
Terrarum.itemCodex.loadFromSave(codices.item)
|
||||
Terrarum.apocryphas = HashMap(codices.apocryphas)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,6 +678,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
IngameRenderer.invoke(
|
||||
paused,
|
||||
screenZoom,
|
||||
visibleActorsRenderBehind,
|
||||
visibleActorsRenderMiddle,
|
||||
visibleActorsRenderMidTop,
|
||||
|
||||
@@ -18,7 +18,7 @@ object ImportWorld : ConsoleCommand {
|
||||
if (args.size == 2) {
|
||||
try {
|
||||
val reader = java.io.FileReader(AppLoader.defaultDir + "/Exports/${args[1]}.json")
|
||||
ReadWorld(Terrarum.ingame!! as TerrarumIngame, reader)
|
||||
ReadWorld.readWorldAndSetNewWorld(Terrarum.ingame!! as TerrarumIngame, reader)
|
||||
Echo("Importworld: imported a world from ${args[1]}.json")
|
||||
}
|
||||
catch (e: IOException) {
|
||||
@@ -41,7 +41,7 @@ object ImportActor : ConsoleCommand {
|
||||
if (args.size == 2) {
|
||||
try {
|
||||
val reader = java.io.FileReader(AppLoader.defaultDir + "/Exports/${args[1]}.json")
|
||||
ReadActor(Terrarum.ingame!! as TerrarumIngame, reader)
|
||||
ReadActor.readActorAndAddToWorld(Terrarum.ingame!! as TerrarumIngame, reader)
|
||||
Echo("Importactor: imported an actor from ${args[1]}.json")
|
||||
}
|
||||
catch (e: IOException) {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package net.torvald.terrarum.modulebasegame.console
|
||||
|
||||
import net.torvald.ELLIPSIS
|
||||
import net.torvald.terrarum.AppLoader
|
||||
import net.torvald.terrarum.ccC
|
||||
import net.torvald.terrarum.ccG
|
||||
import net.torvald.terrarum.ccR
|
||||
import net.torvald.terrarum.console.ConsoleCommand
|
||||
import net.torvald.terrarum.console.Echo
|
||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64Reader
|
||||
@@ -20,12 +24,13 @@ object Load : ConsoleCommand {
|
||||
override fun execute(args: Array<String>) {
|
||||
if (args.size == 2) {
|
||||
try {
|
||||
Echo("${ccC}Changing context, ${ccR}do not touch the controller$ccC and ${ccG}wait$ccC$ELLIPSIS")
|
||||
|
||||
val charset = Common.CHARSET
|
||||
val file = File(AppLoader.defaultDir + "/Exports/${args[1]}")
|
||||
val disk = VDUtil.readDiskArchive(file, charset = charset)
|
||||
val meta = ReadMeta(disk)
|
||||
|
||||
println(meta.loadorder.joinToString())
|
||||
LoadSavegame(disk)
|
||||
}
|
||||
catch (e: IOException) {
|
||||
Echo("Load: IOException raised.")
|
||||
|
||||
@@ -13,7 +13,7 @@ import net.torvald.terrarum.modulebasegame.gameactors.FixtureTikiTorch
|
||||
@ConsoleNoExport
|
||||
internal object SpawnTikiTorch : ConsoleCommand {
|
||||
override fun execute(args: Array<String>) {
|
||||
val torch = FixtureTikiTorch { "Tiki Torch" }
|
||||
val torch = FixtureTikiTorch()
|
||||
torch.setPosition(Terrarum.mouseX, Terrarum.mouseY)
|
||||
|
||||
Terrarum.ingame!!.addNewActor(torch)
|
||||
|
||||
@@ -26,6 +26,8 @@ interface Electric {
|
||||
}
|
||||
|
||||
/**
|
||||
* Protip: do not make child classes take any argument, especially no function (function "classes" have no zero-arg constructor)
|
||||
*
|
||||
* Created by minjaesong on 2016-06-17.
|
||||
*/
|
||||
open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
@@ -37,7 +39,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
var mainUI: UICanvas? = null
|
||||
var inventory: FixtureInventory? = null
|
||||
|
||||
protected constructor()
|
||||
protected constructor() : super(RenderOrder.BEHIND, PhysProperties.IMMOBILE, null)
|
||||
|
||||
constructor(blockBox0: BlockBox,
|
||||
blockBoxProps: BlockBoxProps = BlockBoxProps(0),
|
||||
@@ -45,7 +47,8 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
nameFun: () -> String,
|
||||
mainUI: UICanvas? = null,
|
||||
inventory: FixtureInventory? = null,
|
||||
id: ActorID? = null) : super(renderOrder, PhysProperties.IMMOBILE, id) {
|
||||
id: ActorID? = null
|
||||
) : super(renderOrder, PhysProperties.IMMOBILE, id) {
|
||||
blockBox = blockBox0
|
||||
this.blockBoxProps = blockBoxProps
|
||||
this.renderOrder = renderOrder
|
||||
@@ -223,7 +226,10 @@ inline class BlockBoxProps(val flags: Int) {
|
||||
* @param width Width of the block box, tile-wise
|
||||
* @param height Height of the block box, tile-wise
|
||||
*/
|
||||
data class BlockBox(val collisionType: ItemID, val width: Int, val height: Int) {
|
||||
data class BlockBox(
|
||||
val collisionType: ItemID = NO_COLLISION,
|
||||
val width: Int = 0,
|
||||
val height: Int = 0) {
|
||||
|
||||
/*fun redefine(collisionType: Int, width: Int, height: Int) {
|
||||
redefine(collisionType)
|
||||
@@ -246,6 +252,6 @@ data class BlockBox(val collisionType: ItemID, val width: Int, val height: Int)
|
||||
const val NO_PASS_RIGHT = Block.ACTORBLOCK_NO_PASS_RIGHT
|
||||
const val NO_PASS_LEFT = Block.ACTORBLOCK_NO_PASS_LEFT
|
||||
|
||||
val NULL = BlockBox(NO_COLLISION, 0, 0)
|
||||
val NULL = BlockBox()
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.blockproperties.WireCodex
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import org.dyn4j.geometry.Vector2
|
||||
|
||||
@@ -13,13 +14,15 @@ class FixtureLogicSignalEmitter : FixtureBase, Electric {
|
||||
override val wireEmission: HashMap<BlockBoxIndex, Vector2> = HashMap()
|
||||
override val wireConsumption: HashMap<BlockBoxIndex, Vector2> = HashMap()
|
||||
|
||||
protected constructor()
|
||||
|
||||
constructor(nameFun: () -> String) : super(
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.NO_COLLISION, 1, 1),
|
||||
nameFun = nameFun)
|
||||
nameFun = { Lang["ITEM_LOGIC_SIGNAL_EMITTER"] }
|
||||
)
|
||||
|
||||
init {
|
||||
println("INIT AGAIN FixtureLogicSignalEmitter")
|
||||
|
||||
density = 1400.0
|
||||
setHitboxDimension(TILE_SIZE, TILE_SIZE, 0, -1)
|
||||
|
||||
|
||||
@@ -32,13 +32,11 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
*/
|
||||
internal class FixtureStorageChest : FixtureBase {
|
||||
|
||||
private constructor()
|
||||
|
||||
constructor(nameFun: () -> String) : super(
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 1, 1),
|
||||
mainUI = UIStorageChest(),
|
||||
inventory = FixtureInventory(40, CAPACITY_MODE_COUNT),
|
||||
nameFun = nameFun
|
||||
nameFun = { Lang["ITEM_STORAGE_CHEST"] }
|
||||
) {
|
||||
|
||||
(mainUI as UIStorageChest).chestInventory = this.inventory!!
|
||||
|
||||
@@ -12,6 +12,7 @@ import net.torvald.terrarum.gameactors.Hitbox
|
||||
import net.torvald.terrarum.gameactors.Luminous
|
||||
import net.torvald.terrarum.gameparticles.ParticleVanishingSprite
|
||||
import net.torvald.terrarum.gameparticles.ParticleVanishingText
|
||||
import net.torvald.terrarum.langpack.Lang
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import java.util.*
|
||||
@@ -34,11 +35,9 @@ internal class FixtureTikiTorch : FixtureBase, Luminous {
|
||||
|
||||
override val lightBoxList: ArrayList<Hitbox> = ArrayList(1)
|
||||
|
||||
private constructor()
|
||||
|
||||
constructor(nameFun: () -> String) : super(
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.NO_COLLISION, 1, 2),
|
||||
nameFun = nameFun
|
||||
nameFun = { Lang["ITEM_TIKI_TORCH"] }
|
||||
) {
|
||||
|
||||
// loading textures
|
||||
|
||||
@@ -19,7 +19,7 @@ class TapestryObject : FixtureBase {
|
||||
var artName = ""; private set
|
||||
var artAuthor = ""; private set
|
||||
|
||||
private constructor()
|
||||
private constructor() : super()
|
||||
|
||||
constructor(pixmap: Pixmap, artName: String, artAuthor: String, nameFun: () -> String) : super() {
|
||||
this.artName = artName
|
||||
|
||||
@@ -15,7 +15,7 @@ import net.torvald.terrarum.modulebasegame.gameactors.FixtureLogicSignalEmitter
|
||||
class ItemLogicSignalEmitter(originalID: ItemID) : GameItem(originalID) {
|
||||
|
||||
override var dynamicID: ItemID = originalID
|
||||
override val originalName = "ITEM_TIKI_TORCH"
|
||||
override val originalName = "ITEM_LOGIC_SIGNAL_EMITTER"
|
||||
override var baseMass = FixtureLogicSignalEmitter.MASS
|
||||
override var stackable = true
|
||||
override var inventoryCategory = Category.FIXTURE
|
||||
@@ -38,7 +38,7 @@ class ItemLogicSignalEmitter(originalID: ItemID) : GameItem(originalID) {
|
||||
}
|
||||
|
||||
override fun startPrimaryUse(delta: Float): Boolean {
|
||||
val item = FixtureLogicSignalEmitter { Lang[originalName] }
|
||||
val item = FixtureLogicSignalEmitter()
|
||||
|
||||
return item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY)
|
||||
// return true when placed, false when cannot be placed
|
||||
|
||||
@@ -32,7 +32,7 @@ class ItemStorageChest(originalID: ItemID) : GameItem(originalID) {
|
||||
}
|
||||
|
||||
override fun startPrimaryUse(delta: Float): Boolean {
|
||||
val item = FixtureStorageChest { Lang[originalName] }
|
||||
val item = FixtureStorageChest()
|
||||
|
||||
return item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1)
|
||||
// return true when placed, false when cannot be placed
|
||||
|
||||
@@ -31,7 +31,7 @@ class TikiTorchTester(originalID: ItemID) : GameItem(originalID) {
|
||||
}
|
||||
|
||||
override fun startPrimaryUse(delta: Float): Boolean {
|
||||
val item = FixtureTikiTorch { Lang[originalName] }
|
||||
val item = FixtureTikiTorch()
|
||||
|
||||
return item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1)
|
||||
// return true when placed, false when cannot be placed
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.serialise
|
||||
|
||||
import net.torvald.spriteanimation.HasAssembledSprite
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import net.torvald.terrarum.AppLoader.printdbgerr
|
||||
import net.torvald.terrarum.NoSuchActorWithIDException
|
||||
import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
@@ -25,10 +26,19 @@ object WriteActor {
|
||||
fun encodeToByteArray64(actor: Actor): ByteArray64 {
|
||||
val baw = ByteArray64Writer(Common.CHARSET)
|
||||
|
||||
val classDef = """{"class":"${actor.javaClass.canonicalName}""""
|
||||
baw.write(classDef)
|
||||
Common.jsoner.toJson(actor, actor.javaClass, baw)
|
||||
baw.flush(); baw.close()
|
||||
// by this moment, contents of the baw will be:
|
||||
// {"class":"some.class.Name"{"actorValue":{},......}
|
||||
// (note that first bracket is not closed, and another open bracket after "class" property)
|
||||
// and we want to turn it into this:
|
||||
// {"class":"some.class.Name","actorValue":{},......}
|
||||
val ba = baw.toByteArray64()
|
||||
ba[classDef.toByteArray(Common.CHARSET).size.toLong()] = ','.code.toByte()
|
||||
|
||||
return baw.toByteArray64()
|
||||
return ba
|
||||
}
|
||||
|
||||
}
|
||||
@@ -45,14 +55,11 @@ object WriteActor {
|
||||
*/
|
||||
object ReadActor {
|
||||
|
||||
fun readActorOnly(worldDataStream: Reader): Actor =
|
||||
Common.jsoner.fromJson(null, worldDataStream)
|
||||
operator fun invoke(worldDataStream: Reader): Actor =
|
||||
fillInDetails(Common.jsoner.fromJson(null, worldDataStream))
|
||||
|
||||
operator fun invoke(ingame: TerrarumIngame, worldDataStream: Reader): Actor =
|
||||
postRead(ingame, readActorOnly(worldDataStream))
|
||||
|
||||
private fun postRead(ingame: TerrarumIngame, actor: Actor): Actor {
|
||||
// filling in Transients
|
||||
private fun fillInDetails(actor: Actor): Actor {
|
||||
actor.actorValue.actor = actor
|
||||
|
||||
if (actor is Pocketed)
|
||||
@@ -66,6 +73,13 @@ object ReadActor {
|
||||
actor.reassembleSprite(actor.sprite!!, actor.spriteGlow)
|
||||
}
|
||||
}
|
||||
|
||||
return actor
|
||||
}
|
||||
|
||||
fun readActorAndAddToWorld(ingame: TerrarumIngame, worldDataStream: Reader): Actor {
|
||||
val actor = invoke(worldDataStream)
|
||||
|
||||
// replace existing player
|
||||
val oldPlayerID = ingame.actorNowPlaying?.referenceID
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package net.torvald.terrarum.serialise
|
||||
|
||||
import net.torvald.ELLIPSIS
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.AppLoader.printdbg
|
||||
import net.torvald.terrarum.console.Echo
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.*
|
||||
@@ -39,29 +43,33 @@ object WriteSavegame {
|
||||
addFile(disk, meta)
|
||||
|
||||
// Write BlockCodex//
|
||||
val blockCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(BlockCodex).toByteArray(Common.CHARSET))))
|
||||
val blocks = DiskEntry(-16, 0, "blocks".toByteArray(), creation_t, time_t, blockCodexContent)
|
||||
addFile(disk, blocks)
|
||||
// val blockCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(BlockCodex).toByteArray(Common.CHARSET))))
|
||||
// val blocks = DiskEntry(-16, 0, "blocks".toByteArray(), creation_t, time_t, blockCodexContent)
|
||||
// addFile(disk, blocks)
|
||||
// Commented out; nothing to write
|
||||
|
||||
// Write ItemCodex//
|
||||
val itemCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(ItemCodex).toByteArray(Common.CHARSET))))
|
||||
val items = DiskEntry(-17, 0, "items".toByteArray(), creation_t, time_t, itemCodexContent)
|
||||
addFile(disk, items)
|
||||
// Gotta save dynamicIDs
|
||||
|
||||
// Write WireCodex//
|
||||
val wireCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(WireCodex).toByteArray(Common.CHARSET))))
|
||||
val wires = DiskEntry(-18, 0, "wires".toByteArray(), creation_t, time_t, wireCodexContent)
|
||||
addFile(disk, wires)
|
||||
// val wireCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(WireCodex).toByteArray(Common.CHARSET))))
|
||||
// val wires = DiskEntry(-18, 0, "wires".toByteArray(), creation_t, time_t, wireCodexContent)
|
||||
// addFile(disk, wires)
|
||||
// Commented out; nothing to write
|
||||
|
||||
// Write MaterialCodex//
|
||||
val materialCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(MaterialCodex).toByteArray(Common.CHARSET))))
|
||||
val materials = DiskEntry(-19, 0, "materials".toByteArray(), creation_t, time_t, materialCodexContent)
|
||||
addFile(disk, materials)
|
||||
// val materialCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(MaterialCodex).toByteArray(Common.CHARSET))))
|
||||
// val materials = DiskEntry(-19, 0, "materials".toByteArray(), creation_t, time_t, materialCodexContent)
|
||||
// addFile(disk, materials)
|
||||
// Commented out; nothing to write
|
||||
|
||||
// Write FactionCodex//
|
||||
val factionCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(FactionCodex).toByteArray(Common.CHARSET))))
|
||||
val factions = DiskEntry(-20, 0, "factions".toByteArray(), creation_t, time_t, factionCodexContent)
|
||||
addFile(disk, factions)
|
||||
// val factionCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(FactionCodex).toByteArray(Common.CHARSET))))
|
||||
// val factions = DiskEntry(-20, 0, "factions".toByteArray(), creation_t, time_t, factionCodexContent)
|
||||
// addFile(disk, factions)
|
||||
|
||||
// Write Apocryphas//
|
||||
val apocryphasContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(Apocryphas).toByteArray(Common.CHARSET))))
|
||||
@@ -105,29 +113,41 @@ object LoadSavegame {
|
||||
private fun getFileReader(disk: VirtualDisk, id: Int): Reader = ByteArray64Reader(getFileBytes(disk, id), Common.CHARSET)
|
||||
|
||||
operator fun invoke(disk: VirtualDisk) {
|
||||
val ingame = TerrarumIngame(AppLoader.batch)
|
||||
|
||||
// NOTE: do NOT set ingame.actorNowPlaying as one read directly from the disk;
|
||||
// you'll inevitably read the player actor twice, and they're separate instances of the player!
|
||||
val meta = ReadMeta(disk)
|
||||
val player = ReadActor.readActorOnly(getFileReader(disk, 9545698)) as IngamePlayer
|
||||
val world = ReadWorld.readWorldOnly(getFileReader(disk, player.worldCurrentlyPlaying))
|
||||
val actors = world.actors.map { ReadActor.readActorOnly(getFileReader(disk, it)) }
|
||||
val block = Common.jsoner.fromJson(BlockCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -16)))
|
||||
val currentWorld = (ReadActor(getFileReader(disk, Terrarum.PLAYER_REF_ID)) as IngamePlayer).worldCurrentlyPlaying
|
||||
val world = ReadWorld(getFileReader(disk, currentWorld))
|
||||
val actors = world.actors.map { ReadActor(getFileReader(disk, it)) }
|
||||
// val block = Common.jsoner.fromJson(BlockCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -16)))
|
||||
val item = Common.jsoner.fromJson(ItemCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -17)))
|
||||
val wire = Common.jsoner.fromJson(WireCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -18)))
|
||||
val material = Common.jsoner.fromJson(MaterialCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -19)))
|
||||
val faction = Common.jsoner.fromJson(FactionCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -20)))
|
||||
// val wire = Common.jsoner.fromJson(WireCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -18)))
|
||||
// val material = Common.jsoner.fromJson(MaterialCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -19)))
|
||||
// val faction = Common.jsoner.fromJson(FactionCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -20)))
|
||||
val apocryphas = Common.jsoner.fromJson(Apocryphas.javaClass, getUnzipInputStream(getFileBytes(disk, -1024)))
|
||||
|
||||
val ingame = TerrarumIngame(AppLoader.batch)
|
||||
val worldParam = TerrarumIngame.Codices(meta, block, item, wire, material, faction, apocryphas)
|
||||
val worldParam = TerrarumIngame.Codices(meta, item, apocryphas)
|
||||
ingame.world = world
|
||||
ingame.gameLoadInfoPayload = worldParam
|
||||
ingame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM
|
||||
ingame.savegameArchive = disk
|
||||
actors.forEach { ingame.addNewActor(it) }
|
||||
ingame.actorNowPlaying = player
|
||||
|
||||
// by doing this, whatever the "possession" the player had will be broken by the game load
|
||||
ingame.actorNowPlaying = ingame.getActorByID(Terrarum.PLAYER_REF_ID) as IngamePlayer
|
||||
|
||||
|
||||
// ModMgr.reloadModules()
|
||||
|
||||
Terrarum.setCurrentIngameInstance(ingame)
|
||||
val loadScreen = SanicLoadScreen
|
||||
AppLoader.setLoadScreen(loadScreen)
|
||||
AppLoader.setScreen(ingame)
|
||||
|
||||
Echo("${ccW}Savegame loaded from $ccY${disk.getDiskNameString(Common.CHARSET)}")
|
||||
printdbg(this, "Savegame loaded from ${disk.getDiskNameString(Common.CHARSET)}")
|
||||
|
||||
Terrarum.ingame!!.consoleHandler.setAsOpen()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -53,17 +53,21 @@ object WriteWorld {
|
||||
*/
|
||||
object ReadWorld {
|
||||
|
||||
fun readWorldOnly(worldDataStream: Reader): GameWorld =
|
||||
Common.jsoner.fromJson(GameWorld::class.java, worldDataStream)
|
||||
operator fun invoke(worldDataStream: Reader): GameWorld =
|
||||
fillInDetails(Common.jsoner.fromJson(GameWorld::class.java, worldDataStream))
|
||||
|
||||
operator fun invoke(ingame: TerrarumIngame, worldDataStream: Reader): GameWorld =
|
||||
postRead(ingame, readWorldOnly(worldDataStream))
|
||||
|
||||
private fun postRead(ingame: TerrarumIngame, world: GameWorld): GameWorld {
|
||||
world.postLoad()
|
||||
ingame.world = world
|
||||
private fun fillInDetails(world: GameWorld): GameWorld {
|
||||
world.tileNumberToNameMap.forEach { l, s ->
|
||||
world.tileNameToNumberMap[s] = l.toInt()
|
||||
}
|
||||
|
||||
return world
|
||||
}
|
||||
|
||||
fun readWorldAndSetNewWorld(ingame: TerrarumIngame, worldDataStream: Reader): GameWorld {
|
||||
val world = invoke(worldDataStream)
|
||||
ingame.world = world
|
||||
return world
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user