mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-10 10:34:06 +09:00
BlockStats is upgraded to TileSurvey
This commit is contained in:
@@ -1,59 +0,0 @@
|
|||||||
package net.torvald.terrarum.blockstats
|
|
||||||
|
|
||||||
import com.jme3.math.FastMath
|
|
||||||
import net.torvald.terrarum.App
|
|
||||||
import net.torvald.terrarum.INGAME
|
|
||||||
import net.torvald.terrarum.Terrarum
|
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
|
||||||
import net.torvald.terrarum.gameitems.ItemID
|
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
|
||||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by minjaesong on 2016-02-01.
|
|
||||||
*/
|
|
||||||
object BlockStats {
|
|
||||||
|
|
||||||
private val tilestat = HashMap<ItemID, Int>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update tile stats from tiles on screen
|
|
||||||
*/
|
|
||||||
fun update() {
|
|
||||||
tilestat.clear()
|
|
||||||
|
|
||||||
// Get stats on no-zoomed screen area. In other words, will behave as if screen zoom were 1.0
|
|
||||||
// no matter how the screen is zoomed.
|
|
||||||
val map = (INGAME.world)
|
|
||||||
val player = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying
|
|
||||||
if (player == null) return
|
|
||||||
|
|
||||||
val renderWidth = FastMath.ceil(App.scr.wf)
|
|
||||||
val renderHeight = FastMath.ceil(App.scr.hf)
|
|
||||||
|
|
||||||
val noZoomCameraX = Math.round(FastMath.clamp(
|
|
||||||
player.hitbox.centeredX.toFloat() - renderWidth / 2, TILE_SIZEF, map.width * TILE_SIZE - renderWidth - TILE_SIZEF))
|
|
||||||
val noZoomCameraY = Math.round(FastMath.clamp(
|
|
||||||
player.hitbox.centeredY.toFloat() - renderHeight / 2, TILE_SIZEF, map.width * TILE_SIZE - renderHeight - TILE_SIZEF))
|
|
||||||
|
|
||||||
val for_x_start = noZoomCameraX / TILE_SIZE
|
|
||||||
val for_y_start = noZoomCameraY / TILE_SIZE
|
|
||||||
val for_y_end = BlocksDrawer.clampHTile(for_y_start + (renderHeight / TILE_SIZE) + 2)
|
|
||||||
val for_x_end = BlocksDrawer.clampWTile(for_x_start + (renderWidth / TILE_SIZE) + 2)
|
|
||||||
|
|
||||||
for (y in for_y_start..for_y_end - 1) {
|
|
||||||
for (x in for_x_start..for_x_end - 1) {
|
|
||||||
val tileWall = map.getTileFromWall(x, y)
|
|
||||||
val tileTerrain = map.getTileFromTerrain(x, y)
|
|
||||||
tilestat[tileWall] = 1 + (tilestat[tileWall] ?: 0)
|
|
||||||
tilestat[tileTerrain] = 1 + (tilestat[tileTerrain] ?: 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getCount(vararg tiles: ItemID): Int {
|
|
||||||
return tiles.fold(0) { acc, key -> acc + (tilestat[key] ?: 0) }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
78
src/net/torvald/terrarum/blockstats/TileSurvey.kt
Normal file
78
src/net/torvald/terrarum/blockstats/TileSurvey.kt
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package net.torvald.terrarum.blockstats
|
||||||
|
|
||||||
|
import com.jme3.math.FastMath
|
||||||
|
import net.torvald.terrarum.App
|
||||||
|
import net.torvald.terrarum.INGAME
|
||||||
|
import net.torvald.terrarum.Terrarum
|
||||||
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2016-02-01.
|
||||||
|
*/
|
||||||
|
object TileSurvey {
|
||||||
|
|
||||||
|
data class SurveyProposal(
|
||||||
|
val surveyIdentifier: String,
|
||||||
|
val width: Int,
|
||||||
|
val height: Int,
|
||||||
|
val spatialGranularity: Int, // 1: survey every (w*h) tile, 2: survey every other (w*h/4) tile ...
|
||||||
|
val temporalGranularity: Int, // 1: survey every frame, 2: every other frame ...
|
||||||
|
val predicate: (GameWorld, Int, Int) -> Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
private val proposals = HashMap<String, SurveyProposal>()
|
||||||
|
private val results = HashMap<String, Pair<Double, Int>>() // (matching tiles/actually surveyed tiles)
|
||||||
|
|
||||||
|
fun submitProposal(proposal: SurveyProposal) {
|
||||||
|
proposals[proposal.surveyIdentifier] = proposal
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withdrawProposal(surveyIdentifier: String) {
|
||||||
|
proposals.remove(surveyIdentifier)
|
||||||
|
results.remove(surveyIdentifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update tile stats from tiles on screen
|
||||||
|
*/
|
||||||
|
fun update() {
|
||||||
|
|
||||||
|
// Get stats on no-zoomed screen area. In other words, will behave as if screen zoom were 1.0
|
||||||
|
// no matter how the screen is zoomed.
|
||||||
|
val world = INGAME.world
|
||||||
|
val player = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying
|
||||||
|
if (player == null) return
|
||||||
|
|
||||||
|
proposals.forEach { (_, proposal) ->
|
||||||
|
|
||||||
|
if (INGAME.WORLD_UPDATE_TIMER % proposal.temporalGranularity == 0) {
|
||||||
|
val for_x_start = floor(player.intTilewiseHitbox.centeredX - proposal.width / 2.0).toInt()
|
||||||
|
val for_y_start = floor(player.intTilewiseHitbox.centeredY - proposal.height / 2.0).toInt()
|
||||||
|
val for_x_end = ceil(player.intTilewiseHitbox.centeredX + proposal.width / 2.0).toInt()
|
||||||
|
val for_y_end = ceil(player.intTilewiseHitbox.centeredY + proposal.height / 2.0).toInt()
|
||||||
|
|
||||||
|
var akku = 0
|
||||||
|
|
||||||
|
for (y in for_y_start until for_y_end step proposal.spatialGranularity) {
|
||||||
|
for (x in for_x_start until for_x_end step proposal.spatialGranularity) {
|
||||||
|
if (proposal.predicate(world, x, y)) akku += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val surveyedTileCount =
|
||||||
|
(proposal.width * proposal.height) / (proposal.spatialGranularity * proposal.spatialGranularity)
|
||||||
|
val ratio = akku.toDouble() / surveyedTileCount
|
||||||
|
|
||||||
|
results[proposal.surveyIdentifier] = ratio to akku
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getRawCount(surveyIdentifier: String) = results[surveyIdentifier]?.second
|
||||||
|
fun getRatio(surveyIdentifier: String) = results[surveyIdentifier]?.first
|
||||||
|
fun getRatioAndRawCount(surveyIdentifier: String) = results[surveyIdentifier]
|
||||||
|
|
||||||
|
}
|
||||||
@@ -11,7 +11,7 @@ import net.torvald.terrarum.Terrarum.getWorldSaveFiledesc
|
|||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||||
import net.torvald.terrarum.blockproperties.BlockPropUtil
|
import net.torvald.terrarum.blockproperties.BlockPropUtil
|
||||||
import net.torvald.terrarum.blockstats.BlockStats
|
import net.torvald.terrarum.blockstats.TileSurvey
|
||||||
import net.torvald.terrarum.blockstats.MinimapComposer
|
import net.torvald.terrarum.blockstats.MinimapComposer
|
||||||
import net.torvald.terrarum.concurrent.ThreadExecutor
|
import net.torvald.terrarum.concurrent.ThreadExecutor
|
||||||
import net.torvald.terrarum.console.AVTracker
|
import net.torvald.terrarum.console.AVTracker
|
||||||
@@ -800,7 +800,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
|
|||||||
WeatherMixer.update(delta, actorNowPlaying, world)
|
WeatherMixer.update(delta, actorNowPlaying, world)
|
||||||
}
|
}
|
||||||
measureDebugTime("BlockStats.update") {
|
measureDebugTime("BlockStats.update") {
|
||||||
BlockStats.update()
|
TileSurvey.update()
|
||||||
}
|
}
|
||||||
// fill up visibleActorsRenderFront for wires but not on every update
|
// fill up visibleActorsRenderFront for wires but not on every update
|
||||||
measureDebugTime("Ingame.FillUpWiresBuffer*") {
|
measureDebugTime("Ingame.FillUpWiresBuffer*") {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
|
|||||||
import net.torvald.terrarum.blendMul
|
import net.torvald.terrarum.blendMul
|
||||||
import net.torvald.terrarum.blendNormalStraightAlpha
|
import net.torvald.terrarum.blendNormalStraightAlpha
|
||||||
import net.torvald.terrarum.blockproperties.Block
|
import net.torvald.terrarum.blockproperties.Block
|
||||||
import net.torvald.terrarum.blockstats.BlockStats
|
import net.torvald.terrarum.blockstats.TileSurvey
|
||||||
import net.torvald.terrarum.gameworld.GameWorld
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
@@ -42,6 +42,19 @@ object FeaturesDrawer {
|
|||||||
Block.SAND_DESERT
|
Block.SAND_DESERT
|
||||||
, Block.SAND_RED)
|
, Block.SAND_RED)
|
||||||
|
|
||||||
|
init {
|
||||||
|
TileSurvey.submitProposal(
|
||||||
|
TileSurvey.SurveyProposal(
|
||||||
|
"basegame.FeaturesDrawer.coldTiles", 72, 48, 2, 2
|
||||||
|
) { world, x, y -> TILES_COLD.contains(world.getTileFromTerrain(x, y)) }
|
||||||
|
)
|
||||||
|
TileSurvey.submitProposal(
|
||||||
|
TileSurvey.SurveyProposal(
|
||||||
|
"basegame.FeaturesDrawer.warmTiles", 72, 48, 2, 2
|
||||||
|
) { world, x, y -> TILES_WARM.contains(world.getTileFromTerrain(x, y)) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun update(delta: Float) {
|
fun update(delta: Float) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,13 +63,12 @@ object FeaturesDrawer {
|
|||||||
* usually targeted for the environmental temperature (desert/winterland), hence the name.
|
* usually targeted for the environmental temperature (desert/winterland), hence the name.
|
||||||
*/
|
*/
|
||||||
fun drawEnvOverlay(batch: SpriteBatch) {
|
fun drawEnvOverlay(batch: SpriteBatch) {
|
||||||
val onscreen_tiles_max = FastMath.ceil(App.scr.height * App.scr.width / FastMath.sqr(TILE_SIZEF)) * 2
|
val onscreen_tiles_cap = 0.3
|
||||||
val onscreen_tiles_cap = onscreen_tiles_max / 4f
|
val onscreen_cold_tiles = (TileSurvey.getRatio("basegame.FeaturesDrawer.coldTiles") ?: 0.0).coerceAtMost(onscreen_tiles_cap)
|
||||||
val onscreen_cold_tiles = BlockStats.getCount(*TILES_COLD).toFloat()
|
val onscreen_warm_tiles = (TileSurvey.getRatio("basegame.FeaturesDrawer.warmTiles") ?: 0.0).coerceAtMost(onscreen_tiles_cap)
|
||||||
val onscreen_warm_tiles = BlockStats.getCount(*TILES_WARM).toFloat()
|
|
||||||
|
|
||||||
val colTemp_cold = colTempLinearFunc(onscreen_cold_tiles / onscreen_tiles_cap)
|
val colTemp_cold = colTempLinearFunc((onscreen_cold_tiles / onscreen_tiles_cap).toFloat())
|
||||||
val colTemp_warm = colTempLinearFunc(-(onscreen_warm_tiles / onscreen_tiles_cap))
|
val colTemp_warm = colTempLinearFunc(-(onscreen_warm_tiles / onscreen_tiles_cap).toFloat())
|
||||||
colTemp = colTemp_warm + colTemp_cold - ENV_COLTEMP_NOON
|
colTemp = colTemp_warm + colTemp_cold - ENV_COLTEMP_NOON
|
||||||
val zoom = Terrarum.ingame?.screenZoom ?: 1f
|
val zoom = Terrarum.ingame?.screenZoom ?: 1f
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user