mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
no idea
Former-commit-id: 9738d12e5a468b71142745fbf0ce02fcf1ca623c Former-commit-id: a26b80a1990996d9c05b0909128c210e0f897312
This commit is contained in:
@@ -8,6 +8,9 @@
|
|||||||
### Physics ###
|
### Physics ###
|
||||||
|
|
||||||
|
|
||||||
|
### System ###
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Resolved #
|
# Resolved #
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 347 KiB After Width: | Height: | Size: 347 KiB |
@@ -416,12 +416,11 @@ constructor() : BasicGameState() {
|
|||||||
/**
|
/**
|
||||||
* Check for duplicates, append actor and sort the list
|
* Check for duplicates, append actor and sort the list
|
||||||
*/
|
*/
|
||||||
fun addActor(actor: Actor): Boolean {
|
fun addActor(actor: Actor) {
|
||||||
if (hasActor(actor.referenceID))
|
if (hasActor(actor.referenceID))
|
||||||
throw RuntimeException("Actor with ID ${actor.referenceID} already exists.")
|
throw RuntimeException("Actor with ID ${actor.referenceID} already exists.")
|
||||||
actorContainer.add(actor)
|
actorContainer.add(actor)
|
||||||
insertionSortLastElem(actorContainer) // we can do this as we are only adding single 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
|
var index: Int = arr.size - 1
|
||||||
x = arr[index]
|
x = arr[index]
|
||||||
j = index - 1
|
j = index - 1
|
||||||
while (j > 0 && arr[j].referenceID > x.referenceID) {
|
while (j > 0 && arr[j] > x) {
|
||||||
arr[j + 1] = arr[j]
|
arr[j + 1] = arr[j]
|
||||||
j -= 1
|
j -= 1
|
||||||
}
|
}
|
||||||
|
|||||||
6
src/net/torvald/terrarum/REFERENCING.md
Normal file
6
src/net/torvald/terrarum/REFERENCING.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|Range|Description|
|
||||||
|
|-----|-----------|
|
||||||
|
|0..4095|Tiles|
|
||||||
|
|4096..32767|Items|
|
||||||
|
|32768..0x7FFFFFFF|Actors|
|
||||||
|
|0x80000000L..0xFFFFFFFFL|Faction|
|
||||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.gameactors
|
|||||||
|
|
||||||
import net.torvald.random.HQRNG
|
import net.torvald.random.HQRNG
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
|
import net.torvald.terrarum.itemproperties.ItemPropCodex
|
||||||
import org.newdawn.slick.GameContainer
|
import org.newdawn.slick.GameContainer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,11 +22,13 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
|||||||
|
|
||||||
override fun equals(other: Any?) = referenceID == (other as Actor).referenceID
|
override fun equals(other: Any?) = referenceID == (other as Actor).referenceID
|
||||||
override fun hashCode() = 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()}"
|
"ID: ${hashCode()}"
|
||||||
else
|
else
|
||||||
"ID: ${hashCode()} (${actorValue.getAsString(AVKey.NAME)})"
|
"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:
|
* Usage:
|
||||||
@@ -33,11 +36,10 @@ abstract class Actor : Comparable<Actor>, Runnable {
|
|||||||
* override var referenceID: Int = generateUniqueReferenceID()
|
* override var referenceID: Int = generateUniqueReferenceID()
|
||||||
*/
|
*/
|
||||||
fun generateUniqueReferenceID(): Int {
|
fun generateUniqueReferenceID(): Int {
|
||||||
fun Int.abs() = if (this < 0) -this else this
|
|
||||||
var ret: Int
|
var ret: Int
|
||||||
do {
|
do {
|
||||||
ret = HQRNG().nextInt().abs() // set new ID
|
ret = HQRNG().nextInt().and(0x7FFFFFFF) // set new ID
|
||||||
} while (Terrarum.game.hasActor(ret)) // check for collision
|
} while (Terrarum.game.hasActor(ret) || ret < ItemPropCodex.ITEM_UNIQUE_MAX) // check for collision
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
actorValue[AVKey.BASEMASS] = value
|
actorValue[AVKey.BASEMASS] = value
|
||||||
}
|
}
|
||||||
/** Valid range: [0, 1] */
|
/** Valid range: [0, 1] */
|
||||||
var elasticity = 0.0
|
var elasticity: Double = 0.0
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value < 0)
|
if (value < 0)
|
||||||
throw IllegalArgumentException("[ActorWithBody] Invalid elasticity value: $value; valid elasticity value is [0, 1].")
|
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
|
field = value * ELASTICITY_MAX
|
||||||
}
|
}
|
||||||
@Transient private val ELASTICITY_MAX = 0.993 // No perpetual motion!
|
@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
|
private var density = 1000.0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,9 +187,11 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
@Transient val DYNAMIC = 2
|
@Transient val DYNAMIC = 2
|
||||||
@Transient val STATIC = 3
|
@Transient val STATIC = 3
|
||||||
|
|
||||||
private val SLEEP_THRE = 0.125
|
private val SLEEP_THRE = 1.0 / 16.0
|
||||||
private val CCD_THRE = 1.0
|
private val CCD_TICK = 1.0 / 16.0
|
||||||
private val CCD_TICK = 0.125
|
|
||||||
|
internal var walledLeft = false
|
||||||
|
internal var walledRight = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
@@ -297,6 +311,9 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
clampNextHitbox()
|
clampNextHitbox()
|
||||||
clampHitbox()
|
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 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)
|
val ccdDelta = delta.setMagnitude(CCD_TICK)
|
||||||
|
|
||||||
while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
|
if (ccdDelta.x.abs() >= SLEEP_THRE || ccdDelta.y.abs() >= SLEEP_THRE) { // regular situation
|
||||||
|| isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM)
|
// CCD to delta while still colliding
|
||||||
) {
|
while (isColliding(CONTACT_AREA_LEFT) || isColliding(CONTACT_AREA_RIGHT)
|
||||||
// while still colliding, CCD to the 'delta'
|
|| isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_BOTTOM)
|
||||||
nextHitbox.translate(ccdDelta)
|
) {
|
||||||
|
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() {
|
private fun applyNormalForce() {
|
||||||
if (!isNoCollideWorld) {
|
if (!isNoCollideWorld) {
|
||||||
// axis Y
|
// axis Y
|
||||||
if (veloY >= 0) { // check downward
|
if (moveDelta.y >= 0) { // check downward
|
||||||
if (isColliding(CONTACT_AREA_BOTTOM) || isColliding(CONTACT_AREA_BOTTOM, 0, 1)) {
|
if (isColliding(CONTACT_AREA_BOTTOM) || isColliding(CONTACT_AREA_BOTTOM, 0, 1)) {
|
||||||
// the actor is hitting the ground
|
// the actor is hitting the ground
|
||||||
//veloY = 0.0 // reset veloY, simulating normal force
|
|
||||||
hitAndReflectY()
|
hitAndReflectY()
|
||||||
grounded = true
|
grounded = true
|
||||||
}
|
}
|
||||||
@@ -557,33 +596,30 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
grounded = false
|
grounded = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (veloY < 0) { // check upward
|
else if (moveDelta.y < 0) { // check upward
|
||||||
grounded = false
|
grounded = false
|
||||||
if (isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_TOP, 0, -1)) {
|
if (isColliding(CONTACT_AREA_TOP) || isColliding(CONTACT_AREA_TOP, 0, -1)) {
|
||||||
// the actor is hitting the ceiling
|
// the actor is hitting the ceiling
|
||||||
//veloY = 0.0 // reset veloY, simulating normal force
|
|
||||||
hitAndReflectY()
|
hitAndReflectY()
|
||||||
}
|
}
|
||||||
else { // the actor is not grounded at all
|
else { // the actor is not grounded at all
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// axis X
|
// axis X
|
||||||
if (veloX >= 0.5) { // check right
|
if (moveDelta.x > 0) { // check right
|
||||||
if ((isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT))
|
if ((isColliding(CONTACT_AREA_RIGHT) && !isColliding(CONTACT_AREA_LEFT))
|
||||||
|| (isColliding(CONTACT_AREA_RIGHT, 1, 0) && !isColliding(CONTACT_AREA_LEFT, 0, -1))) {
|
|| (isColliding(CONTACT_AREA_RIGHT, 1, 0) && !isColliding(CONTACT_AREA_LEFT, 0, -1))) {
|
||||||
// the actor is hitting the right wall
|
// the actor is hitting the right wall
|
||||||
//veloX = 0.0 // reset veloX, simulating normal force
|
|
||||||
hitAndReflectX()
|
hitAndReflectX()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (veloX <= -0.5) { // check left
|
else if (moveDelta.x < 0) { // check left
|
||||||
// System.out.println("collidingleft");
|
// System.out.println("collidingleft");
|
||||||
if ((isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT))
|
if ((isColliding(CONTACT_AREA_LEFT) && !isColliding(CONTACT_AREA_RIGHT))
|
||||||
|| (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0))) {
|
|| (isColliding(CONTACT_AREA_LEFT, -1, 0) && !isColliding(CONTACT_AREA_RIGHT, 1, 0))) {
|
||||||
// the actor is hitting the left wall
|
// the actor is hitting the left wall
|
||||||
//veloX = 0.0 // reset veloX, simulating normal force
|
|
||||||
hitAndReflectX()
|
hitAndReflectX()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -597,18 +633,22 @@ open class ActorWithBody constructor() : Actor(), Visible {
|
|||||||
private fun hitAndReflectX() {
|
private fun hitAndReflectX() {
|
||||||
if ((veloX * elasticity).abs() > SLEEP_THRE) {
|
if ((veloX * elasticity).abs() > SLEEP_THRE) {
|
||||||
veloX *= -elasticity
|
veloX *= -elasticity
|
||||||
|
walkX *= -elasticity
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
veloX = 0.0
|
veloX = 0.0
|
||||||
|
walkX = 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hitAndReflectY() {
|
private fun hitAndReflectY() {
|
||||||
if ((veloY * elasticity).abs() > SLEEP_THRE) {
|
if ((veloY * elasticity).abs() > SLEEP_THRE) {
|
||||||
veloY *= -elasticity
|
veloY *= -elasticity
|
||||||
|
walkY *= -elasticity
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
veloY = 0.0
|
veloY = 0.0
|
||||||
|
walkY *= 0.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class DroppedItem constructor(itemID: Int) : ActorWithBody() {
|
|||||||
|
|
||||||
isVisible = true
|
isVisible = true
|
||||||
|
|
||||||
mass = if (itemID < 4096)
|
mass = if (itemID < TilePropCodex.TILE_UNIQUE_MAX)
|
||||||
TilePropCodex.getProp(itemID).density / 1000.0
|
TilePropCodex.getProp(itemID).density / 1000.0
|
||||||
else
|
else
|
||||||
ItemPropCodex.getProp(itemID).mass
|
ItemPropCodex.getProp(itemID).mass
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
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 internal const val WALK_ACCEL_BASE: Double = 0.67
|
||||||
|
|
||||||
@Transient const val PLAYER_REF_ID: Int = 0x51621D
|
@Transient const val PLAYER_REF_ID: Int = 0x51621D
|
||||||
@@ -130,33 +130,35 @@ class Player : ActorWithBody, Controllable, Pocketed, Factionable, Luminous, Lan
|
|||||||
* @author minjaesong
|
* @author minjaesong
|
||||||
*/
|
*/
|
||||||
private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
|
private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
|
||||||
readonly_totalX = //veloX +
|
if ((!walledLeft && left) || (!walledRight && !left)) {
|
||||||
/*actorValue.getAsDouble(AVKey.ACCEL)!! *
|
readonly_totalX = //veloX +
|
||||||
|
/*actorValue.getAsDouble(AVKey.ACCEL)!! *
|
||||||
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
|
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
|
||||||
Math.sqrt(scale) *
|
Math.sqrt(scale) *
|
||||||
applyAccelRealism(walkPowerCounter) *
|
applyAccelRealism(walkPowerCounter) *
|
||||||
(if (left) -1 else 1).toFloat() *
|
(if (left) -1 else 1).toFloat() *
|
||||||
absAxisVal*/
|
absAxisVal*/
|
||||||
actorValue.getAsDouble(AVKey.ACCEL)!! *
|
actorValue.getAsDouble(AVKey.ACCEL)!! *
|
||||||
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
|
actorValue.getAsDouble(AVKey.ACCELMULT)!! *
|
||||||
Math.sqrt(scale) *
|
Math.sqrt(scale) *
|
||||||
applyVelo(walkCounter) *
|
applyVelo(walkCounter) *
|
||||||
(if (left) -1 else 1).toFloat() *
|
(if (left) -1 else 1).toFloat() *
|
||||||
absAxisVal
|
absAxisVal
|
||||||
|
|
||||||
//applyForce(Vector2(readonly_totalX, 0.0))
|
//applyForce(Vector2(readonly_totalX, 0.0))
|
||||||
walkX += readonly_totalX
|
walkX += readonly_totalX
|
||||||
walkX = absClamp(walkX, actorValue.getAsDouble(AVKey.SPEED)!! * actorValue.getAsDouble(AVKey.SPEEDMULT)!!)
|
walkX = absClamp(walkX, actorValue.getAsDouble(AVKey.SPEED)!! * actorValue.getAsDouble(AVKey.SPEEDMULT)!!)
|
||||||
|
|
||||||
walkCounter += 1
|
walkCounter += 1
|
||||||
|
|
||||||
// Heading flag
|
// Heading flag
|
||||||
if (left)
|
if (left)
|
||||||
walkHeading = LEFT
|
walkHeading = LEFT
|
||||||
else
|
else
|
||||||
walkHeading = RIGHT
|
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() {
|
private fun jump() {
|
||||||
if (jumping) {
|
if (jumping) {
|
||||||
|
|||||||
@@ -7,17 +7,16 @@ import java.util.HashSet
|
|||||||
/**
|
/**
|
||||||
* Created by minjaesong on 16-02-15.
|
* Created by minjaesong on 16-02-15.
|
||||||
*/
|
*/
|
||||||
class Faction(factionName: String) {
|
class Faction(name: String) : Comparable<Faction> {
|
||||||
|
|
||||||
lateinit var factionName: String
|
var factionName: String = name
|
||||||
lateinit var factionAmicable: HashSet<String>
|
lateinit var factionAmicable: HashSet<String>
|
||||||
lateinit var factionNeutral: HashSet<String>
|
lateinit var factionNeutral: HashSet<String>
|
||||||
lateinit var factionHostile: HashSet<String>
|
lateinit var factionHostile: HashSet<String>
|
||||||
lateinit var factionFearful: HashSet<String>
|
lateinit var factionFearful: HashSet<String>
|
||||||
var factionID: Long = generateUniqueID()
|
var referenceID: Long = generateUniqueID()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.factionName = factionName
|
|
||||||
factionAmicable = HashSet<String>()
|
factionAmicable = HashSet<String>()
|
||||||
factionNeutral = HashSet<String>()
|
factionNeutral = HashSet<String>()
|
||||||
factionHostile = HashSet<String>()
|
factionHostile = HashSet<String>()
|
||||||
@@ -60,8 +59,18 @@ class Faction(factionName: String) {
|
|||||||
factionFearful.remove(faction)
|
factionFearful.remove(faction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun generateUniqueID(): Long {
|
private fun generateUniqueID(): Long {
|
||||||
fun Long.abs() = if (this < 0) -this else this
|
var ret: Long
|
||||||
return HQRNG().nextLong().abs() // set new ID
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
66
src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt
Normal file
66
src/net/torvald/terrarum/gameactors/faction/FactionCodex.kt
Normal file
@@ -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<Faction>()
|
||||||
|
|
||||||
|
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<Faction>) {
|
||||||
|
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<Faction>.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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,6 @@ object FactionFactory {
|
|||||||
val jsonObj = JsonFetcher.readJson(JSONPATH + filename)
|
val jsonObj = JsonFetcher.readJson(JSONPATH + filename)
|
||||||
val factionObj = Faction(jsonObj.get("factionname").asString)
|
val factionObj = Faction(jsonObj.get("factionname").asString)
|
||||||
|
|
||||||
|
|
||||||
jsonObj.get("factionamicable").asJsonArray.forEach { s -> factionObj.addFactionAmicable(s.asString) }
|
jsonObj.get("factionamicable").asJsonArray.forEach { s -> factionObj.addFactionAmicable(s.asString) }
|
||||||
jsonObj.get("factionneutral").asJsonArray.forEach { s -> factionObj.addFactionNeutral(s.asString) }
|
jsonObj.get("factionneutral").asJsonArray.forEach { s -> factionObj.addFactionNeutral(s.asString) }
|
||||||
jsonObj.get("factionhostile").asJsonArray.forEach { s -> factionObj.addFactionHostile(s.asString) }
|
jsonObj.get("factionhostile").asJsonArray.forEach { s -> factionObj.addFactionHostile(s.asString) }
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class MapLayer(var width: Int, var height: Int) : Iterable<Byte> {
|
|||||||
private fun uint8ToInt32(x: Byte): Int = java.lang.Byte.toUnsignedInt(x)
|
private fun uint8ToInt32(x: Byte): Int = java.lang.Byte.toUnsignedInt(x)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Transient val RANGE = 256
|
@Transient const val RANGE = 256
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,6 @@ class PairedMapLayer(width: Int, var height: Int) : Iterable<Byte> {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@Transient val RANGE = 16
|
@Transient const val RANGE = 16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ object MapCamera {
|
|||||||
, TileNameCode.SANDSTONE_RED
|
, TileNameCode.SANDSTONE_RED
|
||||||
, TileNameCode.SANDSTONE_WHITE
|
, TileNameCode.SANDSTONE_WHITE
|
||||||
, TileNameCode.SANDSTONE_GREEN
|
, TileNameCode.SANDSTONE_GREEN
|
||||||
|
, TileNameCode.DAYLIGHT_CAPACITOR
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package net.torvald.terrarum.realestate
|
package net.torvald.terrarum.realestate
|
||||||
|
|
||||||
import net.torvald.terrarum.Terrarum
|
import net.torvald.terrarum.Terrarum
|
||||||
|
import net.torvald.terrarum.gameactors.faction.FactionCodex
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by minjaesong on 16-03-27.
|
* Created by minjaesong on 16-03-27.
|
||||||
@@ -11,4 +12,13 @@ object RealEstateUtility {
|
|||||||
|
|
||||||
fun resolveAbsoluteTileNumber(t: Long): Pair<Int, Int> =
|
fun resolveAbsoluteTileNumber(t: Long): Pair<Int, Int> =
|
||||||
Pair((t % Terrarum.game.map.width).toInt(), (t / Terrarum.game.map.width).toInt())
|
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)
|
||||||
}
|
}
|
||||||
@@ -13,7 +13,7 @@ import java.io.IOException
|
|||||||
class TilePropCodex {
|
class TilePropCodex {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
tileProps = Array<TileProp>(MapLayer.RANGE * PairedMapLayer.RANGE + 1,
|
tileProps = Array<TileProp>(TILE_UNIQUE_MAX + 1,
|
||||||
{i -> TileProp() }
|
{i -> TileProp() }
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -44,6 +44,8 @@ class TilePropCodex {
|
|||||||
|
|
||||||
val CSV_PATH = "./src/net/torvald/terrarum/tileproperties/tileprop.csv"
|
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 {
|
fun getProp(index: Int, damage: Int): TileProp {
|
||||||
try {
|
try {
|
||||||
tileProps[idDamageToIndex(index, damage)].id
|
tileProps[idDamageToIndex(index, damage)].id
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
"11"; "1";"TILE_TORCH_FROST" ; "8396808"; "0"; "N/A"; "0"; "0"; "0"; "81916159"; "11"; "1"; "0";"16"
|
"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"; "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"
|
"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"; "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"; "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"
|
"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"; "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"
|
"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"
|
"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
|
# Friction: 0: frictionless, <16: slippery, 16: regular, >16: sticky
|
||||||
# Opacity/Lumcolor: 40-step RGB
|
# Opacity/Lumcolor: 40-step RGB
|
||||||
# Solid: whether the tile has full collision
|
# Solid: whether the tile has full collision
|
||||||
# movr: Movement resistance, (walkspeedmax) / (1 + (n/16)), 16 halves movement speed
|
# 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]
|
# 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.
|
# 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
|
# 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.
|
# 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 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
|
# * 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.
|
Reference in New Issue
Block a user