always sorting arraylist; more wire stuffs

This commit is contained in:
minjaesong
2019-03-12 19:50:28 +09:00
parent 0563ef0940
commit 08aa0e8f34
30 changed files with 288 additions and 115 deletions

26
shit.kts Normal file
View File

@@ -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])

View File

@@ -35,9 +35,6 @@
package com.jme3.math;
import java.util.Arrays;
import java.util.Random;
/**
* <code>FastMath</code> 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; }

View File

@@ -1,6 +1,6 @@
package net.torvald.parametricsky
import net.torvald.dataclass.Matrix
import net.torvald.util.Matrix
import kotlin.math.pow
/**

View File

@@ -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;

View File

@@ -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<Actor>(ACTORCONTAINER_INITIAL_SIZE)
val actorContainerInactive = ArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
val actorContainerActive = SortedArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
val actorContainerInactive = SortedArrayList<Actor>(ACTORCONTAINER_INITIAL_SIZE)
protected val terrainChangeQueue = Queue<BlockChangeQueueItem>()
protected val wallChangeQueue = Queue<BlockChangeQueueItem>()
@@ -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<Actor>) {
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)
}

View File

@@ -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
/**

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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<Actor>,
val actorContainerInactive: ArrayList<Actor>) : JFrame() {
val actorContainer: SortedArrayList<Actor>,
val actorContainerInactive: SortedArrayList<Actor>) : JFrame() {
private val activeActorArea = JTextArea()
private val activeActorScroller = JScrollPane(activeActorArea)

View File

@@ -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<BlockAddress, Float> // size of gas packet on the block
get() = conduitFills[1]
private val wiringNodes = SortedArrayList<WiringNode>()
//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<WiringNode>
) : Comparable<WiringNode> {
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

View File

@@ -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<Float16Bits> {
constructor(width: Int, height: Int, init: Float) : this(width, height) {

View File

@@ -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

View File

@@ -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) {

View File

@@ -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<ActorWithBody>?,
@@ -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)

View File

@@ -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<Int, Col4096>()
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<String>) {
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<Int, Col4096>)
.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 <name>")

View File

@@ -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 {

View File

@@ -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))

View File

@@ -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!")
}
}

View File

@@ -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

View File

@@ -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<Int, Int> =

View File

@@ -1,4 +1,4 @@
import net.torvald.dataclass.CircularArray
import net.torvald.util.CircularArray
/**
* Created by minjaesong on 2019-01-09.

View File

@@ -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

View File

@@ -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()
}

View File

@@ -1,4 +1,4 @@
package net.torvald.dataclass
package net.torvald.util
import java.util.function.BiConsumer
import java.util.function.BiFunction

View File

@@ -1,4 +1,4 @@
package net.torvald.dataclass
package net.torvald.util
/**

View File

@@ -1,4 +1,4 @@
package net.torvald.dataclass
package net.torvald.util
import kotlin.experimental.or

View File

@@ -1,4 +1,4 @@
package net.torvald.dataclass
package net.torvald.util
import java.util.*

View File

@@ -1,4 +1,4 @@
package net.torvald.dataclass
package net.torvald.util
import java.util.*

View File

@@ -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

View File

@@ -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<T: Comparable<T>>(initialSize: Int = 10) {
private val arrayList = ArrayList<T>(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 <R> 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
}