mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 18:44:05 +09:00
this fixes *some* case of abnormal displacement
This commit is contained in:
@@ -171,7 +171,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
* think of a grass cutting on the Zelda games. It would also make a great puzzle to solve.
|
* think of a grass cutting on the Zelda games. It would also make a great puzzle to solve.
|
||||||
* --minjaesong)
|
* --minjaesong)
|
||||||
*/
|
*/
|
||||||
@Volatile var isChronostasis = false
|
var isChronostasis = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gravitational Constant G. Load from gameworld.
|
* Gravitational Constant G. Load from gameworld.
|
||||||
@@ -190,8 +190,6 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
actorValue[AVKey.DRAGCOEFF] = value
|
actorValue[AVKey.DRAGCOEFF] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transient private val UD_COMPENSATOR_MAX = TILE_SIZE
|
|
||||||
@Transient private val LR_COMPENSATOR_MAX = TILE_SIZE
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Post-hit invincibility, in milliseconds
|
* Post-hit invincibility, in milliseconds
|
||||||
@@ -200,10 +198,15 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
@Transient internal val BASE_FRICTION = 0.3
|
@Transient internal val BASE_FRICTION = 0.3
|
||||||
|
|
||||||
|
@Transient internal val BASE_FALLDAMAGE_DAMPEN = 50.0
|
||||||
|
val fallDamageDampening: Double
|
||||||
|
get() = BASE_FALLDAMAGE_DAMPEN * (actorValue.getAsDouble(AVKey.FALLDAMPENMULT) ?: 1.0)
|
||||||
|
|
||||||
|
|
||||||
var collisionType = COLLISION_DYNAMIC
|
var collisionType = COLLISION_DYNAMIC
|
||||||
|
|
||||||
@Transient private val CCD_TICK = 1.0 / 16.0
|
//@Transient private val CCD_TICK = 1.0 / 16.0
|
||||||
@Transient private val CCD_TRY_MAX = 12800
|
//@Transient private val CCD_TRY_MAX = 12800
|
||||||
|
|
||||||
// just some trivial magic numbers
|
// just some trivial magic numbers
|
||||||
@Transient private val A_PIXEL = 1.0
|
@Transient private val A_PIXEL = 1.0
|
||||||
@@ -225,11 +228,11 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
@Transient private var assertPrinted = false
|
@Transient private var assertPrinted = false
|
||||||
|
|
||||||
// debug only
|
// debug only
|
||||||
internal @Volatile var walledLeft = false
|
internal var walledLeft = false
|
||||||
internal @Volatile var walledRight = false
|
internal var walledRight = false
|
||||||
internal @Volatile var walledTop = false // UNUSED; only for BasicDebugInfoWindow
|
internal var walledTop = false // UNUSED; only for BasicDebugInfoWindow
|
||||||
internal @Volatile var walledBottom = false // UNUSED; only for BasicDebugInfoWindow
|
internal var walledBottom = false // UNUSED; only for BasicDebugInfoWindow
|
||||||
internal @Volatile var colliding = false
|
internal var colliding = false
|
||||||
|
|
||||||
protected val gameContainer: GameContainer
|
protected val gameContainer: GameContainer
|
||||||
get() = Terrarum.appgc
|
get() = Terrarum.appgc
|
||||||
@@ -490,7 +493,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
* Apply only if not grounded; normal force is precessed separately.
|
* Apply only if not grounded; normal force is precessed separately.
|
||||||
*/
|
*/
|
||||||
private fun applyGravitation() {
|
private fun applyGravitation() {
|
||||||
if (!isNoSubjectToGrav && !isWalled(hitbox, COLLIDING_BOTTOM)) {
|
if (!isNoSubjectToGrav && !(gravitation.y > 0 && walledBottom || gravitation.y < 0 && walledTop)) {
|
||||||
//if (!isWalled(hitbox, COLLIDING_BOTTOM)) {
|
//if (!isWalled(hitbox, COLLIDING_BOTTOM)) {
|
||||||
/**
|
/**
|
||||||
* weight; gravitational force in action
|
* weight; gravitational force in action
|
||||||
@@ -541,12 +544,6 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/**
|
|
||||||
* nextHitbox must NOT be altered before this method is called!
|
|
||||||
*/
|
|
||||||
private val ccdSteps = 32 // max allowed velocity = backtrackSteps * TILE_SIZE
|
|
||||||
private val binaryBranchingMax = 54 // higher = more precise; theoretical max = 54 (# of mantissa + 2)
|
|
||||||
|
|
||||||
private fun displaceHitbox() {
|
private fun displaceHitbox() {
|
||||||
|
|
||||||
fun debug1(wut: Any?) {
|
fun debug1(wut: Any?) {
|
||||||
@@ -570,7 +567,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
|
|
||||||
val vectorSum = externalForce + controllerMoveDelta
|
val vectorSum = externalForce + controllerMoveDelta
|
||||||
val ccdSteps = 16
|
val ccdSteps = minOf(16, (vectorSum.magnitudeSquared / TILE_SIZE.sqr()).floorInt() + 1) // adaptive
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -626,14 +623,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
}
|
}
|
||||||
// collision detected
|
// collision detected
|
||||||
else {
|
else {
|
||||||
println("Collision step: $collidingStep")
|
println("== Collision step: $collidingStep / $ccdSteps")
|
||||||
|
|
||||||
|
|
||||||
affectingTiles.forEach {
|
|
||||||
val tileCoord = LandUtil.resolveBlockAddr(it)
|
|
||||||
println("affectign tile: ${tileCoord.first}, ${tileCoord.second}")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val newHitbox = hitbox.reassign(sixteenStep[collidingStep])
|
val newHitbox = hitbox.reassign(sixteenStep[collidingStep])
|
||||||
@@ -646,6 +636,12 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
// fixme UP and RIGHT && LEFT and DOWN bug
|
// fixme UP and RIGHT && LEFT and DOWN bug
|
||||||
|
|
||||||
|
println("Collision type: $selfCollisionStatus")
|
||||||
|
affectingTiles.forEach {
|
||||||
|
val tileCoord = LandUtil.resolveBlockAddr(it)
|
||||||
|
println("affectign tile: ${tileCoord.first}, ${tileCoord.second}")
|
||||||
|
}
|
||||||
|
|
||||||
when (selfCollisionStatus) {
|
when (selfCollisionStatus) {
|
||||||
0 -> { println("[ActorWithPhysics] Contradiction -- collision detected by CCD, but isWalled() says otherwise") }
|
0 -> { println("[ActorWithPhysics] Contradiction -- collision detected by CCD, but isWalled() says otherwise") }
|
||||||
5 -> { zeroX = true }
|
5 -> { zeroX = true }
|
||||||
@@ -658,12 +654,13 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
2, 7 -> { newHitbox.translatePosY( - newHitbox.endY.modTileDelta()) ; bounceY = true }
|
2, 7 -> { newHitbox.translatePosY( - newHitbox.endY.modTileDelta()) ; bounceY = true }
|
||||||
// two-side collision
|
// two-side collision
|
||||||
3 -> {
|
3 -> {
|
||||||
newHitbox.translatePosX(TILE_SIZE - newHitbox.startX.modTileDelta())
|
println("translateX: ${(TILE_SIZE - newHitbox.startX.modTileDelta()).rem(TILE_SIZE)}")
|
||||||
|
newHitbox.translatePosX((TILE_SIZE - newHitbox.startX.modTileDelta()).rem(TILE_SIZE))
|
||||||
newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
|
newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
|
||||||
bounceX = true; bounceY = true
|
bounceX = true; bounceY = true
|
||||||
}
|
}
|
||||||
6 -> {
|
6 -> {
|
||||||
println(- newHitbox.endY.modTileDelta())
|
println("translateX: ${( - newHitbox.endX.modTileDelta())}")
|
||||||
newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
|
newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
|
||||||
newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
|
newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
|
||||||
bounceX = true; bounceY = true
|
bounceX = true; bounceY = true
|
||||||
@@ -674,8 +671,9 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
bounceX = true; bounceY = true
|
bounceX = true; bounceY = true
|
||||||
}
|
}
|
||||||
12 -> {
|
12 -> {
|
||||||
|
println("translateY: ${(TILE_SIZE - newHitbox.startY.modTileDelta()).rem(TILE_SIZE)}")
|
||||||
newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
|
newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
|
||||||
newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta())
|
newHitbox.translatePosY((TILE_SIZE - newHitbox.startY.modTileDelta()).rem(TILE_SIZE))
|
||||||
bounceX = true; bounceY = true
|
bounceX = true; bounceY = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -707,6 +705,13 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
hitbox.reassign(newHitbox)
|
hitbox.reassign(newHitbox)
|
||||||
|
|
||||||
|
|
||||||
|
// slam-into-whatever damage (such dirty; much hack; wow)
|
||||||
|
// vvvv hack (supposed to be 1.0) vvv 50% hack
|
||||||
|
val collisionDamage = mass * (vectorSum.magnitude / (10.0 / Terrarum.TARGET_FPS).sqr()) / fallDamageDampening.sqr() * GAME_TO_SI_ACC
|
||||||
|
// kg * m / s^2 (mass * acceleration), acceleration -> (vectorMagn / (0.01)^2).gameToSI()
|
||||||
|
if (collisionDamage != 0.0) println("Collision damage: $collisionDamage N")
|
||||||
|
|
||||||
|
|
||||||
// grounded = true
|
// grounded = true
|
||||||
}// end of collision not detected
|
}// end of collision not detected
|
||||||
|
|
||||||
@@ -1193,9 +1198,9 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
blendLightenOnly()
|
blendLightenOnly()
|
||||||
|
|
||||||
val offsetX = if (!spriteGlow!!.flippedHorizontal())
|
val offsetX = if (!spriteGlow!!.flippedHorizontal())
|
||||||
hitboxTranslateX * scale + 1
|
hitboxTranslateX * scale
|
||||||
else
|
else
|
||||||
spriteGlow!!.cellWidth * scale - (hitbox.width + hitboxTranslateX * scale) + 1
|
spriteGlow!!.cellWidth * scale - (hitbox.width + hitboxTranslateX * scale)
|
||||||
|
|
||||||
val offsetY = spriteGlow!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1
|
val offsetY = spriteGlow!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1
|
||||||
|
|
||||||
@@ -1234,9 +1239,9 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
BlendMode.resolve(drawMode)
|
BlendMode.resolve(drawMode)
|
||||||
|
|
||||||
val offsetX = if (!sprite!!.flippedHorizontal())
|
val offsetX = if (!sprite!!.flippedHorizontal())
|
||||||
hitboxTranslateX * scale + 1
|
hitboxTranslateX * scale
|
||||||
else
|
else
|
||||||
sprite!!.cellWidth * scale - (hitbox.width + hitboxTranslateX * scale) + 1
|
sprite!!.cellWidth * scale - (hitbox.width + hitboxTranslateX * scale)
|
||||||
|
|
||||||
val offsetY = sprite!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1
|
val offsetY = sprite!!.cellHeight * scale - hitbox.height - hitboxTranslateY * scale - 1
|
||||||
|
|
||||||
@@ -1407,12 +1412,18 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
/**
|
/**
|
||||||
* [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2]
|
* [m / s^2] * SI_TO_GAME_ACC -> [px / InternalFrame^2]
|
||||||
*/
|
*/
|
||||||
@Transient val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS).toDouble()
|
@Transient val SI_TO_GAME_ACC = METER / (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS)
|
||||||
/**
|
/**
|
||||||
* [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame]
|
* [m / s] * SI_TO_GAME_VEL -> [px / InternalFrame]
|
||||||
*/
|
*/
|
||||||
@Transient val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
|
@Transient val SI_TO_GAME_VEL = METER / Terrarum.TARGET_FPS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [px / InternalFrame^2] * GAME_TO_SI_ACC -> [m / s^2]
|
||||||
|
*/
|
||||||
|
@Transient val GAME_TO_SI_ACC = (Terrarum.TARGET_FPS * Terrarum.TARGET_FPS) / METER
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enumerations that exported to JSON
|
* Enumerations that exported to JSON
|
||||||
*/
|
*/
|
||||||
@@ -1486,6 +1497,7 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
scale.sqrt()
|
scale.sqrt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Int.sqr(): Int = this * this
|
||||||
fun Double.floorInt() = Math.floor(this).toInt()
|
fun Double.floorInt() = Math.floor(this).toInt()
|
||||||
fun Float.floorInt() = FastMath.floor(this)
|
fun Float.floorInt() = FastMath.floor(this)
|
||||||
fun Float.floor() = FastMath.floor(this).toFloat()
|
fun Float.floor() = FastMath.floor(this).toFloat()
|
||||||
|
|||||||
Reference in New Issue
Block a user