diff --git a/Known problems.md b/Known problems.md index 17ad40760..82a285536 100644 --- a/Known problems.md +++ b/Known problems.md @@ -8,6 +8,9 @@ ### Physics ### +### System ### + + # Resolved # diff --git a/res/graphics/terrain/terrain.png b/res/graphics/terrain/terrain.png index 026aecf94..477b6b02a 100644 Binary files a/res/graphics/terrain/terrain.png and b/res/graphics/terrain/terrain.png differ diff --git a/src/net/torvald/terrarum/Game.kt b/src/net/torvald/terrarum/Game.kt index e3f738c5e..cba664333 100644 --- a/src/net/torvald/terrarum/Game.kt +++ b/src/net/torvald/terrarum/Game.kt @@ -416,12 +416,11 @@ constructor() : BasicGameState() { /** * Check for duplicates, append actor and sort the list */ - fun addActor(actor: Actor): Boolean { + fun addActor(actor: Actor) { if (hasActor(actor.referenceID)) throw RuntimeException("Actor with ID ${actor.referenceID} already exists.") actorContainer.add(actor) insertionSortLastElem(actorContainer) // we can do this as we are only adding single actor - return true } /** @@ -445,7 +444,7 @@ constructor() : BasicGameState() { var index: Int = arr.size - 1 x = arr[index] j = index - 1 - while (j > 0 && arr[j].referenceID > x.referenceID) { + while (j > 0 && arr[j] > x) { arr[j + 1] = arr[j] j -= 1 } diff --git a/src/net/torvald/terrarum/REFERENCING.md b/src/net/torvald/terrarum/REFERENCING.md new file mode 100644 index 000000000..5202f1d25 --- /dev/null +++ b/src/net/torvald/terrarum/REFERENCING.md @@ -0,0 +1,6 @@ +|Range|Description| +|-----|-----------| +|0..4095|Tiles| +|4096..32767|Items| +|32768..0x7FFFFFFF|Actors| +|0x80000000L..0xFFFFFFFFL|Faction| diff --git a/src/net/torvald/terrarum/gameactors/Actor.kt b/src/net/torvald/terrarum/gameactors/Actor.kt index 7f9e61f28..1874e04a2 100644 --- a/src/net/torvald/terrarum/gameactors/Actor.kt +++ b/src/net/torvald/terrarum/gameactors/Actor.kt @@ -2,6 +2,7 @@ package net.torvald.terrarum.gameactors import net.torvald.random.HQRNG import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.itemproperties.ItemPropCodex import org.newdawn.slick.GameContainer /** @@ -21,11 +22,13 @@ abstract class Actor : Comparable, Runnable { override fun equals(other: Any?) = referenceID == (other as Actor).referenceID override fun hashCode() = referenceID - override fun toString() = if (actorValue.getAsString(AVKey.NAME).isNullOrEmpty()) + override fun toString() = "Actor, " + if (actorValue.getAsString(AVKey.NAME).isNullOrEmpty()) "ID: ${hashCode()}" else "ID: ${hashCode()} (${actorValue.getAsString(AVKey.NAME)})" - override fun compareTo(other: Actor): Int = this.referenceID - other.referenceID + override fun compareTo(other: Actor): Int = (this.referenceID - other.referenceID).sign() + + fun Int.sign(): Int = if (this > 0) 1 else if (this < 0) -1 else this /** * Usage: @@ -33,11 +36,10 @@ abstract class Actor : Comparable, Runnable { * override var referenceID: Int = generateUniqueReferenceID() */ fun generateUniqueReferenceID(): Int { - fun Int.abs() = if (this < 0) -this else this var ret: Int do { - ret = HQRNG().nextInt().abs() // set new ID - } while (Terrarum.game.hasActor(ret)) // check for collision + ret = HQRNG().nextInt().and(0x7FFFFFFF) // set new ID + } while (Terrarum.game.hasActor(ret) || ret < ItemPropCodex.ITEM_UNIQUE_MAX) // check for collision return ret } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index 013d10363..06c18fa4d 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -91,7 +91,7 @@ open class ActorWithBody constructor() : Actor(), Visible { actorValue[AVKey.BASEMASS] = value } /** Valid range: [0, 1] */ - var elasticity = 0.0 + var elasticity: Double = 0.0 set(value) { if (value < 0) throw IllegalArgumentException("[ActorWithBody] Invalid elasticity value: $value; valid elasticity value is [0, 1].") @@ -103,6 +103,18 @@ open class ActorWithBody constructor() : Actor(), Visible { field = value * ELASTICITY_MAX } @Transient private val ELASTICITY_MAX = 0.993 // No perpetual motion! + + /** + * what pretty much every physics engine has, instead of my 'elasticity' + * + * This is just a simple macro for 'elasticity'. + * + * Formula: restitution = 1.0 - elasticity + */ + var restitution: Double + set(value) { elasticity = 1.0 - value } + get() = 1.0 - elasticity + private var density = 1000.0 /** @@ -175,9 +187,11 @@ open class ActorWithBody constructor() : Actor(), Visible { @Transient val DYNAMIC = 2 @Transient val STATIC = 3 - private val SLEEP_THRE = 0.125 - private val CCD_THRE = 1.0 - private val CCD_TICK = 0.125 + private val SLEEP_THRE = 1.0 / 16.0 + private val CCD_TICK = 1.0 / 16.0 + + internal var walledLeft = false + internal var walledRight = false init { @@ -297,6 +311,9 @@ open class ActorWithBody constructor() : Actor(), Visible { clampNextHitbox() clampHitbox() } + + walledLeft = isColliding(CONTACT_AREA_LEFT, -1, 0) + walledRight = isColliding(CONTACT_AREA_RIGHT, 1, 0) } } @@ -534,11 +551,34 @@ open class ActorWithBody constructor() : Actor(), Visible { val delta: Vector2 = Vector2(hitbox.toVector() - nextHitbox.toVector()) // we need to traverse back, so may as well negate at the first place val ccdDelta = delta.setMagnitude(CCD_TICK) - while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT) - || isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM) - ) { - // while still colliding, CCD to the 'delta' - nextHitbox.translate(ccdDelta) + if (ccdDelta.x.abs() >= SLEEP_THRE || ccdDelta.y.abs() >= SLEEP_THRE) { // regular situation + // CCD to delta while still colliding + while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT) + || isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM) + ) { + nextHitbox.translate(ccdDelta) + } + } + else { // stuck while standing still + // CCD upward + var upwardDelta = 0.0 + while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT) + || isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM) + ) { + nextHitbox.translate(0.0, -CCD_TICK) + upwardDelta += CCD_TICK + + if (upwardDelta >= TSIZE) break + + /* TODO CCD in order of: + + .. 10 11 12 13 14 .. + .. 08 03 04 05 09 .. + .. 06 01 [] 02 07 .. + + until the stucking is resolved + */ + } } } } @@ -546,10 +586,9 @@ open class ActorWithBody constructor() : Actor(), Visible { private fun applyNormalForce() { if (!isNoCollideWorld) { // axis Y - if (veloY >= 0) { // check downward + if (moveDelta.y >= 0) { // check downward if (isColliding(CONTACT_AREA_BOTTOM) || isColliding(CONTACT_AREA_BOTTOM, 0, 1)) { // the actor is hitting the ground - //veloY = 0.0 // reset veloY, simulating normal force hitAndReflectY() grounded = true } @@ -557,33 +596,30 @@ open class ActorWithBody constructor() : Actor(), Visible { grounded = false } } - else if (veloY < 0) { // check upward + else if (moveDelta.y < 0) { // check upward grounded = false if (isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_TOP, 0, -1)) { // the actor is hitting the ceiling - //veloY = 0.0 // reset veloY, simulating normal force hitAndReflectY() } else { // the actor is not grounded at all } } // axis X - if (veloX >= 0.5) { // check right + if (moveDelta.x > 0) { // check right if ((isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT)) || (isColliding(CONTACT_AREA_RIGHT, 1, 0) && !isColliding(CONTACT_AREA_LEFT, 0, -1))) { // the actor is hitting the right wall - //veloX = 0.0 // reset veloX, simulating normal force hitAndReflectX() } else { } } - else if (veloX <= -0.5) { // check left + else if (moveDelta.x < 0) { // check left // System.out.println("collidingleft"); if ((isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT)) || (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0))) { // the actor is hitting the left wall - //veloX = 0.0 // reset veloX, simulating normal force hitAndReflectX() } else { @@ -597,18 +633,22 @@ open class ActorWithBody constructor() : Actor(), Visible { private fun hitAndReflectX() { if ((veloX * elasticity).abs() > SLEEP_THRE) { veloX *= -elasticity + walkX *= -elasticity } else { veloX = 0.0 + walkX = 0.0 } } private fun hitAndReflectY() { if ((veloY * elasticity).abs() > SLEEP_THRE) { veloY *= -elasticity + walkY *= -elasticity } else { veloY = 0.0 + walkY *= 0.0 } } diff --git a/src/net/torvald/terrarum/gameactors/DroppedItem.kt b/src/net/torvald/terrarum/gameactors/DroppedItem.kt index fa4b2384e..a8fb4ca8d 100644 --- a/src/net/torvald/terrarum/gameactors/DroppedItem.kt +++ b/src/net/torvald/terrarum/gameactors/DroppedItem.kt @@ -16,7 +16,7 @@ class DroppedItem constructor(itemID: Int) : ActorWithBody() { isVisible = true - mass = if (itemID < 4096) + mass = if (itemID < TilePropCodex.TILE_UNIQUE_MAX) TilePropCodex.getProp(itemID).density / 1000.0 else ItemPropCodex.getProp(itemID).mass diff --git a/src/net/torvald/terrarum/gameactors/Player.kt b/src/net/torvald/terrarum/gameactors/Player.kt index f4965bcae..6b186e50c 100644 --- a/src/net/torvald/terrarum/gameactors/Player.kt +++ b/src/net/torvald/terrarum/gameactors/Player.kt @@ -73,7 +73,7 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan } companion object { - @Transient internal const val ACCEL_MULT_IN_FLIGHT: Double = 0.31 + @Transient internal const val ACCEL_MULT_IN_FLIGHT: Double = 0.21 // TODO air control still too 'slippery' with 0.31, lower the value! @Transient internal const val WALK_ACCEL_BASE: Double = 0.67 @Transient const val PLAYER_REF_ID: Int = 0x51621D @@ -130,33 +130,35 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan * @author minjaesong */ private fun walkHorizontal(left: Boolean, absAxisVal: Float) { - readonly_totalX = //veloX + - /*actorValue.getAsDouble(AVKey.ACCEL)!! * + if ((!walledLeft && left) || (!walledRight && !left)) { + readonly_totalX = //veloX + + /*actorValue.getAsDouble(AVKey.ACCEL)!! * actorValue.getAsDouble(AVKey.ACCELMULT)!! * Math.sqrt(scale) * applyAccelRealism(walkPowerCounter) * (if (left) -1 else 1).toFloat() * absAxisVal*/ - actorValue.getAsDouble(AVKey.ACCEL)!! * - actorValue.getAsDouble(AVKey.ACCELMULT)!! * - Math.sqrt(scale) * - applyVelo(walkCounter) * - (if (left) -1 else 1).toFloat() * - absAxisVal + actorValue.getAsDouble(AVKey.ACCEL)!! * + actorValue.getAsDouble(AVKey.ACCELMULT)!! * + Math.sqrt(scale) * + applyVelo(walkCounter) * + (if (left) -1 else 1).toFloat() * + absAxisVal - //applyForce(Vector2(readonly_totalX, 0.0)) - walkX += readonly_totalX - walkX = absClamp(walkX, actorValue.getAsDouble(AVKey.SPEED)!! * actorValue.getAsDouble(AVKey.SPEEDMULT)!!) + //applyForce(Vector2(readonly_totalX, 0.0)) + walkX += readonly_totalX + walkX = absClamp(walkX, actorValue.getAsDouble(AVKey.SPEED)!! * actorValue.getAsDouble(AVKey.SPEEDMULT)!!) - walkCounter += 1 + walkCounter += 1 - // Heading flag - if (left) - walkHeading = LEFT - else - walkHeading = RIGHT + // Heading flag + if (left) + walkHeading = LEFT + else + walkHeading = RIGHT - println("$walkCounter: ${readonly_totalX}") + // println("$walkCounter: ${readonly_totalX}") + } } /** @@ -243,7 +245,9 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan } /** - * See ./work_files/Jump\ power\ by\ pressing\ time.gcx + * See ./work_files/Jump power by pressing time.gcx + * + * TODO linear function (play Super Mario Bros. and you'll get what I'm talking about) */ private fun jump() { if (jumping) { diff --git a/src/net/torvald/terrarum/gameactors/faction/Faction.kt b/src/net/torvald/terrarum/gameactors/faction/Faction.kt index 1ac12ba92..34a06d588 100644 --- a/src/net/torvald/terrarum/gameactors/faction/Faction.kt +++ b/src/net/torvald/terrarum/gameactors/faction/Faction.kt @@ -7,17 +7,16 @@ import java.util.HashSet /** * Created by minjaesong on 16-02-15. */ -class Faction(factionName: String) { +class Faction(name: String) : Comparable { - lateinit var factionName: String + var factionName: String = name lateinit var factionAmicable: HashSet lateinit var factionNeutral: HashSet lateinit var factionHostile: HashSet lateinit var factionFearful: HashSet - var factionID: Long = generateUniqueID() + var referenceID: Long = generateUniqueID() init { - this.factionName = factionName factionAmicable = HashSet() factionNeutral = HashSet() factionHostile = HashSet() @@ -60,8 +59,18 @@ class Faction(factionName: String) { factionFearful.remove(faction) } - fun generateUniqueID(): Long { - fun Long.abs() = if (this < 0) -this else this - return HQRNG().nextLong().abs() // set new ID + private fun generateUniqueID(): Long { + var ret: Long + do { + ret = HQRNG().nextLong().or(0x80000000L).and(0xFFFFFFFFL) // guaranteed to be 2147483648..4294967295 + } while (FactionCodex.hasFaction(ret)) // check for collision + return ret } + + override fun equals(other: Any?) = referenceID == (other as Faction).referenceID + override fun hashCode() = (referenceID - 0x80000000L).toInt() + override fun toString() = "Faction, ID: $referenceID ($factionName)" + override fun compareTo(other: Faction): Int = (this.referenceID - other.referenceID).toInt().sign() + + fun Int.sign(): Int = if (this > 0) 1 else if (this < 0) -1 else this } diff --git a/src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt b/src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt new file mode 100644 index 000000000..166efdb59 --- /dev/null +++ b/src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt @@ -0,0 +1,66 @@ +package net.torvald.terrarum.gameactors.faction + +import net.torvald.terrarum.Terrarum +import java.util.* + +/** + * Created by minjaesong on 16-05-09. + */ +object FactionCodex { + val factionContainer = ArrayList() + + fun hasFaction(ID: Long): Boolean = + if (factionContainer.size == 0) + false + else + factionContainer.binarySearch(ID) >= 0 + + fun addFaction(faction: Faction) { + if (hasFaction(faction.referenceID)) + throw RuntimeException("Faction with ID ${faction.referenceID} already exists.") + factionContainer.add(faction) + insertionSortLastElem(factionContainer) // we can do this as we are only adding single actor + } + + fun getFactionByID(ID: Long): Faction { + if (factionContainer.size == 0) throw IllegalArgumentException("Faction with ID $ID does not exist.") + + val index = factionContainer.binarySearch(ID) + if (index < 0) + throw IllegalArgumentException("Faction with ID $ID does not exist.") + else + return factionContainer[index] + } + + private fun insertionSortLastElem(arr: ArrayList) { + var x: Faction + var j: Int + var index: Int = arr.size - 1 + x = arr[index] + j = index - 1 + while (j > 0 && arr[j] > x) { + arr[j + 1] = arr[j] + j -= 1 + } + arr[j + 1] = x + } + + private fun ArrayList.binarySearch(ID: Long): Int { + // code from collections/Collections.kt + var low = 0 + var high = factionContainer.size - 1 + + while (low <= high) { + val mid = (low + high).ushr(1) // safe from overflows + val midVal = get(mid) + + if (ID > midVal.referenceID) + low = mid + 1 + else if (ID < midVal.referenceID) + high = mid - 1 + else + return mid // key found + } + return -(low + 1) // key not found + } +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt b/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt index 10f88a208..f3baeba5f 100644 --- a/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt +++ b/src/net/torvald/terrarum/gameactors/faction/FactionFactory.kt @@ -20,7 +20,6 @@ object FactionFactory { val jsonObj = JsonFetcher.readJson(JSONPATH + filename) val factionObj = Faction(jsonObj.get("factionname").asString) - jsonObj.get("factionamicable").asJsonArray.forEach { s -> factionObj.addFactionAmicable(s.asString) } jsonObj.get("factionneutral").asJsonArray.forEach { s -> factionObj.addFactionNeutral(s.asString) } jsonObj.get("factionhostile").asJsonArray.forEach { s -> factionObj.addFactionHostile(s.asString) } diff --git a/src/net/torvald/terrarum/gamemap/MapLayer.kt b/src/net/torvald/terrarum/gamemap/MapLayer.kt index 33665093b..3e6469436 100644 --- a/src/net/torvald/terrarum/gamemap/MapLayer.kt +++ b/src/net/torvald/terrarum/gamemap/MapLayer.kt @@ -50,7 +50,7 @@ class MapLayer(var width: Int, var height: Int) : Iterable { private fun uint8ToInt32(x: Byte): Int = java.lang.Byte.toUnsignedInt(x) companion object { - @Transient val RANGE = 256 + @Transient const val RANGE = 256 } } diff --git a/src/net/torvald/terrarum/gamemap/PairedMapLayer.kt b/src/net/torvald/terrarum/gamemap/PairedMapLayer.kt index 027192736..f12973e8f 100644 --- a/src/net/torvald/terrarum/gamemap/PairedMapLayer.kt +++ b/src/net/torvald/terrarum/gamemap/PairedMapLayer.kt @@ -81,6 +81,6 @@ class PairedMapLayer(width: Int, var height: Int) : Iterable { companion object { - @Transient val RANGE = 16 + @Transient const val RANGE = 16 } } diff --git a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt index cffa67723..4e07339b5 100644 --- a/src/net/torvald/terrarum/mapdrawer/MapCamera.kt +++ b/src/net/torvald/terrarum/mapdrawer/MapCamera.kt @@ -95,6 +95,7 @@ object MapCamera { , TileNameCode.SANDSTONE_RED , TileNameCode.SANDSTONE_WHITE , TileNameCode.SANDSTONE_GREEN + , TileNameCode.DAYLIGHT_CAPACITOR ) /** diff --git a/src/net/torvald/terrarum/realestate/RealEstateUtility.kt b/src/net/torvald/terrarum/realestate/RealEstateUtility.kt index 3849b0eb4..34176eff1 100644 --- a/src/net/torvald/terrarum/realestate/RealEstateUtility.kt +++ b/src/net/torvald/terrarum/realestate/RealEstateUtility.kt @@ -1,6 +1,7 @@ package net.torvald.terrarum.realestate import net.torvald.terrarum.Terrarum +import net.torvald.terrarum.gameactors.faction.FactionCodex /** * Created by minjaesong on 16-03-27. @@ -11,4 +12,13 @@ object RealEstateUtility { fun resolveAbsoluteTileNumber(t: Long): Pair = Pair((t % Terrarum.game.map.width).toInt(), (t / Terrarum.game.map.width).toInt()) + + /** + * Get owner ID as an Actor/Faction + */ + fun resolveOwner(id: Long): Any = + if (id < 0x80000000L) + Terrarum.game.getActorByID(id.toInt()) + else + FactionCodex.getFactionByID(id) } \ No newline at end of file diff --git a/src/net/torvald/terrarum/tileproperties/TilePropCodex.kt b/src/net/torvald/terrarum/tileproperties/TilePropCodex.kt index 0a993440e..95f93a87c 100644 --- a/src/net/torvald/terrarum/tileproperties/TilePropCodex.kt +++ b/src/net/torvald/terrarum/tileproperties/TilePropCodex.kt @@ -13,7 +13,7 @@ import java.io.IOException class TilePropCodex { init { - tileProps = Array(MapLayer.RANGE * PairedMapLayer.RANGE + 1, + tileProps = Array(TILE_UNIQUE_MAX + 1, {i -> TileProp() } ) @@ -44,6 +44,8 @@ class TilePropCodex { val CSV_PATH = "./src/net/torvald/terrarum/tileproperties/tileprop.csv" + const val TILE_UNIQUE_MAX = MapLayer.RANGE * PairedMapLayer.RANGE + fun getProp(index: Int, damage: Int): TileProp { try { tileProps[idDamageToIndex(index, damage)].id diff --git a/src/net/torvald/terrarum/tileproperties/tileprop.csv b/src/net/torvald/terrarum/tileproperties/tileprop.csv index be11fb108..5a26fece9 100644 --- a/src/net/torvald/terrarum/tileproperties/tileprop.csv +++ b/src/net/torvald/terrarum/tileproperties/tileprop.csv @@ -45,7 +45,7 @@ "11"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "81916159"; "11"; "1"; "0";"16" "12"; "0";"TILE_TORCH" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "11"; "0"; "0";"16" "12"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "0"; "11"; "1"; "0";"16" - "13"; "0";"TILE_ILLUMINATOR_WHITE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246656235"; "13"; "0"; "0";"16" + "13"; "0";"TILE_ILLUMINATOR_WHITE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "248768744"; "13"; "0"; "0";"16" "13"; "1";"TILE_ILLUMINATOR_YELLOW" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246656000"; "13"; "1"; "0";"16" "13"; "2";"TILE_ILLUMINATOR_ORANGE" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246602752"; "13"; "2"; "0";"16" "13"; "3";"TILE_ILLUMINATOR_RED" ; "8396808"; "0"; "N/A"; "0"; "1"; "1"; "246415360"; "13"; "3"; "0";"16" @@ -119,23 +119,30 @@ "255"; "14";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16" "255"; "15";"TILE_WATER" ; "27282445"; "100";"1000"; "1"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16" "256"; "0";"TILE_NULL" ; "0"; "-1";"2600"; "0"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16" +## Notes ## + # Friction: 0: frictionless, <16: slippery, 16: regular, >16: sticky # Opacity/Lumcolor: 40-step RGB # Solid: whether the tile has full collision # movr: Movement resistance, (walkspeedmax) / (1 + (n/16)), 16 halves movement speed # dsty: density. As we are putting water an 1000, it is identical to specific gravity. [g/l] -# Sunstone: Artificial sunlight, change colour over time in sync with sunlight -# Sunlight capacitor: daylight at 11h of 22h day +## Illuminants ## + +# Illuminant white: RGB(237,250,232), simulation of mercury-vapour lamp (If you want high CRI lamp, collect a daylight!) # Defalut torch : L 70 a 51 b 59; real candlelight colour taken from properly configured camera. +# Sunstone: Artificial sunlight, change colour over time in sync with sunlight. Set by game's code. +# Sunlight capacitor: daylight at 11h of 22h day. Set by game's code. + + +## Tiles ## # 16 colour palette : Old Apple Macintosh 16-colour palette - # Magical ice: theoretical __metallic__ ice that might form under super-high pressure (> 5 TPa). Its density is a wild guess. -# Off illuminator: NO OPACITY! this is intended! -# References: +## References ## + # * Density of various woods : http://www.engineeringtoolbox.com/wood-density-d_40.html # * Density of various phases of ice : http://www1.lsbu.ac.uk/water/ice_phases.html \ No newline at end of file