mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 20:44:05 +09:00
signs persisting through load/save
This commit is contained in:
@@ -16,6 +16,7 @@ ImportWorld
|
|||||||
Inventory
|
Inventory
|
||||||
KillActor
|
KillActor
|
||||||
LangTest
|
LangTest
|
||||||
|
MakeSign
|
||||||
MoneyDisp
|
MoneyDisp
|
||||||
MusicTest
|
MusicTest
|
||||||
Possess
|
Possess
|
||||||
|
|||||||
|
Binary file not shown.
@@ -211,12 +211,12 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
|||||||
@Transient var tags = HashSet<String>()
|
@Transient var tags = HashSet<String>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tags added/removed by dynamic items
|
* Tags added/removed by dynamic items (e.g. enchanting)
|
||||||
*/
|
*/
|
||||||
var modifiers = HashSet<String>()
|
var modifiers = HashSet<String>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mainly intended to be used by third-party modules
|
* Used to hold extra data. Keys are case-insensitive and gets converted to lowercase.
|
||||||
*/
|
*/
|
||||||
open val extra = Codex()
|
open val extra = Codex()
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
|||||||
@JvmStatic val MISC = "misc"
|
@JvmStatic val MISC = "misc"
|
||||||
}
|
}
|
||||||
|
|
||||||
override public fun clone(): GameItem {
|
public override fun clone(): GameItem {
|
||||||
val clonedItem = super.clone()
|
val clonedItem = super.clone()
|
||||||
// properly clone ItemValue
|
// properly clone ItemValue
|
||||||
(clonedItem as GameItem).itemProperties = this.itemProperties.clone()
|
(clonedItem as GameItem).itemProperties = this.itemProperties.clone()
|
||||||
@@ -376,8 +376,17 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
|||||||
return clonedItem
|
return clonedItem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun makeDynamic(inventory: ActorInventory): GameItem {
|
||||||
|
return this.clone().also {
|
||||||
|
it.generateUniqueDynamicID(inventory)
|
||||||
|
it.stackable = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun generateUniqueDynamicID(inventory: ActorInventory): GameItem {
|
|
||||||
|
|
||||||
|
|
||||||
|
private fun generateUniqueDynamicID(inventory: ActorInventory): GameItem {
|
||||||
dynamicID = "$PREFIX_DYNAMICITEM:${Companion.generateUniqueDynamicID(inventory)}"
|
dynamicID = "$PREFIX_DYNAMICITEM:${Companion.generateUniqueDynamicID(inventory)}"
|
||||||
ItemCodex.registerNewDynamicItem(dynamicID, this)
|
ItemCodex.registerNewDynamicItem(dynamicID, this)
|
||||||
return this
|
return this
|
||||||
@@ -395,7 +404,7 @@ abstract class GameItem(val originalID: ItemID) : Comparable<GameItem>, Cloneabl
|
|||||||
fun generateUniqueDynamicID(inventory: ActorInventory): Int {
|
fun generateUniqueDynamicID(inventory: ActorInventory): Int {
|
||||||
var ret: Int
|
var ret: Int
|
||||||
do {
|
do {
|
||||||
ret = (1..2147483647).random()
|
ret = (1..999999999).random()
|
||||||
} while (inventory.contains("$PREFIX_DYNAMICITEM:$ret"))
|
} while (inventory.contains("$PREFIX_DYNAMICITEM:$ret"))
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ object Item {
|
|||||||
|
|
||||||
const val TREE_STICK = "item@basegame:18"
|
const val TREE_STICK = "item@basegame:18"
|
||||||
|
|
||||||
const val TREE_SEED_OAK = "item@basegame:160"
|
const val COPPER_SIGN = "item@basegame:33280"
|
||||||
const val TREE_LOGS_OAK = "item@basegame:168"
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -84,6 +84,8 @@ class ItemCodex {
|
|||||||
get() = CommonResourcePool.getAsTextureRegion("itemplaceholder_24") // copper pickaxe
|
get() = CommonResourcePool.getAsTextureRegion("itemplaceholder_24") // copper pickaxe
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Unused IDs are purged when the game saves, as only the active entries are written to the savegame.
|
||||||
|
*
|
||||||
* @param: dynamicID string of "dyn:<random id>"
|
* @param: dynamicID string of "dyn:<random id>"
|
||||||
*/
|
*/
|
||||||
fun registerNewDynamicItem(dynamicID: ItemID, item: GameItem) {
|
fun registerNewDynamicItem(dynamicID: ItemID, item: GameItem) {
|
||||||
|
|||||||
@@ -1693,7 +1693,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
|
|
||||||
// pickup a fixture
|
// pickup a fixture
|
||||||
if (fixture != null) {
|
if (fixture != null) {
|
||||||
val fixtureItem = ItemCodex.fixtureToItemID(fixture)
|
val fixtureItem = fixture.itemise()
|
||||||
printdbg(this, "Fixture pickup at F${WORLD_UPDATE_TIMER}: ${fixture.javaClass.canonicalName} -> $fixtureItem")
|
printdbg(this, "Fixture pickup at F${WORLD_UPDATE_TIMER}: ${fixture.javaClass.canonicalName} -> $fixtureItem")
|
||||||
// 0. hide tooltips
|
// 0. hide tooltips
|
||||||
setTooltipMessage(null)
|
setTooltipMessage(null)
|
||||||
|
|||||||
41
src/net/torvald/terrarum/modulebasegame/console/MakeSign.kt
Normal file
41
src/net/torvald/terrarum/modulebasegame/console/MakeSign.kt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package net.torvald.terrarum.modulebasegame.console
|
||||||
|
|
||||||
|
import net.torvald.terrarum.*
|
||||||
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
||||||
|
import net.torvald.terrarum.console.ConsoleCommand
|
||||||
|
import net.torvald.terrarum.console.Echo
|
||||||
|
import net.torvald.terrarum.itemproperties.Item
|
||||||
|
import net.torvald.terrarum.modulebasegame.gameitems.ItemTextSignCopper
|
||||||
|
import net.torvald.unicode.TIMES
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2024-03-21.
|
||||||
|
*/
|
||||||
|
class MakeSign : ConsoleCommand {
|
||||||
|
override fun execute(args: Array<String>) {
|
||||||
|
if (args.size !in 2..3) {
|
||||||
|
printUsage(); return
|
||||||
|
}
|
||||||
|
|
||||||
|
val text = args[1]
|
||||||
|
val textLen = App.fontGame.getWidth(text)
|
||||||
|
val panelCount = (args.getOrNull(2)?.toInt() ?: (textLen / TILE_SIZEF).ceilToInt()).coerceAtLeast(2)
|
||||||
|
|
||||||
|
val actorInventory = INGAME.actorNowPlaying!!.inventory
|
||||||
|
|
||||||
|
val item = ItemTextSignCopper(Item.COPPER_SIGN).makeDynamic(actorInventory).also {
|
||||||
|
it.extra["signContent"] = text
|
||||||
|
it.extra["signPanelCount"] = panelCount
|
||||||
|
it.nameSecondary = "[$panelCount${TIMES}2] $text"
|
||||||
|
}
|
||||||
|
|
||||||
|
actorInventory.add(item)
|
||||||
|
Echo("Sign added: ${item.nameSecondary}")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun printUsage() {
|
||||||
|
Echo("Usage: makesign <text>")
|
||||||
|
Echo("Usage: makesign <text> <panelcount>")
|
||||||
|
Echo("If panel count is not given, smallest possible panel count will be used.")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -115,10 +115,8 @@ class ActorInventory() : FixtureInventory() {
|
|||||||
remove(item, 1)
|
remove(item, 1)
|
||||||
|
|
||||||
|
|
||||||
newItem = item.clone()
|
newItem = item.makeDynamic(this)
|
||||||
newItem.generateUniqueDynamicID(this)
|
|
||||||
|
|
||||||
newItem.stackable = false
|
|
||||||
add(newItem)
|
add(newItem)
|
||||||
itemEquipped[newItem.equipPosition] = newItem.dynamicID //invSearchByDynamicID(newItem.dynamicID)!!.item // will test if some sketchy code is written. Test fail: kotlinNullpointerException
|
itemEquipped[newItem.equipPosition] = newItem.dynamicID //invSearchByDynamicID(newItem.dynamicID)!!.item // will test if some sketchy code is written. Test fail: kotlinNullpointerException
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
|||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.gameactors.*
|
import net.torvald.terrarum.gameactors.*
|
||||||
|
import net.torvald.terrarum.gameitems.GameItem
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
import net.torvald.terrarum.gameworld.fmod
|
import net.torvald.terrarum.gameworld.fmod
|
||||||
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
|
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
|
||||||
@@ -462,6 +463,14 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
|||||||
} as TextureRegionPack)
|
} as TextureRegionPack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For some customisable fixtures, they must create new dynamicItem out of their static "template",
|
||||||
|
* register the new dynamicID to the ItemCodex, then return the dynamicID.
|
||||||
|
*/
|
||||||
|
open fun itemise(): ItemID {
|
||||||
|
return ItemCodex.fixtureToItemID(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CuedByTerrainChange {
|
interface CuedByTerrainChange {
|
||||||
|
|||||||
@@ -66,10 +66,10 @@ internal class FixtureTapestry : FixtureBase {
|
|||||||
|
|
||||||
// draw canvas and frame texture over the pixmap
|
// draw canvas and frame texture over the pixmap
|
||||||
val tileFilename = "${frameBlock.replace(':','-')}"
|
val tileFilename = "${frameBlock.replace(':','-')}"
|
||||||
val frame = CommonResourcePool.getOrPut("tapestries-common-frame_$tileFilename.tga") {
|
val frame = CommonResourcePool.getOrPut("pixmap:tapestries-common-frame_$tileFilename.tga") {
|
||||||
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/frame_$tileFilename.tga").last().second)
|
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/frame_$tileFilename.tga").last().second)
|
||||||
} as Pixmap
|
} as Pixmap
|
||||||
val canvas = CommonResourcePool.getOrPut("tapestries-common-canvas.tga") {
|
val canvas = CommonResourcePool.getOrPut("pixmap:tapestries-common-canvas.tga") {
|
||||||
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/canvas.tga").last().second)
|
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/canvas.tga").last().second)
|
||||||
} as Pixmap
|
} as Pixmap
|
||||||
|
|
||||||
|
|||||||
@@ -12,10 +12,15 @@ import net.torvald.spriteanimation.SheetSpriteAnimation
|
|||||||
import net.torvald.terrarum.*
|
import net.torvald.terrarum.*
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||||
|
import net.torvald.terrarum.gameitems.GameItem
|
||||||
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
|
import net.torvald.terrarum.itemproperties.Item
|
||||||
import net.torvald.terrarum.langpack.Lang
|
import net.torvald.terrarum.langpack.Lang
|
||||||
|
import net.torvald.terrarum.modulebasegame.gameitems.ItemTextSignCopper
|
||||||
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.tooltipShowing
|
import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.tooltipShowing
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
|
import net.torvald.unicode.TIMES
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -53,6 +58,19 @@ class FixtureTextSignCopper : Electric {
|
|||||||
reload()
|
reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun _itemise(actor: ActorHumanoid): GameItem {
|
||||||
|
return ItemTextSignCopper(Item.COPPER_SIGN).makeDynamic(actor.inventory).also {
|
||||||
|
it.extra["signContent"] = text
|
||||||
|
it.extra["signPanelCount"] = panelCount
|
||||||
|
it.nameSecondary = "[$panelCount${TIMES}2] $text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun itemise(): ItemID {
|
||||||
|
val item = _itemise(INGAME.actorNowPlaying!!)
|
||||||
|
return item.dynamicID
|
||||||
|
}
|
||||||
|
|
||||||
override fun spawn(posX: Int, posY: Int, installersUUID: UUID?): Boolean = spawn(posX, posY, installersUUID, panelCount.coerceAtLeast(2), 2)
|
override fun spawn(posX: Int, posY: Int, installersUUID: UUID?): Boolean = spawn(posX, posY, installersUUID, panelCount.coerceAtLeast(2), 2)
|
||||||
|
|
||||||
override fun reload() {
|
override fun reload() {
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import net.torvald.terrarum.modulebasegame.gameactors.FixtureTapestry
|
|||||||
*/
|
*/
|
||||||
class ItemTapestry(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTapestry") {
|
class ItemTapestry(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTapestry") {
|
||||||
|
|
||||||
|
constructor() : this("") // item that can be dynamic needs no-arg constructor, as the class gets serialised into the savegame under dynamicItemInventory.[dynamicID]
|
||||||
|
|
||||||
override var dynamicID: ItemID = originalID
|
override var dynamicID: ItemID = originalID
|
||||||
override var baseMass = 6.0
|
override var baseMass = 6.0
|
||||||
override val canBeDynamic = false
|
override val canBeDynamic = false
|
||||||
@@ -25,8 +27,9 @@ class ItemTapestry(originalID: ItemID) : FixtureItemBase(originalID, "net.torval
|
|||||||
|
|
||||||
@Transient override val makeFixture: () -> FixtureBase = {
|
@Transient override val makeFixture: () -> FixtureBase = {
|
||||||
FixtureTapestry(
|
FixtureTapestry(
|
||||||
Gdx.files.internal("assets/monkey_island").readBytes(),
|
// TODO use extra["fileRef"] (string) and extra["framingMaterial"] (string)
|
||||||
Block.PLANK_NORMAL
|
Gdx.files.internal("assets/monkey_island").readBytes(),
|
||||||
|
Block.PLANK_NORMAL
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,19 @@ import net.torvald.terrarum.CommonResourcePool
|
|||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
import net.torvald.terrarum.gameitems.ItemID
|
||||||
|
import net.torvald.terrarum.itemproperties.Item
|
||||||
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.FixtureLogicSignalEmitter
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureLogicSignalEmitter
|
||||||
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureTextSignCopper
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 2024-03-20.
|
* Created by minjaesong on 2024-03-20.
|
||||||
*/
|
*/
|
||||||
class ItemTextSignCopper(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTextSignCopper") {
|
class ItemTextSignCopper(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTextSignCopper") {
|
||||||
|
|
||||||
|
constructor() : this("") // item that can be dynamic needs no-arg constructor, as the class gets serialised into the savegame under dynamicItemInventory.[dynamicID]
|
||||||
|
|
||||||
override var dynamicID: ItemID = originalID
|
override var dynamicID: ItemID = originalID
|
||||||
override var baseMass = 10.0
|
override var baseMass = 10.0
|
||||||
override val canBeDynamic = false
|
override val canBeDynamic = false
|
||||||
@@ -25,4 +30,10 @@ class ItemTextSignCopper(originalID: ItemID) : FixtureItemBase(originalID, "net.
|
|||||||
override var baseToolSize: Double? = baseMass
|
override var baseToolSize: Double? = baseMass
|
||||||
override var originalName = "ITEM_COPPER_SIGN"
|
override var originalName = "ITEM_COPPER_SIGN"
|
||||||
|
|
||||||
|
@Transient override val makeFixture: () -> FixtureBase = {
|
||||||
|
FixtureTextSignCopper(
|
||||||
|
extra.getAsString("signContent") ?: "",
|
||||||
|
extra.getAsInt("signPanelCount") ?: 2
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
Reference in New Issue
Block a user