mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-16 13:34:06 +09:00
weather in weathercodex
This commit is contained in:
@@ -2,10 +2,10 @@ package net.torvald.terrarum.weather
|
||||
|
||||
import com.badlogic.gdx.graphics.Texture
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.badlogic.gdx.math.Vector3
|
||||
import com.badlogic.gdx.utils.JsonValue
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.GdxColorMap
|
||||
import net.torvald.terrarum.TaggedProp
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
@@ -21,7 +21,7 @@ data class BaseModularWeather(
|
||||
val json: JsonValue,
|
||||
var skyboxGradColourMap: GdxColorMap, // row 0: skybox grad top, row 1: skybox grad bottom, row 2: sunlight (RGBA)
|
||||
val daylightClut: GdxColorMap,
|
||||
val classification: String,
|
||||
val tags: List<String>,
|
||||
val cloudChance: Float,
|
||||
val windSpeed: Float,
|
||||
val windSpeedVariance: Float,
|
||||
@@ -33,7 +33,7 @@ data class BaseModularWeather(
|
||||
|
||||
val mixFrom: String? = null,
|
||||
val mixPercentage: Double? = null,
|
||||
) {
|
||||
) : TaggedProp {
|
||||
|
||||
|
||||
/**
|
||||
@@ -60,6 +60,10 @@ data class BaseModularWeather(
|
||||
|
||||
return Vector2(gx, gy)
|
||||
}
|
||||
|
||||
|
||||
override fun hasTag(s: String) = tags.contains(s)
|
||||
|
||||
}
|
||||
|
||||
data class CloudProps(
|
||||
|
||||
121
src/net/torvald/terrarum/weather/WeatherCodex.kt
Normal file
121
src/net/torvald/terrarum/weather/WeatherCodex.kt
Normal file
@@ -0,0 +1,121 @@
|
||||
package net.torvald.terrarum.weather
|
||||
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.badlogic.gdx.utils.Disposable
|
||||
import net.torvald.terrarum.App
|
||||
import net.torvald.terrarum.GdxColorMap
|
||||
import net.torvald.terrarum.ModMgr
|
||||
import net.torvald.terrarum.tryDispose
|
||||
import net.torvald.terrarum.utils.JsonFetcher
|
||||
import net.torvald.terrarum.utils.forEachSiblings
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Created by minjaesong on 2024-04-13.
|
||||
*/
|
||||
class WeatherCodex : Disposable {
|
||||
|
||||
internal val weatherById = HashMap<String, BaseModularWeather>()
|
||||
internal val weatherByTags = HashMap<String, MutableSet<BaseModularWeather>>()
|
||||
|
||||
fun getById(id: String) = weatherById[id]
|
||||
|
||||
fun getByAllTags(tags: Array<String>) = weatherById.values.filter { it.hasAllTags(tags) }.ifEmpty { null }
|
||||
fun getByAllTags(tags: Collection<String>) = weatherById.values.filter { it.hasAllTags(tags) }.ifEmpty { null }
|
||||
fun getByAllTagsOf(tag: String, vararg tags: String) = weatherById.values.filter { it.hasAllTags(tags.toList() + tag) }.ifEmpty { null }
|
||||
|
||||
fun getByAnyTag(tags: Array<String>) = weatherById.values.filter { it.hasAnyTags(tags) }.ifEmpty { null }
|
||||
fun getByAnyTag(tags: Collection<String>) = weatherById.values.filter { it.hasAnyTags(tags) }.ifEmpty { null }
|
||||
fun getByAnyTag(tag: String, vararg tags: String) = weatherById.values.filter { it.hasAnyTags(tags.toList() + tag) }.ifEmpty { null }
|
||||
|
||||
fun getByTag(tag: String) = weatherByTags[tag]
|
||||
|
||||
|
||||
init {
|
||||
App.disposables.add(this)
|
||||
}
|
||||
|
||||
|
||||
fun readFromJson(modname: String, file: File) = readFromJson(modname, file.path)
|
||||
|
||||
fun readFromJson(modname: String, path: String) {
|
||||
/* JSON structure:
|
||||
{
|
||||
"skyboxGradColourMap": "colourmap/sky_colour.tga", // string (path to image) for dynamic. Image must be RGBA8888 or RGB888
|
||||
"extraImages": [
|
||||
// if any, it will be like:
|
||||
sun01.tga,
|
||||
clouds01.tga,
|
||||
clouds02.tga,
|
||||
auroraBlueViolet.tga
|
||||
]
|
||||
}
|
||||
*/
|
||||
val pathToImage = "weathers"
|
||||
|
||||
val JSON = JsonFetcher(path)
|
||||
|
||||
val skyboxInJson = JSON.getString("skyboxGradColourMap")
|
||||
val lightbox = JSON.getString("daylightClut")
|
||||
|
||||
val cloudsMap = ArrayList<CloudProps>()
|
||||
val clouds = JSON["clouds"]
|
||||
clouds.forEachSiblings { name, json ->
|
||||
cloudsMap.add(CloudProps(
|
||||
name,
|
||||
TextureRegionPack(ModMgr.getGdxFile(modname, "$pathToImage/${json.getString("filename")}"), json.getInt("tw"), json.getInt("th")),
|
||||
json.getFloat("probability"),
|
||||
json.getFloat("baseScale"),
|
||||
json.getFloat("scaleVariance"),
|
||||
json.getFloat("altLow"),
|
||||
json.getFloat("altHigh"),
|
||||
))
|
||||
}
|
||||
cloudsMap.sortBy { it.probability }
|
||||
|
||||
|
||||
val ident = JSON.getString("identifier")
|
||||
val tags = JSON.getString("tags").split(',')
|
||||
|
||||
val obj = BaseModularWeather(
|
||||
identifier = ident,
|
||||
json = JSON,
|
||||
skyboxGradColourMap = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${skyboxInJson}")),
|
||||
daylightClut = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${lightbox}")),
|
||||
tags = tags,
|
||||
cloudChance = JSON.getFloat("cloudChance"),
|
||||
windSpeed = JSON.getFloat("windSpeed"),
|
||||
windSpeedVariance = JSON.getFloat("windSpeedVariance"),
|
||||
windSpeedDamping = JSON.getFloat("windSpeedDamping"),
|
||||
cloudGamma = JSON["cloudGamma"].asFloatArray().let { Vector2(it[0], it[1]) },
|
||||
cloudGammaVariance = JSON["cloudGammaVariance"].asFloatArray().let { Vector2(it[0], it[1]) },
|
||||
clouds = cloudsMap,
|
||||
shaderVibrancy = JSON["shaderVibrancy"].asFloatArray()
|
||||
)
|
||||
|
||||
weatherById[ident] = obj
|
||||
tags.forEach {
|
||||
if (weatherByTags[it] == null) {
|
||||
weatherByTags[it] = mutableSetOf()
|
||||
}
|
||||
|
||||
weatherByTags[it]!!.add(obj)
|
||||
}
|
||||
}
|
||||
|
||||
override fun dispose() {
|
||||
weatherById.values.forEach {
|
||||
it.clouds.forEach { it.spriteSheet.tryDispose() }
|
||||
}
|
||||
}
|
||||
|
||||
fun getRandom(tag: String? = null): BaseModularWeather {
|
||||
return if (tag == null) {
|
||||
var k = weatherById.values.random()
|
||||
if (k.identifier == "titlescreen") k = weatherById.values.random()
|
||||
k
|
||||
}
|
||||
else getByTag(tag)!!.random()
|
||||
}
|
||||
}
|
||||
@@ -59,7 +59,7 @@ internal object WeatherMixer : RNGConsumer {
|
||||
JsonValue(JsonValue.ValueType.`object`),
|
||||
GdxColorMap(1, 3, Color(0x55aaffff), Color(0xaaffffff.toInt()), Color.WHITE),
|
||||
GdxColorMap(2, 2, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE),
|
||||
"default",
|
||||
listOf("default"),
|
||||
0f,
|
||||
0f,
|
||||
0f,
|
||||
@@ -74,9 +74,6 @@ internal object WeatherMixer : RNGConsumer {
|
||||
|
||||
var globalLightOverridden = false
|
||||
|
||||
val weatherDB: HashMap<String, ArrayList<BaseModularWeather>> // search by classification
|
||||
val weatherDict: HashMap<String, BaseModularWeather> // search by identifier
|
||||
|
||||
private var forceWindVec: Vector3? = null
|
||||
|
||||
val globalLightNow = Cvec(0)
|
||||
@@ -153,37 +150,6 @@ internal object WeatherMixer : RNGConsumer {
|
||||
oldCamPos.set(WorldCamera.camVector)
|
||||
}
|
||||
|
||||
init {
|
||||
weatherDB = HashMap<String, ArrayList<BaseModularWeather>>()
|
||||
weatherDict = HashMap<String, BaseModularWeather>()
|
||||
|
||||
|
||||
// read weather descriptions from assets/weather (modular weather)
|
||||
val weatherRawValidList = ArrayList<Pair<String, File>>()
|
||||
val weatherRawsDir = ModMgr.getFilesFromEveryMod("weathers")
|
||||
weatherRawsDir.forEach { (modname, parentdir) ->
|
||||
printdbg(this, "Scanning dir $parentdir")
|
||||
parentdir.listFiles(FileFilter { !it.isDirectory && it.name.endsWith(".json") })?.forEach {
|
||||
weatherRawValidList.add(modname to it)
|
||||
printdbg(this, "Registering weather '$it' from module $modname")
|
||||
}
|
||||
}
|
||||
// --> read from directory and store file that looks like RAW
|
||||
for ((modname, raw) in weatherRawValidList) {
|
||||
val weather = readFromJson(modname, raw)
|
||||
|
||||
weatherDict[weather.identifier] = weather
|
||||
|
||||
// if List for the classification does not exist, make one
|
||||
if (!weatherDB.containsKey(weather.classification))
|
||||
weatherDB.put(weather.classification, ArrayList())
|
||||
|
||||
weatherDB[weather.classification]!!.add(weather)
|
||||
}
|
||||
|
||||
weatherDict["titlescreen"] = weatherDB[WEATHER_GENERIC]?.get(0)?.copy(identifier = "titlescreen", windSpeed = 1f) ?: DEFAULT_WEATHER
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of Ingame update
|
||||
*/
|
||||
@@ -527,7 +493,7 @@ internal object WeatherMixer : RNGConsumer {
|
||||
}
|
||||
|
||||
internal fun titleScreenInitWeather(weatherbox: Weatherbox) {
|
||||
weatherbox.initWith(weatherDict["titlescreen"]!!, Long.MAX_VALUE)
|
||||
weatherbox.initWith(WeatherCodex.getById("titlescreen")!!, Long.MAX_VALUE)
|
||||
forceWindVec = Vector3(
|
||||
-0.98f,
|
||||
0f,
|
||||
@@ -923,72 +889,7 @@ internal object WeatherMixer : RNGConsumer {
|
||||
return lerp(x, c1.linearise(), c2.linearise()).unlinearise()
|
||||
}
|
||||
|
||||
fun getWeatherList(classification: String) = weatherDB[classification]!!
|
||||
fun getRandomWeather(classification: String) =
|
||||
getWeatherList(classification)[RNG.nextInt(getWeatherList(classification).size)]
|
||||
|
||||
fun readFromJson(modname: String, file: File): BaseModularWeather = readFromJson(modname, file.path)
|
||||
|
||||
fun readFromJson(modname: String, path: String): BaseModularWeather {
|
||||
/* JSON structure:
|
||||
{
|
||||
"skyboxGradColourMap": "colourmap/sky_colour.tga", // string (path to image) for dynamic. Image must be RGBA8888 or RGB888
|
||||
"extraImages": [
|
||||
// if any, it will be like:
|
||||
sun01.tga,
|
||||
clouds01.tga,
|
||||
clouds02.tga,
|
||||
auroraBlueViolet.tga
|
||||
]
|
||||
}
|
||||
*/
|
||||
val pathToImage = "weathers"
|
||||
|
||||
val JSON = JsonFetcher(path)
|
||||
|
||||
val skyboxInJson = JSON.getString("skyboxGradColourMap")
|
||||
val lightbox = JSON.getString("daylightClut")
|
||||
|
||||
val cloudsMap = ArrayList<CloudProps>()
|
||||
val clouds = JSON["clouds"]
|
||||
clouds.forEachSiblings { name, json ->
|
||||
cloudsMap.add(CloudProps(
|
||||
name,
|
||||
TextureRegionPack(ModMgr.getGdxFile(modname, "$pathToImage/${json.getString("filename")}"), json.getInt("tw"), json.getInt("th")),
|
||||
json.getFloat("probability"),
|
||||
json.getFloat("baseScale"),
|
||||
json.getFloat("scaleVariance"),
|
||||
json.getFloat("altLow"),
|
||||
json.getFloat("altHigh"),
|
||||
))
|
||||
}
|
||||
cloudsMap.sortBy { it.probability }
|
||||
|
||||
|
||||
|
||||
return BaseModularWeather(
|
||||
identifier = JSON.getString("identifier"),
|
||||
json = JSON,
|
||||
skyboxGradColourMap = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${skyboxInJson}")),
|
||||
daylightClut = GdxColorMap(ModMgr.getGdxFile(modname, "$pathToImage/${lightbox}")),
|
||||
classification = JSON.getString("classification"),
|
||||
cloudChance = JSON.getFloat("cloudChance"),
|
||||
windSpeed = JSON.getFloat("windSpeed"),
|
||||
windSpeedVariance = JSON.getFloat("windSpeedVariance"),
|
||||
windSpeedDamping = JSON.getFloat("windSpeedDamping"),
|
||||
cloudGamma = JSON["cloudGamma"].asFloatArray().let { Vector2(it[0], it[1]) },
|
||||
cloudGammaVariance = JSON["cloudGammaVariance"].asFloatArray().let { Vector2(it[0], it[1]) },
|
||||
clouds = cloudsMap,
|
||||
shaderVibrancy = JSON["shaderVibrancy"].asFloatArray()
|
||||
)
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
weatherDB.values.forEach { list ->
|
||||
list.forEach { weather ->
|
||||
weather.clouds.forEach { it.spriteSheet.dispose() }
|
||||
}
|
||||
}
|
||||
starmapTex.texture.dispose()
|
||||
shaderAstrum.dispose()
|
||||
shaderClouds.dispose()
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.weather
|
||||
import com.badlogic.gdx.math.Vector2
|
||||
import com.jme3.math.FastMath
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.WeatherCodex
|
||||
import net.torvald.terrarum.floorToInt
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.gameworld.fmod
|
||||
@@ -64,9 +65,9 @@ class Weatherbox {
|
||||
|
||||
private fun pickNextWeather(): WeatherSchedule {
|
||||
// temporary setup for the release
|
||||
val newName = if (takeUniformRand(0f..1f) < 0.5f) "generic01" else "generic02"
|
||||
val newWeather = WeatherCodex.getRandom()
|
||||
val newDuration = takeTriangularRand(3600f..10800f).roundToLong()
|
||||
return WeatherSchedule(WeatherMixer.weatherDict[newName]!!, newDuration)
|
||||
return WeatherSchedule(newWeather, newDuration)
|
||||
}
|
||||
|
||||
fun update(world: GameWorld) {
|
||||
|
||||
Reference in New Issue
Block a user