proper impl of walk friction control (WIP submerged case)

Former-commit-id: cf8c11dee3eed491893bbfa61167e47863524366
Former-commit-id: 30a8fbedcc05cb6aee5f131708152d4db1fd9415
This commit is contained in:
Song Minjae
2017-01-19 03:25:22 +09:00
parent 50d594446c
commit 9efcb1684f
2 changed files with 69 additions and 31 deletions

View File

@@ -22,6 +22,10 @@ import java.util.*
open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
: HistoricalFigure(birth, death), Controllable, Pocketed, Factionable, Luminous, LandHolder {
// FIXME disable all water-related movement mods (slow ESDF velo while submerged)ssssst
/** Must be set by PlayerFactory */
override var inventory: ActorInventory = ActorInventory()
@@ -74,7 +78,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
@Transient val BASE_DENSITY = 980.0
companion object {
@Transient internal const val ACCEL_MULT_IN_FLIGHT: Double = 0.21
//@Transient internal const val ACCEL_MULT_IN_FLIGHT: Double = 0.21
@Transient internal const val WALK_ACCEL_BASE: Double = 0.67
@Transient const val BASE_HEIGHT = 40
@@ -144,7 +148,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
// don't put this into keyPressed; execution order is important!
updateGamerControlBox(gc.input)
updateMovementControl()
updateSprite(delta)
if (noClip) {
@@ -218,20 +221,6 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
}
}
private fun updateMovementControl() {
if (!noClip) {
if (grounded) {
actorValue[AVKey.ACCELMULT_MOVEMENT] = 1.0
}
else {
actorValue[AVKey.ACCELMULT_MOVEMENT] = ACCEL_MULT_IN_FLIGHT
}
}
else {
actorValue[AVKey.ACCELMULT_MOVEMENT] = 1.0
}
}
private val hasController: Boolean
get() = if (isGamer) Terrarum.controller != null
else true

View File

@@ -24,6 +24,9 @@ import java.util.*
open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
// FIXME disable all water-related movement mods (slow ESDF velo while submerged)
/** !! ActorValue macros are on the very bottom of the source !! **/
override var actorValue: ActorValue = ActorValue()
@@ -248,6 +251,8 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
protected val updateDelta: Int
get() = Terrarum.ingame.UPDATE_DELTA
@Transient private var accelMultMovement = 1.0
/**
* true: This actor had just made collision
*/
@@ -355,6 +360,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
* Actual physics thing (altering velocity) starts from here
*/
updateMovementControl()
// Combine velo and walk
applyMovementVelocity()
@@ -384,8 +390,9 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
}
setHorizontalFriction()
if (isPlayerNoClip) // or hanging on the rope, etc.
if (isPlayerNoClip) { // or hanging on the rope, etc.
setVerticalFriction()
}
// apply our compensation to actual hitbox
updateHitbox()
@@ -404,6 +411,30 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
}
}
/** about get going
* for about stopping, see setHorizontalFriction */
private fun updateMovementControl() {
/* if not submerged:
if grounded:
feetTileFriction
else:
bodyTileFriction
else:
linearMix(not submerged, fluidViscosity, submergedRatio)
*/
if (!isPlayerNoClip) {
if (grounded) {
accelMultMovement = feetFriction.frictionToMult()
}
else {
accelMultMovement = bodyFriction.frictionToMult()
}
}
else {
accelMultMovement = 1.0
}
}
private fun applyMovementVelocity() {
if (this is Controllable) {
// decide whether to ignore walkX
@@ -756,11 +787,15 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
return contactAreaCounter
}
/** about stopping
* for about get moving, see updateMovementControl */
private fun setHorizontalFriction() {
val friction = if (isPlayerNoClip)
BASE_FRICTION * TileCodex[Tile.STONE].friction.tileFrictionToMult()
else
BASE_FRICTION * bodyFriction.tileFrictionToMult()
BASE_FRICTION * TileCodex[Tile.STONE].friction.frictionToMult()
else {
// TODO status quo if !submerged else linearBlend(feetFriction, bodyFriction, submergedRatio)
BASE_FRICTION * (if (grounded) feetFriction else bodyFriction).frictionToMult()
}
if (veloX < 0) {
veloX += friction
@@ -785,9 +820,9 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
private fun setVerticalFriction() {
val friction = if (isPlayerNoClip)
BASE_FRICTION * TileCodex[Tile.STONE].friction.tileFrictionToMult()
BASE_FRICTION * TileCodex[Tile.STONE].friction.frictionToMult()
else
BASE_FRICTION * bodyFriction.tileFrictionToMult()
BASE_FRICTION * bodyFriction.frictionToMult()
if (veloY < 0) {
veloY += friction
@@ -827,24 +862,23 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
}
}*/
/*private val submergedVolume: Double
private val submergedRatio: Double
get() = submergedHeight / hitbox.height
private val submergedVolume: Double
get() = submergedHeight * hitbox.width * hitbox.width
private val submergedHeight: Double
get() = Math.max(
getContactingAreaFluid(COLLIDING_LEFT),
getContactingAreaFluid(COLLIDING_RIGHT)
).toDouble()*/
).toDouble()
/**
* Get highest friction value from surrounding tiles
* @return
*/
internal val bodyFriction: Int
get() {
var friction = 0
forEachFeetTile {
forEachOccupyingTile { // get max friction
if (it?.friction ?: TileCodex[Tile.AIR].friction > friction)
friction = it?.friction ?: TileCodex[Tile.AIR].friction
}
@@ -852,7 +886,22 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
return friction
}
fun Int.tileFrictionToMult(): Double = this / 16.0
/**
* Get highest friction value from surrounding tiles
* @return
*/
internal val feetFriction: Int // FIXME sharp turn on ice is still possible as on soil/rocks
get() {
var friction = 0
forEachFeetTile { // get max friction
if (it?.friction ?: TileCodex[Tile.AIR].friction > friction)
friction = it?.friction ?: TileCodex[Tile.AIR].friction
}
return friction
}
fun Int.frictionToMult(): Double = this / 16.0
/**
* Get highest tile density from occupying tiles, fluid only
@@ -1177,7 +1226,7 @@ open class ActorWithBody(renderOrder: ActorOrder) : Actor(renderOrder) {
val avAcceleration: Double
get() = actorValue.getAsDouble(AVKey.ACCEL)!! *
actorValue.getAsDouble(AVKey.ACCELBUFF)!! *
(actorValue.getAsDouble(AVKey.ACCELMULT_MOVEMENT) ?: 1.0) *
accelMultMovement *
scale.sqrt()
val avSpeedCap: Double
get() = actorValue.getAsDouble(AVKey.SPEED)!! *