From 08aa0e8f344bc8db43bbdaacda5de86e15c33cc5 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Tue, 12 Mar 2019 19:50:28 +0900 Subject: [PATCH] always sorting arraylist; more wire stuffs --- shit.kts | 26 ++++++ src/com/jme3/math/FastMath.java | 21 +++-- src/net/torvald/parametricsky/Model.kt | 2 +- src/net/torvald/terrarum/AppLoader.java | 2 +- src/net/torvald/terrarum/IngameInstance.kt | 23 ++--- src/net/torvald/terrarum/LoadScreen.kt | 2 +- src/net/torvald/terrarum/Terrarum.kt | 2 +- .../torvald/terrarum/blockproperties/Wire.kt | 26 ++++++ .../terrarum/debuggerapp/ActorsLister.kt | 7 +- .../torvald/terrarum/gameworld/GameWorld.kt | 49 +++++++++-- .../terrarum/gameworld/MapLayerHalfFloat.kt | 5 +- .../terrarum/modulebasegame/EntryPoint.kt | 4 +- .../torvald/terrarum/modulebasegame/Ingame.kt | 4 +- .../terrarum/modulebasegame/IngameRenderer.kt | 22 +++-- .../modulebasegame/console/ExportMap.kt | 63 ++++---------- .../gameactors/ActorHumanoid.kt | 5 +- .../modulebasegame/items/PickaxeGeneric.kt | 4 +- .../items/WirePieceSignalWire.kt | 4 +- .../worldgenerator/RoguelikeRandomiser.kt | 2 +- .../torvald/terrarum/realestate/LandUtil.kt | 2 +- .../terrarum/tests/CircularArrayTest.kt | 2 +- src/net/torvald/terrarum/ui/ConsoleWindow.kt | 2 +- .../terrarum/worlddrawer/BlocksDrawerNew.kt | 26 ++++-- .../{dataclass => util}/ArrayListMap.kt | 2 +- .../{dataclass => util}/CircularArray.kt | 2 +- .../torvald/{dataclass => util}/Float16.kt | 2 +- .../{dataclass => util}/HistoryArray.kt | 2 +- .../{dataclass => util}/IntArrayStack.kt | 2 +- src/net/torvald/{dataclass => util}/Matrix.kt | 2 +- src/net/torvald/util/SortedArrayList.kt | 86 +++++++++++++++++++ 30 files changed, 288 insertions(+), 115 deletions(-) create mode 100644 shit.kts create mode 100644 src/net/torvald/terrarum/blockproperties/Wire.kt rename src/net/torvald/{dataclass => util}/ArrayListMap.kt (99%) rename src/net/torvald/{dataclass => util}/CircularArray.kt (98%) rename src/net/torvald/{dataclass => util}/Float16.kt (99%) rename src/net/torvald/{dataclass => util}/HistoryArray.kt (98%) rename src/net/torvald/{dataclass => util}/IntArrayStack.kt (98%) rename src/net/torvald/{dataclass => util}/Matrix.kt (99%) create mode 100644 src/net/torvald/util/SortedArrayList.kt diff --git a/shit.kts b/shit.kts new file mode 100644 index 000000000..ac59697b4 --- /dev/null +++ b/shit.kts @@ -0,0 +1,26 @@ +val list = intArrayOf(0,2,4,6,9,13,16,54,88) + +val ID = 555 + +var low = 0 +var high = list.size +var mid = -1 + +while (low < high) { + mid = (low + high).ushr(1) + + if (list[mid] > ID) + high = mid + else + low = mid + 1 + + low +} + +println("$low, $high, $mid") + +val ll = arrayListOf(1,1,1,1,1) +ll.add(5, 8) +println(ll) + +// take mid value? (except for ID < list[0]) \ No newline at end of file diff --git a/src/com/jme3/math/FastMath.java b/src/com/jme3/math/FastMath.java index 0bb380738..f06424615 100644 --- a/src/com/jme3/math/FastMath.java +++ b/src/com/jme3/math/FastMath.java @@ -35,9 +35,6 @@ package com.jme3.math; -import java.util.Arrays; -import java.util.Random; - /** * FastMath provides 'fast' math approximations and float equivalents of Math * functions. These are all used as static values and functions. @@ -118,10 +115,24 @@ final public class FastMath { * Throws runtimeException for all numbers <= 1. * * @param number The number to obtain the POT for. - * @return The next power of two. + * @return The next power of two. (0 -> 0, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, etc.) */ public static int intLog2(int number) { - if (number == 0) return 0; + return intLog2(number, 0); + } + + /** + * Get the next binary log of the given number. + * + * E.g. for an input 100, this returns 6. + * Throws runtimeException for all numbers <= 1. + * + * @param number The number to obtain the POT for. + * @param zeroCase What to return if the input number is zero. + * @return The next power of two. (0 -> zeroCase, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, etc.) + */ + public static int intLog2(int number, int zeroCase) { // zeroCase can't be null, for some reason... + if (number == 0) return zeroCase; int log = 0; if( ( number & 0xffff0000 ) != 0 ) { number >>>= 16; log = 16; } if( number >= 256 ) { number >>>= 8; log += 8; } diff --git a/src/net/torvald/parametricsky/Model.kt b/src/net/torvald/parametricsky/Model.kt index cc9d81927..a4114631a 100644 --- a/src/net/torvald/parametricsky/Model.kt +++ b/src/net/torvald/parametricsky/Model.kt @@ -1,6 +1,6 @@ package net.torvald.parametricsky -import net.torvald.dataclass.Matrix +import net.torvald.util.Matrix import kotlin.math.pow /** diff --git a/src/net/torvald/terrarum/AppLoader.java b/src/net/torvald/terrarum/AppLoader.java index ffcae31e4..987dfb3dc 100644 --- a/src/net/torvald/terrarum/AppLoader.java +++ b/src/net/torvald/terrarum/AppLoader.java @@ -18,7 +18,7 @@ import com.github.strikerx3.jxinput.XInputDevice; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; -import net.torvald.dataclass.ArrayListMap; +import net.torvald.util.ArrayListMap; import net.torvald.getcpuname.GetCpuName; import net.torvald.terrarum.blockstats.MinimapComposer; import net.torvald.terrarum.controller.GdxControllerAdapter; diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index d1c70128c..84161cb03 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -8,9 +8,9 @@ import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.ui.ConsoleWindow +import net.torvald.util.SortedArrayList import java.util.* import java.util.concurrent.locks.Lock -import java.util.concurrent.locks.ReentrantLock /** * Although the game (as product) can have infinitely many stages/planets/etc., those stages must be manually managed by YOU; @@ -48,8 +48,8 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { internal set val ACTORCONTAINER_INITIAL_SIZE = 64 - val actorContainerActive = ArrayList(ACTORCONTAINER_INITIAL_SIZE) - val actorContainerInactive = ArrayList(ACTORCONTAINER_INITIAL_SIZE) + val actorContainerActive = SortedArrayList(ACTORCONTAINER_INITIAL_SIZE) + val actorContainerInactive = SortedArrayList(ACTORCONTAINER_INITIAL_SIZE) protected val terrainChangeQueue = Queue() protected val wallChangeQueue = Queue() @@ -184,6 +184,9 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { return -(low + 1) // key not found } + fun SortedArrayList<*>.binarySearch(actor: Actor) = this.toArrayList().binarySearch(actor.referenceID!!) + fun SortedArrayList<*>.binarySearch(ID: Int) = this.toArrayList().binarySearch(ID) + open fun removeActor(ID: Int) = removeActor(getActorByID(ID)) /** * get index of the actor and delete by the index. @@ -213,7 +216,6 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { } else { actorContainerActive.add(actor) - insertionSortLastElem(actorContainerActive) // we can do this as we are only adding single actor } } @@ -240,19 +242,6 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { - fun insertionSortLastElem(arr: ArrayList) { - ReentrantLock().lock { - var j = arr.lastIndex - 1 - val x = arr.last() - while (j >= 0 && arr[j] > x) { - arr[j + 1] = arr[j] - j -= 1 - } - arr[j + 1] = x - } - } - - data class BlockChangeQueueItem(val old: Int, val new: Int, val posX: Int, val posY: Int) } diff --git a/src/net/torvald/terrarum/LoadScreen.kt b/src/net/torvald/terrarum/LoadScreen.kt index 2b4221e8a..d8d703bbf 100644 --- a/src/net/torvald/terrarum/LoadScreen.kt +++ b/src/net/torvald/terrarum/LoadScreen.kt @@ -8,7 +8,7 @@ import com.badlogic.gdx.graphics.Pixmap import com.badlogic.gdx.graphics.Texture import com.badlogic.gdx.graphics.glutils.FrameBuffer import com.jme3.math.FastMath -import net.torvald.dataclass.HistoryArray +import net.torvald.util.HistoryArray import net.torvald.terrarum.langpack.Lang /** diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index 3746fe656..6e90b42c7 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -12,7 +12,7 @@ import com.badlogic.gdx.graphics.glutils.ShaderProgram import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.utils.GdxRuntimeException import com.jme3.math.FastMath -import net.torvald.dataclass.CircularArray +import net.torvald.util.CircularArray import net.torvald.random.HQRNG import net.torvald.terrarum.AppLoader.* import net.torvald.terrarum.gameactors.Actor diff --git a/src/net/torvald/terrarum/blockproperties/Wire.kt b/src/net/torvald/terrarum/blockproperties/Wire.kt new file mode 100644 index 000000000..c9aac971a --- /dev/null +++ b/src/net/torvald/terrarum/blockproperties/Wire.kt @@ -0,0 +1,26 @@ +package net.torvald.terrarum.blockproperties + +/** + * Created by minjaesong on 2019-03-12. + */ +object Wire { + + /* A mapping for World's conduitTypes bits */ + const val BIT_NONE = 0 + const val BIT_SIGNAL_RED = 1 + const val BIT_UTILITY_PROTOTYPE = 2 + const val BIT_POWER_LOW = 4 + const val BIT_POWER_HIGHT = 8 + const val BIT_ETHERNET = 16 + + /* A mapping for World's conduitFills[] index */ + const val FILL_ID_SIGNAL_RED = 0 + const val FILL_ID_UTILITY_PROTOTYPE = 1 + + fun bitToConduitFillID(bit: Int) = when(bit) { + BIT_SIGNAL_RED -> FILL_ID_SIGNAL_RED + BIT_UTILITY_PROTOTYPE -> FILL_ID_UTILITY_PROTOTYPE + else -> null + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/debuggerapp/ActorsLister.kt b/src/net/torvald/terrarum/debuggerapp/ActorsLister.kt index 7e7c391a0..9aa5b3a31 100644 --- a/src/net/torvald/terrarum/debuggerapp/ActorsLister.kt +++ b/src/net/torvald/terrarum/debuggerapp/ActorsLister.kt @@ -1,18 +1,17 @@ package net.torvald.terrarum.debuggerapp import net.torvald.terrarum.gameactors.Actor +import net.torvald.util.SortedArrayList import java.awt.BorderLayout import java.awt.Dimension -import java.awt.GridLayout -import java.util.* import javax.swing.* /** * Created by minjaesong on 2016-12-29. */ class ActorsLister( - val actorContainer: ArrayList, - val actorContainerInactive: ArrayList) : JFrame() { + val actorContainer: SortedArrayList, + val actorContainerInactive: SortedArrayList) : JFrame() { private val activeActorArea = JTextArea() private val activeActorScroller = JScrollPane(activeActorArea) diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index 6a980f71b..621ce9532 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.gameworld import com.badlogic.gdx.graphics.Color +import net.torvald.util.SortedArrayList import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.Terrarum import net.torvald.terrarum.blockproperties.Block @@ -10,8 +11,10 @@ import net.torvald.terrarum.blockproperties.Fluid import net.torvald.terrarum.modulebasegame.gameworld.WorldSimulator import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.serialise.ReadLayerDataZip +import net.torvald.terrarum.toInt import org.dyn4j.geometry.Vector2 import kotlin.math.absoluteValue +import kotlin.math.sign typealias BlockAddress = Long @@ -80,6 +83,8 @@ open class GameWorld { val conduitFills1: HashMap // size of gas packet on the block get() = conduitFills[1] + private val wiringNodes = SortedArrayList() + //public World physWorld = new World( new Vec2(0, -Terrarum.game.gravitationalAccel) ); //physics /** Meter per second squared. Currently only the downward gravity is supported. No reverse gravity :p */ @@ -183,7 +188,7 @@ open class GameWorld { //val wireArray: ByteArray // get() = layerWire.data - private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceWorld()) + private fun coerceXY(x: Int, y: Int) = (x fmod width) to (y.coerceIn(0, height - 1)) fun getTileFromWall(x: Int, y: Int): Int? { val (x, y) = coerceXY(x, y) @@ -205,12 +210,7 @@ open class GameWorld { terrain * PairedMapLayer.RANGE + terrainDamage } - /*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? { + fun getWires(x: Int, y: Int): Int { return conduitTypes.getOrDefault(LandUtil.getBlockAddr(this, x, y), 0) } @@ -291,6 +291,28 @@ open class GameWorld { Terrarum.ingame?.queueWireChangedEvent(oldWire, tile.toUint(), LandUtil.getBlockAddr(this, x, y)) }*/ + /** + * Overrides entire bits with given value. DO NOT USE THIS if you don't know what this means, you'll want to use setWire(). + * Besides, this function won't fire WireChangedEvent + */ + fun setWires(x: Int, y: Int, wireBits: Int) { + val (x, y) = coerceXY(x, y) + conduitTypes[LandUtil.getBlockAddr(this, x, y)] = wireBits + } + + /** + * Sets single bit for given tile. YOU'LL WANT TO USE THIS instead of setWires() + * @param selectedWire wire-bit to modify, must be power of two + */ + fun setWire(x: Int, y: Int, selectedWire: Int, bitToSet: Boolean) { + val oldWireBits = getWires(x, y) + val oldStatus = getWires(x, y) or selectedWire != 0 + if (oldStatus != bitToSet) { + setWires(x, y, (oldWireBits and selectedWire.inv()) or (selectedWire * oldStatus.toInt())) + Terrarum.ingame?.queueWireChangedEvent(selectedWire * oldStatus.toInt(), selectedWire * bitToSet.toInt(), LandUtil.getBlockAddr(this, x, y)) + } + } + fun getTileFrom(mode: Int, x: Int, y: Int): Int? { if (mode == TERRAIN) { return getTileFromTerrain(x, y) @@ -460,6 +482,17 @@ open class GameWorld { override fun toString() = "Fluid type: ${type.value}, amount: $amount" } + private data class WiringNode( + val position: BlockAddress, + /** One defined in WireCodex, always power of two */ + val typeBitMask: Int, + var fills: Float = 0f, + var connectedNodes: ArrayList + ) : Comparable { + override fun compareTo(other: WiringNode): Int { + return (this.position - other.position).sign + } + } fun getTemperature(worldTileX: Int, worldTileY: Int): Float? { return null @@ -470,8 +503,6 @@ open class GameWorld { } - private fun Int.coerceWorld() = this.coerceIn(0, height - 1) - companion object { @Transient val WALL = 0 @Transient val TERRAIN = 1 diff --git a/src/net/torvald/terrarum/gameworld/MapLayerHalfFloat.kt b/src/net/torvald/terrarum/gameworld/MapLayerHalfFloat.kt index a1e6aae3b..d9757b28b 100644 --- a/src/net/torvald/terrarum/gameworld/MapLayerHalfFloat.kt +++ b/src/net/torvald/terrarum/gameworld/MapLayerHalfFloat.kt @@ -1,13 +1,14 @@ package net.torvald.terrarum.gameworld -import net.torvald.dataclass.Float16 -import net.torvald.dataclass.Float16Bits +import net.torvald.util.Float16 +import net.torvald.util.Float16Bits /** * MapLayer that contains raw Float16 values * * Created by minjaesong on 2017-04-21. */ +@Deprecated("Don't need this anymore") open class MapLayerHalfFloat(val width: Int, val height: Int) : Iterable { constructor(width: Int, height: Int, init: Float) : this(width, height) { diff --git a/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt b/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt index 63ef1defd..0536cf0b9 100644 --- a/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt +++ b/src/net/torvald/terrarum/modulebasegame/EntryPoint.kt @@ -80,10 +80,12 @@ class EntryPoint : ModuleEntryPoint() { // check for collision with actors (BLOCK only) if (this.inventoryCategory == Category.BLOCK) { + var ret1 = true ingame.actorContainerActive.forEach { if (it is ActorWBMovable && it.hIntTilewiseHitbox.intersects(mousePoint)) - return false + ret1 = false // return is not allowed here } + if (!ret1) return ret1 } // return false if the tile is already there diff --git a/src/net/torvald/terrarum/modulebasegame/Ingame.kt b/src/net/torvald/terrarum/modulebasegame/Ingame.kt index 2b721e3ec..c64bf0867 100644 --- a/src/net/torvald/terrarum/modulebasegame/Ingame.kt +++ b/src/net/torvald/terrarum/modulebasegame/Ingame.kt @@ -4,7 +4,6 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.g2d.SpriteBatch -import net.torvald.dataclass.CircularArray import net.torvald.terrarum.* import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.blockproperties.BlockPropUtil @@ -34,6 +33,7 @@ import net.torvald.terrarum.worlddrawer.CreateTileAtlas import net.torvald.terrarum.worlddrawer.FeaturesDrawer import net.torvald.terrarum.worlddrawer.LightmapRenderer import net.torvald.terrarum.worlddrawer.WorldCamera +import net.torvald.util.CircularArray import java.util.* import java.util.concurrent.locks.ReentrantLock @@ -795,7 +795,6 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) { printStackTrace() actorContainerActive.add(actor) - insertionSortLastElem(actorContainerActive) // we can do this as we are only adding single actor if (actor is ActorWithBody) { when (actor.renderOrder) { @@ -829,7 +828,6 @@ open class Ingame(batch: SpriteBatch) : IngameInstance(batch) { else { actorContainerInactive.remove(actor) actorContainerActive.add(actor) - insertionSortLastElem(actorContainerActive) // we can do this as we are only adding single actor if (actor is ActorWithBody) { when (actor.renderOrder) { diff --git a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt index adc46a7a7..52f2b85a6 100644 --- a/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt +++ b/src/net/torvald/terrarum/modulebasegame/IngameRenderer.kt @@ -6,7 +6,7 @@ import com.badlogic.gdx.graphics.* import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.FrameBuffer import com.badlogic.gdx.utils.ScreenUtils -import net.torvald.dataclass.CircularArray +import net.torvald.util.CircularArray import net.torvald.terrarum.* import net.torvald.terrarum.gameactors.ActorWithBody import net.torvald.terrarum.gamecontroller.KeyToggler @@ -94,7 +94,7 @@ object IngameRenderer { LightmapRenderer.fireRecalculateEvent(actorsRenderBehind, actorsRenderFront, actorsRenderMidTop, actorsRenderMiddle, actorsRenderOverlay) prepLightmapRGBA() - BlocksDrawer.renderData() + BlocksDrawer.renderData(selectedWireBitToDraw) drawToRGB(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer) drawToA(actorsRenderBehind, actorsRenderMiddle, actorsRenderMidTop, actorsRenderFront, particlesContainer) drawOverlayActors(actorsRenderOverlay) @@ -216,7 +216,7 @@ object IngameRenderer { batch.color = Color.WHITE - drawWires = false + selectedWireBitToDraw = 0 } @@ -235,7 +235,19 @@ object IngameRenderer { internal var fboRGBexportRequested = false - var drawWires = false + /** + * Which wires should be drawn. Normally this value is set by the wiring item (e.g. wire pieces, wirecutters) + * This number is directly related with the World's wire bits: + * + * ``` + * world.getWires(x, y) -> 0000101 (for example) + * value of 3 selects this ^ ^ + * value of 1 selects this | + * + * The wire piece gets rendered when selected bit is set. + * ``` + */ + var selectedWireBitToDraw = 0 private fun drawToRGB( actorsRenderBehind: List?, @@ -279,7 +291,7 @@ object IngameRenderer { } setCameraPosition(0f, 0f) - BlocksDrawer.drawFront(batch.projectionMatrix, drawWires) // blue coloured filter of water, etc. + BlocksDrawer.drawFront(batch.projectionMatrix, selectedWireBitToDraw) // blue coloured filter of water, etc. batch.inUse { FeaturesDrawer.drawEnvOverlay(batch) diff --git a/src/net/torvald/terrarum/modulebasegame/console/ExportMap.kt b/src/net/torvald/terrarum/modulebasegame/console/ExportMap.kt index 572a73682..6bccc3f53 100644 --- a/src/net/torvald/terrarum/modulebasegame/console/ExportMap.kt +++ b/src/net/torvald/terrarum/modulebasegame/console/ExportMap.kt @@ -1,16 +1,14 @@ package net.torvald.terrarum.modulebasegame.console -import net.torvald.colourutil.Col4096 import net.torvald.terrarum.AppLoader -import net.torvald.terrarum.utils.RasterWriter import net.torvald.terrarum.Terrarum -import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.console.ConsoleCommand import net.torvald.terrarum.console.Echo import net.torvald.terrarum.console.EchoError - -import java.io.* -import java.util.HashMap +import net.torvald.terrarum.utils.RasterWriter +import net.torvald.terrarum.worlddrawer.CreateTileAtlas +import java.io.File +import java.io.IOException /** * Created by minjaesong on 2016-01-17. @@ -20,57 +18,20 @@ internal object ExportMap : ConsoleCommand { //private var mapData: ByteArray? = null // private var mapDataPointer = 0 - private val colorTable = HashMap() - init { - colorTable.put(Block.AIR, Col4096(0xCEF)) - colorTable.put(Block.STONE, Col4096(0x888)) - colorTable.put(Block.DIRT, Col4096(0x753)) - colorTable.put(Block.GRASS, Col4096(0x472)) - - colorTable.put(Block.ORE_COPPER, Col4096(0x6A8)) - colorTable.put(Block.ORE_IRON, Col4096(0xC75)) - colorTable.put(Block.ORE_GOLD, Col4096(0xA87)) - colorTable.put(Block.ORE_ILMENITE, Col4096(0x8AB)) - colorTable.put(Block.ORE_AURICHALCUM, Col4096(0xD92)) - colorTable.put(Block.ORE_SILVER, Col4096(0xDDD)) - - colorTable.put(Block.RAW_DIAMOND, Col4096(0x2BF)) - colorTable.put(Block.RAW_RUBY, Col4096(0xB10)) - colorTable.put(Block.RAW_EMERALD, Col4096(0x0B1)) - colorTable.put(Block.RAW_SAPPHIRE, Col4096(0x01B)) - colorTable.put(Block.RAW_TOPAZ, Col4096(0xC70)) - colorTable.put(Block.RAW_AMETHYST, Col4096(0x70C)) - - colorTable.put(Block.WATER, Col4096(0x038)) - - colorTable.put(Block.SAND, Col4096(0xDDB)) - colorTable.put(Block.SAND_WHITE, Col4096(0xFFD)) - colorTable.put(Block.SAND_RED, Col4096(0xA32)) - colorTable.put(Block.SAND_DESERT, Col4096(0xEDB)) - colorTable.put(Block.SAND_BLACK, Col4096(0x444)) - colorTable.put(Block.SAND_GREEN, Col4096(0x9A6)) - - colorTable.put(Block.GRAVEL, Col4096(0x664)) - colorTable.put(Block.GRAVEL_GREY, Col4096(0x999)) - - colorTable.put(Block.ICE_NATURAL, Col4096(0x9AB)) - colorTable.put(Block.ICE_MAGICAL, Col4096(0x7AC)) - colorTable.put(Block.ICE_FRAGILE, Col4096(0x6AF)) - colorTable.put(Block.SNOW, Col4096(0xCDE)) - } override fun execute(args: Array) { val world = (Terrarum.ingame!!.world) if (args.size == 2) { + // TODO rewrite to use Pixmap and PixmapIO + var mapData = ByteArray(world.width * world.height * 3) var mapDataPointer = 0 for (tile in world.terrainIterator()) { - val colArray = (colorTable as Map) - .getOrElse(tile, { Col4096(0xFFF) }).toByteArray() + val colArray = CreateTileAtlas.terrainTileColourMap.getRaw(tile % 16, tile / 16).toByteArray() for (i in 0..2) { mapData[mapDataPointer + i] = colArray[i] @@ -107,6 +68,16 @@ internal object ExportMap : ConsoleCommand { } } + /*** + * R-G-B-A order for RGBA input value + */ + private fun Int.toByteArray() = byteArrayOf( + this.shl(24).and(0xff).toByte(), + this.shl(16).and(0xff).toByte(), + this.shl(8).and(0xff).toByte(), + this.and(0xff).toByte() + ) + override fun printUsage() { Echo("Usage: export ") diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt index fddc22f32..e7b1896fd 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/ActorHumanoid.kt @@ -588,7 +588,7 @@ open class ActorHumanoid( } override fun onActorValueChange(key: String, value: Any?) { - // quickslot implementation + // make quickslot work if (key == AVKey.__PLAYER_QUICKSLOTSEL && value != null) { // ONLY FOR HAND_GRIPs!! val quickBarItem = ItemCodex[inventory.getQuickslot(actorValue.getAsInt(key)!!)?.item] @@ -596,6 +596,9 @@ open class ActorHumanoid( if (quickBarItem != null && quickBarItem.equipPosition == GameItem.EquipPosition.HAND_GRIP) { equipItem(quickBarItem) } + else { + unequipSlot(GameItem.EquipPosition.HAND_GRIP) + } // force update inventory UI try { diff --git a/src/net/torvald/terrarum/modulebasegame/items/PickaxeGeneric.kt b/src/net/torvald/terrarum/modulebasegame/items/PickaxeGeneric.kt index fc5a5a034..019010b13 100644 --- a/src/net/torvald/terrarum/modulebasegame/items/PickaxeGeneric.kt +++ b/src/net/torvald/terrarum/modulebasegame/items/PickaxeGeneric.kt @@ -35,10 +35,12 @@ object PickaxeCore { // linear search filter (check for intersection with tilewise mouse point and tilewise hitbox) // return false if hitting actors + var ret1 = true Terrarum.ingame!!.actorContainerActive.forEach { if (it is ActorWBMovable && it.hIntTilewiseHitbox.intersects(mousePoint)) - return false + ret1 = false // return is not allowed here } + if (!ret1) return ret1 // return false if here's no tile if (Block.AIR == (Terrarum.ingame!!.world).getTileFromTerrain(mouseTileX, mouseTileY)) diff --git a/src/net/torvald/terrarum/modulebasegame/items/WirePieceSignalWire.kt b/src/net/torvald/terrarum/modulebasegame/items/WirePieceSignalWire.kt index 3462b734e..18e24f1f3 100644 --- a/src/net/torvald/terrarum/modulebasegame/items/WirePieceSignalWire.kt +++ b/src/net/torvald/terrarum/modulebasegame/items/WirePieceSignalWire.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.items import com.badlogic.gdx.graphics.g2d.TextureRegion import net.torvald.terrarum.AppLoader +import net.torvald.terrarum.blockproperties.Wire import net.torvald.terrarum.itemproperties.GameItem import net.torvald.terrarum.itemproperties.ItemID import net.torvald.terrarum.itemproperties.Material @@ -35,6 +36,7 @@ class WirePieceSignalWire(override val originalID: ItemID) : GameItem() { } override fun effectWhenEquipped(delta: Float) { - IngameRenderer.drawWires = true + IngameRenderer.selectedWireBitToDraw = Wire.BIT_SIGNAL_RED + //println("wires!") } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/worldgenerator/RoguelikeRandomiser.kt b/src/net/torvald/terrarum/modulebasegame/worldgenerator/RoguelikeRandomiser.kt index 4affe3f4a..97e7f57ed 100644 --- a/src/net/torvald/terrarum/modulebasegame/worldgenerator/RoguelikeRandomiser.kt +++ b/src/net/torvald/terrarum/modulebasegame/worldgenerator/RoguelikeRandomiser.kt @@ -1,7 +1,7 @@ package net.torvald.terrarum.modulebasegame.worldgenerator import com.badlogic.gdx.graphics.Color -import net.torvald.dataclass.IntArrayStack +import net.torvald.util.IntArrayStack import net.torvald.colourutil.Col4096 import net.torvald.random.HQRNG import net.torvald.terrarum.modulebasegame.RNGConsumer diff --git a/src/net/torvald/terrarum/realestate/LandUtil.kt b/src/net/torvald/terrarum/realestate/LandUtil.kt index e0ca501c3..46541c21b 100644 --- a/src/net/torvald/terrarum/realestate/LandUtil.kt +++ b/src/net/torvald/terrarum/realestate/LandUtil.kt @@ -11,7 +11,7 @@ import net.torvald.terrarum.gameworld.fmod */ object LandUtil { fun getBlockAddr(world: GameWorld, x: Int, y: Int): BlockAddress = - // coercing and fmod-ing follows ROUNDWORLD rule + // coercing and fmod-ing follows ROUNDWORLD rule. See: GameWorld.coerceXY() (world.width * y.coerceIn(0, world.height - 1)).toLong() + x.fmod(world.width) fun resolveBlockAddr(world: GameWorld, t: BlockAddress): Pair = diff --git a/src/net/torvald/terrarum/tests/CircularArrayTest.kt b/src/net/torvald/terrarum/tests/CircularArrayTest.kt index 8bcb0b580..7c0635e03 100644 --- a/src/net/torvald/terrarum/tests/CircularArrayTest.kt +++ b/src/net/torvald/terrarum/tests/CircularArrayTest.kt @@ -1,4 +1,4 @@ -import net.torvald.dataclass.CircularArray +import net.torvald.util.CircularArray /** * Created by minjaesong on 2019-01-09. diff --git a/src/net/torvald/terrarum/ui/ConsoleWindow.kt b/src/net/torvald/terrarum/ui/ConsoleWindow.kt index d3606e25a..a61bf4b45 100644 --- a/src/net/torvald/terrarum/ui/ConsoleWindow.kt +++ b/src/net/torvald/terrarum/ui/ConsoleWindow.kt @@ -4,7 +4,7 @@ import com.badlogic.gdx.Input import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch -import net.torvald.dataclass.HistoryArray +import net.torvald.util.HistoryArray import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.Terrarum import net.torvald.terrarum.AppLoader diff --git a/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt b/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt index b99dc375b..baa2d9ee7 100644 --- a/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt +++ b/src/net/torvald/terrarum/worlddrawer/BlocksDrawerNew.kt @@ -3,6 +3,7 @@ package net.torvald.terrarum.worlddrawer import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.* import com.badlogic.gdx.math.Matrix4 +import com.jme3.math.FastMath import net.torvald.terrarum.* import net.torvald.terrarum.AppLoader.printdbg import net.torvald.terrarum.blockproperties.Block @@ -184,7 +185,7 @@ internal object BlocksDrawer { // NO draw lightmap using colour filter, actors must also be hidden behind the darkness /////////////////////////////////////////// - internal fun renderData() { + internal fun renderData(wireBit: Int) { try { drawTIME_T = (world as GameWorldExtension).time.TIME_T - (WorldTime.DAY_LENGTH * 15) // offset by -15 days @@ -197,7 +198,7 @@ internal object BlocksDrawer { drawTiles(WALL) drawTiles(TERRAIN) // regular tiles - drawTiles(WIRE) + drawTiles(WIRE, wireBit) drawTiles(FLUID) } @@ -214,7 +215,7 @@ internal object BlocksDrawer { renderUsingBuffer(FLUID, projectionMatrix) } - internal fun drawFront(projectionMatrix: Matrix4, drawWires: Boolean) { + internal fun drawFront(projectionMatrix: Matrix4, drawWires: Int) { // blend mul Gdx.gl.glEnable(GL20.GL_TEXTURE_2D) Gdx.gl.glEnable(GL20.GL_BLEND) @@ -227,7 +228,8 @@ internal object BlocksDrawer { gdxSetBlendNormal() - if (drawWires) { + if (drawWires != 0) { + //println("drawing wires") renderUsingBuffer(WIRE, projectionMatrix) } } @@ -257,12 +259,24 @@ internal object BlocksDrawer { private val tileDrawLightThreshold = 2f / LightmapRenderer.MUL + /** + * Turns bitmask-with-single-bit-set into its bit index. The LSB is counted as 1, and thus the index starts at one. + * @return 0 -> null, 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3, 16 -> 4, ... + */ + private fun Int.toBitOrd(): Int? = + if (this > 0 && !FastMath.isPowerOfTwo(this)) throw IllegalArgumentException("value must be power of two: $this") + else { + val k = FastMath.intLog2(this, -1) + if (k == -1) null else k + } + /** * Writes to buffer. Actual draw code must be called after this operation. * * @param drawModeTilesBlendMul If current drawing mode is MULTIPLY. Doesn't matter if mode is FLUID. + * @param wire coduitTypes bit that is selected to be drawn. Must be the power of two. */ - private fun drawTiles(mode: Int) { + private fun drawTiles(mode: Int, wireBit: Int = 0) { // can't be "WorldCamera.y / TILE_SIZE": // ( 3 / 16) == 0 // (-3 / 16) == -1 <-- We want it to be '-1', not zero @@ -291,7 +305,7 @@ internal object BlocksDrawer { val thisTile = when (mode) { WALL -> world.getTileFromWall(x, y) TERRAIN -> world.getTileFromTerrain(x, y) - WIRE -> world.getWires(x, y) + WIRE -> world.getWires(x, y).and(wireBit).toBitOrd() FLUID -> world.getFluid(x, y).type.abs() else -> throw IllegalArgumentException() } diff --git a/src/net/torvald/dataclass/ArrayListMap.kt b/src/net/torvald/util/ArrayListMap.kt similarity index 99% rename from src/net/torvald/dataclass/ArrayListMap.kt rename to src/net/torvald/util/ArrayListMap.kt index babf8c0cd..93711cc31 100644 --- a/src/net/torvald/dataclass/ArrayListMap.kt +++ b/src/net/torvald/util/ArrayListMap.kt @@ -1,4 +1,4 @@ -package net.torvald.dataclass +package net.torvald.util import java.util.function.BiConsumer import java.util.function.BiFunction diff --git a/src/net/torvald/dataclass/CircularArray.kt b/src/net/torvald/util/CircularArray.kt similarity index 98% rename from src/net/torvald/dataclass/CircularArray.kt rename to src/net/torvald/util/CircularArray.kt index 1f0234fee..89f4f5da9 100644 --- a/src/net/torvald/dataclass/CircularArray.kt +++ b/src/net/torvald/util/CircularArray.kt @@ -1,4 +1,4 @@ -package net.torvald.dataclass +package net.torvald.util /** diff --git a/src/net/torvald/dataclass/Float16.kt b/src/net/torvald/util/Float16.kt similarity index 99% rename from src/net/torvald/dataclass/Float16.kt rename to src/net/torvald/util/Float16.kt index aaa45d2e5..0264ff8c4 100644 --- a/src/net/torvald/dataclass/Float16.kt +++ b/src/net/torvald/util/Float16.kt @@ -1,4 +1,4 @@ -package net.torvald.dataclass +package net.torvald.util import kotlin.experimental.or diff --git a/src/net/torvald/dataclass/HistoryArray.kt b/src/net/torvald/util/HistoryArray.kt similarity index 98% rename from src/net/torvald/dataclass/HistoryArray.kt rename to src/net/torvald/util/HistoryArray.kt index 61bfc661f..5c4762050 100644 --- a/src/net/torvald/dataclass/HistoryArray.kt +++ b/src/net/torvald/util/HistoryArray.kt @@ -1,4 +1,4 @@ -package net.torvald.dataclass +package net.torvald.util import java.util.* diff --git a/src/net/torvald/dataclass/IntArrayStack.kt b/src/net/torvald/util/IntArrayStack.kt similarity index 98% rename from src/net/torvald/dataclass/IntArrayStack.kt rename to src/net/torvald/util/IntArrayStack.kt index 40721fdcd..8f8349da9 100644 --- a/src/net/torvald/dataclass/IntArrayStack.kt +++ b/src/net/torvald/util/IntArrayStack.kt @@ -1,4 +1,4 @@ -package net.torvald.dataclass +package net.torvald.util import java.util.* diff --git a/src/net/torvald/dataclass/Matrix.kt b/src/net/torvald/util/Matrix.kt similarity index 99% rename from src/net/torvald/dataclass/Matrix.kt rename to src/net/torvald/util/Matrix.kt index b0f118cca..ce232c81e 100644 --- a/src/net/torvald/dataclass/Matrix.kt +++ b/src/net/torvald/util/Matrix.kt @@ -1,4 +1,4 @@ -package net.torvald.dataclass +package net.torvald.util /** * Taken and improved from https://introcs.cs.princeton.edu/java/95linear/Matrix.java.html diff --git a/src/net/torvald/util/SortedArrayList.kt b/src/net/torvald/util/SortedArrayList.kt new file mode 100644 index 000000000..a49c51e0b --- /dev/null +++ b/src/net/torvald/util/SortedArrayList.kt @@ -0,0 +1,86 @@ +package net.torvald.util + +import net.torvald.terrarum.lock +import java.util.concurrent.locks.ReentrantLock + +/** + * The modification of the arraylist that its element is always sorted. + * + * Created by minjaesong on 2019-03-12. + */ +class SortedArrayList>(initialSize: Int = 10) { + + private val arrayList = ArrayList(initialSize) + + /** + */ + fun add(elem: T) { + // don't append-at-tail-and-sort; just insert at right index + ReentrantLock().lock { + var low = 0 + var high = arrayList.size + + while (low < high) { + val mid = (low + high).ushr(1) + + if (arrayList[mid] > elem) + high = mid + else + low = mid + 1 + } + + arrayList.add(low, elem) + } + } + + val size: Int + get() = arrayList.size + + fun removeAt(index: Int) = arrayList.removeAt(index) + fun remove(element: T) = arrayList.remove(element) + fun removeLast() = arrayList.removeAt(arrayList.size) + + operator fun get(index: Int) = arrayList[index] + + fun iterator() = arrayList.iterator() + fun forEach(action: (T) -> Unit) = arrayList.forEach(action) + fun forEachIndexed(action: (Int, T) -> Unit) = arrayList.forEachIndexed(action) + //fun map(transformation: (T) -> R) = arrayList.map(transformation) + + /** + * Select one unsorted element from the array and put it onto the sorted spot. + * + * The list must be fully sorted except for that one "renegade", otherwise the operation is undefined behaviour. + */ + private fun sortThisRenegade(index: Int) { + if ( + (index == arrayList.lastIndex && arrayList[index - 1] <= arrayList[index]) || + (index == 0 && arrayList[index] <= arrayList[index + 1]) || + (arrayList[index - 1] <= arrayList[index] && arrayList[index] <= arrayList[index + 1]) + ) return + + // modified binary search + ReentrantLock().lock { + val renegade = arrayList.removeAt(index) + + var low = 0 + var high = arrayList.size + + while (low < high) { + val mid = (low + high).ushr(1) + + if (arrayList[mid] > renegade) + high = mid + else + low = mid + 1 + } + + arrayList.add(low, renegade) + } + } + + /** + * Does NOT create copies! + */ + fun toArrayList() = arrayList +} \ No newline at end of file