mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-17 00:56:07 +09:00
platform sorta works as intended
This commit is contained in:
@@ -69,18 +69,18 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
/** half integer tilewise hitbox */ // got the idea from gl_FragCoord
|
/** half integer tilewise hitbox */ // got the idea from gl_FragCoord
|
||||||
val hIntTilewiseHitbox: Hitbox
|
val hIntTilewiseHitbox: Hitbox
|
||||||
get() = Hitbox.fromTwoPoints(
|
get() = Hitbox.fromTwoPoints(
|
||||||
hitbox.startX.plus(0.0001f).div(TILE_SIZE).floor() + 0.5f,
|
hitbox.startX.plus(0.00001f).div(TILE_SIZE).floor() + 0.5f,
|
||||||
hitbox.startY.plus(0.0001f).div(TILE_SIZE).floor() + 0.5f,
|
hitbox.startY.plus(0.00001f).div(TILE_SIZE).floor() + 0.5f,
|
||||||
hitbox.endX.plus(0.0001f).div(TILE_SIZE).floor() + 0.5f,
|
hitbox.endX.plus(0.00001f).div(TILE_SIZE).floor() + 0.5f,
|
||||||
hitbox.endY.plus(0.0001f).div(TILE_SIZE).floor() + 0.5f
|
hitbox.endY.plus(0.00001f).div(TILE_SIZE).floor() + 0.5f
|
||||||
)
|
)
|
||||||
|
|
||||||
val intTilewiseHitbox: Hitbox
|
val intTilewiseHitbox: Hitbox
|
||||||
get() = Hitbox.fromTwoPoints(
|
get() = Hitbox.fromTwoPoints(
|
||||||
hitbox.startX.plus(0.0001f).div(TILE_SIZE).floor(),
|
hitbox.startX.plus(0.00001f).div(TILE_SIZE).floor(),
|
||||||
hitbox.startY.plus(0.0001f).div(TILE_SIZE).floor(),
|
hitbox.startY.plus(0.00001f).div(TILE_SIZE).floor(),
|
||||||
hitbox.endX.plus(0.0001f).div(TILE_SIZE).floor(),
|
hitbox.endX.plus(0.00001f).div(TILE_SIZE).floor(),
|
||||||
hitbox.endY.plus(0.0001f).div(TILE_SIZE).floor()
|
hitbox.endY.plus(0.00001f).div(TILE_SIZE).floor()
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -595,6 +595,20 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
if (false) printdbg(this, wut)
|
if (false) printdbg(this, wut)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun BlockAddress.isFeetTile(hitbox: Hitbox): Boolean {
|
||||||
|
val (x, y) = LandUtil.resolveBlockAddr(world!!, this)
|
||||||
|
val newTilewiseHitbox = Hitbox.fromTwoPoints(
|
||||||
|
hitbox.startX.div(TILE_SIZE).floor(),
|
||||||
|
hitbox.startY.div(TILE_SIZE).floor(),
|
||||||
|
hitbox.endX.minus(0.00001).div(TILE_SIZE).floor(),
|
||||||
|
hitbox.endY.minus(0.00001).div(TILE_SIZE).floor()
|
||||||
|
)
|
||||||
|
|
||||||
|
// offset 1 pixel to the down so that friction would work
|
||||||
|
return (y == hitbox.endY.plus(1.0).div(TILE_SIZE).floorInt()) && // copied from forEachFeetTileNum
|
||||||
|
(x in newTilewiseHitbox.startX.toInt()..newTilewiseHitbox.endX.toInt()) // copied from forEachOccupyingTilePos
|
||||||
|
}
|
||||||
|
|
||||||
fun Double.modTile() = this.toInt().div(TILE_SIZE).times(TILE_SIZE)
|
fun Double.modTile() = this.toInt().div(TILE_SIZE).times(TILE_SIZE)
|
||||||
fun Double.modTileDelta() = this - this.modTile()
|
fun Double.modTileDelta() = this - this.modTile()
|
||||||
|
|
||||||
@@ -628,7 +642,7 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
val tileCoord = LandUtil.resolveBlockAddr(world!!, it)
|
val tileCoord = LandUtil.resolveBlockAddr(world!!, it)
|
||||||
val tile = world!!.getTileFromTerrain(tileCoord.first, tileCoord.second) ?: Block.STONE
|
val tile = world!!.getTileFromTerrain(tileCoord.first, tileCoord.second) ?: Block.STONE
|
||||||
|
|
||||||
if (shouldICollideWithThis(tile)) {
|
if (shouldICollideWithThis(tile) || (it.isFeetTile(stepBox) && shouldICollideWithThisFeet(tile))) {
|
||||||
collidingStep = step
|
collidingStep = step
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -665,7 +679,7 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
if (isWalled(newHitbox, COLLIDING_BOTTOM)) selfCollisionStatus += COLL_BOTTOMSIDE // 2
|
if (isWalled(newHitbox, COLLIDING_BOTTOM)) selfCollisionStatus += COLL_BOTTOMSIDE // 2
|
||||||
|
|
||||||
// fixme UP and RIGHT && LEFT and DOWN bug
|
// fixme UP and RIGHT && LEFT and DOWN bug
|
||||||
|
|
||||||
when (selfCollisionStatus) {
|
when (selfCollisionStatus) {
|
||||||
0 -> {
|
0 -> {
|
||||||
debug1("[ActorWBMovable] Contradiction -- collision detected by CCD, but isWalled() says otherwise")
|
debug1("[ActorWBMovable] Contradiction -- collision detected by CCD, but isWalled() says otherwise")
|
||||||
@@ -928,18 +942,24 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
val tyStart = y1.plus(0.5f).div(TILE_SIZE).floorInt()
|
val tyStart = y1.plus(0.5f).div(TILE_SIZE).floorInt()
|
||||||
val tyEnd = y2.plus(0.5f).div(TILE_SIZE).floorInt()
|
val tyEnd = y2.plus(0.5f).div(TILE_SIZE).floorInt()
|
||||||
|
|
||||||
return isCollidingInternal(txStart, tyStart, txEnd, tyEnd)
|
return isCollidingInternal(txStart, tyStart, txEnd, tyEnd, option == COLLIDING_BOTTOM)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isCollidingInternal(txStart: Int, tyStart: Int, txEnd: Int, tyEnd: Int): Boolean {
|
private fun isCollidingInternal(txStart: Int, tyStart: Int, txEnd: Int, tyEnd: Int, feet: Boolean = false): Boolean {
|
||||||
if (world == null) return false
|
if (world == null) return false
|
||||||
|
|
||||||
for (y in tyStart..tyEnd) {
|
for (y in tyStart..tyEnd) {
|
||||||
for (x in txStart..txEnd) {
|
for (x in txStart..txEnd) {
|
||||||
val tile = world!!.getTileFromTerrain(x, y) ?: Block.STONE
|
val tile = world!!.getTileFromTerrain(x, y) ?: Block.STONE
|
||||||
|
|
||||||
if (shouldICollideWithThis(tile))
|
if (feet) {
|
||||||
return true
|
if (shouldICollideWithThisFeet(tile))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (shouldICollideWithThis(tile))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// this weird statement means that if's the condition is TRUE, return TRUE;
|
// this weird statement means that if's the condition is TRUE, return TRUE;
|
||||||
// if the condition is FALSE, do nothing and let succeeding code handle it.
|
// if the condition is FALSE, do nothing and let succeeding code handle it.
|
||||||
@@ -955,17 +975,25 @@ open class ActorWBMovable(renderOrder: RenderOrder, val immobileBody: Boolean =
|
|||||||
* Very straightforward for the actual solid tiles, not so much for the platforms
|
* Very straightforward for the actual solid tiles, not so much for the platforms
|
||||||
*/
|
*/
|
||||||
private fun shouldICollideWithThis(tile: Int) =
|
private fun shouldICollideWithThis(tile: Int) =
|
||||||
// regular solid block
|
// regular solid block
|
||||||
(BlockCodex[tile].isSolid) ||
|
(BlockCodex[tile].isSolid)
|
||||||
// platforms, moving downward AND not "going down"
|
|
||||||
(this is ActorHumanoid && BlockCodex[tile].isPlatform &&
|
|
||||||
externalForce.y + (controllerMoveDelta?.y ?: 0.0) >= 0.0 &&
|
|
||||||
!this.isDownDown && this.axisY <= 0f) ||
|
|
||||||
// platforms, moving downward
|
|
||||||
(this !is ActorHumanoid && BlockCodex[tile].isPlatform &&
|
|
||||||
externalForce.y + (controllerMoveDelta?.y ?: 0.0) >= 0.0)
|
|
||||||
// TODO: as for the platform, only apply it when it's a feet tile
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this tile should be treated as "collidable"
|
||||||
|
*
|
||||||
|
* Just like "shouldICollideWithThis" but it's intended to work with feet tiles
|
||||||
|
*/
|
||||||
|
private fun shouldICollideWithThisFeet(tile: Int) =
|
||||||
|
// regular solid block
|
||||||
|
(BlockCodex[tile].isSolid) ||
|
||||||
|
// platforms, moving downward AND not "going down"
|
||||||
|
(this is ActorHumanoid && BlockCodex[tile].isPlatform &&
|
||||||
|
externalForce.y + (controllerMoveDelta?.y ?: 0.0) >= 0.0 &&
|
||||||
|
!this.isDownDown && this.axisY <= 0f) ||
|
||||||
|
// platforms, moving downward
|
||||||
|
(this !is ActorHumanoid && BlockCodex[tile].isPlatform &&
|
||||||
|
externalForce.y + (controllerMoveDelta?.y ?: 0.0) >= 0.0)
|
||||||
|
// TODO: as for the platform, only apply it when it's a feet tile
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user