mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-11 19:14:05 +09:00
fixed LB/RB/BR bug (actor jitters because of false positive collision?) with a hack
This commit is contained in:
@@ -68,6 +68,19 @@ object BlockCodex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getOrNull(rawIndex: Int?): BlockProp? {
|
||||||
|
if (rawIndex == null || rawIndex == Block.NULL) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return blockProps[rawIndex]
|
||||||
|
}
|
||||||
|
catch (e: NullPointerException) {
|
||||||
|
throw NullPointerException("Blockprop with raw id $rawIndex does not exist.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setProp(prop: BlockProp, record: CSVRecord) {
|
private fun setProp(prop: BlockProp, record: CSVRecord) {
|
||||||
prop.nameKey = record.get("name")
|
prop.nameKey = record.get("name")
|
||||||
|
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
|||||||
/**
|
/**
|
||||||
* Up/Down movement
|
* Up/Down movement
|
||||||
*/
|
*/
|
||||||
if (noClip) {
|
if (noClip || COLLISION_TEST_MODE) {
|
||||||
if (hasController) {
|
if (hasController) {
|
||||||
if (axisY != 0f) {
|
if (axisY != 0f) {
|
||||||
walkVertical(axisY < 0, axisY.abs())
|
walkVertical(axisY < 0, axisY.abs())
|
||||||
@@ -363,25 +363,27 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
|||||||
* @author minjaesong
|
* @author minjaesong
|
||||||
*/
|
*/
|
||||||
private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
|
private fun walkHorizontal(left: Boolean, absAxisVal: Float) {
|
||||||
if ((!walledLeft && left) || (!walledRight && !left)) {
|
if (left && walledLeft || !left && walledRight) return
|
||||||
readonly_totalX =
|
|
||||||
if (absAxisVal == AXIS_KEYBOARD)
|
|
||||||
avAcceleration * applyVelo(walkCounterX) * (if (left) -1f else 1f)
|
|
||||||
else
|
|
||||||
avAcceleration * (if (left) -1f else 1f) * absAxisVal
|
|
||||||
|
|
||||||
if (absAxisVal != AXIS_KEYBOARD)
|
|
||||||
controllerMoveDelta?.x?.let { controllerMoveDelta!!.x = controllerMoveDelta!!.x.plus(readonly_totalX).bipolarClamp(avSpeedCap * absAxisVal) }
|
|
||||||
else
|
|
||||||
controllerMoveDelta?.x?.let { controllerMoveDelta!!.x = controllerMoveDelta!!.x.plus(readonly_totalX).bipolarClamp(avSpeedCap) }
|
|
||||||
|
|
||||||
if (absAxisVal == AXIS_KEYBOARD) {
|
readonly_totalX =
|
||||||
walkCounterX += 1
|
if (absAxisVal == AXIS_KEYBOARD)
|
||||||
}
|
avAcceleration * applyVelo(walkCounterX) * (if (left) -1f else 1f)
|
||||||
|
else
|
||||||
|
avAcceleration * (if (left) -1f else 1f) * absAxisVal
|
||||||
|
|
||||||
isWalkingH = true
|
if (absAxisVal != AXIS_KEYBOARD)
|
||||||
|
controllerMoveDelta?.x?.let { controllerMoveDelta!!.x = controllerMoveDelta!!.x.plus(readonly_totalX).bipolarClamp(avSpeedCap * absAxisVal) }
|
||||||
|
else
|
||||||
|
controllerMoveDelta?.x?.let { controllerMoveDelta!!.x = controllerMoveDelta!!.x.plus(readonly_totalX).bipolarClamp(avSpeedCap) }
|
||||||
|
|
||||||
|
if (absAxisVal == AXIS_KEYBOARD) {
|
||||||
|
walkCounterX += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isWalkingH = true
|
||||||
|
|
||||||
|
|
||||||
// Heading flag
|
// Heading flag
|
||||||
walkHeading = if (left) LEFT else RIGHT
|
walkHeading = if (left) LEFT else RIGHT
|
||||||
}
|
}
|
||||||
@@ -393,6 +395,9 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
|||||||
* @param absAxisVal (set AXIS_KEYBOARD if keyboard controlled)
|
* @param absAxisVal (set AXIS_KEYBOARD if keyboard controlled)
|
||||||
*/
|
*/
|
||||||
private fun walkVertical(up: Boolean, absAxisVal: Float) {
|
private fun walkVertical(up: Boolean, absAxisVal: Float) {
|
||||||
|
if (up && walledTop || !up && walledBottom) return
|
||||||
|
|
||||||
|
|
||||||
readonly_totalY =
|
readonly_totalY =
|
||||||
if (absAxisVal == AXIS_KEYBOARD)
|
if (absAxisVal == AXIS_KEYBOARD)
|
||||||
avAcceleration * applyVelo(walkCounterY) * (if (up) -1f else 1f)
|
avAcceleration * applyVelo(walkCounterY) * (if (up) -1f else 1f)
|
||||||
@@ -400,14 +405,15 @@ open class ActorHumanoid(birth: GameDate, death: GameDate? = null)
|
|||||||
avAcceleration * (if (up) -1f else 1f) * absAxisVal
|
avAcceleration * (if (up) -1f else 1f) * absAxisVal
|
||||||
|
|
||||||
if (absAxisVal != AXIS_KEYBOARD)
|
if (absAxisVal != AXIS_KEYBOARD)
|
||||||
controllerMoveDelta?.y?.let { controllerMoveDelta!!.y = controllerMoveDelta!!.y.plus(readonly_totalX).bipolarClamp(avSpeedCap * absAxisVal) }
|
controllerMoveDelta?.y?.let { controllerMoveDelta!!.y = controllerMoveDelta!!.y.plus(readonly_totalY).bipolarClamp(avSpeedCap * absAxisVal) }
|
||||||
else
|
else
|
||||||
controllerMoveDelta?.y?.let { controllerMoveDelta!!.y = controllerMoveDelta!!.y.plus(readonly_totalX).bipolarClamp(avSpeedCap) }
|
controllerMoveDelta?.y?.let { controllerMoveDelta!!.y = controllerMoveDelta!!.y.plus(readonly_totalY).bipolarClamp(avSpeedCap) }
|
||||||
|
|
||||||
if (absAxisVal == AXIS_KEYBOARD) {
|
if (absAxisVal == AXIS_KEYBOARD) {
|
||||||
walkCounterY += 1
|
walkCounterY += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
isWalkingV = true
|
isWalkingV = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,14 +56,14 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
* * Unit: pixel
|
* * Unit: pixel
|
||||||
* !! external class should not hitbox.set(); use setHitboxDimension() and setPosition()
|
* !! external class should not hitbox.set(); use setHitboxDimension() and setPosition()
|
||||||
*/
|
*/
|
||||||
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double;
|
override val hitbox = Hitbox(0.0, 0.0, 0.0, 0.0) // Hitbox is implemented using Double;
|
||||||
|
|
||||||
val tilewiseHitbox: Hitbox
|
val tilewiseHitbox: Hitbox
|
||||||
get() = Hitbox.fromTwoPoints(
|
get() = Hitbox.fromTwoPoints(
|
||||||
hitbox.startX.div(TILE_SIZE).floor(),
|
hitbox.startX.div(TILE_SIZE).floor(),
|
||||||
hitbox.startY.div(TILE_SIZE).floor(),
|
hitbox.startY.div(TILE_SIZE).floor(),
|
||||||
hitbox.endX.div(TILE_SIZE).floor(),
|
hitbox.endX.minus(0.00001).div(TILE_SIZE).floor(),
|
||||||
hitbox.endY.div(TILE_SIZE).floor()
|
hitbox.endY.minus(0.00001).div(TILE_SIZE).floor()
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -589,15 +589,20 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
val affectingTiles = ArrayList<BlockAddress>()
|
val affectingTiles = ArrayList<BlockAddress>()
|
||||||
var collidingStep: Int? = null
|
var collidingStep: Int? = null
|
||||||
|
|
||||||
for (step in 1..ccdSteps) {
|
for (step in 1..ccdSteps) {
|
||||||
|
|
||||||
val stepBox = sixteenStep[step]
|
val stepBox = sixteenStep[step]
|
||||||
|
|
||||||
forEachOccupyingTilePos(stepBox) {
|
forEachOccupyingTilePos(stepBox) {
|
||||||
val tileCoord = LandUtil.resolveBlockAddr(it)
|
val tileCoord = LandUtil.resolveBlockAddr(it)
|
||||||
val tileProp = BlockCodex.getOrNull(world.getTileFromTerrain(tileCoord.first, tileCoord.second))
|
val tileProp = BlockCodex.getOrNull(world.getTileFromTerrain(tileCoord.first, tileCoord.second))
|
||||||
|
|
||||||
if (tileProp == null || tileProp.isSolid) {
|
if (tileProp == null || tileProp.isSolid) {
|
||||||
affectingTiles.add(it)
|
affectingTiles.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (affectingTiles.isNotEmpty()) {
|
if (affectingTiles.isNotEmpty()) {
|
||||||
collidingStep = step
|
collidingStep = step
|
||||||
break // collision found on this step, break and proceed to next step
|
break // collision found on this step, break and proceed to next step
|
||||||
@@ -612,6 +617,8 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
|
|
||||||
var bounceX = false
|
var bounceX = false
|
||||||
var bounceY = false
|
var bounceY = false
|
||||||
|
var zeroX = false
|
||||||
|
var zeroY = false
|
||||||
// collision NOT detected
|
// collision NOT detected
|
||||||
if (collidingStep == null) {
|
if (collidingStep == null) {
|
||||||
hitbox.translate(vectorSum)
|
hitbox.translate(vectorSum)
|
||||||
@@ -619,6 +626,16 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
}
|
}
|
||||||
// collision detected
|
// collision detected
|
||||||
else {
|
else {
|
||||||
|
println("Collision step: $collidingStep")
|
||||||
|
|
||||||
|
|
||||||
|
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])
|
||||||
|
|
||||||
var selfCollisionStatus = 0
|
var selfCollisionStatus = 0
|
||||||
@@ -627,40 +644,46 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
if (isWalled(newHitbox, COLLIDING_TOP)) selfCollisionStatus += COLL_TOPSIDE
|
if (isWalled(newHitbox, COLLIDING_TOP)) selfCollisionStatus += COLL_TOPSIDE
|
||||||
if (isWalled(newHitbox, COLLIDING_BOTTOM)) selfCollisionStatus += COLL_BOTTOMSIDE
|
if (isWalled(newHitbox, COLLIDING_BOTTOM)) selfCollisionStatus += COLL_BOTTOMSIDE
|
||||||
|
|
||||||
|
// fixme UP and RIGHT && LEFT and DOWN bug
|
||||||
|
|
||||||
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 -> { bounceX = true }
|
5 -> { zeroX = true }
|
||||||
10 -> { bounceY = true }
|
10 -> { zeroY = true }
|
||||||
15 -> { newHitbox.reassign(sixteenStep[0]); bounceX = true; bounceY = true }
|
15 -> { newHitbox.reassign(sixteenStep[0]); zeroX = true; zeroY = true }
|
||||||
// one-side collision
|
// one-side collision
|
||||||
1, 11 -> { newHitbox.translatePosX(TILE_SIZE - newHitbox.startX.modTileDelta ()); bounceX = true }
|
1, 11 -> { newHitbox.translatePosX(TILE_SIZE - newHitbox.startX.modTileDelta()); bounceX = true }
|
||||||
4, 14 -> { newHitbox.translatePosX( - newHitbox.endX.modTileDelta ()) ; bounceX = true }
|
4, 14 -> { newHitbox.translatePosX( - newHitbox.endX.modTileDelta()) ; bounceX = true }
|
||||||
8, 13 -> { newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta ()); bounceY = true }
|
8, 13 -> { newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta()); bounceY = true }
|
||||||
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 ())
|
newHitbox.translatePosX(TILE_SIZE - newHitbox.startX.modTileDelta())
|
||||||
newHitbox.translatePosY( - newHitbox.endY.modTileDelta ())
|
newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
|
||||||
bounceX = true; bounceY = true
|
bounceX = true; bounceY = true
|
||||||
}
|
}
|
||||||
6 -> {
|
6 -> {
|
||||||
newHitbox.translatePosX( - newHitbox.endX.modTileDelta ())
|
println(- newHitbox.endY.modTileDelta())
|
||||||
newHitbox.translatePosY( - newHitbox.endY.modTileDelta ())
|
newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
|
||||||
|
newHitbox.translatePosY( - newHitbox.endY.modTileDelta())
|
||||||
bounceX = true; bounceY = true
|
bounceX = true; bounceY = true
|
||||||
}
|
}
|
||||||
9 -> {
|
9 -> {
|
||||||
newHitbox.translatePosX(TILE_SIZE - newHitbox.startX.modTileDelta ())
|
newHitbox.translatePosX(TILE_SIZE - newHitbox.startX.modTileDelta())
|
||||||
newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta ())
|
newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta())
|
||||||
bounceX = true; bounceY = true
|
bounceX = true; bounceY = true
|
||||||
}
|
}
|
||||||
12 -> {
|
12 -> {
|
||||||
newHitbox.translatePosX( - newHitbox.endX.modTileDelta ())
|
newHitbox.translatePosX( - newHitbox.endX.modTileDelta())
|
||||||
newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta ())
|
newHitbox.translatePosY(TILE_SIZE - newHitbox.startY.modTileDelta())
|
||||||
bounceX = true; bounceY = true
|
bounceX = true; bounceY = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selfCollisionStatus in listOf(3,6,9,12)) {
|
||||||
|
println("twoside collision $selfCollisionStatus")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// bounce X/Y
|
// bounce X/Y
|
||||||
if (bounceX) {
|
if (bounceX) {
|
||||||
@@ -671,6 +694,14 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
externalForce.y *= elasticity
|
externalForce.y *= elasticity
|
||||||
controllerMoveDelta?.let { controllerMoveDelta!!.y *= elasticity }
|
controllerMoveDelta?.let { controllerMoveDelta!!.y *= elasticity }
|
||||||
}
|
}
|
||||||
|
if (zeroX) {
|
||||||
|
externalForce.x = 0.0
|
||||||
|
controllerMoveDelta?.let { controllerMoveDelta!!.x = 0.0 }
|
||||||
|
}
|
||||||
|
if (zeroY) {
|
||||||
|
externalForce.y = 0.0
|
||||||
|
controllerMoveDelta?.let { controllerMoveDelta!!.y = 0.0 }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
hitbox.reassign(newHitbox)
|
hitbox.reassign(newHitbox)
|
||||||
@@ -1296,6 +1327,8 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
flagDespawn = true
|
flagDespawn = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private fun forEachOccupyingTileNum(consumer: (Int?) -> Unit) {
|
private fun forEachOccupyingTileNum(consumer: (Int?) -> Unit) {
|
||||||
val tiles = ArrayList<Int?>()
|
val tiles = ArrayList<Int?>()
|
||||||
for (y in tilewiseHitbox.startY.toInt()..tilewiseHitbox.endY.toInt()) {
|
for (y in tilewiseHitbox.startY.toInt()..tilewiseHitbox.endY.toInt()) {
|
||||||
@@ -1322,8 +1355,8 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
val newTilewiseHitbox = Hitbox.fromTwoPoints(
|
val newTilewiseHitbox = Hitbox.fromTwoPoints(
|
||||||
hitbox.startX.div(TILE_SIZE).floor(),
|
hitbox.startX.div(TILE_SIZE).floor(),
|
||||||
hitbox.startY.div(TILE_SIZE).floor(),
|
hitbox.startY.div(TILE_SIZE).floor(),
|
||||||
hitbox.endX.div(TILE_SIZE).floor(),
|
hitbox.endX.minus(0.00001).div(TILE_SIZE).floor(),
|
||||||
hitbox.endY.div(TILE_SIZE).floor()
|
hitbox.endY.minus(0.00001).div(TILE_SIZE).floor()
|
||||||
)
|
)
|
||||||
|
|
||||||
val tilePosList = ArrayList<BlockAddress>()
|
val tilePosList = ArrayList<BlockAddress>()
|
||||||
@@ -1362,6 +1395,8 @@ open class ActorWithPhysics(renderOrder: RenderOrder, val immobileBody: Boolean
|
|||||||
return tileProps.forEach(consumer)
|
return tileProps.forEach(consumer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ object LandUtil {
|
|||||||
fun getBlockAddr(x: Int, y: Int): BlockAddress =
|
fun getBlockAddr(x: Int, y: Int): BlockAddress =
|
||||||
(Terrarum.ingame!!.world.width * y).toLong() + x
|
(Terrarum.ingame!!.world.width * y).toLong() + x
|
||||||
|
|
||||||
fun resolveAbsoluteBlockNumber(t: BlockAddress): Pair<Int, Int> =
|
fun resolveBlockAddr(t: BlockAddress): Pair<Int, Int> =
|
||||||
Pair((t % Terrarum.ingame!!.world.width).toInt(), (t / Terrarum.ingame!!.world.width).toInt())
|
Pair((t % Terrarum.ingame!!.world.width).toInt(), (t / Terrarum.ingame!!.world.width).toInt())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user