Add unification races to db migration, add rgd samples

This commit is contained in:
Anibus 2025-03-19 01:13:27 +03:00
parent 0248c49aa1
commit 117186c06b
9 changed files with 335 additions and 245 deletions

View File

@ -207,12 +207,12 @@
{
"column": {
"name": "id",
"value": "ynnari"
"value": "tyranids"
}
},{
"column": {
"name": "name",
"value": "Ynnari"
"value": "Tyranids"
}
}
]
@ -224,12 +224,12 @@
{
"column": {
"name": "id",
"value": "ynnari"
"value": "thirteenth_company"
}
},{
"column": {
"name": "name",
"value": "Ynnari"
"value": "13th Company (Space Wolves)"
}
}
]
@ -241,12 +241,12 @@
{
"column": {
"name": "id",
"value": "ynnari"
"value": "mechanicus"
}
},{
"column": {
"name": "name",
"value": "Ynnari"
"value": "Adeptus Mechanicus Explorators"
}
}
]
@ -258,12 +258,12 @@
{
"column": {
"name": "id",
"value": "ynnari"
"value": "blood_angels"
}
},{
"column": {
"name": "name",
"value": "Ynnari"
"value": "Blood Angels"
}
}
]
@ -275,12 +275,12 @@
{
"column": {
"name": "id",
"value": "ynnari"
"value": "black_templars"
}
},{
"column": {
"name": "name",
"value": "Ynnari"
"value": "Black Templars"
}
}
]
@ -292,12 +292,148 @@
{
"column": {
"name": "id",
"value": "ynnari"
"value": "daemons"
}
},{
"column": {
"name": "name",
"value": "Ynnari"
"value": "Chaos Daemons"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "darkangels"
}
},{
"column": {
"name": "name",
"value": "Dark Angels"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "death_guard"
}
},{
"column": {
"name": "name",
"value": "Death Guard"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "emperors_children"
}
},{
"column": {
"name": "name",
"value": "Emperors Children"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "firstborn"
}
},{
"column": {
"name": "name",
"value": "Vostroyan Firstborn"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "harlequin"
}
},{
"column": {
"name": "name",
"value": "Harlequins"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "imperial_fists"
}
},{
"column": {
"name": "name",
"value": "Imperial Fists Siege Vanguard"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "inquisition_daemonhunt"
}
},{
"column": {
"name": "name",
"value": "Daemon Hunters"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "krieg"
}
},{
"column": {
"name": "name",
"value": "Death Korps of Krieg"
}
}
]
@ -314,7 +450,160 @@
},{
"column": {
"name": "name",
"value": "Renegade guard"
"value": "Renegade Guard"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "lotd"
}
},{
"column": {
"name": "name",
"value": "Legion of the Damned"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "night_lords"
}
},{
"column": {
"name": "name",
"value": "Night Lords"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "praetorian"
}
},{
"column": {
"name": "name",
"value": "Praetorian Guard"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "salamanders"
}
},{
"column": {
"name": "name",
"value": "Salamanders"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "thousand_sons"
}
},{
"column": {
"name": "name",
"value": "Thousand Sons"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "enclaves"
}
},{
"column": {
"name": "name",
"value": "Farsight Enclaves"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "fallenangels"
}
},{
"column": {
"name": "name",
"value": "Fallen Angels"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "raven_guard"
}
},{
"column": {
"name": "name",
"value": "Raven Guard"
}
}
]
}
},{
"insert": {
"tableName": "races",
"columns": [
{
"column": {
"name": "id",
"value": "khm"
}
},{
"column": {
"name": "name",
"value": "World Eaters"
}
}
]

View File

@ -1,14 +0,0 @@
import com.dowstats.configuration.StorageConfig
import com.dowstats.service.w40k.IconsService
import org.junit.jupiter.api.Test
class InconConvertServiceTest {
@Test
fun convertIcon() {
println(mapOf(1 to 3, 2 to 4) + mapOf(3 to 5, 5 to 6))
}
}

View File

@ -10,7 +10,7 @@ import java.io.File
import java.io.PrintWriter
import java.nio.ByteBuffer
class ModParserServiceTest {
class ModDiffPrinter {
val zeroByte: Byte = 0

View File

@ -7,7 +7,7 @@ import java.math.RoundingMode
import java.nio.ByteBuffer
import java.nio.file.Paths
class RgdParserServiceTest {
class RgdParserLab {
val zeroByte: Byte = 0

View File

@ -0,0 +1,31 @@
import com.dowstats.data.rgd.RgdData
import org.junit.jupiter.api.Test
import java.io.DataInputStream
import java.io.File
import java.io.PrintWriter
import java.math.RoundingMode
import java.nio.ByteBuffer
import java.nio.file.Paths
class Test {
@Test
fun test() {
File("M:\\SteamLibrary\\steamapps\\common\\Dawn of War Soulstorm\\Unification").listFiles().forEach {
if(it.name.endsWith(".sga")) {
try {
File(it.path + "\\Data\\attrib\\ebps\\races").listFiles().forEach {
println(it.name + " - " + it.path)
}
} catch (e: Exception) {
}
}
}
}
}

View File

@ -1,216 +0,0 @@
import com.dowstats.data.rgd.RgdData
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
import com.dowstats.service.w40k.RgdParserService
import com.dowstats.service.w40k.RgdService
import org.junit.jupiter.api.Test
import java.io.DataInputStream
import java.io.File
import java.nio.ByteBuffer
class UnificationResearchTest {
val zeroByte: Byte = 0
val rgdDictionary: MutableMap<Int, String> = mutableMapOf()
val rgdParseService = RgdParserService()
val rgdService = RgdService()
val blackTemplars = "black_templars"
val racesWikiPaths = setOf(blackTemplars)
fun readDictionary() {
File("src/test/resources/RGD_DIC.TXT").forEachLine {
if(it.isNotEmpty() && it[0] != '#'){
val kv = it.split('=')
val key = kv.first().drop(2).decodeHex().getUIntAt(0).toInt()
val value = kv.last()
rgdDictionary[key] = value
}
}
}
data class UnitAsSquad(val squadData: List<RgdData>?,val uintData: List<RgdData>?)
@Test
fun getAllUnits(): Map<String, UnitAsSquad> {
return racesWikiPaths.map{racePath ->
val rgdData42 = File("src/main/resources/static/mods/unification/attrib/sbps/races/$racePath").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
}else{
null
}
it.name to rgdData
}.filter { it.second != null }
.toMap()
val newUnits = File("src/main/resources/static/mods/unification/attrib/ebps/races/$racePath/troops").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
}else{
null
}
it.name to rgdData
}.filter { it.second != null }
.toMap()
rgdData42.map {newSquad ->
val baseUnitPath = ((newSquad.value?.find { it.name == "squad_loadout_ext" }?.value as List<RgdData>)
.find { it.name == "trooper_base" }?.value as List<RgdData>)
.find { it.name == "type" }?.value as String
val baseUnitName = baseUnitPath.split("\\").last().replace(".lua", ".rgd")
baseUnitName to UnitAsSquad(newSquad.value, newUnits[baseUnitName])
}.toMap()
}.fold(emptyMap()){sum, map -> map + sum}
}
fun getWeaponRgdMap(): Map<String, List<RgdData>?> {
return File("src/main/resources/static/mods/unification/attrib/weapon").walkTopDown().map {
val rgdData = if(it.isFile && !it.name.contains("hg_dxp3") && !it.name.contains("npc")){
rgdParseService.parseRgdFileStream(DataInputStream(it.inputStream()))
} else {
null
}
it.name.replace(".rgd", "") to rgdData
}.toMap()
}
@Test
fun getAllWeaponDamage() {
val weapons = getWeaponRgdMap()
val weaponsByDeamonDmg = weapons.toList()
.sortedByDescending { (key, weaponRgd) ->
try {
val reloadTime: Double = weaponRgd?.getDoubleByName("reload_time")!!
val accuracy: Double = weaponRgd?.getDoubleByName("accuracy")!!
val armourDamage = weaponRgd?.getRgdTableByName("area_effect")
?.getRgdTableByName("weapon_damage")
?.getRgdTableByName("armour_damage")
val minDamage = armourDamage?.getDoubleByName("min_damage")!!
val maxDamage = armourDamage.getDoubleByName("max_damage")!!
val avgDamage = (minDamage + maxDamage) / 2
val weaponDmgMap: Map<String, Double>? =
armourDamage
?.getRgdTableByName("armour_piercing_types")?.mapNotNull { armour_piercing ->
if (armour_piercing.name.contains("entry")) {
val entry = armour_piercing.value as List<RgdData>
val dmgType = entry.getRgdTableByName("armour_type")?.getStringByName("\$REF")?.replace("type_armour\\tp_","")?.replace(".lua","")
val dmgValue = entry.getDoubleByName("armour_piercing_value")
dmgType!! to dmgValue!!
} else null
}?.toMap()?.toSortedMap()
val dmgK = accuracy * (1/(reloadTime - reloadTime.mod(0.125)))
val piercingK = weaponDmgMap?.get("vehicle_low")!! / 100
val totalDmg = piercingK * dmgK * avgDamage
val res = (Math.round(totalDmg * 100.0) / 100.00)
res
} catch(exception: Exception) {
0.0
}
}
.filter { it.second != null }
.toMap()
print("<table><tr><th>name</th>")
weaponsByDeamonDmg.values.first()?.getRgdTableByName("area_effect")
?.getRgdTableByName("weapon_damage")
?.getRgdTableByName("armour_damage")
?.getRgdTableByName("armour_piercing_types")?.mapNotNull { armour_piercing ->
if (armour_piercing.name.contains("entry")) {
val entry = armour_piercing.value as List<RgdData>
val dmgType = entry.getRgdTableByName("armour_type")?.getStringByName("\$REF")?.replace("type_armour\\tp_","")?.replace(".lua","")
val dmgValue = entry.getDoubleByName("armour_piercing_value")
dmgType!! to dmgValue!!
} else null
}?.toMap()?.toSortedMap()?.forEach {
print("<th>${ it.key}</th>")
}
print("</tr>")
weaponsByDeamonDmg.forEach { (key, weaponRgd) ->
val reloadTime: Double = weaponRgd?.getDoubleByName("reload_time")!!
val accuracy: Double = weaponRgd.getDoubleByName("accuracy")!!
val armourDamage = weaponRgd?.getRgdTableByName("area_effect")
?.getRgdTableByName("weapon_damage")
?.getRgdTableByName("armour_damage")
val minDamage = armourDamage?.getDoubleByName("min_damage")!!
val maxDamage = armourDamage.getDoubleByName("max_damage")!!
val avgDamage = (minDamage + maxDamage) / 2
val weaponDmgMap: Map<String, Double>? =
armourDamage
?.getRgdTableByName("armour_piercing_types")?.mapNotNull { armour_piercing ->
if (armour_piercing.name.contains("entry")) {
val entry = armour_piercing.value as List<RgdData>
val dmgType = entry.getRgdTableByName("armour_type")?.getStringByName("\$REF")?.replace("type_armour\\tp_","")?.replace(".lua","")
val dmgValue = entry.getDoubleByName("armour_piercing_value")
dmgType!! to dmgValue!!
} else null
}?.toMap()?.toSortedMap()
println("<tr><td>$key</td>")
val dmgK = accuracy * (1/(reloadTime - reloadTime.mod(0.125)))
weaponDmgMap?.forEach {
val piercingK = it.value / 100
val totalDmg = piercingK * dmgK * avgDamage
print("<td>${ (Math.round(totalDmg * 100.0) / 100.00)}</td>")
}
println()
println("</tr>")
}
println("</table>")
}
private fun findStrategicPointCaptureRate(rgdDataList: List<RgdData>): Double? {
val capRgdData = rgdDataList.find { it.name == "squad_capture_strategic_point_ext" }?.value as List<RgdData>?
val canCapture = capRgdData?.find { it.name == "able_to_capture" }?.value == "[1]"
val captureRate = capRgdData?.find { it.name == "capture_rate" }
return if(canCapture){
captureRate?.value as Double?
} else null
}
private fun findVisionCaptureRate(rgdDataList: List<RgdData>): Double? {
val visionRgdData = rgdDataList.find { it.name == "sight_ext" }?.value as List<RgdData>?
return visionRgdData?.find { it.name == "sight_radius" }?.value as Double?
}
private fun String.decodeHex(): ByteArray {
check(length % 2 == 0) { "Must have an even length" }
return chunked(2)
.map { it.toInt(16).toByte() }
.toByteArray()
}
private fun ByteArray.getFloat(): Float {
val buffer = ByteBuffer.wrap(this)
return buffer.float
}
private fun ByteArray.getUIntAt(idx: Int): UInt =
((this[idx].toUInt() and 0xFFu) shl 24) or
((this[idx + 1].toUInt() and 0xFFu) shl 16) or
((this[idx + 2].toUInt() and 0xFFu) shl 8) or
(this[idx + 3].toUInt() and 0xFFu)
}