This commit is contained in:
minjaesong
2021-02-11 20:45:38 +09:00
parent 8fdc11288c
commit 9eb757b7b9
29 changed files with 199 additions and 281 deletions

View File

@@ -1,7 +1,7 @@
"id";"classname"
"0";"net.torvald.terrarum.modulebasegame.gameitems.PickaxeCopper"
"1";"net.torvald.terrarum.modulebasegame.gameitems.PickaxeIron"
"2";"net.torvald.terrarum.modulebasegame.gameitems.PickaxeSteel"
"3";"net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire"
"4";"net.torvald.terrarum.modulebasegame.gameitems.TikiTorchTester"
"5";"net.torvald.terrarum.modulebasegame.gameitems.ItemCraftingTable"
"1";"net.torvald.terrarum.modulebasegame.gameitems.PickaxeCopper"
"2";"net.torvald.terrarum.modulebasegame.gameitems.PickaxeIron"
"3";"net.torvald.terrarum.modulebasegame.gameitems.PickaxeSteel"
"4";"net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire"
"5";"net.torvald.terrarum.modulebasegame.gameitems.TikiTorchTester"
"6";"net.torvald.terrarum.modulebasegame.gameitems.ItemCraftingTable"
1 id classname
2 0 1 net.torvald.terrarum.modulebasegame.gameitems.PickaxeCopper
3 1 2 net.torvald.terrarum.modulebasegame.gameitems.PickaxeIron
4 2 3 net.torvald.terrarum.modulebasegame.gameitems.PickaxeSteel
5 3 4 net.torvald.terrarum.modulebasegame.gameitems.WirePieceSignalWire
6 4 5 net.torvald.terrarum.modulebasegame.gameitems.TikiTorchTester
7 5 6 net.torvald.terrarum.modulebasegame.gameitems.ItemCraftingTable

View File

@@ -1123,6 +1123,21 @@ public class AppLoader implements ApplicationListener {
return ((float[]) cfg);
}
public static String[] getConfigStringArray(String key) {
Object cfg = getConfigMaster(key);
if (cfg instanceof JsonArray) {
JsonArray jsonArray = ((JsonArray) cfg).getAsJsonArray();
//return IntArray(jsonArray.size(), { i -> jsonArray[i].asInt })
String[] intArray = new String[jsonArray.size()];
for (int i = 0; i < jsonArray.size(); i++) {
intArray[i] = jsonArray.get(i).getAsString();
}
return intArray;
}
else
return ((String[]) cfg);
}
/**
* Get config from config file. If the entry does not exist, get from defaults; if the entry is not in the default, NullPointerException will be thrown
*/

View File

