From 46a3065423c83a38af743bc5dcf12f08f94c8425 Mon Sep 17 00:00:00 2001 From: Song Minjae Date: Fri, 13 May 2016 20:17:31 +0900 Subject: [PATCH] no idea Former-commit-id: 9738d12e5a468b71142745fbf0ce02fcf1ca623c Former-commit-id: a26b80a1990996d9c05b0909128c210e0f897312 --- Known problems.md | 3 + res/graphics/terrain/terrain.png | Bin 355090 -> 355246 bytes src/net/torvald/terrarum/Game.kt | 5 +- src/net/torvald/terrarum/REFERENCING.md | 6 ++ src/net/torvald/terrarum/gameactors/Actor.kt | 12 +-- .../terrarum/gameactors/ActorWithBody.kt | 74 ++++++++++++++---- .../terrarum/gameactors/DroppedItem.kt | 2 +- src/net/torvald/terrarum/gameactors/Player.kt | 44 ++++++----- .../terrarum/gameactors/faction/Faction.kt | 23 ++++-- .../gameactors/faction/FactionCodex.kt | 66 ++++++++++++++++ .../gameactors/faction/FactionFactory.kt | 1 - src/net/torvald/terrarum/gamemap/MapLayer.kt | 2 +- .../terrarum/gamemap/PairedMapLayer.kt | 2 +- .../torvald/terrarum/mapdrawer/MapCamera.kt | 1 + .../terrarum/realestate/RealEstateUtility.kt | 10 +++ .../terrarum/tileproperties/TilePropCodex.kt | 4 +- .../terrarum/tileproperties/tileprop.csv | 19 +++-- 17 files changed, 211 insertions(+), 63 deletions(-) create mode 100644 src/net/torvald/terrarum/REFERENCING.md create mode 100644 src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt 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 026aecf9408279d27f0001315ee30146293e8bd7..477b6b02a8f57935973d744f96affebd4aed89e0 100644 GIT binary patch delta 44062 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 delta 44639 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 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