tapestry is decoded and itemised just fine but does not spawn

This commit is contained in:
minjaesong
2022-02-28 15:34:48 +09:00
parent 68d8bf13b7
commit e8330af14a
12 changed files with 191 additions and 128 deletions

View File

@@ -7,3 +7,5 @@
"7";"net.torvald.terrarum.modulebasegame.gameitems.WireGraphDebugger"
"8";"net.torvald.terrarum.modulebasegame.gameitems.ItemLogicSignalEmitter"
"9";"net.torvald.terrarum.modulebasegame.gameitems.WireCutterAll"
"999";"net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry"
1 id classname
7 7 net.torvald.terrarum.modulebasegame.gameitems.WireGraphDebugger
8 8 net.torvald.terrarum.modulebasegame.gameitems.ItemLogicSignalEmitter
9 9 net.torvald.terrarum.modulebasegame.gameitems.WireCutterAll
10 999 net.torvald.terrarum.modulebasegame.gameitems.ItemTapestry
11

View File

@@ -115,10 +115,14 @@ object CommonResourcePool {
return pool[identifier]!!
}
fun getOrNull(identifier: String) = pool[identifier]
fun getOrDefault(identifier: String, defaultValue: Any) = pool.getOrDefault(identifier, defaultValue)
fun getOrPut(identifier: String, defaultValue: () -> Any) = pool.getOrPut(identifier, defaultValue)
fun getOrElse(identifier: String, defaultValue: () -> Any) = pool.getOrElse(identifier, defaultValue)
fun getOrNull(name: String) = pool[name]
fun getOrPut(name: String, loadfun: () -> Any) = CommonResourcePool.getOrPut(name, loadfun, null)
fun getOrPut(name: String, loadfun: () -> Any, killfun: ((Any) -> Unit)?): Any {
if (pool.containsKey(name)) return pool[name]!!
pool[name] = loadfun.invoke()
poolKillFun[name] = killfun
return pool[name]!!
}
inline fun <reified T> getAs(identifier: String) = get(identifier) as T
fun getAsTextureRegionPack(identifier: String) = getAs<TextureRegionPack>(identifier)

View File