@@ -235,15 +235,15 @@ object ModMgr {
@JvmStatic operator fun invoke(module: String) {
val csv = CSVFetcher.readFromModule(module, itemPath + "itemid.csv")
csv.forEach {
val className = it["classname"].toString()
val internalID = it["id"].toInt()
val itemName = "item@$module:$internalID"
val className: String = it["classname"].toString()
val internalID: Int = it["id"].toInt()
val itemName: String = "item@$module:$internalID"
printdbg(this, "Reading item #$internalID with className $className")
val loadedClass = Class.forName(className)
val loadedClassConstructor = loadedClass.getConstructor(ItemID::class.java)
val loadedClassInstance = loadedClassConstructor.newInstance(internalID)
val loadedClassInstance = loadedClassConstructor.newInstance(itemName)
ItemCodex[itemName] = loadedClassInstance as GameItem
}

View File

@@ -71,36 +71,34 @@ object BlockPropUtil {
catch (skip: NullPointerException) {}
}*/
// update randomised virtual props instead
for (keyMax in BlockCodex.dynamicToVirtualPropMapping) {
repeat(BlockCodex.DYNAMIC_RANDOM_CASES) {
val prop = BlockCodex[keyMax.second - it]
val domain = when (prop.dynamicLuminosityFunction) {
1 -> flickerFuncDomain
4 -> breathCycleDuration
5 -> pulsateCycleDuration
else -> 0f
}
// FPS-time compensation
if (Gdx.graphics.framesPerSecond > 0) {
prop.rngBase0 += Gdx.graphics.rawDeltaTime
}
// reset timer
if (prop.rngBase0 > domain) {
prop.rngBase0 -= domain
// flicker related
prop.rngBase1 = prop.rngBase2
prop.rngBase2 = getNewRandom()
}
prop._lumCol.set(getDynamicLumFunc(prop))
//prop.lumColR = prop.lumCol.r
//prop.lumColG = prop.lumCol.g
//prop.lumColB = prop.lumCol.b
//prop.lumColA = prop.lumCol.a
for (key in BlockCodex.tileToVirtual.values.flatten()) {
val prop = BlockCodex[key]
val domain = when (prop.dynamicLuminosityFunction) {
1 -> flickerFuncDomain
4 -> breathCycleDuration
5 -> pulsateCycleDuration
else -> 0f
}
// FPS-time compensation
if (Gdx.graphics.framesPerSecond > 0) {
prop.rngBase0 += Gdx.graphics.rawDeltaTime
}
// reset timer
if (prop.rngBase0 > domain) {
prop.rngBase0 -= domain
// flicker related
prop.rngBase1 = prop.rngBase2
prop.rngBase2 = getNewRandom()
}
prop._lumCol.set(getDynamicLumFunc(prop))
//prop.lumColR = prop.lumCol.r
//prop.lumColG = prop.lumCol.g
//prop.lumColB = prop.lumCol.b
//prop.lumColA = prop.lumCol.a
}
}

View File

@@ -3,6 +3,7 @@ package net.torvald.terrarum.blockstats
import com.jme3.math.FastMath
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.worlddrawer.BlocksDrawer
@@ -14,7 +15,7 @@ import java.util.*
*/
object BlockStats {
private val tilestat = ShortArray(GameWorld.TILES_SUPPORTED)
private val tilestat = HashMap<ItemID, Int>()
private val TSIZE = CreateTileAtlas.TILE_SIZE
@@ -22,7 +23,7 @@ object BlockStats {
* Update tile stats from tiles on screen
*/
fun update() {
Arrays.fill(tilestat, 0.toShort())
tilestat.clear()
// Get stats on no-zoomed screen area. In other words, will behave as if screen zoom were 1.0
// no matter how the screen is zoomed.
@@ -47,29 +48,14 @@ object BlockStats {
for (x in for_x_start..for_x_end - 1) {
val tileWall = map.getTileFromWall(x, y)
val tileTerrain = map.getTileFromTerrain(x, y)
++tilestat[tileWall ?: 0]
++tilestat[tileTerrain ?: 0]
tilestat[tileWall] = 1 + (tilestat[tileWall] ?: 0)
tilestat[tileTerrain] = 1 + (tilestat[tileTerrain] ?: 0)
}
}
}
fun getCount(vararg tile: Byte): Int {
var sum = 0
for (i in tile.indices) {
val newArgs = java.lang.Byte.toUnsignedInt(tile[i])
sum += java.lang.Short.toUnsignedInt(tilestat[newArgs])
}
return sum
fun getCount(vararg tiles: ItemID): Int {
return tiles.fold(0) { acc, key -> acc + (tilestat[key] ?: 0) }
}
fun getCount(vararg tile: Int): Int {
var sum = 0
for (i in tile.indices) {
sum += java.lang.Short.toUnsignedInt(tilestat[tile[i]])
}
return sum
}
}

View File

@@ -134,10 +134,10 @@ object MinimapComposer : Disposable {
for (y in topLeftY until topLeftY + LIVETILE_SIZE) {
for (x in if (tileSlotIndexY >= TILES_IN_X / 2) (topLeftX + LIVETILE_SIZE - 1) downTo topLeftX else topLeftX until topLeftX + LIVETILE_SIZE) {
val tileTerr = world.getTileFromTerrain(x, y) ?: throw Error("OoB: $x, $y")
val wallTerr = world.getTileFromWall(x, y) ?: Block.AIR
val colTerr = CreateTileAtlas.terrainTileColourMap.get(tileTerr % 16, tileTerr / 16)
val colWall = CreateTileAtlas.terrainTileColourMap.get(wallTerr % 16, wallTerr / 16).mul(BlocksDrawer.wallOverlayColour)
val tileTerr = world.getTileFromTerrain(x, y)
val wallTerr = world.getTileFromWall(x, y)
val colTerr = CreateTileAtlas.terrainTileColourMap.get(tileTerr)!!.toGdxColor()
val colWall = CreateTileAtlas.terrainTileColourMap.get(wallTerr)!!.toGdxColor().mul(BlocksDrawer.wallOverlayColour)
val outCol = if (colTerr.a > 0.1f) colTerr else colWall

View File

@@ -10,6 +10,7 @@ import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.blockproperties.BlockProp
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.gameworld.BlockAddress
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
@@ -1231,7 +1232,7 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties)
*
* Very straightforward for the actual solid tiles, not so much for the platforms
*/
private fun shouldICollideWithThis(tile: Int) =
private fun shouldICollideWithThis(tile: ItemID) =
// regular solid block
(BlockCodex[tile].isSolid)
@@ -1240,7 +1241,7 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties)
*
* Just like "shouldICollideWithThis" but it's intended to work with feet tiles
*/
private fun shouldICollideWithThisFeet(tile: Int) =
private fun shouldICollideWithThisFeet(tile: ItemID) =
// regular solid block
(BlockCodex[tile].isSolid) ||
// platforms, moving downward AND not "going down"
@@ -1295,7 +1296,7 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties)
return contactAreaCounter
}
private fun getTileFriction(tile: Int) =
private fun getTileFriction(tile: ItemID) =
if (physProp.immobileBody && tile == Block.AIR)
BlockCodex[Block.AIR].friction.frictionToMult().div(500)
.times(if (!grounded) elasticity else 1.0)
@@ -1705,11 +1706,11 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties)
}
private fun forEachOccupyingTileNum(consumer: (Int?) -> Unit) {
private fun forEachOccupyingTileNum(consumer: (ItemID?) -> Unit) {
if (world == null) return
val tiles = ArrayList<Int?>()
val tiles = ArrayList<ItemID?>()
for (y in hIntTilewiseHitbox.startY.toInt()..hIntTilewiseHitbox.endY.toInt()) {
for (x in hIntTilewiseHitbox.startX.toInt()..hIntTilewiseHitbox.endX.toInt()) {
tiles.add(world!!.getTileFromTerrain(x, y))
@@ -1770,11 +1771,11 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties)
return tilePosList.forEach(consumer)
}
private fun forEachFeetTileNum(consumer: (Int?) -> Unit) {
private fun forEachFeetTileNum(consumer: (ItemID?) -> Unit) {
if (world == null) return
val tiles = ArrayList<Int?>()
val tiles = ArrayList<ItemID?>()
// offset 1 pixel to the down so that friction would work
val y = hitbox.endY.plus(1.0).div(TILE_SIZE).floorInt()

View File

@@ -107,7 +107,9 @@ open class GameWorld : Disposable {
// does not go to the savefile
val tileNameToNumberMap: HashMap<ItemID, Int>
/**
* Create new world
*/
constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) {
if (width <= 0 || height <= 0) throw IllegalArgumentException("Non-positive width/height: ($width, $height)")
@@ -150,6 +152,9 @@ open class GameWorld : Disposable {
}
}
/**
* Load existing world
*/
internal constructor(worldIndex: Int, layerData: ReadLayerDataZip.LayerData, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Int) {
this.worldIndex = worldIndex
@@ -176,16 +181,24 @@ open class GameWorld : Disposable {
lastPlayTime = lastPlayTIME_T
this.totalPlayTime = totalPlayTime
tileNumberToNameMap = layerData.tileNumberToNameMap
// TODO perform renaming of tile layers
// after the renaming, update the name maps
// before the renaming, update the name maps
tileNumberToNameMap = HashMap<Int, ItemID>()
tileNameToNumberMap = HashMap<ItemID, Int>()
CreateTileAtlas.tags.forEach {
tileNumberToNameMap[it.value.tileNumber] = it.key
tileNameToNumberMap[it.key] = it.value.tileNumber
}
// perform renaming of tile layers
val oldTileNumberToNameMap = layerData.tileNumberToNameMap
for (y in 0 until layerTerrain.height) {
for (x in 0 until layerTerrain.width) {
layerTerrain.unsafeSetTile(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerTerrain.unsafeGetTile(x, y)]]!!)
layerWall.unsafeSetTile(x, y, tileNameToNumberMap[oldTileNumberToNameMap[layerWall.unsafeGetTile(x, y)]]!!)
// TODO rename fluid map
// TODO rename wire map
}
}
}
/**
@@ -199,7 +212,7 @@ open class GameWorld : Disposable {
fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceIn(0, height - 1))
/**
* @return ItemID
* @return ItemID, WITHOUT wall tag
*/
fun getTileFromWall(rawX: Int, rawY: Int): ItemID {
val (x, y) = coerceXY(rawX, rawY)
@@ -239,7 +252,7 @@ open class GameWorld : Disposable {
* *
* @param y
* *
* @param itemID Tile as in ItemID
* @param itemID Tile as in ItemID, with tag removed!
*/
fun setTileWall(x: Int, y: Int, itemID: ItemID) {
val (x, y) = coerceXY(x, y)
@@ -261,7 +274,7 @@ open class GameWorld : Disposable {
* *
* @param y
* *
* @param itemID Tile as in ItemID
* @param itemID Tile as in ItemID, with tag removed!
*/
fun setTileTerrain(x: Int, y: Int, itemID: ItemID) {
val (x, y) = coerceXY(x, y)

View File

@@ -424,10 +424,10 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
when (currentPenMode) {
// test paint terrain layer
PENMODE_PENCIL -> {
if (palSelection < BlockCodex.MAX_TERRAIN_TILES)
if (palSelection.startsWith("wall@"))
world.setTileWall(x, y, palSelection.substring(5))
else
world.setTileTerrain(x, y, palSelection)
else if (palSelection < 2 * BlockCodex.MAX_TERRAIN_TILES)
world.setTileWall(x, y, palSelection - BlockCodex.MAX_TERRAIN_TILES)
}
PENMODE_PENCIL_ERASE -> {
if (currentPenTarget and PENTARGET_WALL != 0)
@@ -437,9 +437,9 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
}
PENMODE_EYEDROPPER -> {
uiPaletteSelector.fore = if (world.getTileFromTerrain(x, y) == Block.AIR)
world.getTileFromWall(x, y)!! + BlockCodex.MAX_TERRAIN_TILES
"wall@"+world.getTileFromWall(x, y)
else
world.getTileFromTerrain(x, y)!!
world.getTileFromTerrain(x, y)
}
PENMODE_MARQUEE -> {
addBlockMarker(x, y)
@@ -455,7 +455,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
return selection.last() - selection.first()
}
private fun serialiseSelection(outfile: File) {
/*private fun serialiseSelection(outfile: File) {
// save format: sparse list encoded in following binary format:
/*
Header: TEaT0bLD -- magic: Terrarum Attachment
@@ -498,7 +498,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
}
fos.write(FILE_FOOTER)
fos.close()
}
}*/
}
class BuildingMakerController(val screen: BuildingMaker) : InputAdapter() {

View File

@@ -93,7 +93,7 @@ class WorldgenLoadScreen(screenToBeLoaded: IngameInstance, private val worldwidt
val wx = (world.width.toFloat() / previewWidth * x).roundToInt()
val wy = (world.height.toFloat() / previewHeight * y).roundToInt()
val outCol = if (world.getTileFromTerrain(wx, wy) > 15) COL_TERR else if (world.getTileFromWall(wx, wy) > 15) COL_WALLED else COL_AIR
val outCol = if (world.getTileNumFromTerrain(wx, wy) > 0) COL_TERR else if (world.getTileNumFromWall(wx, wy) > 0) COL_WALLED else COL_AIR
previewPixmap.setColor(outCol)
previewPixmap.drawPixel(x, previewHeight - 1 - y) // this flips Y

View File

@@ -1,5 +1,6 @@
package net.torvald.terrarum.modulebasegame.console
import net.torvald.gdx.graphics.Cvec
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.console.ConsoleCommand
@@ -7,6 +8,7 @@ import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.console.EchoError
import net.torvald.terrarum.utils.RasterWriter
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
import net.torvald.terrarum.worlddrawer.toRGBA
import java.io.File
import java.io.IOException
@@ -31,7 +33,8 @@ internal object ExportMap : ConsoleCommand {
var mapDataPointer = 0
for (tile in world.terrainIterator()) {
val colArray = CreateTileAtlas.terrainTileColourMap.getRaw(tile % 16, tile / 16).toByteArray()
val tileNumber = CreateTileAtlas.tileIDtoItemSheetNumber(tile)
val colArray = CreateTileAtlas.terrainTileColourMap.get(tileNumber)!!.toByteArray()
for (i in 0..2) {
mapData[mapDataPointer + i] = colArray[i]
@@ -71,11 +74,13 @@ internal object ExportMap : ConsoleCommand {
/***
* R-G-B-A order for RGBA input value
*/
private fun Cvec.toByteArray() = this.toRGBA().toByteArray()
private fun Int.toByteArray() = byteArrayOf(
this.shr(24).and(0xff).toByte(),
this.shr(16).and(0xff).toByte(),
this.shr(8).and(0xff).toByte(),
this.and(0xff).toByte()
this.ushr(24).and(255).toByte(),
this.ushr(16).and(255).toByte(),
this.ushr(8).and(255).toByte(),
this.and(255).toByte()
)
override fun printUsage() {

View File

@@ -4,6 +4,7 @@ import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.console.ConsoleCommand
import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.console.EchoError
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
@@ -22,10 +23,10 @@ internal object Inventory : ConsoleCommand {
else {
when (args[1]) {
"list" -> listInventory()
"add" -> if (args.size > 3) addItem(args[2].toInt(), args[3].toInt())
else addItem(args[2].toInt())
"add" -> if (args.size > 3) addItem(args[2], args[3].toInt())
else addItem(args[2])
"target" -> setTarget(args[2].toInt())
"equip" -> equipItem(args[2].toInt())
"equip" -> equipItem(args[2])
else -> printUsage()
}
}
@@ -57,13 +58,13 @@ internal object Inventory : ConsoleCommand {
}
}
private fun addItem(refId: Int, amount: Int = 1) {
private fun addItem(refId: ItemID, amount: Int = 1) {
if (target != null) {
target!!.addItem(ItemCodex[refId]!!, amount)
}
}
private fun equipItem(refId: Int) {
private fun equipItem(refId: ItemID) {
if (target != null) {
val item = ItemCodex[refId]!!
target!!.equipItem(item)

View File

@@ -168,7 +168,7 @@ open class ActorHumanoid(
private var jumpJustPressedLatched = false
@Transient private val nullItem = object : GameItem(0) {
@Transient private val nullItem = object : GameItem("item@basegame:0") {
override val isUnique: Boolean = false
override var baseMass: Double = 0.0
override var baseToolSize: Double? = null

View File

@@ -14,15 +14,15 @@ import net.torvald.terrarum.itemproperties.ItemCodex
open class DroppedItem(private val item: GameItem) : ActorWithBody(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT) {
init {
if (item.dynamicID >= ItemCodex.ACTORID_MIN)
if (item.dynamicID.startsWith("actor@"))
throw RuntimeException("Attempted to create DroppedItem actor of a real actor; the real actor must be dropped instead.")
isVisible = true
avBaseMass = if (item.dynamicID < BlockCodex.MAX_TERRAIN_TILES)
BlockCodex[item.dynamicID].density / 1000.0
else
avBaseMass = if (item.dynamicID.startsWith("item@"))
ItemCodex[item.dynamicID]!!.mass
else
BlockCodex[item.dynamicID].density / 1000.0 // block and wall
actorValue[AVKey.SCALE] = ItemCodex[item.dynamicID]!!.scale
}

View File

@@ -7,6 +7,7 @@ import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.gameactors.PhysProperties
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.ui.UICanvas
@@ -201,7 +202,7 @@ inline class BlockBoxProps(val flags: Int) {
* @param width Width of the block box, tile-wise
* @param height Height of the block box, tile-wise
*/
data class BlockBox(val collisionType: Int, val width: Int, val height: Int) {
data class BlockBox(val collisionType: ItemID, val width: Int, val height: Int) {
/*fun redefine(collisionType: Int, width: Int, height: Int) {
redefine(collisionType)

View File

@@ -27,7 +27,7 @@ open class HumanoidNPC(
}
// we're having GameItem data so that this class could be somewhat universal
override var itemData: GameItem = object : GameItem(referenceID) {//GameItem(referenceID ?: forceAssignRefID!!) {
override var itemData: GameItem = object : GameItem("actor:"+referenceID) {//GameItem(referenceID ?: forceAssignRefID!!) {
override val isUnique = true
override var baseMass: Double
get() = actorValue.getAsDouble(AVKey.BASEMASS)!!

View File

@@ -77,12 +77,12 @@ interface Pocketed {
}
fun equipped(itemID: ItemID) = equipped(ItemCodex[itemID]!!)
fun addItem(itemID: Int, count: Int = 1) = inventory.add(ItemCodex[itemID]!!, count)
fun addItem(itemID: ItemID, count: Int = 1) = inventory.add(ItemCodex[itemID]!!, count)
fun addItem(item: GameItem, count: Int = 1) = inventory.add(item, count)
fun removeItem(itemID: Int, count: Int = 1) = inventory.remove(ItemCodex[itemID]!!, count)
fun removeItem(itemID: ItemID, count: Int = 1) = inventory.remove(ItemCodex[itemID]!!, count)
fun removeItem(item: GameItem, count: Int = 1) = inventory.remove(item, count)
fun hasItem(item: GameItem) = inventory.contains(item.dynamicID)
fun hasItem(id: Int) = inventory.contains(id)
fun hasItem(id: ItemID) = inventory.contains(id)
}

View File

@@ -7,6 +7,7 @@ import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.blockproperties.Fluid
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.gameworld.FluidType
import net.torvald.terrarum.gameworld.GameWorld
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
@@ -416,7 +417,7 @@ object WorldSimulator {
}
fun Int.isFallable() = BlockCodex[this].maxSupport
fun ItemID.isFallable() = BlockCodex[this].maxSupport
private val actorMBRConverter = object : MBRConverter<ActorWithBody> {

View File

@@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.fillRect
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.modulebasegame.BuildingMaker
@@ -14,6 +15,7 @@ import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.ui.UIItemImageButton
import net.torvald.terrarum.ui.UIItemTextButtonList
import net.torvald.terrarum.ui.UIItemTextButtonList.Companion.DEFAULT_BACKGROUNDCOL
import net.torvald.terrarum.worlddrawer.CreateTileAtlas
import kotlin.math.roundToInt
/**
@@ -37,19 +39,10 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() {
override var height = HEIGHT
override var openCloseTime = 0f
private val palette = Array<UIItemImageButton>(TILES_X * TILES_Y) {
// initialise with terrain blocks
UIItemImageButton(
this, ItemCodex.getItemImage(it),
initialX = MENUBAR_SIZE + (it % 16) * TILESREGION_SIZE,
initialY = (it / 16) * TILESREGION_SIZE,
highlightable = false,
width = TILESREGION_SIZE,
height = TILESREGION_SIZE,
highlightCol = Color.WHITE,
activeCol = Color.WHITE
)
}
val palette = ArrayList<UIItemImageButton>()
// TODO scrolling of the palette, as the old method flat out won't work with The Flattening
private val tabs = UIItemTextButtonList(
this, arrayOf("Terrain", "Wall", "Wire"),
0, 0, textAreaWidth = MENUBAR_SIZE, width = MENUBAR_SIZE,
@@ -62,12 +55,25 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() {
)
init {
palette.forEachIndexed { index, it ->
uiItems.add(it)
it.clickOnceListener = { _, _, _ ->
parent.setPencilColour(paletteScroll * 16 + index)
BlockCodex.getAll().forEachIndexed { index, prop ->
val paletteItem = UIItemImageButton(
this, ItemCodex.getItemImage(prop.id)!!,
initialX = MENUBAR_SIZE + (index % 16) * TILESREGION_SIZE,
initialY = (index / 16) * TILESREGION_SIZE,
highlightable = false,
width = TILESREGION_SIZE,
height = TILESREGION_SIZE,
highlightCol = Color.WHITE,
activeCol = Color.WHITE
)
paletteItem.clickOnceListener = { _, _, _ ->
parent.setPencilColour(prop.id)
}
uiItems.add(paletteItem)
palette.add(paletteItem)
}
}
@@ -119,9 +125,7 @@ class UIBuildingMakerBlockChooser(val parent: BuildingMaker): UICanvas() {
}
private fun rebuildPalette() {
palette.forEachIndexed { index, it ->
it.image = ItemCodex.getItemImage(paletteScroll * 16 + index)
}
}
override fun renderUI(batch: SpriteBatch, camera: Camera) {

View File

@@ -153,7 +153,7 @@ class UIBuildingMakerPenMenu(val parent: BuildingMaker): UICanvas() {
// draw blocks slot
batch.color = blockCellCol
val slotConfig = AppLoader.getConfigIntArray("buildingmakerfavs")
val slotConfig = AppLoader.getConfigStringArray("buildingmakerfavs")
for (i in 0 until PALETTE_SIZE) {
val x = blockCellPos[i].x.roundToInt().toFloat()
val y = blockCellPos[i].y.roundToInt().toFloat()

View File

@@ -9,6 +9,7 @@ import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.blendNormal
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.fillRect
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.modulebasegame.BuildingMaker
import net.torvald.terrarum.modulebasegame.ui.ItemSlotImageFactory.CELLCOLOUR_BLACK
@@ -31,8 +32,8 @@ class UIPaletteSelector(val parent: BuildingMaker) : UICanvas() {
fun mouseOnTitleBar() =
relativeMouseX in 0 until width && relativeMouseY in 0 until LINE_HEIGHT
var fore = Block.STONE_BRICKS
var back = Block.GLASS_CRUDE
var fore: ItemID = Block.STONE_BRICKS
var back: ItemID = Block.GLASS_CRUDE
private val titleText = "Pal."
@@ -102,10 +103,9 @@ class UIPaletteSelector(val parent: BuildingMaker) : UICanvas() {
}
fun swapForeAndBack() {
// xor used, because why not?
fore = fore xor back
back = back xor fore
fore = fore xor back
val t = fore
fore = back
back = t
}
override fun doOpening(delta: Float) {

View File

@@ -69,7 +69,7 @@ class Terragen(world: GameWorld, seed: Long, params: Any) : Gen(world, seed, par
val cave = if (noiseValue[1] < 0.5) 0 else 1
val wallBlock = groundDepthBlock[terr]
val terrBlock = wallBlock * cave // AIR is always zero, this is the standard
val terrBlock = if (cave == 0) Block.AIR else wallBlock //wallBlock * cave // AIR is always zero, this is the standard
world.setTileTerrain(x, y, terrBlock)
world.setTileWall(x, y, wallBlock)

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum.serialise
import com.badlogic.gdx.utils.compression.Lzma
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.gameworld.BlockAddress
import net.torvald.terrarum.gameworld.BlockLayer
import net.torvald.terrarum.gameworld.FluidType
@@ -151,6 +152,7 @@ internal object ReadLayerDataLzma {
val wallDamages = HashMap<BlockAddress, Float>()
val fluidTypes = HashMap<BlockAddress, FluidType>()
val fluidFills = HashMap<BlockAddress, Float>()
val tileNumToName = HashMap<Int, ItemID>()
// parse terrain damages
for (c in payloadBytes["TdMG"]!!.indices step 10) {
@@ -176,6 +178,8 @@ internal object ReadLayerDataLzma {
// TODO parse fluid(Types|Fills)
// TODO parse tileNumToName
return ReadLayerDataZip.LayerData(
BlockLayer(width, height, payloadBytes["WALL"]!!),
@@ -183,7 +187,7 @@ internal object ReadLayerDataLzma {
spawnPoint.first, spawnPoint.second,
wallDamages, terrainDamages, fluidTypes, fluidFills
wallDamages, terrainDamages, fluidTypes, fluidFills, tileNumToName
)
}

View File

@@ -1,6 +1,7 @@
package net.torvald.terrarum.serialise
import com.badlogic.gdx.Gdx
import net.torvald.random.HQRNG
import net.torvald.terrarum.AppLoader
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.AVKey
@@ -9,10 +10,24 @@ import net.torvald.terrarum.gameitem.GameItem
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.*
import net.torvald.terrarum.utils.JsonWriter.getJsonBuilder
import net.torvald.util.SortedArrayList
import java.io.File
import java.nio.charset.Charset
import kotlin.math.roundToInt
internal class RNGPool() {
private val RNG = HQRNG()
private val used = SortedArrayList<Int>()
fun next(): Int {
var n = RNG.nextLong().ushr(32).toInt()
while (used.contains(n)) {
n = RNG.nextLong().ushr(32).toInt()
}
used.add(n)
return n
}
}
/**
* Created by minjaesong on 2018-10-03.
*/
@@ -20,6 +35,8 @@ object SavegameWriter {
// TODO create temporary files (worldinfo), create JSON files on RAM, pack those into TEVd as per Savegame container.txt
private val rngPool = RNGPool()
private val charset = Charset.forName("UTF-8")
private lateinit var playerName: String
@@ -99,16 +116,16 @@ object SavegameWriter {
// actors
ingame.actorContainerActive.forEach {
VDUtil.registerFile(disk, DiskEntry(
it.referenceID!!, ROOT,
it.referenceID!!.toString(16).toUpperCase().toByteArray(charset),
rngPool.next(), ROOT,
it.referenceID.toString(16).toUpperCase().toByteArray(charset),
creationDate, creationDate,
EntryFile(serialiseActor(it))
))
}
ingame.actorContainerInactive.forEach {
VDUtil.registerFile(disk, DiskEntry(
it.referenceID!!, ROOT,
it.referenceID!!.toString(16).toUpperCase().toByteArray(charset),
rngPool.next(), ROOT,
it.referenceID.toString(16).toUpperCase().toByteArray(charset),
creationDate, creationDate,
EntryFile(serialiseActor(it))
))
@@ -117,8 +134,8 @@ object SavegameWriter {
// items
ItemCodex.dynamicItemDescription.forEach { dynamicID, item ->
VDUtil.registerFile(disk, DiskEntry(
item.dynamicID, ROOT,
dynamicID.toString(16).toUpperCase().toByteArray(charset),
rngPool.next(), ROOT,
dynamicID.toByteArray(charset),
creationDate, creationDate,
EntryFile(serialiseItem(item))
))

View File

@@ -52,8 +52,8 @@ object WriteWorldInfo {
val infile = infileList[filenum - 1]
infile.forEach {
outputStream.write("## from file: ${it.nameWithoutExtension()} ##############################\n".toByteArray())
val readBytes = it.readBytes()
outputStream.write("## from file: ${it.second.nameWithoutExtension()} ##############################\n".toByteArray())
val readBytes = it.second.readBytes()
outputStream.write(readBytes)
outputStream.write("\n".toByteArray())
}

View File

@@ -161,7 +161,7 @@ class BasicDebugInfoWindow : UICanvas() {
val wireNum = ingame!!.world.getWiringBlocks(mouseTileX, mouseTileY)
val fluid = ingame!!.world.getFluid(mouseTileX, mouseTileY)
printLine(batch, 9, "tile@cursor ${ccO}W$ccG$wallNum ${ccO}T$ccG$tileNum ${ccO}C$ccG${wireNum.toString(2)} $ccY($mtX, $mtY)")
printLine(batch, 9, "tile@cursor ${ccO}W$ccG$wallNum ${ccO}T$ccG$tileNum ${ccO}C$ccG${wireNum} $ccY($mtX, $mtY)")
printLine(batch, 10, "fluid@cursor ${ccO}Type $ccG${fluid.type.value} ${ccO}Fill $ccG${fluid.amount}f")
}

View File

@@ -213,7 +213,7 @@ object CreateTileAtlas {
16 + (376 * (fluid.type.abs() - 1)) + (47 * (fluidLevel - 1))
}
private val nullTile = Pixmap(TILE_SIZE * 16, TILE_SIZE * 16, Pixmap.Format.RGBA8888)
val nullTile = Pixmap(TILE_SIZE * 16, TILE_SIZE * 16, Pixmap.Format.RGBA8888)
private fun fileToAtlantes(modname: String, matte: FileHandle, glow: FileHandle?) {
val tilesPixmap = Pixmap(matte)
@@ -374,6 +374,8 @@ object CreateTileAtlas {
atlasSpring.dispose()
atlasFluid.dispose()
atlasGlow.dispose()
//itemTerrainTexture.dispose() //BlocksDrawer will dispose of it as it disposes of 'tileItemTerrain (TextureRegionPack)'
//itemWallTexture.dispose() //BlocksDrawer will dispose of it as it disposes of 'tileItemWall (TextureRegionPack)'
nullTile.dispose()
}

View File

@@ -27,13 +27,13 @@ object FeaturesDrawer {
var colTemp: Int = 0
private set
private val TILES_COLD = intArrayOf(
private val TILES_COLD = arrayOf(
Block.ICE_MAGICAL
, Block.ICE_FRAGILE
, Block.ICE_NATURAL
, Block.SNOW)
private val TILES_WARM = intArrayOf(
private val TILES_WARM = arrayOf(
Block.SAND_DESERT
, Block.SAND_RED)

View File

@@ -20,135 +20,5 @@ internal class LightCalculatorContext(
private val lightmap: UnsafeCvecArray,
private val lanternMap: HashMap<BlockAddress, Cvec>
) {
private val colourNull = Cvec(0)
private val ambientAccumulator = Cvec(0f,0f,0f,0f)
private val lightLevelThis = Cvec(0)
private val fluidAmountToCol = Cvec(0)
private val thisTileLuminosity = Cvec(0)
private val thisTileOpacity = Cvec(0)
private val thisTileOpacity2 = Cvec(0) // thisTileOpacity * sqrt(2)
private val sunLight = Cvec(0)
private var thisFluid = GameWorld.FluidInfo(Fluid.NULL, 0f)
private var thisTerrain = 0
private var thisWall = 0
private fun getLightsAndShades(x: Int, y: Int) {
val (x, y) = world.coerceXY(x, y)
lightLevelThis.set(colourNull)
thisTerrain = world.getTileFromTerrainRaw(x, y)
thisFluid = world.getFluid(x, y)
thisWall = world.getTileFromWallRaw(x, y)
// regarding the issue #26
// uncomment this if you're facing diabolically indescribable bugs
/*try {
val fuck = BlockCodex[thisTerrain].getLumCol(x, y)
}
catch (e: NullPointerException) {
System.err.println("## NPE -- x: $x, y: $y, value: ${thisTerrain}")
e.printStackTrace()
// create shitty minidump
System.err.println("MINIMINIDUMP START")
for (xx in x - 16 until x + 16) {
val raw = world.getTileFromTerrain(xx, y)
val lsb = raw.and(0xff).toString(16).padStart(2, '0')
val msb = raw.ushr(8).and(0xff).toString(16).padStart(2, '0')
System.err.print(lsb)
System.err.print(msb)
System.err.print(" ")
}
System.err.println("\nMINIMINIDUMP END")
exitProcess(1)
}*/
if (thisFluid.type != Fluid.NULL) {
fluidAmountToCol.set(thisFluid.amount, thisFluid.amount, thisFluid.amount, thisFluid.amount)
thisTileLuminosity.set(BlockCodex[thisTerrain].getLumCol(x, y))
thisTileLuminosity.maxAndAssign(BlockCodex[thisFluid.type].getLumCol(x, y).mul(fluidAmountToCol)) // already been div by four
thisTileOpacity.set(BlockCodex[thisTerrain].opacity)
thisTileOpacity.maxAndAssign(BlockCodex[thisFluid.type].opacity.mul(fluidAmountToCol)) // already been div by four
}
else {
thisTileLuminosity.set(BlockCodex[thisTerrain].getLumCol(x, y))
thisTileOpacity.set(BlockCodex[thisTerrain].opacity)
}
thisTileOpacity2.set(thisTileOpacity); thisTileOpacity2.mul(1.41421356f)
//sunLight.set(world.globalLight); sunLight.mul(DIV_FLOAT) // moved to fireRecalculateEvent()
// open air || luminous tile backed by sunlight
if ((thisTerrain == AIR && thisWall == AIR) || (thisTileLuminosity.nonZero() && thisWall == AIR)) {
lightLevelThis.set(sunLight)
}
// blend lantern
lightLevelThis.maxAndAssign(thisTileLuminosity).maxAndAssign(lanternMap[LandUtil.getBlockAddr(world, x, y)] ?: colourNull)
}
fun calculateAndAssign(worldX: Int, worldY: Int) {
//if (inNoopMask(worldX, worldY)) return
// O(9n) == O(n) where n is a size of the map
getLightsAndShades(worldX, worldY)
val x = worldX.convX()
val y = worldY.convY()
// calculate ambient
/* + * + 0 4 1
* * @ * 6 @ 7
* + * + 2 5 3
* sample ambient for eight points and apply attenuation for those
* maxblend eight values and use it
*/
// will "overwrite" what's there in the lightmap if it's the first pass
// takes about 2 ms on 6700K
/* + */lightLevelThis.maxAndAssign(LightmapRenderer.darkenColoured(x - 1, y - 1, thisTileOpacity2))
/* + */lightLevelThis.maxAndAssign(LightmapRenderer.darkenColoured(x + 1, y - 1, thisTileOpacity2))
/* + */lightLevelThis.maxAndAssign(LightmapRenderer.darkenColoured(x - 1, y + 1, thisTileOpacity2))
/* + */lightLevelThis.maxAndAssign(LightmapRenderer.darkenColoured(x + 1, y + 1, thisTileOpacity2))
/* * */lightLevelThis.maxAndAssign(LightmapRenderer.darkenColoured(x, y - 1, thisTileOpacity))
/* * */lightLevelThis.maxAndAssign(LightmapRenderer.darkenColoured(x, y + 1, thisTileOpacity))
/* * */lightLevelThis.maxAndAssign(LightmapRenderer.darkenColoured(x - 1, y, thisTileOpacity))
/* * */lightLevelThis.maxAndAssign(LightmapRenderer.darkenColoured(x + 1, y, thisTileOpacity))
//return lightLevelThis.cpy() // it HAS to be a cpy(), otherwise all cells gets the same instance
//setLightOf(lightmap, x, y, lightLevelThis.cpy())
lightmap.setR(x, y, lightLevelThis.r)
lightmap.setG(x, y, lightLevelThis.g)
lightmap.setB(x, y, lightLevelThis.b)
lightmap.setA(x, y, lightLevelThis.a)
}
private fun Cvec.maxAndAssign(other: Cvec): Cvec {
// TODO investigate: if I use assignment instead of set(), it blackens like the vector branch. --Torvald, 2019-06-07
// that was because you forgot 'this.r/g/b/a = ' part, bitch. --Torvald, 2019-06-07
this.r = if (this.r > other.r) this.r else other.r
this.g = if (this.g > other.g) this.g else other.g
this.b = if (this.b > other.b) this.b else other.b
this.a = if (this.a > other.a) this.a else other.a
return this
}
private fun Cvec.nonZero() = this.r.abs() > LightmapRenderer.epsilon ||
this.g.abs() > LightmapRenderer.epsilon ||
this.b.abs() > LightmapRenderer.epsilon ||
this.a.abs() > LightmapRenderer.epsilon
/** World coord to array coord */
private inline fun Int.convX() = this - LightmapRenderer.for_x_start + LightmapRenderer.overscan_open
/** World coord to array coord */
private inline fun Int.convY() = this - LightmapRenderer.for_y_start + LightmapRenderer.overscan_open
// No longer in use because of the much efficient light updating method
}