diff --git a/assets/mods/basegame/creatures/CreatureHuman.json b/assets/mods/basegame/creatures/CreatureHuman.json index e22e73a25..22e9cce84 100644 --- a/assets/mods/basegame/creatures/CreatureHuman.json +++ b/assets/mods/basegame/creatures/CreatureHuman.json @@ -12,6 +12,8 @@ "speed": 3.0, "speedmult": [100,100,100,100,100,100,100], + "vertstride": 8, + "jumppower": 13.0, "jumppowermult": [100,100,100,100,100,100,100], diff --git a/assets/mods/basegame/creatures/CreatureWerebeastBase.json b/assets/mods/basegame/creatures/CreatureWerebeastBase.json new file mode 100644 index 000000000..d5b482acf --- /dev/null +++ b/assets/mods/basegame/creatures/CreatureWerebeastBase.json @@ -0,0 +1,31 @@ +{ + "racename": "RACE_HUMAN", + "racenameplural": "RACE_HUMAN_PLURAL", + "baseheight": 90, + "basemass": 600.0, + + "strength": 5000, + "strengthmult": [90,95,98,100,102,105,110], + + "accel": 0.67, + + "speed": 6.0, + "speedmult": [100,100,100,100,100,100,100], + + "vertstride": 32, + + "jumppower": 19.0, + "jumppowermult": [100,100,100,100,100,100,100], + + "scale": 1.0, + "scalemult": [100,100,100,100,100,100,100], + + "encumbrance": 10000, + "basedefence": 100, + "basereach": 114, + + "toolsize": 40, + + "intelligent": true + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/gameactors/AVKey.kt b/src/net/torvald/terrarum/gameactors/AVKey.kt index ec791be07..14ec3c724 100644 --- a/src/net/torvald/terrarum/gameactors/AVKey.kt +++ b/src/net/torvald/terrarum/gameactors/AVKey.kt @@ -29,6 +29,9 @@ object AVKey { const val JUMPPOWER = "jumppower" const val JUMPPOWERBUFF = "$JUMPPOWER$BUFF" + /** Maximum height of a stair the actor can climb */ + const val VERTSTRIDE = "vertstride" + /** How much air jumping you can perform. 0 is same as 1. INT */ const val AIRJUMPPOINT = "airjumppoint" /** How much air jumping you have performed before you run out of the point. INT */ diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index b0d6bb1cd..893cb1880 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -760,12 +760,20 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) val newHitbox = hitbox.reassign(sixteenStep[collidingStep]) var staircaseStatus = 0 + var stairHeightLeft = 0.0 + var stairHeightRight = 0.0 val selfCollisionStatus = intArrayOf(1,2,4,8).fold(0) { acc, state -> // also update staircaseStatus while we're iterating if (state and 5 != 0) { - staircaseStatus = staircaseStatus or (state * (isWalledStairs(newHitbox, state) == 1).toInt()) + isWalledStairs(newHitbox, state).let { + staircaseStatus = staircaseStatus or (state * (it.first == 1).toInt()) + if (state == COLLIDING_LEFT) + stairHeightLeft = it.second.toDouble() + else + stairHeightRight = it.second.toDouble() + } } - acc or (state * isWalledStairs(newHitbox, state).coerceAtMost(1)) + acc or (state * isWalledStairs(newHitbox, state).first.coerceAtMost(1)) } // superseded by isWalledStairs-related codes @@ -776,7 +784,7 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) // fixme UP and RIGHT && LEFT and DOWN bug - println("collision: $selfCollisionStatus\tstaircasing: $staircaseStatus") + //println("collision: $selfCollisionStatus\tstaircasing: $staircaseStatus") when (selfCollisionStatus) { 0 -> { @@ -901,6 +909,17 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) // remove Y displacement // let original X velocity to pass-thru instead of snapping to tiles coded above // pass-thru values are held by the vectorSum + println("staiscasing: $staircaseStatus for $selfCollisionStatus") + + finalDisplacement.y = if (staircaseStatus == COLLIDING_LEFT) -stairHeightLeft else -stairHeightRight + finalDisplacement.x = vectorSum.x + + bounceX = false + bounceY = false + } + else { + bounceX = angleOfIncidence == angleThreshold || displacementUnitVector.x != 0.0 + bounceY = angleOfIncidence == angleThreshold || displacementUnitVector.y != 0.0 } @@ -912,8 +931,6 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) // TODO: translate other axis proportionally to the incident vector - bounceX = angleOfIncidence == angleThreshold || displacementUnitVector.x != 0.0 - bounceY = angleOfIncidence == angleThreshold || displacementUnitVector.y != 0.0 } @@ -1037,7 +1054,7 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) val tyStart = y1.plus(HALF_PIXEL).floorInt() val tyEnd = y2.plus(HALF_PIXEL).floorInt() - return isCollidingInternalStairs(txStart, tyStart, txEnd, tyEnd, feet) > 0 + return isCollidingInternalStairs(txStart, tyStart, txEnd, tyEnd, feet).first > 0 } /** @@ -1104,13 +1121,13 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) val tyStart = y1.plus(HALF_PIXEL).floorInt() val tyEnd = y2.plus(HALF_PIXEL).floorInt() - return isCollidingInternalStairs(txStart, tyStart, txEnd, tyEnd, option == COLLIDING_BOTTOM) > 0 + return isCollidingInternalStairs(txStart, tyStart, txEnd, tyEnd, option == COLLIDING_BOTTOM).first > 0 } /** - * @return 0 - no collision, 1 - stair, 2 - "bonk" to the wall + * @return First int: 0 - no collision, 1 - staircasing, 2 - "bonk" to the wall; Second int: stair height */ - private fun isWalledStairs(hitbox: Hitbox, option: Int): Int { + private fun isWalledStairs(hitbox: Hitbox, option: Int): Pair { val x1: Double val x2: Double val y1: Double @@ -1154,15 +1171,20 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) y2 = hitbox.endY - A_PIXEL } else if (option == COLLIDING_ALLSIDE) { - return maxOf(maxOf(isWalledStairs(hitbox, COLLIDING_LEFT), isWalledStairs(hitbox, COLLIDING_RIGHT)), - maxOf(isWalledStairs(hitbox, COLLIDING_BOTTOM), isWalledStairs(hitbox, COLLIDING_TOP))) + return maxOf(maxOf(isWalledStairs(hitbox, COLLIDING_LEFT).first, + isWalledStairs(hitbox, COLLIDING_RIGHT).first), + maxOf(isWalledStairs(hitbox, COLLIDING_BOTTOM).first, + isWalledStairs(hitbox, COLLIDING_TOP).first)) to 0 } else if (option == COLLIDING_LR) { - return maxOf(isWalledStairs(hitbox, COLLIDING_LEFT),isWalledStairs(hitbox, COLLIDING_RIGHT)) + val v1 = isWalledStairs(hitbox, COLLIDING_LEFT) + val v2 = isWalledStairs(hitbox, COLLIDING_RIGHT) + return maxOf(v1.first, v2.first) to maxOf(v2.first, v2.second) } else if (option == COLLIDING_UD) { - return maxOf(isWalledStairs(hitbox, COLLIDING_BOTTOM), isWalledStairs(hitbox, COLLIDING_TOP)) + return maxOf(isWalledStairs(hitbox, COLLIDING_BOTTOM).first, + isWalledStairs(hitbox, COLLIDING_TOP).first) to 0 } else throw IllegalArgumentException("$option") @@ -1199,15 +1221,15 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) }*/ private val AUTO_CLIMB_STRIDE: Int - get() = (8 * scale).toInt() // number inspired by SM64 + get() = ((actorValue.getAsInt(AVKey.VERTSTRIDE) ?: 8) * scale).toInt() //private val AUTO_CLIMB_RATE: Int // we'll just climb stairs instantly to make things work wo worrying about the details // get() = Math.min(TILE_SIZE / 8 * Math.sqrt(scale), TILE_SIZED).toInt() /** - * @return 0 - no collision, 1 - stair, 2 - "bonk" to the wall + * @return First int: 0 - no collision, 1 - staircasing, 2 - "bonk" to the wall; Second int: stair height */ - private fun isCollidingInternalStairs(pxStart: Int, pyStart: Int, pxEnd: Int, pyEnd: Int, feet: Boolean = false): Int { - if (world == null) return 0 + private fun isCollidingInternalStairs(pxStart: Int, pyStart: Int, pxEnd: Int, pyEnd: Int, feet: Boolean = false): Pair { + if (world == null) return 0 to 0 val ys = if (gravitation.y >= 0) pyEnd downTo pyStart else pyStart..pyEnd val yheight = (ys.last - ys.first).absoluteValue @@ -1248,7 +1270,7 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) if (stairHeight > AUTO_CLIMB_STRIDE) { //println(" -> $stairHeight ending prematurely") - return 2 + return 2 to stairHeight } } @@ -1256,11 +1278,11 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties) //println("-> $stairHeight") // edge-detect mode - return if (yheight == 0) hitFloor.toInt() * 2 + return if (yheight == 0) hitFloor.toInt() * 2 to stairHeight // not an edge-detect && no collision - else if (stairHeight == 0) 0 + else if (stairHeight == 0) 0 to 0 // there was collision and stairHeight <= AUTO_CLIMB_STRIDE - else 1 // 1; your main code is not ready to handle return code 1 (try "setscale 2") + else 1 to stairHeight // 1; your main code is not ready to handle return code 1 (try "setscale 2") } /** diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index cb3b8aaa2..89bcf0277 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -339,8 +339,8 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { /** Load rest of the game with GL context */ fun postInit() { //setTheRealGamerFirstTime(PlayerBuilderSigrid()) - setTheRealGamerFirstTime(PlayerBuilderTestSubject1()) - //setTheRealGamerFirstTime(PlayerBuilderWerebeastTest()) +// setTheRealGamerFirstTime(PlayerBuilderTestSubject1()) + setTheRealGamerFirstTime(PlayerBuilderWerebeastTest()) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt index e2335dfe8..1d21b934f 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/InjectCreatureRaw.kt @@ -25,6 +25,8 @@ object InjectCreatureRaw { operator fun invoke(actorValueRef: ActorValue, module: String, jsonFileName: String) { val jsonObj = JsonFetcher(ModMgr.getPath(module, "creatures/$jsonFileName")) + // TODO make it work for every possible keys (maybe except ones starts with '_') + val elementsInt = arrayOf(AVKey.BASEHEIGHT, AVKey.TOOLSIZE, AVKey.ENCUMBRANCE) val elementsString = arrayOf(AVKey.RACENAME, AVKey.RACENAMEPLURAL) val elementsDouble = arrayOf(AVKey.BASEMASS, AVKey.ACCEL) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt index d7bceda20..847a0fc95 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt @@ -16,23 +16,8 @@ object PlayerBuilderWerebeastTest { ModMgr.getPath("basegame", "sprites/taimu_glow.properties"), -589141658L // random value thrown ) - //InjectCreatureRaw(p.actorValue, "basegame", "CreatureHuman.json") + InjectCreatureRaw(p.actorValue, "basegame", "CreatureWerebeastBase.json") - p.actorValue[AVKey.SCALE] = 1.0 - p.actorValue[AVKey.SPEED] = 6.0 - p.actorValue[AVKey.SPEEDBUFF] = 1.0 - p.actorValue[AVKey.ACCEL] = ActorHumanoid.WALK_ACCEL_BASE - p.actorValue[AVKey.ACCELBUFF] = 1.0 - p.actorValue[AVKey.JUMPPOWER] = 19.0 - p.actorValue[AVKey.BASEREACH] = 114 // 7 tiles + 2 px - - p.actorValue[AVKey.BASEMASS] = 599.16 - p.actorValue[AVKey.SCALEBUFF] = 1.0 // Constant 1.0 for player, meant to be used by random mobs - p.actorValue[AVKey.STRENGTH] = 5000 - p.actorValue[AVKey.ENCUMBRANCE] = 10000 - p.actorValue[AVKey.BASEHEIGHT] = 90 - - p.actorValue[AVKey.INTELLIGENT] = true p.actorValue[AVKey.__PLAYER_QUICKSLOTSEL] = 0 p.actorValue[AVKey.__ACTION_TIMER] = 0.0