game item to load its own image if needed; common resource pool to assist that

This commit is contained in:
minjaesong
2019-03-10 17:46:48 +09:00
parent d895da9e96
commit 833d8814a7
21 changed files with 197 additions and 66 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -4,7 +4,6 @@ import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Files;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.audio.AudioDevice;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
@@ -290,11 +289,12 @@ public class AppLoader implements ApplicationListener {
private FrameBuffer renderFBO;
public static AssetManager assetManager;
public static CommonResourcePool resourcePool;
@Override
public void create() {
assetManager = new AssetManager();
resourcePool = CommonResourcePool.INSTANCE;
// set basis of draw
logoBatch = new SpriteBatch();
@@ -533,7 +533,7 @@ public class AppLoader implements ApplicationListener {
shaderPassthruRGB.dispose();
shaderColLUT.dispose();
assetManager.dispose();
resourcePool.dispose();
fullscreenQuad.dispose();
logoBatch.dispose();
@@ -604,6 +604,11 @@ public class AppLoader implements ApplicationListener {
}
ModMgr.INSTANCE.invoke(); // invoke Module Manager
AppLoader.resourcePool.loadAll();
printdbg(this, "all modules loaded successfully");
BlocksDrawer.INSTANCE.getWorld(); // will initialize the BlocksDrawer by calling dummy method
LightmapRenderer.INSTANCE.hdr(0f);

View File

@@ -0,0 +1,64 @@
package net.torvald.terrarum
import com.badlogic.gdx.utils.Disposable
import com.badlogic.gdx.utils.Queue
/**
* Created by minjaesong on 2019-03-10.
*/
object CommonResourcePool {
private val loadingList = Queue<Pair<Pair<String, Class<*>>, () -> Disposable>>()
private val pool = HashMap<String, Disposable>()
//private val typesMap = HashMap<String, Class<*>>()
private var loadCounter = -1 // using counters so that the loading can be done on separate thread (gg if the asset requires GL context to be loaded)
val loaded: Boolean
get() = loadCounter == 0
fun <T> addToLoadingList(identifier: String, type: Class<T>, loadFunction: () -> Disposable) {
loadingList.addFirst(identifier to type to loadFunction)
if (loadCounter == -1)
loadCounter = 1
else
loadCounter += 1
}
/**
* You are supposed to call this function only once.
*/
fun loadAll() {
if (loaded) throw IllegalStateException("Assets are already loaded and shipped out :p")
while (!loadingList.isEmpty) {
val (k, loadfun) = loadingList.removeFirst()
val (name, type) = k
if (pool.containsKey(name)) {
throw IllegalArgumentException("Assets with identifier '$name' already exists.")
}
//typesMap[name] = type
pool[name] = loadfun.invoke()
loadCounter -= 1
}
}
operator fun get(identifier: String): Disposable {
val obj = pool[identifier]!!
return obj
}
fun dispose() {
pool.forEach { _, u ->
try {
u.dispose()
}
catch (e: Throwable) {
e.printStackTrace()
}
}
}
}

View File

@@ -140,6 +140,8 @@ object ModMgr {
}*/
}
operator fun invoke() { }
private fun checkExistence(module: String) {
if (!moduleInfo.containsKey(module))
throw FileNotFoundException("No such module: $module")

View File

@@ -2,7 +2,6 @@ package net.torvald.terrarum
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Screen
import com.badlogic.gdx.assets.AssetManager
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.GL20
import com.badlogic.gdx.graphics.OrthographicCamera
@@ -195,9 +194,6 @@ object Terrarum : Screen {
lateinit var assetManager: AssetManager // TODO
init {
println("$NAME version ${AppLoader.getVERSION_STRING()}")
println("Java Runtime version ${System.getProperty("java.version")}")
@@ -302,8 +298,6 @@ object Terrarum : Screen {
val MINIMAL_GL_MAX_TEXTURE_SIZE = 4096
override fun show() {
assetManager = AssetManager()
testTexture = Texture(Gdx.files.internal("./assets/test_texture.tga"))
@@ -388,13 +382,6 @@ object Terrarum : Screen {
ModMgr // invoke Module Manager
printdbg(this, "all modules loaded successfully")
// jump straight into the ingame
/*val ingame = Ingame(batch)

View File

@@ -46,7 +46,7 @@ open class GameWorld {
//layers
val layerWall: MapLayer
val layerTerrain: MapLayer
val layerWire: MapLayer
//val layerWire: MapLayer
val layerWallLowBits: PairedMapLayer
val layerTerrainLowBits: PairedMapLayer
@@ -63,6 +63,12 @@ open class GameWorld {
val terrainDamages: HashMap<BlockAddress, Float>
val fluidTypes: HashMap<BlockAddress, FluidType>
val fluidFills: HashMap<BlockAddress, Float>
val conduitTypes: HashMap<BlockAddress, Int> // 1 bit = 1 conduit (pipe/wire) type
val conduitFills: Array<HashMap<BlockAddress, Float>>
val conduitFills0: HashMap<BlockAddress, Float> // size of liquid packet on the block
get() = conduitFills[0]
val conduitFills1: HashMap<BlockAddress, Float> // size of gas packet on the block
get() = conduitFills[1]
//public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) );
//physics
@@ -89,7 +95,7 @@ open class GameWorld {
layerTerrain = MapLayer(width, height)
layerWall = MapLayer(width, height)
layerWire = MapLayer(width, height)
//layerWire = MapLayer(width, height)
layerTerrainLowBits = PairedMapLayer(width, height)
layerWallLowBits = PairedMapLayer(width, height)
@@ -98,6 +104,9 @@ open class GameWorld {
fluidTypes = HashMap<BlockAddress, FluidType>()
fluidFills = HashMap<BlockAddress, Float>()
conduitTypes = HashMap<BlockAddress, Int>()
conduitFills = Array(16) { HashMap<BlockAddress, Float>() }
// temperature layer: 2x2 is one cell
//layerThermal = MapLayerHalfFloat(width, height, averageTemperature)
@@ -115,7 +124,7 @@ open class GameWorld {
layerTerrain = layerData.layerTerrain
layerWall = layerData.layerWall
layerWire = layerData.layerWire
//layerWire = layerData.layerWire
layerTerrainLowBits = layerData.layerTerrainLowBits
layerWallLowBits = layerData.layerWallLowBits
@@ -124,6 +133,9 @@ open class GameWorld {
fluidTypes = layerData.fluidTypes
fluidFills = layerData.fluidFills
conduitTypes = HashMap<BlockAddress, Int>()
conduitFills = Array(16) { HashMap<BlockAddress, Float>() }
spawnX = layerData.spawnX
spawnY = layerData.spawnY
@@ -158,16 +170,8 @@ open class GameWorld {
* @return byte[][] wire layer
*/
val wireArray: ByteArray
get() = layerWire.data
/**
* Get paired array data of damage codes.
* Format: 0baaaabbbb, aaaa for x = 0, 2, 4, ..., bbbb for x = 1, 3, 5, ...
* @return byte[][] damage code pair
*/
val damageDataArray: ByteArray
get() = layerTerrainLowBits.data
//val wireArray: ByteArray
// get() = layerWire.data
private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceWorld())
@@ -191,9 +195,13 @@ open class GameWorld {
terrain * PairedMapLayer.RANGE + terrainDamage
}
fun getTileFromWire(x: Int, y: Int): Int? {
/*fun getTileFromWire(x: Int, y: Int): Int? {
val (x, y) = coerceXY(x, y)
return layerWire.getTile(x, y)
}*/
fun getWires(x: Int, y: Int): Int? {
return conduitTypes.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0)
}
fun getWallLowBits(x: Int, y: Int): Int? {
@@ -264,14 +272,14 @@ open class GameWorld {
Terrarum.ingame?.queueTerrainChangedEvent(oldTerrain, tile.toUint() * PairedMapLayer.RANGE + damage, LandUtil.getBlockAddr(this, x, y))
}
fun setTileWire(x: Int, y: Int, tile: Byte) {
/*fun setTileWire(x: Int, y: Int, tile: Byte) {
val (x, y) = coerceXY(x, y)
val oldWire = getTileFromWire(x, y)
layerWire.setTile(x, y, tile)
if (oldWire != null)
Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y))
}
}*/
fun getTileFrom(mode: Int, x: Int, y: Int): Int? {
if (mode == TERRAIN) {
@@ -281,7 +289,7 @@ open class GameWorld {
return getTileFromWall(x, y)
}
else if (mode == WIRE) {
return getTileFromWire(x, y)
return getWires(x, y)
}
else
throw IllegalArgumentException("illegal mode input: " + mode.toString())

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.itemproperties
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.random.HQRNG
import net.torvald.terrarum.ItemValue
import net.torvald.terrarum.itemproperties.ItemCodex.ITEM_DYNAMIC
@@ -82,6 +83,12 @@ abstract class GameItem : Comparable<GameItem>, Cloneable {
abstract val material: Material
/**
* Don't assign! Create getter -- there's inevitable execution order fuckup on ModMgr,
* where it simultaneously wanted to be called before and after the Mod's EntryPoint if you assign value to it on init block.
*/
@Transient open val itemImage: TextureRegion? = null
/**
* Apparent mass of the item. (basemass * scale^3)
*/
@@ -168,12 +175,12 @@ abstract class GameItem : Comparable<GameItem>, Cloneable {
open fun endSecondaryUse(delta: Float): Boolean = false
/**
* Effects applied immediately only once if thrown from pocket
* Effects applied immediately only once if thrown (discarded) from pocket
*/
open fun effectWhenThrown(delta: Float) { }
/**
* Effects applied (continuously or not) when equipped (drawn)
* Effects applied (continuously or not) when equipped (drawn/pulled out)
*/
open fun effectWhenEquipped(delta: Float) { }
@@ -291,6 +298,8 @@ abstract class GameItem : Comparable<GameItem>, Cloneable {
return ret
}
val NULL_MATERIAL = Material(0,0,0,0,0,0,0,0,1,0.0)
}
}

View File

@@ -1,6 +1,5 @@
package net.torvald.terrarum.itemproperties
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.AppLoader.printdbg
@@ -10,6 +9,7 @@ import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.Ingame
import net.torvald.terrarum.modulebasegame.gameactors.CanBeAnItem
import net.torvald.terrarum.worlddrawer.BlocksDrawer
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
import java.util.*
/**
@@ -31,7 +31,8 @@ object ItemCodex {
val ITEM_DYNAMIC = 0x10_0000..0x0FFF_FFFF
val ACTORID_MIN = ITEM_DYNAMIC.endInclusive + 1
private val itemImagePlaceholder = TextureRegion(Texture("./assets/item_kari_24.tga"))
private val itemImagePlaceholder: TextureRegion
get() = (AppLoader.resourcePool["basegame.items24"] as TextureRegionPack).get(0,0) // copper pickaxe
//private val ingame = Terrarum.ingame!! as Ingame // WARNING you can't put this here, ExceptionInInitializerError
@@ -294,12 +295,11 @@ object ItemCodex {
)
}
// wire
else if (itemOriginalID in ITEM_WIRES) {
/*else if (itemOriginalID in ITEM_WIRES) {
return BlocksDrawer.tilesWire.get((itemOriginalID % 16) * 16, itemOriginalID / 16)
}
// TODO get it real, using originalID...?
}*/
else
return itemImagePlaceholder
return itemCodex[itemOriginalID]?.itemImage ?: itemImagePlaceholder
}
fun hasItem(itemID: Int): Boolean = dynamicItemDescription.containsKey(itemID)

View File

@@ -1,17 +1,15 @@
package net.torvald.terrarum.modulebasegame
import net.torvald.terrarum.*
import net.torvald.terrarum.AppLoader.IS_DEVELOPMENT_BUILD
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.ModMgr
import net.torvald.terrarum.ModuleEntryPoint
import net.torvald.terrarum.Point2d
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.gameactors.ActorWBMovable
import net.torvald.terrarum.itemproperties.GameItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.itemproperties.Material
import net.torvald.terrarum.modulebasegame.imagefont.WatchFont
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* The entry point for the module "Basegame"
@@ -27,6 +25,18 @@ class EntryPoint : ModuleEntryPoint() {
ModMgr.GameLanguageLoader.invoke("basegame")
// load common resources to the AssetsManager
AppLoader.resourcePool.addToLoadingList("basegame.items16", TextureRegionPack.javaClass) {
TextureRegionPack(ModMgr.getGdxFile("basegame", "items/items.tga"), 16, 16)
}
AppLoader.resourcePool.addToLoadingList("basegame.items24", TextureRegionPack.javaClass) {
TextureRegionPack(ModMgr.getGdxFile("basegame", "items/items24.tga"), 24, 24)
}
AppLoader.resourcePool.addToLoadingList("basegame.items48", TextureRegionPack.javaClass) {
TextureRegionPack(ModMgr.getGdxFile("basegame", "items/items48.tga"), 48, 48)
}
/////////////////////////////////
// load customised item loader //
/////////////////////////////////
@@ -77,7 +87,7 @@ class EntryPoint : ModuleEntryPoint() {
this.inventoryCategory == Category.WALL &&
this.dynamicID - ItemCodex.ITEM_WALLS.start == ingame.world.getTileFromWall(Terrarum.mouseTileX, Terrarum.mouseTileY) ||
this.inventoryCategory == Category.WIRE &&
this.dynamicID - ItemCodex.ITEM_WIRES.start == ingame.world.getTileFromWire(Terrarum.mouseTileX, Terrarum.mouseTileY)
1.shl(this.dynamicID - ItemCodex.ITEM_WIRES.start) and (ingame.world.getWires(Terrarum.mouseTileX, Terrarum.mouseTileY) ?: 0) != 0
)
return false

View File

@@ -214,6 +214,9 @@ object IngameRenderer {
// works but some UI elements have wrong transparency -> should be fixed with Terrarum.gdxCleanAndSetBlend -- Torvald 2019-01-12
blendNormal(batch)
batch.color = Color.WHITE
drawWires = false
}
@@ -232,6 +235,8 @@ object IngameRenderer {
internal var fboRGBexportRequested = false
var drawWires = false
private fun drawToRGB(
actorsRenderBehind: List<ActorWithBody>?,
actorsRenderMiddle: List<ActorWithBody>?,
@@ -274,7 +279,7 @@ object IngameRenderer {
}
setCameraPosition(0f, 0f)
BlocksDrawer.drawFront(batch.projectionMatrix, false) // blue coloured filter of water, etc.
BlocksDrawer.drawFront(batch.projectionMatrix, drawWires) // blue coloured filter of water, etc.
batch.inUse {
FeaturesDrawer.drawEnvOverlay(batch)

View File

@@ -1,5 +1,7 @@
package net.torvald.terrarum.modulebasegame.items
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.Point2d
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.blockproperties.Block
@@ -10,6 +12,7 @@ import net.torvald.terrarum.itemproperties.GameItem
import net.torvald.terrarum.itemproperties.ItemID
import net.torvald.terrarum.itemproperties.Material
import net.torvald.terrarum.modulebasegame.Ingame
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2017-07-17.
@@ -22,9 +25,11 @@ class PickaxeGeneric(override val originalID: ItemID) : GameItem() {
override var baseToolSize: Double? = 10.0
override var stackable = true
override var inventoryCategory = Category.TOOL
override var isUnique = false
override var isDynamic = true
override val isUnique = false
override val isDynamic = true
override var material = Material(0,0,0,0,0,0,0,0,1,0.0)
override val itemImage: TextureRegion?
get() = (AppLoader.resourcePool["basegame.items24"] as TextureRegionPack).get(2,0)
init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP

View File

@@ -0,0 +1,39 @@
package net.torvald.terrarum.modulebasegame.items
import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.itemproperties.GameItem
import net.torvald.terrarum.itemproperties.ItemID
import net.torvald.terrarum.modulebasegame.IngameRenderer
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2019-03-10.
*/
class WirePieceSignalWire(override val originalID: ItemID) : GameItem() {
override var dynamicID: ItemID = originalID
override val originalName = "ITEM_WIRE"
override var baseMass = 0.001
override var baseToolSize: Double? = null
override var stackable = true
override var inventoryCategory = Category.WIRE
override val isUnique = false
override val isDynamic = false
override val material = GameItem.NULL_MATERIAL
override val itemImage: TextureRegion?
get() = (AppLoader.resourcePool["basegame.items16"] as TextureRegionPack).get(1,9)
init {
super.equipPosition = GameItem.EquipPosition.HAND_GRIP
}
override fun startPrimaryUse(delta: Float): Boolean {
return super.startPrimaryUse(delta)
}
override fun effectWhenEquipped(delta: Float) {
IngameRenderer.drawWires = true
}
}

View File

@@ -176,9 +176,6 @@ object WorldGenerator {
//post-process
generateFloatingIslands()
//wire layer
Arrays.fill(world.wireArray, 0.toByte())
// determine spawn position
world.spawnY = getSpawnHeight(world.spawnX)

View File

@@ -71,9 +71,6 @@ internal object ReadLayerData {
retWorld.layerTerrainLowBits.data = terrainLayerLSB
retWorld.layerWallLowBits.data = wallLayerLSB
if (wireLayer != null) {
retWorld.layerWire.data = wireLayer
}
retWorld.spawnX = spawnCoordXBytes.toLittleInt()
retWorld.spawnY = spawnCoordYBytes.toLittleInt()

View File

@@ -62,7 +62,6 @@ internal object WriteLayerData {
outputStream.write(map.layerWall.data)
outputStream.write(map.layerTerrainLowBits.data)
outputStream.write(map.layerWallLowBits.data)
outputStream.write(map.layerWire.data)
// replace savemeta with tempfile
try {

View File

@@ -113,10 +113,10 @@ internal object WriteLayerDataLzma {
wb(PAYLOAD_FOOTER)
// WIRE payload
wb(PAYLOAD_HEADER); wb("WIRE".toByteArray())
/*wb(PAYLOAD_HEADER); wb("WIRE".toByteArray())
wi48(world.width * world.height.toLong())
Lzma.compress(ByteArrayInputStream(world.wireArray), outputStream)
wb(PAYLOAD_FOOTER)
wb(PAYLOAD_FOOTER)*/
// TdMG payload
wb(PAYLOAD_HEADER); wb("TdMG".toByteArray())

View File

@@ -123,12 +123,12 @@ internal object WriteLayerDataZip {
wb(PAYLOAD_FOOTER)
// WIRE payload
wb(PAYLOAD_HEADER); wb("WIRE".toByteArray())
/*wb(PAYLOAD_HEADER); wb("WIRE".toByteArray())
wi48(world.width * world.height.toLong())
deflater = DeflaterOutputStream(outputStream, Deflater(Deflater.BEST_COMPRESSION, true), false)
deflater.write(world.wireArray)
deflater.flush(); deflater.finish()
wb(PAYLOAD_FOOTER)
wb(PAYLOAD_FOOTER)*/
// TdMG payload
wb(PAYLOAD_HEADER); wb("TdMG".toByteArray())

View File

@@ -291,7 +291,7 @@ internal object BlocksDrawer {
val thisTile = when (mode) {
WALL -> world.getTileFromWall(x, y)
TERRAIN -> world.getTileFromTerrain(x, y)
WIRE -> world.getTileFromWire(x, y)
WIRE -> world.getWires(x, y)
FLUID -> world.getFluid(x, y).type.abs()
else -> throw IllegalArgumentException()
}

View File

@@ -71,6 +71,10 @@ Payload "FlTP" -- world fluid types, array of: (Int48 tileAddress, Signed Int16
Payload "FlFL" -- world fluid fills, array of: (Int48 tileAddress, Float32 amount)
Uncompressed size will be arbitrary (multiple of tens)
If the 'amount' < 0.0001f (WorldSimulator.FLUID_MIN_MASS), the entry must be discarded
Payload "CtYP" -- conduit types, array of: (Int48 tileAddress, Uint32 bitarray)
can hold 32 different wires simultaneously
Payload "CfL0" -- conduit fills, aka size of liquid/gas packet, array of: (Int48 tileAddress, Float32 fill)
CfL0..CfL9, CfLa..CfLf are available to store values for 16 different things.
EOF 45 E
EOF 6E n

Binary file not shown.