newton's law-compliant physics simulator for ActorWithBody, which would make implementing fluid resistance simulation easier job. Player's stop will now be processed by this phys simulator.

Former-commit-id: d9767dc54f8eaea7bbb4886fdad5ef38bab4c933
Former-commit-id: 74b7ea76c5d04272474b68760ad3958e715fe551
This commit is contained in:
Song Minjae
2016-04-26 01:15:53 +09:00
parent 519ecec774
commit 6ae31f1858
6 changed files with 116 additions and 185 deletions

View File

@@ -151,7 +151,9 @@ constructor() : BasicGameState() {
// determine whether the actor should be active or dormant
// also updates active actors
inactivateDistantActors(gc, delta)
updateAndInactivateDistantActors(gc, delta)
CollisionSolver.process()
uiContainer.forEach { ui -> ui.update(gc, delta) }
consoleHandler.update(gc, delta)
@@ -327,7 +329,7 @@ constructor() : BasicGameState() {
}
}
fun inactivateDistantActors(gc: GameContainer, delta: Int) {
fun updateAndInactivateDistantActors(gc: GameContainer, delta: Int) {
var actorContainerSize = actorContainer.size
var i = 0
// determine whether the actor should be active or dormant by its distance from the player

View File

@@ -106,7 +106,6 @@ open class ActorWithBody constructor() : Actor(), Visible {
@Transient private val UD_COMPENSATOR_MAX = TSIZE
@Transient private val LR_COMPENSATOR_MAX = TSIZE
@Transient private val TILE_AUTOCLIMB_RATE = 4
/**
* A constant to make falling faster so that the game is more playable
@@ -136,6 +135,8 @@ open class ActorWithBody constructor() : Actor(), Visible {
private var posAdjustX = 0
private var posAdjustY = 0
private val BASE_FRICTION = 0.3f
init {
map = Terrarum.game.map
}
@@ -211,9 +212,6 @@ open class ActorWithBody constructor() : Actor(), Visible {
// copy gravitational constant from the map the actor is in
gravitation = map.gravitation
// Auto climb rate. Clamp to TSIZE
AUTO_CLIMB_RATE = Math.min(TSIZE / 8 * FastMath.sqrt(scale), TSIZE.toFloat()).toInt()
// Actors are subject to the gravity and the buoyancy if they are not levitating
if (!isNoSubjectToGrav) {
applyGravitation()
@@ -234,8 +232,10 @@ open class ActorWithBody constructor() : Actor(), Visible {
//}
//else {
// compensate for colliding
updateHorizontalPos()
updateVerticalPos()
updateHorizontalCollision()
updateVerticalCollision()
setHorizontalFriction()
//}
// apply our compensation to actual hitbox
@@ -274,7 +274,19 @@ open class ActorWithBody constructor() : Actor(), Visible {
}
}
private fun updateVerticalPos() {
private fun setHorizontalFriction() {
val friction = BASE_FRICTION * (tileFriction / 16f) // ground frction * !@#$!@#$ // default val: 0.3
if (veloX < 0) {
veloX += friction
if (veloX > 0) veloX = 0f
}
else if (veloX > 0) {
veloX -= friction
if (veloX < 0) veloX = 0f
}
}
private fun updateVerticalCollision() {
if (!isNoCollideWorld) {
if (veloY >= 0) { // check downward
if (isColliding(CONTACT_AREA_BOTTOM)) { // the ground has dug into the body
@@ -347,7 +359,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
nextHitbox.setPosition(newX, newY)
}
private fun updateHorizontalPos() {
private fun updateHorizontalCollision() {
if (!isNoCollideWorld) {
if (veloX >= 0.5) { // check right
if (isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT)) {
@@ -555,17 +567,15 @@ open class ActorWithBody constructor() : Actor(), Visible {
get() {
var friction = 0
//get highest fluid density
val tilePosXStart = (nextHitbox.posX / TSIZE).roundToInt()
val tilePosXEnd = (nextHitbox.hitboxEnd.x / TSIZE).roundToInt()
val tilePosY = (nextHitbox.pointedY / TSIZE).roundToInt()
//get highest friction
val tilePosXStart = (hitbox.posX / TSIZE).roundToInt()
val tilePosXEnd = (hitbox.hitboxEnd.x / TSIZE).roundToInt()
val tilePosY = (hitbox.pointedY.plus(1) / TSIZE).roundToInt()
for (x in tilePosXStart..tilePosXEnd) {
val tile = map.getTileFromTerrain(x, tilePosY)
if (TilePropCodex.getProp(tile).isFluid) {
val thisFluidDensity = TilePropCodex.getProp(tile).friction
val thisFriction = TilePropCodex.getProp(tile).friction
if (thisFluidDensity > friction) friction = thisFluidDensity
}
if (thisFriction > friction) friction = thisFriction
}
return friction
@@ -615,13 +625,11 @@ open class ActorWithBody constructor() : Actor(), Visible {
private fun updateNextHitboxFromVelo() {
nextHitbox.set(
(hitbox.posX + veloX).round()
, (hitbox.posY + veloY).round()
, (baseHitboxW * scale).round()
, (baseHitboxH * scale).round()
(hitbox.posX + veloX)
, (hitbox.posY + veloY)
, (baseHitboxW * scale)
, (baseHitboxH * scale)
)
/** Full quantisation; wonder what havoc these statements would wreak...
*/
}
private fun updateHitboxX() {
@@ -712,6 +720,9 @@ open class ActorWithBody constructor() : Actor(), Visible {
this.density = density.toFloat()
}
private val AUTO_CLIMB_RATE: Int
get() = Math.min(TSIZE / 8 * FastMath.sqrt(scale), TSIZE.toFloat()).toInt()
fun Float.round() = Math.round(this).toFloat()
fun Float.roundToInt(): Int = Math.round(this)
fun Float.abs() = FastMath.abs(this)
@@ -720,7 +731,6 @@ open class ActorWithBody constructor() : Actor(), Visible {
companion object {
@Transient private val TSIZE = MapDrawer.TILE_SIZE
private var AUTO_CLIMB_RATE = TSIZE / 8
private fun div16TruncateToMapWidth(x: Int): Int {
if (x < 0)

View File

@@ -21,45 +21,93 @@ object CollisionSolver {
private val collCandidateX = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_CANDIDATES_SIZE)
private val collCandidateY = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_CANDIDATES_SIZE)
private val collCandidates = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_FINAL_CANDIDATES_SIZE)
private var collCandidates = ArrayList<Pair<ActorWithBody, ActorWithBody>>(COLL_FINAL_CANDIDATES_SIZE)
private val collCandidateStack = Stack<CollisionMarkings>()
/**
* @link https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects
*/
fun process() {
// clean up before we go
collListX.clear()
collListY.clear()
collCandidateX.clear()
collCandidateY.clear()
// mark list x
Terrarum.game.actorContainer.forEach { it ->
if (it is ActorWithBody) {
collListX.add(CollisionMarkings(it.hitbox.hitboxStart.x, STARTPOINT, it.referenceID))
collListX.add(CollisionMarkings(it.hitbox.hitboxEnd.x, ENDPOINT, it.referenceID))
collListX.add(CollisionMarkings(it.hitbox.hitboxStart.x, STARTPOINT, it))
collListX.add(CollisionMarkings(it.hitbox.hitboxEnd.x, ENDPOINT, it))
}
}
// sort list x
collListX.sortBy { it.pos }
// set candidateX
for (it in collListX) {
if (it.kind == STARTPOINT) {
collCandidateStack.push(it)
}
else if (it.kind == ENDPOINT) {
val mark_this = it
val mark_other = collCandidateStack.pop()
val collCandidate: Pair<ActorWithBody, ActorWithBody>
if (mark_this < mark_other) // make sure actor with lower pos comes left
collCandidate = Pair(mark_this.actor, mark_other.actor)
else
collCandidate = Pair(mark_other.actor, mark_this.actor)
collCandidateX.add(collCandidate)
}
}
collCandidateStack.clear()
// mark list y
Terrarum.game.actorContainer.forEach { it ->
if (it is ActorWithBody) {
collListY.add(CollisionMarkings(it.hitbox.hitboxStart.y, STARTPOINT, it.referenceID))
collListY.add(CollisionMarkings(it.hitbox.hitboxEnd.y, ENDPOINT, it.referenceID))
collListY.add(CollisionMarkings(it.hitbox.hitboxStart.y, STARTPOINT, it))
collListY.add(CollisionMarkings(it.hitbox.hitboxEnd.y, ENDPOINT, it))
}
}
// sort list y
collListY.sortBy { it.pos }
// set candidateY
for (it in collListY) {
if (it.kind == STARTPOINT) {
collCandidateStack.push(it)
}
else if (it.kind == ENDPOINT) {
val mark_this = it
val mark_other = collCandidateStack.pop()
val collCandidate: Pair<ActorWithBody, ActorWithBody>
if (mark_this < mark_other) // make sure actor with lower pos comes left
collCandidate = Pair(mark_this.actor, mark_other.actor)
else
collCandidate = Pair(mark_other.actor, mark_this.actor)
collCandidateY.add(collCandidate)
}
}
// look for overlaps in candidate X/Y and put them into collCandidates
// overlapping in X and Y means they are actually overlapping physically
collCandidateY.retainAll(collCandidateX) // list Y will have intersection of X and Y now
collCandidates = collCandidateY // renaming. X and Y won't be used anyway.
// solve collision for actors in collCandidates
collCandidates.forEach { solveCollision(it.first, it.second) }
}
private fun solveCollision(a: ActorWithBody, b: ActorWithBody) {
// some of the Pair(a, b) are either duplicates or erroneously reported.
// e.g. (A, B), (B, C) and then (A, C);
// in some situation (A, C) will not making any contact with each other
// we are going to filter them
if (a isCollidingWith b) {
}
}
private infix fun ActorWithBody.isCollidingWith(other: ActorWithBody): Boolean {
@@ -90,11 +138,16 @@ object CollisionSolver {
fun Float.abs() = if (this < 0) -this else this
fun Float.sqr() = this * this
data class CollisionMarkings(
class CollisionMarkings(
val pos: Float,
val kind: Int,
val actorID: Int
)
val actor: ActorWithBody
) : Comparable<CollisionMarkings> {
override fun compareTo(other: CollisionMarkings): Int =
if (this.pos > other.pos) 1
else if (this.pos < other.pos) -1
else 0
}
/**
* === Some useful physics knowledge ===

View File

@@ -23,7 +23,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
/**
* empirical value.
*/
// private transient final float JUMP_ACCELERATION_MOD = ???f / 10000f; //quadratic mode
@Transient private val JUMP_ACCELERATION_MOD = 170f / 10000f //linear mode
@Transient private val WALK_FRAMES_TO_MAX_ACCEL = 6
@@ -75,9 +74,8 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
}
companion object {
@Transient internal const val ACCEL_MULT_IN_FLIGHT = 0.48f
@Transient internal const val WALK_STOP_ACCEL = 0.32f
@Transient internal const val WALK_ACCEL_BASE = 0.32f
@Transient internal const val ACCEL_MULT_IN_FLIGHT = 0.31f
@Transient internal const val WALK_ACCEL_BASE = 0.67f
@Transient const val PLAYER_REF_ID: Int = 0x51621D
@Transient const val BASE_HEIGHT = 40
@@ -202,8 +200,9 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
return 0.5f + 0.5f * -FastMath.cos(10 * x / (WALK_FRAMES_TO_MAX_ACCEL * FastMath.PI))
}
// stops; let the friction kick in by doing nothing to the velocity here
private fun walkHStop() {
if (veloX > 0) {
/*if (veloX > 0) {
veloX -= actorValue.getAsFloat(AVKey.ACCEL)!! *
actorValue.getAsFloat(AVKey.ACCELMULT)!! *
FastMath.sqrt(scale)
@@ -219,13 +218,16 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
if (veloX > 0) veloX = 0f
} else {
veloX = 0f
}
}*/
//veloX = 0f
walkPowerCounter = 0
}
// stops; let the friction kick in by doing nothing to the velocity here
private fun walkVStop() {
if (veloY > 0) {
/*if (veloY > 0) {
veloY -= WALK_STOP_ACCEL *
actorValue.getAsFloat(AVKey.ACCELMULT)!! *
FastMath.sqrt(scale)
@@ -242,7 +244,9 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
if (veloY > 0) veloY = 0f
} else {
veloY = 0f
}
}*/
///veloY = 0f
walkPowerCounter = 0
}
@@ -250,12 +254,12 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
private fun updateMovementControl() {
if (!noClip) {
if (grounded) {
actorValue.set(AVKey.ACCELMULT, 1f)
actorValue[AVKey.ACCELMULT] = 1f
} else {
actorValue.set(AVKey.ACCELMULT, ACCEL_MULT_IN_FLIGHT)
actorValue[AVKey.ACCELMULT] = ACCEL_MULT_IN_FLIGHT
}
} else {
actorValue.set(AVKey.ACCELMULT, 1f)
actorValue[AVKey.ACCELMULT] = 1f
}
}
@@ -412,8 +416,6 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
val jumpAcc = pwr * timedJumpCharge * JUMP_ACCELERATION_MOD * FastMath.sqrt(scale)
veloY -= jumpAcc
// try concave mode?
}
// for mob ai:

View File

@@ -1,5 +1,5 @@
"id";"dmg";"name" ; "opacity";"strength";"dsty";"fluid";"movr";"solid";"wall"; "lumcolor";"drop";"ddmg";"fall";"friction"
"0"; "0";"TILE_AIR" ; "8396808"; "0"; "1"; "0"; "0"; "0"; "0"; "0"; "0"; "0"; "0";"16"
"0"; "0";"TILE_AIR" ; "8396808"; "0"; "1"; "0"; "0"; "0"; "0"; "0"; "0"; "0"; "0";"4"
"1"; "0";"TILE_STONE" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "1"; "0"; "1"; "0"; "0";"16"
"1"; "1";"TILE_STONE_QUARRIED" ; "33587232"; "25";"2400"; "0"; "0"; "1"; "1"; "0"; "1"; "1"; "0";"16"
"2"; "0";"TILE_DIRT" ; "33587232"; "6";"1400"; "0"; "0"; "1"; "1"; "0"; "2"; "0"; "0";"16"
Can't render this file because it contains an unexpected character in line 1 and column 18.

View File

@@ -1,136 +0,0 @@
"id";"dmg";"name" ;"opacity";"strength";"dsty";"fluid";"movr";"solid";"wall";"lumcolor";"drop";"ddmg";"fall";"friction"
"0"; "0";"TILE_AIR" ; "526344"; "0"; "1"; "0"; "0"; "0"; "0"; "0"; "0"; "0"; "0";"16"
"1"; "0";"TILE_STONE" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "1"; "0"; "1"; "0"; "0";"16"
"1"; "1";"TILE_STONE_QUARRIED" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "1"; "0"; "1"; "1"; "0";"16"
"2"; "0";"TILE_DIRT" ;"2105376"; "6";"1400"; "0"; "0"; "1"; "1"; "0"; "2"; "0"; "0";"16"
"2"; "1";"TILE_GRASS" ;"2105376"; "6";"1400"; "0"; "0"; "1"; "1"; "0"; "2"; "1"; "0";"16"
"3"; "0";"TILE_PLANK_NORMAL" ;"2105376"; "12"; "740"; "0"; "0"; "1"; "1"; "0"; "3"; "0"; "0";"16"
"3"; "1";"TILE_PLANK_EBONY" ;"2105376"; "12";"1200"; "0"; "0"; "1"; "1"; "0"; "3"; "1"; "0";"16"
"3"; "2";"TILE_PLANK_BIRCH" ;"2105376"; "12"; "670"; "0"; "0"; "1"; "1"; "0"; "3"; "2"; "0";"16"
"3"; "3";"TILE_PLANK_BLOODROSE" ;"2105376"; "12"; "900"; "0"; "0"; "1"; "1"; "0"; "3"; "3"; "0";"16"
"4"; "0";"TILE_TRUNK_NORMAL" ;"2105376"; "12"; "740"; "0"; "0"; "1"; "0"; "0"; "3"; "0"; "0";"16"
"4"; "1";"TILE_TRUNK_EBONY" ;"2105376"; "12";"1200"; "0"; "0"; "1"; "0"; "0"; "3"; "1"; "0";"16"
"4"; "2";"TILE_TRUNK_BIRCH" ;"2105376"; "12"; "670"; "0"; "0"; "1"; "0"; "0"; "3"; "2"; "0";"16"
"4"; "3";"TILE_TRUNK_BLOODROSE" ;"2105376"; "12"; "900"; "0"; "0"; "1"; "0"; "0"; "3"; "3"; "0";"16"
"5"; "0";"TILE_SAND" ;"2105376"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "0"; "1";"16"
"5"; "1";"TILE_SAND_WHITE" ;"2105376"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "1"; "1";"16"
"5"; "2";"TILE_SAND_RED" ;"2105376"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "2"; "1";"16"
"5"; "3";"TILE_SAND_DESERT" ;"2105376"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "3"; "1";"16"
"5"; "4";"TILE_SAND_BLACK" ;"2105376"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "4"; "1";"16"
"5"; "5";"TILE_SAND_GREEN" ;"2105376"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "5"; "5"; "1";"16"
"6"; "0";"TILE_GRAVEL" ;"2105376"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "6"; "0"; "1";"16"
"6"; "1";"TILE_GRAVEL_GREY" ;"2105376"; "6";"2400"; "0"; "0"; "1"; "0"; "0"; "6"; "1"; "1";"16"
"7"; "0";"TILE_ORE_MALACHITE" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "0"; "0";"16"
"7"; "1";"TILE_ORE_HEMATITE" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "1"; "0";"16"
"7"; "2";"TILE_ORE_NATURAL_GOLD" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "2"; "0";"16"
"7"; "3";"TILE_ORE_NATURAL_SILVER" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "3"; "0";"16"
"7"; "4";"TILE_ORE_RUTILE" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "4"; "0";"16"
"7"; "5";"TILE_ORE_AURICHALCUMITE" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "7"; "5"; "0";"16"
"8"; "0";"TILE_GEM_RUBY" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "0"; "0";"16"
"8"; "1";"TILE_GEM_EMERALD" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "1"; "0";"16"
"8"; "2";"TILE_GEM_SAPPHIRE" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "2"; "0";"16"
"8"; "3";"TILE_GEM_TOPAZ" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "3"; "0";"16"
"8"; "4";"TILE_GEM_DIAMOND" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "4"; "0";"16"
"8"; "5";"TILE_GEM_AMETHYST" ;"2105376"; "25";"2400"; "0"; "0"; "1"; "0"; "0"; "8"; "5"; "0";"16"
"9"; "0";"TILE_SNOW" ;"2105376"; "6"; "500"; "0"; "0"; "1"; "1"; "0"; "9"; "0"; "0";"16"
"9"; "1";"TILE_ICE_FRAGILE" ; "855309"; "1"; "930"; "0"; "0"; "1"; "0"; "0"; "9"; "1"; "0";"16"
"9"; "2";"TILE_ICE_NATURAL" ;"1710618"; "25"; "930"; "0"; "0"; "1"; "1"; "0"; "9"; "2"; "0"; "8"
"9"; "3";"TILE_ICE_CLEAR_MAGICAL" ;"2105376"; "25";"3720"; "0"; "0"; "1"; "1"; "1253434"; "9"; "3"; "0"; "8"
"10"; "0";"TILE_PLATFORM_STONE" ; "526344"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "0"; "0";"16"
"10"; "1";"TILE_PLATFORM_WOODEN" ; "526344"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "1"; "0";"16"
"10"; "2";"TILE_PLATFORM_EBONY" ; "526344"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "2"; "0";"16"
"10"; "3";"TILE_PLATFORM_BIRCH" ; "526344"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "3"; "0";"16"
"10"; "4";"TILE_PLATFORM_BLOODROSE" ; "526344"; "1"; "N/A"; "0"; "0"; "0"; "0"; "0"; "10"; "4"; "0";"16"
"11"; "0";"TILE_TORCH" ; "526344"; "0"; "N/A"; "0"; "0"; "0"; "0";"15304000"; "11"; "0"; "0";"16"
"11"; "1";"TILE_TORCH_FROST" ; "526344"; "0"; "N/A"; "0"; "0"; "0"; "0"; "5143807"; "11"; "1"; "0";"16"
"12"; "0";"TILE_TORCH" ; "526344"; "0"; "N/A"; "0"; "0"; "0"; "0"; "0"; "11"; "0"; "0";"16"
"12"; "1";"TILE_TORCH_FROST" ; "526344"; "0"; "N/A"; "0"; "0"; "0"; "0"; "0"; "11"; "1"; "0";"16"
"13"; "0";"TILE_ILLUMINATOR_WHITE" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1";"15461355"; "13"; "0"; "0";"16"
"13"; "1";"TILE_ILLUMINATOR_YELLOW" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1";"15461120"; "13"; "1"; "0";"16"
"13"; "2";"TILE_ILLUMINATOR_ORANGE" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1";"15447808"; "13"; "2"; "0";"16"
"13"; "3";"TILE_ILLUMINATOR_RED" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1";"15400960"; "13"; "3"; "0";"16"
"13"; "4";"TILE_ILLUMINATOR_FUCHSIA" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1";"15401143"; "13"; "4"; "0";"16"
"13"; "5";"TILE_ILLUMINATOR_PURPLE" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1";"11993323"; "13"; "5"; "0";"16"
"13"; "6";"TILE_ILLUMINATOR_BLUE" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "235"; "13"; "6"; "0";"16"
"13"; "7";"TILE_ILLUMINATOR_CYAN" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "51947"; "13"; "7"; "0";"16"
"13"; "8";"TILE_ILLUMINATOR_GREEN" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "4311552"; "13"; "8"; "0";"16"
"13"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "2123776"; "13"; "9"; "0";"16"
"13"; "10";"TILE_ILLUMINATOR_BROWN" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "5578752"; "13"; "10"; "0";"16"
"13"; "11";"TILE_ILLUMINATOR_TAN" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "9857076"; "13"; "11"; "0";"16"
"13"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"526344"; "0"; "N/A"; "0"; "0"; "1"; "1";"12434877"; "13"; "12"; "0";"16"
"13"; "13";"TILE_ILLUMINATOR_GREY_MED"; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "7697781"; "13"; "13"; "0";"16"
"13"; "14";"TILE_ILLUMINATOR_GREY_DARK";"526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "4276545"; "13"; "14"; "0";"16"
"13"; "15";"TILE_ILLUMINATOR_BLACK" ; "526344"; "0"; "N/A"; "0"; "0"; "1"; "1"; "7274751"; "13"; "15"; "0";"16"
"14"; "0";"TILE_ILLUMINATOR_WHITE" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "0"; "0";"16"
"14"; "1";"TILE_ILLUMINATOR_YELLOW" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "1"; "0";"16"
"14"; "2";"TILE_ILLUMINATOR_ORANGE" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "2"; "0";"16"
"14"; "3";"TILE_ILLUMINATOR_RED" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "3"; "0";"16"
"14"; "4";"TILE_ILLUMINATOR_FUCHSIA" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "4"; "0";"16"
"14"; "5";"TILE_ILLUMINATOR_PURPLE" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "5"; "0";"16"
"14"; "6";"TILE_ILLUMINATOR_BLUE" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "6"; "0";"16"
"14"; "7";"TILE_ILLUMINATOR_CYAN" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "7"; "0";"16"
"14"; "8";"TILE_ILLUMINATOR_GREEN" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "8"; "0";"16"
"14"; "9";"TILE_ILLUMINATOR_GREEN_DARK";"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "9"; "0";"16"
"14"; "10";"TILE_ILLUMINATOR_BROWN" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "10"; "0";"16"
"14"; "11";"TILE_ILLUMINATOR_TAN" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "11"; "0";"16"
"14"; "12";"TILE_ILLUMINATOR_GREY_LIGHT";"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "12"; "0";"16"
"14"; "13";"TILE_ILLUMINATOR_GREY_MED";"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "13"; "0";"16"
"14"; "14";"TILE_ILLUMINATOR_GREY_DARK";"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "14"; "0";"16"
"14"; "15";"TILE_ILLUMINATOR_BLACK" ;"2105376"; "0"; "N/A"; "0"; "0"; "1"; "1"; "0"; "13"; "15"; "0";"16"
"15"; "0";"TILE_SANDSTONE" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "0"; "0";"16"
"15"; "1";"TILE_SANDSTONE_WHITE" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "1"; "0";"16"
"15"; "2";"TILE_SANDSTONE_RED" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "2"; "0";"16"
"15"; "3";"TILE_SANDSTONE_DESERT" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "3"; "0";"16"
"15"; "4";"TILE_SANDSTONE_BLACK" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "4"; "0";"16"
"15"; "5";"TILE_SANDSTONE_BLACK" ;"2105376"; "25";"1900"; "0"; "0"; "1"; "1"; "0"; "15"; "5"; "0";"16"
"16"; "0";"TILE_LANTERN_IRON_REGULAR"; "526344"; "0"; "N/A"; "0"; "0"; "0"; "0";"16769944"; "16"; "0"; "0";"16"
"255"; "0";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "1";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "2";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "3";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "4";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "5";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "6";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "7";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "8";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "9";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "10";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "11";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "12";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "13";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "14";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"255"; "15";"TILE_WATER" ;"1708813"; "100";"1000"; "1"; "12"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
"254"; "0";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "1";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "2";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "3";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "4";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "5";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "6";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "7";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "8";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "9";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "10";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "11";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "12";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "13";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "14";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"254"; "15";"TILE_LAVA" ;"16316664"; "100";"2600"; "1"; "48"; "0"; "0";"12858368"; "N/A"; "N/A"; "0";"16"
"256"; "0";"TILE_NULL" ; "0"; "-1";"2600"; "0"; "0"; "0"; "0"; "0"; "N/A"; "N/A"; "0";"16"
# 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]
# Defalut torch : L 77 a 47 b 59; real candlelight colour taken from properly configured camera.
# 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:
# * 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
Can't render this file because it contains an unexpected character in line 1 and column 18.