diff --git a/assets/mods/basegame/commands.csv b/assets/mods/basegame/commands.csv index c7e32c888..3d7d3dfbe 100644 --- a/assets/mods/basegame/commands.csv +++ b/assets/mods/basegame/commands.csv @@ -16,6 +16,7 @@ ImportWorld Inventory KillActor LangTest +MakeSign MoneyDisp MusicTest Possess diff --git a/assets/mods/basegame/items/items.tga b/assets/mods/basegame/items/items.tga index 1b30a62f8..719acb81e 100644 --- a/assets/mods/basegame/items/items.tga +++ b/assets/mods/basegame/items/items.tga @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d10733651b188c717482ec84926ef5d248192c2130a23a82fbbdc8154abf8f05 +oid sha256:c7e3f29270dc3084ff7c01cbbb6d0bef1e5fc1b3ffce534e3df6077f9b54556e size 2408466 diff --git a/src/net/torvald/terrarum/gameitems/GameItem.kt b/src/net/torvald/terrarum/gameitems/GameItem.kt index 3c29aa4d8..2200c4e48 100644 --- a/src/net/torvald/terrarum/gameitems/GameItem.kt +++ b/src/net/torvald/terrarum/gameitems/GameItem.kt @@ -211,12 +211,12 @@ abstract class GameItem(val originalID: ItemID) : Comparable, Cloneabl @Transient var tags = HashSet() /** - * Tags added/removed by dynamic items + * Tags added/removed by dynamic items (e.g. enchanting) */ var modifiers = HashSet() /** - * 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() @@ -368,7 +368,7 @@ abstract class GameItem(val originalID: ItemID) : Comparable, Cloneabl @JvmStatic val MISC = "misc" } - override public fun clone(): GameItem { + public override fun clone(): GameItem { val clonedItem = super.clone() // properly clone ItemValue (clonedItem as GameItem).itemProperties = this.itemProperties.clone() @@ -376,8 +376,17 @@ abstract class GameItem(val originalID: ItemID) : Comparable, Cloneabl 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)}" ItemCodex.registerNewDynamicItem(dynamicID, this) return this @@ -395,7 +404,7 @@ abstract class GameItem(val originalID: ItemID) : Comparable, Cloneabl fun generateUniqueDynamicID(inventory: ActorInventory): Int { var ret: Int do { - ret = (1..2147483647).random() + ret = (1..999999999).random() } while (inventory.contains("$PREFIX_DYNAMICITEM:$ret")) return ret diff --git a/src/net/torvald/terrarum/itemproperties/Item.kt b/src/net/torvald/terrarum/itemproperties/Item.kt index 1fcb956e7..078aed9f6 100644 --- a/src/net/torvald/terrarum/itemproperties/Item.kt +++ b/src/net/torvald/terrarum/itemproperties/Item.kt @@ -7,7 +7,6 @@ object Item { const val TREE_STICK = "item@basegame:18" - const val TREE_SEED_OAK = "item@basegame:160" - const val TREE_LOGS_OAK = "item@basegame:168" + const val COPPER_SIGN = "item@basegame:33280" } \ No newline at end of file diff --git a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt index ad1e206ab..da5af9304 100644 --- a/src/net/torvald/terrarum/itemproperties/ItemCodex.kt +++ b/src/net/torvald/terrarum/itemproperties/ItemCodex.kt @@ -84,6 +84,8 @@ class ItemCodex { 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:" */ fun registerNewDynamicItem(dynamicID: ItemID, item: GameItem) { diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 59fbe3995..11f9e7bc4 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -1693,7 +1693,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) { // pickup a fixture 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") // 0. hide tooltips setTooltipMessage(null) diff --git a/src/net/torvald/terrarum/modulebasegame/console/MakeSign.kt b/src/net/torvald/terrarum/modulebasegame/console/MakeSign.kt new file mode 100644 index 000000000..993d95a52 --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/console/MakeSign.kt @@ -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) { + 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 ") + Echo("Usage: makesign ") + Echo("If panel count is not given, smallest possible panel count will be used.") + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt index ca42c2f61..0bbf85ae7 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorInventory.kt @@ -115,10 +115,8 @@ class ActorInventory() : FixtureInventory() { remove(item, 1) - newItem = item.clone() - newItem.generateUniqueDynamicID(this) + newItem = item.makeDynamic(this) - newItem.stackable = false add(newItem) itemEquipped[newItem.equipPosition] = newItem.dynamicID //invSearchByDynamicID(newItem.dynamicID)!!.item // will test if some sketchy code is written. Test fail: kotlinNullpointerException diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt index b375eb23a..7977eccd2 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt @@ -6,6 +6,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.gameactors.* +import net.torvald.terrarum.gameitems.GameItem import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameworld.fmod import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore @@ -462,6 +463,14 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange { } 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 { diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTapestry.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTapestry.kt index b08135a42..bcfbb2e60 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTapestry.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTapestry.kt @@ -66,10 +66,10 @@ internal class FixtureTapestry : FixtureBase { // draw canvas and frame texture over the pixmap 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) } 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) } as Pixmap diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTextSignCopper.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTextSignCopper.kt index 36f859be3..4521f87a1 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTextSignCopper.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureTextSignCopper.kt @@ -12,10 +12,15 @@ import net.torvald.spriteanimation.SheetSpriteAnimation import net.torvald.terrarum.* import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE 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.modulebasegame.gameitems.ItemTextSignCopper import net.torvald.terrarum.modulebasegame.ui.UIItemInventoryCellCommonRes.tooltipShowing import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack +import net.torvald.unicode.TIMES import org.dyn4j.geometry.Vector2 import java.util.* @@ -53,6 +58,19 @@ class FixtureTextSignCopper : Electric { 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 reload() { diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemTapestry.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemTapestry.kt index 5498d08fe..56944849f 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemTapestry.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemTapestry.kt @@ -14,6 +14,8 @@ import 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 baseMass = 6.0 override val canBeDynamic = false @@ -25,8 +27,9 @@ class ItemTapestry(originalID: ItemID) : FixtureItemBase(originalID, "net.torval @Transient override val makeFixture: () -> FixtureBase = { FixtureTapestry( - Gdx.files.internal("assets/monkey_island").readBytes(), - Block.PLANK_NORMAL + // TODO use extra["fileRef"] (string) and extra["framingMaterial"] (string) + Gdx.files.internal("assets/monkey_island").readBytes(), + Block.PLANK_NORMAL ) } diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemTextSignCopper.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemTextSignCopper.kt index ca81919f7..eaf08901b 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemTextSignCopper.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemTextSignCopper.kt @@ -5,14 +5,19 @@ import net.torvald.terrarum.CommonResourcePool import net.torvald.terrarum.Terrarum import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gameitems.ItemID +import net.torvald.terrarum.itemproperties.Item 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.FixtureTextSignCopper /** * Created by minjaesong on 2024-03-20. */ 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 baseMass = 10.0 override val canBeDynamic = false @@ -25,4 +30,10 @@ class ItemTextSignCopper(originalID: ItemID) : FixtureItemBase(originalID, "net. override var baseToolSize: Double? = baseMass override var originalName = "ITEM_COPPER_SIGN" + @Transient override val makeFixture: () -> FixtureBase = { + FixtureTextSignCopper( + extra.getAsString("signContent") ?: "", + extra.getAsInt("signPanelCount") ?: 2 + ) + } } \ No newline at end of file diff --git a/work_files/graphics/items/basegame_items.kra b/work_files/graphics/items/basegame_items.kra index 1ba9d5f44..a191905b5 100644 --- a/work_files/graphics/items/basegame_items.kra +++ b/work_files/graphics/items/basegame_items.kra @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0d75d07253f4317ef3ed1218703c2aaa59e6a52fddad5696efc9f7f35821a596 -size 1716642 +oid sha256:3c8be6de34bfdc16c07b5caab43a5872c95d3ef5636752f6c15c3fc20d4184a4 +size 1715464