mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-17 00:56:07 +09:00
fixed a bug where a dynamic item would not get saved/loaded at all
This commit is contained in:
@@ -29,3 +29,4 @@ StreamerMode
|
|||||||
Teleport
|
Teleport
|
||||||
ToggleNoClip
|
ToggleNoClip
|
||||||
Zoom
|
Zoom
|
||||||
|
DynToStatic
|
||||||
|
@@ -66,6 +66,7 @@ object Terrarum : Disposable {
|
|||||||
|
|
||||||
|
|
||||||
var blockCodex = BlockCodex(); internal set
|
var blockCodex = BlockCodex(); internal set
|
||||||
|
/** The actual contents of the ItemCodex is sum of Player's Codex and the World's Codex */
|
||||||
var itemCodex = ItemCodex(); internal set
|
var itemCodex = ItemCodex(); internal set
|
||||||
var wireCodex = WireCodex(); internal set
|
var wireCodex = WireCodex(); internal set
|
||||||
var materialCodex = MaterialCodex(); internal set
|
var materialCodex = MaterialCodex(); internal set
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
import com.badlogic.gdx.graphics.g2d.TextureRegion
|
||||||
import net.torvald.terrarum.gameitems.GameItem
|
import net.torvald.terrarum.gameitems.GameItem
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVEN_DEBUG_MODE
|
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellBase
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellBase
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.toItemCountText
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.toItemCountText
|
||||||
@@ -97,23 +96,13 @@ class UIItemInventoryElemWide(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// draw name of the item
|
// draw name of the item
|
||||||
if (INVEN_DEBUG_MODE) {
|
App.fontGame.draw(batch,
|
||||||
App.fontGame.draw(batch,
|
// print name and amount in parens
|
||||||
// print static id, dynamic id, and count
|
item!!.name + (if (amount > 0 && item!!.stackable) "$fwsp($amountString)" else if (amount != 1L) "$fwsp!!$amountString!!" else ""),
|
||||||
"${item!!.originalID}/${item!!.dynamicID}" + (if (amount > 0 && item!!.stackable) "$fwsp($amountString)" else if (amount != 1L) "$fwsp!!$amountString!!" else ""),
|
|
||||||
posX + textOffsetX,
|
|
||||||
posY + textOffsetY
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
App.fontGame.draw(batch,
|
|
||||||
// print name and amount in parens
|
|
||||||
item!!.name + (if (amount > 0 && item!!.stackable) "$fwsp($amountString)" else if (amount != 1L) "$fwsp!!$amountString!!" else ""),
|
|
||||||
|
|
||||||
posX + textOffsetX,
|
posX + textOffsetX,
|
||||||
posY + textOffsetY
|
posY + textOffsetY
|
||||||
)
|
)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// durability metre
|
// durability metre
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ typealias ItemID = String
|
|||||||
*/
|
*/
|
||||||
abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneable {
|
abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneable {
|
||||||
|
|
||||||
|
constructor() : this("-uninitialised-")
|
||||||
|
|
||||||
open var dynamicID: ItemID = originalID
|
open var dynamicID: ItemID = originalID
|
||||||
/**
|
/**
|
||||||
* if the ID is a Actor range, it's an actor contained in a pocket.
|
* if the ID is a Actor range, it's an actor contained in a pocket.
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import net.torvald.terrarum.blockproperties.Fluid
|
|||||||
import net.torvald.terrarum.gameactors.ActorID
|
import net.torvald.terrarum.gameactors.ActorID
|
||||||
import net.torvald.terrarum.gameactors.WireActor
|
import net.torvald.terrarum.gameactors.WireActor
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemTable
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import net.torvald.terrarum.utils.*
|
import net.torvald.terrarum.utils.*
|
||||||
@@ -128,6 +130,9 @@ open class GameWorld() : Disposable {
|
|||||||
internal var genver = -1 // only gets used when the game saves and loads
|
internal var genver = -1 // only gets used when the game saves and loads
|
||||||
internal var comp = -1 // only gets used when the game saves and loads
|
internal var comp = -1 // only gets used when the game saves and loads
|
||||||
|
|
||||||
|
internal val dynamicItemInventory = ItemTable()
|
||||||
|
internal val dynamicToStaticTable = ItemRemapTable()
|
||||||
|
|
||||||
@Deprecated("This value is only used for savegames; DO NOT USE THIS", ReplaceWith("INGAME.actorContainerActive", "net.torvald.terrarum.INGAME"))
|
@Deprecated("This value is only used for savegames; DO NOT USE THIS", ReplaceWith("INGAME.actorContainerActive", "net.torvald.terrarum.INGAME"))
|
||||||
internal val actors = ArrayList<ActorID>() // only filled up on save and load; DO NOT USE THIS
|
internal val actors = ArrayList<ActorID>() // only filled up on save and load; DO NOT USE THIS
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,13 @@ import net.torvald.terrarum.gameitems.ItemID
|
|||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.CanBeAnItem
|
import net.torvald.terrarum.modulebasegame.gameactors.CanBeAnItem
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
||||||
|
import net.torvald.terrarum.serialise.SaveLoadError
|
||||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
||||||
|
import java.io.File
|
||||||
|
import java.io.InvalidObjectException
|
||||||
|
|
||||||
|
typealias ItemRemapTable = java.util.HashMap<ItemID, ItemID>
|
||||||
|
typealias ItemTable = java.util.HashMap<ItemID, GameItem>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ItemCodex holds information of every item in the game, including blocks despite the 'item' naming
|
* ItemCodex holds information of every item in the game, including blocks despite the 'item' naming
|
||||||
@@ -26,9 +32,9 @@ class ItemCodex {
|
|||||||
* <ItemID or RefID for Actor, TheItem>
|
* <ItemID or RefID for Actor, TheItem>
|
||||||
* Will return corresponding Actor if ID >= ACTORID_MIN
|
* Will return corresponding Actor if ID >= ACTORID_MIN
|
||||||
*/
|
*/
|
||||||
@Transient val itemCodex = HashMap<ItemID, GameItem>()
|
@Transient val itemCodex = ItemTable()
|
||||||
@Transient var dynamicItemDescription = HashMap<ItemID, GameItem>(); private set
|
val dynamicItemInventory = ItemTable()
|
||||||
var dynamicToStaticTable = HashMap<ItemID, ItemID>(); private set
|
val dynamicToStaticTable = ItemRemapTable()
|
||||||
|
|
||||||
@Transient val ACTORID_MIN = ReferencingRanges.ACTORS.first
|
@Transient val ACTORID_MIN = ReferencingRanges.ACTORS.first
|
||||||
|
|
||||||
@@ -41,18 +47,33 @@ class ItemCodex {
|
|||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
itemCodex.clear()
|
itemCodex.clear()
|
||||||
dynamicItemDescription.clear()
|
dynamicItemInventory.clear()
|
||||||
dynamicToStaticTable.clear()
|
dynamicToStaticTable.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method does not alter already-been-loaded itemCodex; only filles up dynamicitem-related fields
|
* This method does not alter already-been-loaded itemCodex; only filles up dynamicitem-related fields
|
||||||
|
*
|
||||||
|
* Normally, the player's dynamicToStaticTable is what gets loaded first.
|
||||||
*/
|
*/
|
||||||
fun loadFromSave(other: ItemCodex) {
|
fun loadFromSave(savefile: File?, otherDynamicToStaticTable: ItemRemapTable, otherDynamicItemInventory: ItemTable) {
|
||||||
this.dynamicToStaticTable = other.dynamicToStaticTable
|
otherDynamicToStaticTable.forEach { dynid, itemid ->
|
||||||
dynamicToStaticTable.forEach { dynid, itemid ->
|
|
||||||
printdbg(this, "Loadfromsave dynid $dynid ->> $itemid")
|
printdbg(this, "Loadfromsave dynid $dynid ->> $itemid")
|
||||||
dynamicItemDescription[dynid] = itemCodex[itemid]!!
|
dynamicToStaticTable[dynid]?.let {
|
||||||
|
if (it != itemid) {
|
||||||
|
throw SaveLoadError(savefile, InvalidObjectException("Discrepancy detected -- currently loaded $dynid is mapped to $it, but ${savefile?.name} indicates it should map to $itemid"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamicToStaticTable[dynid] = itemid
|
||||||
|
}
|
||||||
|
otherDynamicItemInventory.forEach { dynid, item ->
|
||||||
|
printdbg(this, "Loadfromsave dynitem $dynid ->> $item")
|
||||||
|
dynamicItemInventory[dynid]?.let {
|
||||||
|
if (it != item) {
|
||||||
|
throw SaveLoadError(savefile, InvalidObjectException("Discrepancy detected -- currently loaded $dynid is mapped to $it, but ${savefile?.name} indicates it should map to $item"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dynamicItemInventory[dynid] = item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +85,7 @@ class ItemCodex {
|
|||||||
*/
|
*/
|
||||||
fun registerNewDynamicItem(dynamicID: ItemID, item: GameItem) {
|
fun registerNewDynamicItem(dynamicID: ItemID, item: GameItem) {
|
||||||
printdbg(this, "Registering new dynamic item $dynamicID (from ${item.originalID})")
|
printdbg(this, "Registering new dynamic item $dynamicID (from ${item.originalID})")
|
||||||
dynamicItemDescription[dynamicID] = item
|
dynamicItemInventory[dynamicID] = item
|
||||||
dynamicToStaticTable[dynamicID] = item.originalID
|
dynamicToStaticTable[dynamicID] = item.originalID
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +97,7 @@ class ItemCodex {
|
|||||||
if (code == null) return null
|
if (code == null) return null
|
||||||
|
|
||||||
if (code.startsWith("$PREFIX_DYNAMICITEM:"))
|
if (code.startsWith("$PREFIX_DYNAMICITEM:"))
|
||||||
return dynamicItemDescription[code] ?: throw NullPointerException("No ItemProp with id $code")
|
return dynamicItemInventory[code] ?: throw NullPointerException("No ItemProp with id $code")
|
||||||
else if (code.startsWith("$PREFIX_ACTORITEM:")) {
|
else if (code.startsWith("$PREFIX_ACTORITEM:")) {
|
||||||
val a = (Terrarum.ingame!! as TerrarumIngame).getActorByID(code.substring(6).toInt()) // actor item
|
val a = (Terrarum.ingame!! as TerrarumIngame).getActorByID(code.substring(6).toInt()) // actor item
|
||||||
if (a is CanBeAnItem) return a.itemData
|
if (a is CanBeAnItem) return a.itemData
|
||||||
@@ -142,5 +163,5 @@ class ItemCodex {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasItem(itemID: ItemID): Boolean = dynamicItemDescription.containsKey(itemID)
|
fun hasItem(itemID: ItemID): Boolean = dynamicItemInventory.containsKey(itemID)
|
||||||
}
|
}
|
||||||
@@ -133,9 +133,10 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val reader = java.io.FileReader(ModMgr.getFile("basegame", "demoworld"))
|
val file = ModMgr.getFile("basegame", "demoworld")
|
||||||
|
val reader = java.io.FileReader(file)
|
||||||
//ReadWorld.readWorldAndSetNewWorld(Terrarum.ingame!! as TerrarumIngame, reader)
|
//ReadWorld.readWorldAndSetNewWorld(Terrarum.ingame!! as TerrarumIngame, reader)
|
||||||
val world = ReadWorld.readLayerFormat(reader)
|
val world = ReadWorld.readLayerFormat(reader, file)
|
||||||
demoWorld = world
|
demoWorld = world
|
||||||
printdbg(this, "Demo world loaded")
|
printdbg(this, "Demo world loaded")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.console
|
||||||
|
|
||||||
|
import net.torvald.terrarum.*
|
||||||
|
import net.torvald.terrarum.console.ConsoleCommand
|
||||||
|
import net.torvald.terrarum.console.Echo
|
||||||
|
import net.torvald.terrarum.serialise.Common
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2022-02-22.
|
||||||
|
*/
|
||||||
|
object DynToStatic : ConsoleCommand {
|
||||||
|
override fun execute(args: Array<String>) {
|
||||||
|
ItemCodex.dynamicToStaticTable.forEach { (d,s) ->
|
||||||
|
Echo("$ccG$d$ccW → $ccY$s")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun printUsage() {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import net.torvald.terrarum.console.Echo
|
|||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.serialise.ReadActor
|
import net.torvald.terrarum.serialise.ReadActor
|
||||||
import net.torvald.terrarum.serialise.ReadWorld
|
import net.torvald.terrarum.serialise.ReadWorld
|
||||||
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -16,8 +17,9 @@ object ImportWorld : ConsoleCommand {
|
|||||||
override fun execute(args: Array<String>) {
|
override fun execute(args: Array<String>) {
|
||||||
if (args.size == 2) {
|
if (args.size == 2) {
|
||||||
try {
|
try {
|
||||||
val reader = java.io.FileReader(App.defaultDir + "/Exports/${args[1]}.json")
|
val file = File(App.defaultDir + "/Exports/${args[1]}.json")
|
||||||
ReadWorld.readWorldAndSetNewWorld(Terrarum.ingame!! as TerrarumIngame, reader)
|
val reader = java.io.FileReader(file)
|
||||||
|
ReadWorld.readWorldAndSetNewWorld(Terrarum.ingame!! as TerrarumIngame, reader, file)
|
||||||
Echo("Importworld: imported a world from ${args[1]}.json")
|
Echo("Importworld: imported a world from ${args[1]}.json")
|
||||||
}
|
}
|
||||||
catch (e: IOException) {
|
catch (e: IOException) {
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ class ActorInventory() : FixtureInventory() {
|
|||||||
/**
|
/**
|
||||||
* List of all equipped items (tools, armours, rings, necklaces, etc.)
|
* List of all equipped items (tools, armours, rings, necklaces, etc.)
|
||||||
*
|
*
|
||||||
|
* It's your responsibility to make sure currently equipped item also exists in the `super.itemList`
|
||||||
|
*
|
||||||
* The ItemID must be `dynamicID`
|
* The ItemID must be `dynamicID`
|
||||||
*/
|
*/
|
||||||
val itemEquipped = Array<ItemID?>(GameItem.EquipPosition.INDEX_MAX) { null }
|
val itemEquipped = Array<ItemID?>(GameItem.EquipPosition.INDEX_MAX) { null }
|
||||||
@@ -62,7 +64,7 @@ class ActorInventory() : FixtureInventory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getQuickslotItem(slot: Int): InventoryPair? = invSearchByDynamicID(quickSlot[slot])
|
fun getQuickslotItem(slot: Int): InventoryPair? = searchByID(quickSlot[slot])
|
||||||
|
|
||||||
fun consumeItem(item: GameItem) {
|
fun consumeItem(item: GameItem) {
|
||||||
val actor = this.actor as Actor
|
val actor = this.actor as Actor
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ import net.torvald.terrarum.ItemCodex
|
|||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.gameitems.GameItem
|
import net.torvald.terrarum.gameitems.GameItem
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.lock
|
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
|
import net.torvald.util.SortedArrayList
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2021-03-16.
|
* Created by minjaesong on 2021-03-16.
|
||||||
@@ -32,7 +31,7 @@ open class FixtureInventory() {
|
|||||||
/**
|
/**
|
||||||
* Sorted by referenceID.
|
* Sorted by referenceID.
|
||||||
*/
|
*/
|
||||||
val itemList = ArrayList<InventoryPair>()
|
val itemList = SortedArrayList<InventoryPair>()
|
||||||
var wallet = BigInteger("0") // unified currency for whole civs; Dwarf Fortress approach seems too complicated
|
var wallet = BigInteger("0") // unified currency for whole civs; Dwarf Fortress approach seems too complicated
|
||||||
|
|
||||||
fun isEmpty() = getTotalCount() == 0L
|
fun isEmpty() = getTotalCount() == 0L
|
||||||
@@ -66,7 +65,7 @@ open class FixtureInventory() {
|
|||||||
|
|
||||||
// If we already have the item, increment the amount
|
// If we already have the item, increment the amount
|
||||||
// If not, add item with specified amount
|
// If not, add item with specified amount
|
||||||
val existingItem = invSearchByDynamicID(item.dynamicID)
|
val existingItem = searchByID(item.dynamicID)
|
||||||
|
|
||||||
// if the item already exists
|
// if the item already exists
|
||||||
if (existingItem != null) {
|
if (existingItem != null) {
|
||||||
@@ -80,7 +79,7 @@ open class FixtureInventory() {
|
|||||||
else {
|
else {
|
||||||
itemList.add(InventoryPair(item.dynamicID, count))
|
itemList.add(InventoryPair(item.dynamicID, count))
|
||||||
}
|
}
|
||||||
insertionSortLastElem(itemList)
|
// insertionSortLastElem(itemList)
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun remove(itemID: ItemID, count: Long) = remove(ItemCodex[itemID]!!, count) {}
|
open fun remove(itemID: ItemID, count: Long) = remove(ItemCodex[itemID]!!, count) {}
|
||||||
@@ -102,7 +101,7 @@ open class FixtureInventory() {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
val existingItem = invSearchByDynamicID(item.dynamicID)
|
val existingItem = searchByID(item.dynamicID)
|
||||||
if (existingItem != null) { // if the item already exists
|
if (existingItem != null) { // if the item already exists
|
||||||
val newCount = existingItem.qty - count
|
val newCount = existingItem.qty - count
|
||||||
|
|
||||||
@@ -171,28 +170,14 @@ open class FixtureInventory() {
|
|||||||
if (itemList.size == 0)
|
if (itemList.size == 0)
|
||||||
false
|
false
|
||||||
else
|
else
|
||||||
itemList.binarySearch(id, DYNAMIC_ID) >= 0
|
itemList.contains(InventoryPair(id, 1))
|
||||||
fun invSearchByDynamicID(id: ItemID?): InventoryPair? {
|
fun searchByID(id: ItemID?): InventoryPair? {
|
||||||
if (itemList.size == 0 || id == null)
|
if (itemList.size == 0 || id == null)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
val index = itemList.binarySearch(id, DYNAMIC_ID)
|
return itemList.searchFor(id) { it.itm }
|
||||||
if (index < 0)
|
|
||||||
return null
|
|
||||||
else
|
|
||||||
return itemList[index]
|
|
||||||
}
|
}
|
||||||
protected fun invSearchByStaticID(id: ItemID?): InventoryPair? {
|
/*protected fun insertionSortLastElem(arr: ArrayList<InventoryPair>) {
|
||||||
if (itemList.size == 0 || id == null)
|
|
||||||
return null
|
|
||||||
|
|
||||||
val index = itemList.binarySearch(id, STATIC_ID)
|
|
||||||
if (index < 0)
|
|
||||||
return null
|
|
||||||
else
|
|
||||||
return itemList[index]
|
|
||||||
}
|
|
||||||
protected fun insertionSortLastElem(arr: ArrayList<InventoryPair>) {
|
|
||||||
ReentrantLock().lock {
|
ReentrantLock().lock {
|
||||||
var j = arr.lastIndex - 1
|
var j = arr.lastIndex - 1
|
||||||
val x = arr.last()
|
val x = arr.last()
|
||||||
@@ -202,7 +187,7 @@ open class FixtureInventory() {
|
|||||||
}
|
}
|
||||||
arr[j + 1] = x
|
arr[j + 1] = x
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
@Transient private val STATIC_ID = 41324534
|
@Transient private val STATIC_ID = 41324534
|
||||||
@Transient private val DYNAMIC_ID = 181643953
|
@Transient private val DYNAMIC_ID = 181643953
|
||||||
protected fun ArrayList<InventoryPair>.binarySearch(ID: ItemID, searchMode: Int): Int {
|
protected fun ArrayList<InventoryPair>.binarySearch(ID: ItemID, searchMode: Int): Int {
|
||||||
@@ -229,7 +214,7 @@ open class FixtureInventory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InventoryPair {
|
class InventoryPair : Comparable<InventoryPair> {
|
||||||
|
|
||||||
var itm: ItemID = ""; private set
|
var itm: ItemID = ""; private set
|
||||||
var qty: Long = 0
|
var qty: Long = 0
|
||||||
@@ -244,4 +229,5 @@ class InventoryPair {
|
|||||||
operator fun component1() = itm
|
operator fun component1() = itm
|
||||||
operator fun component2() = qty
|
operator fun component2() = qty
|
||||||
|
|
||||||
|
override fun compareTo(other: InventoryPair) = this.itm.compareTo(other.itm)
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,9 @@ import net.torvald.terrarum.App
|
|||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.gameactors.AVKey
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarum.gameitems.GameItem
|
import net.torvald.terrarum.gameitems.GameItem
|
||||||
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemTable
|
||||||
import net.torvald.terrarum.savegame.DiskSkimmer
|
import net.torvald.terrarum.savegame.DiskSkimmer
|
||||||
import net.torvald.terrarum.savegame.SimpleFileSystem
|
import net.torvald.terrarum.savegame.SimpleFileSystem
|
||||||
import net.torvald.terrarum.utils.PlayerLastStatus
|
import net.torvald.terrarum.utils.PlayerLastStatus
|
||||||
@@ -33,6 +36,9 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite {
|
|||||||
val uuid = UUID.randomUUID()
|
val uuid = UUID.randomUUID()
|
||||||
var worldCurrentlyPlaying: UUID = UUID(0L,0L) // only filled up on save and load; DO NOT USE THIS
|
var worldCurrentlyPlaying: UUID = UUID(0L,0L) // only filled up on save and load; DO NOT USE THIS
|
||||||
|
|
||||||
|
internal val dynamicItemInventory = ItemTable()
|
||||||
|
internal val dynamicToStaticTable = ItemRemapTable()
|
||||||
|
|
||||||
@Transient override var spriteHeadTexture: TextureRegion? = null
|
@Transient override var spriteHeadTexture: TextureRegion? = null
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ object PickaxeCore {
|
|||||||
* Created by minjaesong on 2017-07-17.
|
* Created by minjaesong on 2017-07-17.
|
||||||
*/
|
*/
|
||||||
class PickaxeCopper(originalID: ItemID) : GameItem(originalID) {
|
class PickaxeCopper(originalID: ItemID) : GameItem(originalID) {
|
||||||
|
internal constructor() : this("-uninitialised-")
|
||||||
|
|
||||||
override val originalName = "PACKAGED_PICK"
|
override val originalName = "PACKAGED_PICK"
|
||||||
override var baseToolSize: Double? = BASE_MASS_AND_SIZE
|
override var baseToolSize: Double? = BASE_MASS_AND_SIZE
|
||||||
@@ -138,6 +139,7 @@ class PickaxeCopper(originalID: ItemID) : GameItem(originalID) {
|
|||||||
* Created by minjaesong on 2019-03-10.
|
* Created by minjaesong on 2019-03-10.
|
||||||
*/
|
*/
|
||||||
class PickaxeIron(originalID: ItemID) : GameItem(originalID) {
|
class PickaxeIron(originalID: ItemID) : GameItem(originalID) {
|
||||||
|
internal constructor() : this("-uninitialised-")
|
||||||
|
|
||||||
override val originalName = "PACKAGED_PICK"
|
override val originalName = "PACKAGED_PICK"
|
||||||
override var baseToolSize: Double? = BASE_MASS_AND_SIZE
|
override var baseToolSize: Double? = BASE_MASS_AND_SIZE
|
||||||
@@ -165,6 +167,7 @@ class PickaxeIron(originalID: ItemID) : GameItem(originalID) {
|
|||||||
* Created by minjaesong on 2019-03-10.
|
* Created by minjaesong on 2019-03-10.
|
||||||
*/
|
*/
|
||||||
class PickaxeSteel(originalID: ItemID) : GameItem(originalID) {
|
class PickaxeSteel(originalID: ItemID) : GameItem(originalID) {
|
||||||
|
internal constructor() : this("-uninitialised-")
|
||||||
|
|
||||||
override val originalName = "PACKAGED_PICK"
|
override val originalName = "PACKAGED_PICK"
|
||||||
override var baseToolSize: Double? = BASE_MASS_AND_SIZE
|
override var baseToolSize: Double? = BASE_MASS_AND_SIZE
|
||||||
|
|||||||
@@ -26,5 +26,8 @@ object WeaponMeleeCore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract class WeaponMeleeBase(originalID: ItemID) : GameItem(originalID) {
|
abstract class WeaponMeleeBase(originalID: ItemID) : GameItem(originalID) {
|
||||||
|
|
||||||
|
internal constructor() : this("-uninitialised-")
|
||||||
|
|
||||||
abstract val velocityMod: Double
|
abstract val velocityMod: Double
|
||||||
}
|
}
|
||||||
@@ -19,7 +19,7 @@ object AmmoMeterProxy {
|
|||||||
else {
|
else {
|
||||||
meter.vitalGetterVal = {
|
meter.vitalGetterVal = {
|
||||||
if (currentItem.stackable && currentItem.maxDurability == GameItem.DURABILITY_NA) {
|
if (currentItem.stackable && currentItem.maxDurability == GameItem.DURABILITY_NA) {
|
||||||
actor.inventory.invSearchByDynamicID(currentItem.dynamicID)!!.qty.toFloat()
|
actor.inventory.searchByID(currentItem.dynamicID)!!.qty.toFloat()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
currentItem.durability
|
currentItem.durability
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELLS_HO
|
|||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELLS_VRT
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.CELLS_VRT
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_X
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_X
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVEN_DEBUG_MODE
|
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.controlHelpHeight
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.controlHelpHeight
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalHeight
|
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalWidth
|
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.internalWidth
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.createInvCellGenericKeyDownFun
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.createInvCellGenericKeyDownFun
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.createInvCellGenericTouchDownFun
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryItemGrid.Companion.createInvCellGenericTouchDownFun
|
||||||
@@ -136,7 +134,7 @@ internal class UIInventoryCells(
|
|||||||
)
|
)
|
||||||
// debug text
|
// debug text
|
||||||
batch.color = Color.LIGHT_GRAY
|
batch.color = Color.LIGHT_GRAY
|
||||||
if (INVEN_DEBUG_MODE) {
|
if (App.IS_DEVELOPMENT_BUILD) {
|
||||||
App.fontSmallNumbers.draw(batch,
|
App.fontSmallNumbers.draw(batch,
|
||||||
"${full.actor.inventory.capacity}/${full.actor.inventory.maxCapacity}",
|
"${full.actor.inventory.capacity}/${full.actor.inventory.maxCapacity}",
|
||||||
encumbBarTextXPos,
|
encumbBarTextXPos,
|
||||||
|
|||||||
@@ -38,8 +38,6 @@ class UIInventoryFull(
|
|||||||
|
|
||||||
val CELL_COL = Toolkit.Theme.COL_CELL_FILL
|
val CELL_COL = Toolkit.Theme.COL_CELL_FILL
|
||||||
|
|
||||||
const val INVEN_DEBUG_MODE = false
|
|
||||||
|
|
||||||
const val REQUIRED_MARGIN: Int = 138 // hard-coded value. Don't know the details. Range: [91-146]. I chose MAX-8 because cell gap is 8
|
const val REQUIRED_MARGIN: Int = 138 // hard-coded value. Don't know the details. Range: [91-146]. I chose MAX-8 because cell gap is 8
|
||||||
const val CELLS_HOR = 10
|
const val CELLS_HOR = 10
|
||||||
val CELLS_VRT: Int; get() = (App.scr.height - REQUIRED_MARGIN - 134 + UIItemInventoryItemGrid.listGap) / // 134 is another magic number
|
val CELLS_VRT: Int; get() = (App.scr.height - REQUIRED_MARGIN - 134 + UIItemInventoryItemGrid.listGap) / // 134 is another magic number
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class UIItemInventoryEquippedView(
|
|||||||
itemGrid[k].equippedSlot = null
|
itemGrid[k].equippedSlot = null
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val itemRecord = it.invSearchByDynamicID(item)!!
|
val itemRecord = it.searchByID(item)!!
|
||||||
|
|
||||||
itemGrid[k].item = ItemCodex[item]
|
itemGrid[k].item = ItemCodex[item]
|
||||||
itemGrid[k].amount = itemRecord.qty
|
itemGrid[k].amount = itemRecord.qty
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
|||||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
import net.torvald.terrarum.modulebasegame.gameactors.ActorInventory
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureInventory
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.InventoryPair
|
import net.torvald.terrarum.modulebasegame.gameactors.InventoryPair
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVEN_DEBUG_MODE
|
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
import net.torvald.terrarum.ui.UIItem
|
import net.torvald.terrarum.ui.UIItem
|
||||||
@@ -162,6 +161,9 @@ class UIItemInventoryItemGrid(
|
|||||||
listRebuildFun()
|
listRebuildFun()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// COMMON variables because more than one instance of this can be up on the screen
|
||||||
|
private val tooltipShowing = HashMap<UIItemInventoryItemGrid, Boolean>()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val itemGrid = Array<UIItemInventoryCellBase>(horizontalCells * verticalCells) {
|
private val itemGrid = Array<UIItemInventoryCellBase>(horizontalCells * verticalCells) {
|
||||||
@@ -347,8 +349,8 @@ class UIItemInventoryItemGrid(
|
|||||||
override fun update(delta: Float) {
|
override fun update(delta: Float) {
|
||||||
super.update(delta)
|
super.update(delta)
|
||||||
|
|
||||||
var tooltipSet = false
|
|
||||||
|
|
||||||
|
tooltipShowing[this] = false
|
||||||
|
|
||||||
|
|
||||||
items.forEach {
|
items.forEach {
|
||||||
@@ -356,20 +358,21 @@ class UIItemInventoryItemGrid(
|
|||||||
|
|
||||||
|
|
||||||
// set tooltip accordingly
|
// set tooltip accordingly
|
||||||
if (isCompactMode && it.item != null && it.mouseUp && !tooltipSet) {
|
if ((App.IS_DEVELOPMENT_BUILD || isCompactMode) && it.item != null && it.mouseUp && tooltipShowing[this] != true) {
|
||||||
INGAME.setTooltipMessage(
|
INGAME.setTooltipMessage(
|
||||||
if (INVEN_DEBUG_MODE) {
|
if (App.IS_DEVELOPMENT_BUILD) {
|
||||||
it.item?.name + " (${it.item?.originalID}${if (it.item?.originalID == it.item?.dynamicID) "" else "/${it.item?.dynamicID}"})"
|
it.item?.name + "\n(${it.item?.originalID}${if (it.item?.originalID == it.item?.dynamicID) "" else "/${it.item?.dynamicID}"})"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
it.item?.name
|
it.item?.name
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
tooltipSet = true
|
|
||||||
|
tooltipShowing[this] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tooltipSet) {
|
if (tooltipShowing.values.all { !it }) {
|
||||||
INGAME.setTooltipMessage(null)
|
INGAME.setTooltipMessage(null)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +464,11 @@ class UIItemInventoryItemGrid(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {
|
override fun dispose() {
|
||||||
|
tooltipShowing.remove(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hide() {
|
||||||
|
tooltipShowing.remove(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
override fun touchDown(screenX: Int, screenY: Int, pointer: Int, button: Int): Boolean {
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ class DiskSkimmer(
|
|||||||
noInit: Boolean = false
|
noInit: Boolean = false
|
||||||
): SimpleFileSystem {
|
): SimpleFileSystem {
|
||||||
|
|
||||||
|
override fun getBackingFile() = diskFile
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
init:
|
init:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package net.torvald.terrarum.savegame
|
package net.torvald.terrarum.savegame
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,4 +10,5 @@ interface SimpleFileSystem {
|
|||||||
fun getEntry(id: EntryID): DiskEntry?
|
fun getEntry(id: EntryID): DiskEntry?
|
||||||
fun getFile(id: EntryID): EntryFile?
|
fun getFile(id: EntryID): EntryFile?
|
||||||
fun getDiskName(charset: Charset): String
|
fun getDiskName(charset: Charset): String
|
||||||
|
fun getBackingFile(): File?
|
||||||
}
|
}
|
||||||
@@ -63,7 +63,7 @@ object VDUtil {
|
|||||||
if (diskSpecVersion != specversion)
|
if (diskSpecVersion != specversion)
|
||||||
throw RuntimeException("Unsupported disk format version: current internal version is $specversion; the file's version is $diskSpecVersion")
|
throw RuntimeException("Unsupported disk format version: current internal version is $specversion; the file's version is $diskSpecVersion")
|
||||||
|
|
||||||
val vdisk = VirtualDisk(diskSize, diskName)
|
val vdisk = VirtualDisk(diskSize, diskName, infile)
|
||||||
|
|
||||||
vdisk.__internalSetFooter__(footers)
|
vdisk.__internalSetFooter__(footers)
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.savegame
|
|||||||
|
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
import net.torvald.terrarum.serialise.Common
|
import net.torvald.terrarum.serialise.Common
|
||||||
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -125,8 +126,12 @@ val specversion = 254.toByte()
|
|||||||
class VirtualDisk(
|
class VirtualDisk(
|
||||||
/** capacity of 0 makes the disk read-only */
|
/** capacity of 0 makes the disk read-only */
|
||||||
var capacity: Long,
|
var capacity: Long,
|
||||||
var diskName: ByteArray = ByteArray(NAME_LENGTH)
|
var diskName: ByteArray = ByteArray(NAME_LENGTH),
|
||||||
|
var origin: File? = null
|
||||||
): SimpleFileSystem {
|
): SimpleFileSystem {
|
||||||
|
|
||||||
|
override fun getBackingFile() = origin
|
||||||
|
|
||||||
var extraInfoBytes = ByteArray(16)
|
var extraInfoBytes = ByteArray(16)
|
||||||
val entries = HashMap<EntryID, DiskEntry>()
|
val entries = HashMap<EntryID, DiskEntry>()
|
||||||
var isReadOnly: Boolean
|
var isReadOnly: Boolean
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum.savegame.finder
|
package net.torvald.terrarum.savegame.finder
|
||||||
|
|
||||||
import net.torvald.terrarum.savegame.*
|
import net.torvald.terrarum.savegame.*
|
||||||
|
import net.torvald.terrarum.serialise.Common
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
import java.awt.event.KeyEvent
|
import java.awt.event.KeyEvent
|
||||||
@@ -676,5 +677,5 @@ ${String(file.contents.bytes.sliceArray64(0L..minOf(PREVIEW_MAX_BYTES, file.cont
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
VirtualDiskCracker(Charset.forName("CP437"))
|
VirtualDiskCracker(Common.CHARSET)
|
||||||
}
|
}
|
||||||
@@ -329,4 +329,4 @@ object Common {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SaveLoadError(file: File, cause: Throwable) : RuntimeException("An error occured while loading save file '${file.absolutePath}'", cause)
|
class SaveLoadError(file: File?, cause: Throwable) : RuntimeException("An error occured while loading save file '${file?.absolutePath}'", cause)
|
||||||
@@ -2,13 +2,20 @@ package net.torvald.terrarum.serialise
|
|||||||
|
|
||||||
import net.torvald.gdx.graphics.PixmapIO2
|
import net.torvald.gdx.graphics.PixmapIO2
|
||||||
import net.torvald.terrarum.App.printdbg
|
import net.torvald.terrarum.App.printdbg
|
||||||
|
import net.torvald.terrarum.ItemCodex
|
||||||
|
import net.torvald.terrarum.ReferencingRanges.PREFIX_DYNAMICITEM
|
||||||
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
||||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||||
|
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||||
import net.torvald.terrarum.realestate.LandUtil
|
import net.torvald.terrarum.realestate.LandUtil
|
||||||
import net.torvald.terrarum.toInt
|
import net.torvald.terrarum.toInt
|
||||||
import net.torvald.terrarum.savegame.*
|
import net.torvald.terrarum.savegame.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.HashMap
|
||||||
import java.util.zip.GZIPOutputStream
|
import java.util.zip.GZIPOutputStream
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -61,14 +68,14 @@ class WorldSavingThread(
|
|||||||
|
|
||||||
val allTheActors = ingame.actorContainerActive.cloneToList() + ingame.actorContainerInactive.cloneToList()
|
val allTheActors = ingame.actorContainerActive.cloneToList() + ingame.actorContainerInactive.cloneToList()
|
||||||
|
|
||||||
val playersList: List<IngamePlayer> = allTheActors.filter{ it is IngamePlayer } as List<IngamePlayer>
|
val playersList: List<IngamePlayer> = allTheActors.filterIsInstance<IngamePlayer>()
|
||||||
val actorsList = allTheActors.filter { WriteWorld.actorAcceptable(it) }
|
val actorsList = allTheActors.filter { WriteWorld.actorAcceptable(it) }
|
||||||
val layers = intArrayOf(0,1).map { ingame.world.getLayer(it) }
|
val layers = intArrayOf(0,1).map { ingame.world.getLayer(it) }
|
||||||
val cw = ingame.world.width / LandUtil.CHUNK_W
|
val cw = ingame.world.width / LandUtil.CHUNK_W
|
||||||
val ch = ingame.world.height / LandUtil.CHUNK_H
|
val ch = ingame.world.height / LandUtil.CHUNK_H
|
||||||
|
|
||||||
WriteSavegame.saveProgress = 0f
|
WriteSavegame.saveProgress = 0f
|
||||||
WriteSavegame.saveProgressMax = 2f + (cw * ch * layers.size) + actorsList.size
|
WriteSavegame.saveProgressMax = 3f + (cw * ch * layers.size) + actorsList.size
|
||||||
|
|
||||||
|
|
||||||
val tgaout = ByteArray64GrowableOutputStream()
|
val tgaout = ByteArray64GrowableOutputStream()
|
||||||
@@ -79,6 +86,39 @@ class WorldSavingThread(
|
|||||||
val creation_t = ingame.world.creationTime
|
val creation_t = ingame.world.creationTime
|
||||||
|
|
||||||
|
|
||||||
|
// Write subset of Ingame.ItemCodex
|
||||||
|
// The existing ItemCodex must be rewritten to clear out obsolete records
|
||||||
|
|
||||||
|
// We're assuming the dynamic item generated by players does exist in the world, and it's recorded
|
||||||
|
// into the world's dynamicToStaticTable, therefore every item recorded into the world's dynamicToStaticTable
|
||||||
|
// can be found in this world without need to look up the players
|
||||||
|
ingame.world.dynamicToStaticTable.clear()
|
||||||
|
ingame.world.dynamicItemInventory.clear()
|
||||||
|
actorsList.filterIsInstance<Pocketed>().forEach { actor ->
|
||||||
|
actor.inventory.forEach { (itemid, _) ->
|
||||||
|
|
||||||
|
printdbg(this, "World side dynamicitem: $itemid contained in $actor")
|
||||||
|
|
||||||
|
if (itemid.startsWith("$PREFIX_DYNAMICITEM:")) {
|
||||||
|
ingame.world.dynamicToStaticTable[itemid] = ItemCodex.dynamicToStaticID(itemid)
|
||||||
|
ingame.world.dynamicItemInventory[itemid] = ItemCodex[itemid]!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
actorsList.filterIsInstance<FixtureBase>().forEach { fixture ->
|
||||||
|
fixture.inventory?.forEach { (itemid, _) ->
|
||||||
|
|
||||||
|
printdbg(this, "World side dynamicitem: $itemid contained in $fixture")
|
||||||
|
|
||||||
|
if (itemid.startsWith("$PREFIX_DYNAMICITEM:")) {
|
||||||
|
ingame.world.dynamicToStaticTable[itemid] = ItemCodex.dynamicToStaticID(itemid)
|
||||||
|
ingame.world.dynamicItemInventory[itemid] = ItemCodex[itemid]!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (hasThumbnail) {
|
if (hasThumbnail) {
|
||||||
PixmapIO2._writeTGA(gzout, IngameRenderer.fboRGBexport, true, true)
|
PixmapIO2._writeTGA(gzout, IngameRenderer.fboRGBexport, true, true)
|
||||||
IngameRenderer.fboRGBexport.dispose()
|
IngameRenderer.fboRGBexport.dispose()
|
||||||
|
|||||||
@@ -4,9 +4,12 @@ import net.torvald.spriteanimation.HasAssembledSprite
|
|||||||
import net.torvald.spriteanimation.SpriteAnimation
|
import net.torvald.spriteanimation.SpriteAnimation
|
||||||
import net.torvald.terrarum.spriteassembler.ADProperties
|
import net.torvald.terrarum.spriteassembler.ADProperties
|
||||||
import net.torvald.terrarum.ItemCodex
|
import net.torvald.terrarum.ItemCodex
|
||||||
|
import net.torvald.terrarum.ReferencingRanges.PREFIX_DYNAMICITEM
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gameitems.GameItem
|
import net.torvald.terrarum.gameitems.GameItem
|
||||||
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||||
import net.torvald.terrarum.savegame.*
|
import net.torvald.terrarum.savegame.*
|
||||||
@@ -74,6 +77,17 @@ object WritePlayer {
|
|||||||
|
|
||||||
player.worldCurrentlyPlaying = ingame?.world?.worldIndex ?: UUID(0L,0L)
|
player.worldCurrentlyPlaying = ingame?.world?.worldIndex ?: UUID(0L,0L)
|
||||||
|
|
||||||
|
// Write subset of Ingame.ItemCodex
|
||||||
|
// The existing ItemCodex must be rewritten to clear out obsolete records
|
||||||
|
player.dynamicToStaticTable.clear()
|
||||||
|
player.dynamicItemInventory.clear()
|
||||||
|
player.inventory.forEach { (itemid, _) ->
|
||||||
|
if (itemid.startsWith("$PREFIX_DYNAMICITEM:")) {
|
||||||
|
player.dynamicToStaticTable[itemid] = ItemCodex.dynamicToStaticID(itemid)
|
||||||
|
player.dynamicItemInventory[itemid] = ItemCodex[itemid]!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
val actorJson = WriteActor.encodeToByteArray64(player)
|
val actorJson = WriteActor.encodeToByteArray64(player)
|
||||||
val adl = player.animDesc!!.getRawADL()
|
val adl = player.animDesc!!.getRawADL()
|
||||||
@@ -142,6 +156,8 @@ object ReadActor {
|
|||||||
actor.animDescGlow = ADProperties(ByteArray64Reader(animFileGlow.bytes, Common.CHARSET))
|
actor.animDescGlow = ADProperties(ByteArray64Reader(animFileGlow.bytes, Common.CHARSET))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemCodex.loadFromSave(disk.getBackingFile(), actor.dynamicToStaticTable, actor.dynamicItemInventory)
|
||||||
|
|
||||||
val heldItem = ItemCodex[actor.inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]]
|
val heldItem = ItemCodex[actor.inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]]
|
||||||
|
|
||||||
if (bodypartsFile != null)
|
if (bodypartsFile != null)
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ object LoadSavegame {
|
|||||||
|
|
||||||
val currentWorldId = player.worldCurrentlyPlaying
|
val currentWorldId = player.worldCurrentlyPlaying
|
||||||
val worldDisk = worldDisk0 ?: App.savegameWorlds[currentWorldId]!!
|
val worldDisk = worldDisk0 ?: App.savegameWorlds[currentWorldId]!!
|
||||||
val world = ReadWorld(ByteArray64Reader(worldDisk.getFile(-1L)!!.bytes, Common.CHARSET))
|
val world = ReadWorld(ByteArray64Reader(worldDisk.getFile(-1L)!!.bytes, Common.CHARSET), worldDisk.diskFile)
|
||||||
|
|
||||||
world.layerTerrain = BlockLayer(world.width, world.height)
|
world.layerTerrain = BlockLayer(world.width, world.height)
|
||||||
world.layerWall = BlockLayer(world.width, world.height)
|
world.layerWall = BlockLayer(world.width, world.height)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum.serialise
|
package net.torvald.terrarum.serialise
|
||||||
|
|
||||||
import net.torvald.terrarum.CommonResourcePool
|
import net.torvald.terrarum.CommonResourcePool
|
||||||
|
import net.torvald.terrarum.ItemCodex
|
||||||
import net.torvald.terrarum.ReferencingRanges
|
import net.torvald.terrarum.ReferencingRanges
|
||||||
import net.torvald.terrarum.gameactors.Actor
|
import net.torvald.terrarum.gameactors.Actor
|
||||||
import net.torvald.terrarum.gameactors.BlockMarkerActor
|
import net.torvald.terrarum.gameactors.BlockMarkerActor
|
||||||
@@ -15,6 +16,7 @@ import net.torvald.terrarum.savegame.ByteArray64
|
|||||||
import net.torvald.terrarum.savegame.ByteArray64Writer
|
import net.torvald.terrarum.savegame.ByteArray64Writer
|
||||||
import net.torvald.terrarum.utils.PlayerLastStatus
|
import net.torvald.terrarum.utils.PlayerLastStatus
|
||||||
import net.torvald.terrarum.weather.WeatherMixer
|
import net.torvald.terrarum.weather.WeatherMixer
|
||||||
|
import java.io.File
|
||||||
import java.io.Reader
|
import java.io.Reader
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,22 +92,24 @@ object WriteWorld {
|
|||||||
*/
|
*/
|
||||||
object ReadWorld {
|
object ReadWorld {
|
||||||
|
|
||||||
fun readLayerFormat(worldDataStream: Reader): GameWorld =
|
fun readLayerFormat(worldDataStream: Reader, origin: File?): GameWorld =
|
||||||
fillInDetails(Common.jsoner.fromJson(GameWorldTitleScreen::class.java, worldDataStream))
|
fillInDetails(Common.jsoner.fromJson(GameWorldTitleScreen::class.java, worldDataStream), origin)
|
||||||
|
|
||||||
operator fun invoke(worldDataStream: Reader): GameWorld =
|
operator fun invoke(worldDataStream: Reader, origin: File?): GameWorld =
|
||||||
fillInDetails(Common.jsoner.fromJson(GameWorld::class.java, worldDataStream))
|
fillInDetails(Common.jsoner.fromJson(GameWorld::class.java, worldDataStream), origin)
|
||||||
|
|
||||||
private fun fillInDetails(world: GameWorld): GameWorld {
|
private fun fillInDetails(world: GameWorld, origin: File?): GameWorld {
|
||||||
world.tileNumberToNameMap.forEach { l, s ->
|
world.tileNumberToNameMap.forEach { l, s ->
|
||||||
world.tileNameToNumberMap[s] = l.toInt()
|
world.tileNameToNumberMap[s] = l.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ItemCodex.loadFromSave(origin, world.dynamicToStaticTable, world.dynamicItemInventory)
|
||||||
|
|
||||||
return world
|
return world
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readWorldAndSetNewWorld(ingame: TerrarumIngame, worldDataStream: Reader): GameWorld {
|
fun readWorldAndSetNewWorld(ingame: TerrarumIngame, worldDataStream: Reader, origin: File?): GameWorld {
|
||||||
val world = readLayerFormat(worldDataStream)
|
val world = readLayerFormat(worldDataStream, origin)
|
||||||
ingame.world = world
|
ingame.world = world
|
||||||
return world
|
return world
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,11 +142,13 @@ class SortedArrayList<T: Comparable<T>>(initialSize: Int = 10) : MutableCollecti
|
|||||||
val second = Math.min(low, this.size - 1)
|
val second = Math.min(low, this.size - 1)
|
||||||
return Pair(first, second)
|
return Pair(first, second)
|
||||||
}
|
}
|
||||||
/** Searches the element using given predicate instead of the element itself. Returns the element desired, null when there is no such element.
|
/** Searches the element using given predicate instead of the element itself
|
||||||
* (e.g. search the Actor by its ID rather than the actor instance)
|
* (e.g. search the Actor by its ID rather than the actor instance)
|
||||||
*
|
*
|
||||||
* @param searchQuery what exactly are we looking for?
|
* @param searchQuery what exactly are we looking for?
|
||||||
* @param searchHow and where or how can it be found?
|
* @param searchHow and where or how can it be found?
|
||||||
|
*
|
||||||
|
* @return The element you're searching; null when there is no such element.
|
||||||
*/
|
*/
|
||||||
fun <R: Comparable<R>> searchFor(searchQuery: R, searchHow: (T) -> R = { it as R }): T? = getOrNull(searchForIndex(searchQuery, searchHow))
|
fun <R: Comparable<R>> searchFor(searchQuery: R, searchHow: (T) -> R = { it as R }): T? = getOrNull(searchForIndex(searchQuery, searchHow))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user