@@ -727,7 +727,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
/** RENDER CODE GOES HERE */
measureDebugTime("Ingame.Render") { renderGame() }
val autosaveInterval = App.getConfigInt("autosaveinterval") / 1000f
val autosaveInterval = App.getConfigInt("autosaveinterval").coerceAtLeast(60000) / 1000f
if (autosaveTimer >= autosaveInterval) {
queueAutosave()
autosaveTimer -= autosaveInterval

View File

@@ -14,14 +14,14 @@ import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
*/
internal object Inventory : ConsoleCommand {
private var targetID: ActorID = PLAYER_REF_ID
private var targetID: ActorID = INGAME.actorNowPlaying?.referenceID ?: PLAYER_REF_ID
override fun execute(args: Array<String>) {
if (args.size == 1) {
printUsage()
}
else if (args[1] == "target") {
targetID = if (args[2].lowercase() == "player") PLAYER_REF_ID else args[2].toInt()
targetID = if (args[2].lowercase() == "player") (INGAME.actorNowPlaying?.referenceID ?: PLAYER_REF_ID) else args[2].toInt()
}
else {
val actor = getActor()

View File

@@ -126,7 +126,7 @@ object DecodeTapestry {
if (colourModel != FORMAT_16 && colourModel != FORMAT_64)
throw RuntimeException("Invalid colour model: $colourModel")
val width = file[7].toUint().shl(8) + file[6].toUint()
val width = file[6].toUint().shl(8) + file[7].toUint()
val artNameBytes = ArrayList<Byte>()
val authorNameBytes = ArrayList<Byte>()

View File

@@ -23,6 +23,8 @@ interface Electric {
/**
* Protip: do not make child classes take any argument, especially no function (function "classes" have no zero-arg constructor)
*
* Initialising Fixture after deserialisation: override `reload()`
*
* Created by minjaesong on 2016-06-17.
*/
open class FixtureBase : ActorWithBody, CuedByTerrainChange {
@@ -34,7 +36,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
@Transient var mainUI: UICanvas? = null
var inventory: FixtureInventory? = null
protected constructor() : super(RenderOrder.BEHIND, PhysProperties.IMMOBILE, null)
private constructor() : super(RenderOrder.BEHIND, PhysProperties.IMMOBILE, null)
constructor(
@@ -130,7 +132,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
if (hasCollision) return false
printdbg(this, "spawn ${nameFun()}")
printdbg(this, "spawn fixture ${nameFun()}, tilewise dim: (${blockBox.width}, ${blockBox.height})")
// set the position of this actor
worldBlockPos = Point2i(posX, posY)
@@ -161,8 +163,10 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
* Removes this instance of the fixture from the world
*/
open fun despawn() {
if (canBeDespawned) {
if (this !is FixtureTapestry && canBeDespawned) {
printdbg(this, "despawn at T${INGAME.WORLD_UPDATE_TIMER}: ${nameFun()}")
printStackTrace(this)
// remove filler block
forEachBlockbox { x, y ->
@@ -181,6 +185,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
}
}
else {
// printdbg(this, "despawn at T${INGAME.WORLD_UPDATE_TIMER}: ${nameFun()}")
printdbg(this, "cannot despawn a fixture with non-empty inventory")
}
}

View File

@@ -105,10 +105,10 @@ open class FixtureInventory() {
if (existingItem != null) { // if the item already exists
val newCount = existingItem.qty - count
if (newCount < 0) {
/*if (newCount < 0) {
throw Error("[${this.javaClass.canonicalName}] Tried to remove $count of $item, but the inventory only contains ${existingItem.qty} of them.")
}
else if (newCount > 0) {
else*/ if (newCount > 0) {
// decrement count
existingItem.qty = newCount
}
@@ -120,7 +120,7 @@ open class FixtureInventory() {
}
}
else {
throw Error("[${this.javaClass.canonicalName}] Tried to remove $item, but the inventory does not have it.")
// throw Error("[${this.javaClass.canonicalName}] Tried to remove $item, but the inventory does not have it.")
}
}

View File

@@ -0,0 +1,108 @@
package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.*
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.langpack.Lang
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2017-01-07.
*/
internal class FixtureTapestry : FixtureBase {
var artName = ""; private set
var artAuthor = ""; private set
val tw = 1
val th = 1
private var rawBytes = ByteArray(tw * th * 256)
private var frameBlock: ItemID = Block.PLANK_NORMAL
private constructor() : super(
BlockBox(BlockBox.NO_COLLISION, 1, 1),
renderOrder = RenderOrder.BEHIND,
nameFun = { Lang["ITEM_TAPESTRY"] }
)
constructor(rawBytes: ByteArray, framingMaterial: ItemID) : super(
BlockBox(BlockBox.NO_COLLISION, 1, 1),
renderOrder = RenderOrder.BEHIND,
nameFun = { Lang["ITEM_TAPESTRY"] }
) {
this.rawBytes = rawBytes
this.frameBlock = framingMaterial
reload()
}
override fun reload() {
super.reload()
val (pixmap, name, author) = DecodeTapestry(rawBytes)
artName = name
artAuthor = author
nameFun = { "$ccW$artAuthor, $ccC$artName" }
if (pixmap.width % TILE_SIZE != 0 || pixmap.height % TILE_SIZE != 0 || pixmap.width * pixmap.height == 0) {
throw UnsupportedOperationException("Tapestry size not multiple of tile size: (${pixmap.width}x${pixmap.height})")
}
// draw canvas and frame texture over the pixmap
val tileFilename = "${frameBlock.replace(':','-')}"
val frame = CommonResourcePool.getOrPut("tapestries-common-frame_$tileFilename.tga") {
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/frame_$tileFilename.tga").last().second)
} as Pixmap
val canvas = CommonResourcePool.getOrPut("tapestries-common-canvas") {
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/canvas.tga").last().second)
} as Pixmap
val tw = pixmap.width.div(TILE_SIZEF).ceilInt()
val th = pixmap.height.div(TILE_SIZEF).ceilInt()
// blend canvas texture
for (y in 0 until pixmap.height) { for (x in 0 until pixmap.width) {
val srcCol = canvas.getPixel(x % pixmap.width, y % pixmap.height)
val dstCol = pixmap.getPixel(x, y)
// pixmap.drawPixel(x, y, dstCol rgbamul srcCol)
val col = Color(dstCol) mul Color(srcCol)
pixmap.setColor(col)
pixmap.drawPixel(x, y)
} }
// draw frame
for (ty in 0 until th) { for (tx in 0 until tw) {
val srcx = TILE_SIZE * (if (tw == 1) 0 else if (tx == 0) 1 else if (tx == tw - 1) 3 else 2)
val srcy = TILE_SIZE * (if (th == 1) 0 else if (ty == 0) 1 else if (ty == th - 1) 3 else 2)
val dstx = tx * TILE_SIZE
val dsty = ty * TILE_SIZE
pixmap.drawPixmap(frame, srcx, srcy, TILE_SIZE, TILE_SIZE, dstx, dsty, TILE_SIZE, TILE_SIZE)
} }
val texture = Texture(pixmap)
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
val texturePack = TextureRegionPack(texture, pixmap.width, pixmap.height)
makeNewSprite(texturePack)
setHitboxDimension(pixmap.width, pixmap.height, 0, 0)
setPosition(Terrarum.mouseX, Terrarum.mouseY)
// redefine blockbox
this.blockBox = BlockBox(BlockBox.NO_COLLISION, tw, th)
this.renderOrder = RenderOrder.BEHIND
pixmap.dispose()
INGAME.disposables.add(texture)
}
override var tooltipText: String? = "$artName\n$artAuthor"
}

View File

@@ -1,108 +0,0 @@
package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.*
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.gameactors.ActorID
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2017-01-07.
*/
class TapestryObject : FixtureBase {
@Transient private var initialised = false
var artName = ""; private set
var artAuthor = ""; private set
val tw = 1
val th = 1
private var rawBytes = ByteArray(tw * th * 256)
private var frameBlock: ItemID = Block.PLANK_NORMAL
private constructor() : super()
constructor(rawBytes: ByteArray, framingMaterial: ItemID) : super() {
this.artName = artName
this.artAuthor = artAuthor
this.nameFun = { "$ccW$artAuthor, $ccC$artName" }
this.rawBytes = rawBytes
this.frameBlock = framingMaterial
}
override fun update(delta: Float) {
if (!initialised) {
initialised = true
val (pixmap, name, author) = DecodeTapestry(rawBytes)
artName = name
artAuthor = author
if (pixmap.width % TILE_SIZE != 0 || pixmap.height % TILE_SIZE != 0 || pixmap.width * pixmap.height == 0) {
throw UnsupportedOperationException("Tapestry size not multiple of tile size: (${pixmap.width}x${pixmap.height})")
}
// draw canvas and frame texture over the pixmap
val tileFilename = "${frameBlock.replace(':','-')}"
val frame = CommonResourcePool.getOrPut("tapestries-common-frame_$tileFilename.tga") {
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/frame_$tileFilename.tga").last().second)
} as Pixmap
val canvas = CommonResourcePool.getOrPut("tapestries-common-canvas") {
Pixmap(ModMgr.getGdxFilesFromEveryMod("tapestries/common/canvas.tga").last().second)
} as Pixmap
val tw = pixmap.width.div(TILE_SIZEF).ceilInt()
val th = pixmap.height.div(TILE_SIZEF).ceilInt()
// blend canvas texture
for (y in 0 until pixmap.height) { for (x in 0 until pixmap.width) {
val srcCol = canvas.getPixel(x % pixmap.width, y % pixmap.height)
val dstCol = pixmap.getPixel(x, y)
pixmap.drawPixel(x, y, dstCol rgbamul srcCol)
} }
// draw frame
for (ty in 0 until th) { for (tx in 0 until tw) {
val srcx = TILE_SIZE * (if (tw == 1) 0 else if (tx == 0) 1 else if (tx == tw - 1) 3 else 2)
val srcy = TILE_SIZE * (if (th == 1) 0 else if (ty == 0) 1 else if (tw == th - 1) 3 else 2)
val dstx = tx * TILE_SIZE
val dsty = ty * TILE_SIZE
pixmap.drawPixmap(frame, srcx, srcy, TILE_SIZE, TILE_SIZE, dstx, dsty, TILE_SIZE, TILE_SIZE)
} }
val texture = Texture(pixmap)
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)
val texturePack = TextureRegionPack(texture, texture.width, texture.height)
makeNewSprite(texturePack)
setHitboxDimension(texture.width, texture.height, 0, 0)
setPosition(Terrarum.mouseX, Terrarum.mouseY)
// redefine blockbox
this.blockBox = BlockBox(BlockBox.NO_COLLISION, tw, th)
this.renderOrder = RenderOrder.BEHIND
pixmap.dispose()
INGAME.disposables.add(texture)
}
super.update(delta)
}
override fun drawBody(batch: SpriteBatch) {
super.drawBody(batch)
}
override var tooltipText: String? = "$artName\n$artAuthor"
}

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.modulebasegame.gameitems
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.INGAME
import net.torvald.terrarum.ItemCodex
@@ -16,9 +17,9 @@ import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
/**
* Created by minjaesong on 2021-12-13.
*/
open class FixtureItemBase(originalID: ItemID, fixtureClassName: String) : GameItem(originalID) {
open class FixtureItemBase(originalID: ItemID, val fixtureClassName: String) : GameItem(originalID) {
private val makeFixture: () -> FixtureBase = {
protected open val makeFixture: () -> FixtureBase = {
Class.forName(fixtureClassName).getDeclaredConstructor().newInstance() as FixtureBase
}
@@ -26,7 +27,12 @@ open class FixtureItemBase(originalID: ItemID, fixtureClassName: String) : GameI
ItemCodex.fixtureToSpawnerItemID[fixtureClassName] = originalID
}
protected val ghostItem = makeFixture()
protected var ghostItem: FixtureBase? = null
get() {
if (field == null)
ghostItem = makeFixture()
return field
}
override var dynamicID: ItemID = originalID
override val originalName = "FIXTUREBASE"
@@ -42,7 +48,7 @@ open class FixtureItemBase(originalID: ItemID, fixtureClassName: String) : GameI
override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) {
(INGAME as TerrarumIngame).blockMarkingActor.let {
it.setGhost(ghostItem)
it.setGhost(ghostItem!!)
it.isVisible = true
it.update(delta)
it.setGhostColourBlock()
@@ -59,7 +65,7 @@ open class FixtureItemBase(originalID: ItemID, fixtureClassName: String) : GameI
}
override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = mouseInInteractableRange(actor) {
val item = makeFixture()
val item = ghostItem!!//makeFixture()
item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1)
// return true when placed, false when cannot be placed

View File

@@ -1,7 +1,9 @@
package net.torvald.terrarum.modulebasegame.gameitems
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.gameitems.ItemID
@@ -20,7 +22,11 @@ class ItemLogicSignalEmitter(originalID: ItemID) : FixtureItemBase(originalID, "
override val isDynamic = false
override val material = Material()
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegion("basegame-sprites-fixtures-signal_source.tga")
get() = CommonResourcePool.getOrPut("basegame-sprites-fixtures-signal_source.tga") {
val t = TextureRegion(Texture(ModMgr.getGdxFile("basegame", "sprites/fixtures/signal_source.tga")))
t.flip(false, false)
/*return*/t
} as TextureRegion
override var baseToolSize: Double? = baseMass
init {

View File

@@ -0,0 +1,40 @@
package net.torvald.terrarum.modulebasegame.gameitems
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.itemproperties.Material
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
import net.torvald.terrarum.modulebasegame.gameactors.FixtureTapestry
/**
* Created by minjaesong on 2022-02-28.
*/
class ItemTapestry(originalID: ItemID) : FixtureItemBase(originalID, "net.torvald.terrarum.modulebasegame.gameactors.FixtureTapestry") {
override var dynamicID: ItemID = originalID
override val originalName = "ITEM_TAPESTRY"
override var baseMass = 6.0
override var stackable = true
override var inventoryCategory = Category.MISC
override val isUnique = false
override val isDynamic = false
override val material = Material()
override val itemImage: TextureRegion
get() = CommonResourcePool.getAsTextureRegion("itemplaceholder_16")
override var baseToolSize: Double? = baseMass
init {
equipPosition = EquipPosition.HAND_GRIP
}
override val makeFixture: () -> FixtureBase = {
FixtureTapestry(
Gdx.files.internal("assets/monkey_island").readBytes(),
Block.PLANK_NORMAL
)
}
}