181 lines
7.9 KiB
Kotlin
181 lines
7.9 KiB
Kotlin
package com.dowstats.service.w40k
|
|
|
|
import com.dowstats.Metadata.Requirements
|
|
import com.dowstats.data.dto.AreaEffect
|
|
import com.dowstats.data.dto.BuildCost
|
|
import com.dowstats.data.dto.ResourceIncome
|
|
import com.dowstats.data.dto.UiInfo
|
|
import com.dowstats.data.entities.Mod
|
|
import com.dowstats.data.entities.ability.Ability
|
|
import com.dowstats.data.rgd.RgdData
|
|
import com.dowstats.data.rgd.RgdDataUtil.getBooleanByName
|
|
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
|
|
import com.dowstats.data.rgd.RgdDataUtil.getIntByName
|
|
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
|
|
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
|
|
import org.slf4j.Logger
|
|
import org.springframework.beans.factory.annotation.Autowired
|
|
import org.springframework.stereotype.Service
|
|
|
|
@Service
|
|
class CommonParseRgdService @Autowired constructor(
|
|
private val modAttribPathService: ModAttribPathService,
|
|
private val iconsService: IconsService,
|
|
) {
|
|
|
|
|
|
fun getRequirementReference(ref: String?, rTable: List<RgdData>, fileName: String, log: Logger): String? = when (ref) {
|
|
Requirements.REFERENCE_REQUIREMENT_POP -> rTable.getDoubleByName("population_required").toString()
|
|
Requirements.REFERENCE_REQUIREMENT_ADDON -> rTable.getStringByName("addon_name")
|
|
Requirements.REFERENCE_GLOBAL_REQUIREMENT_ADDON -> rTable.getStringByName("global_addon_name")
|
|
Requirements.REFERENCE_REQUIREMENT_STRUCTURE_EITHER -> rTable.getStringByName("structure_name_or") + ";" +
|
|
rTable.getStringByName("structure_name_either")
|
|
Requirements.REFERENCE_REQUIREMENT_STRUCTURE -> rTable.getStringByName("structure_name")
|
|
Requirements.REFERENCE_REQUIREMENT_RESEARCH -> rTable.getStringByName("research_name") + ";" +
|
|
rTable.getBooleanByName("research_must_not_be_complete")
|
|
Requirements.REFERENCE_REQUIREMENT_OWNERSHIP -> rTable.getStringByName("own_name")
|
|
Requirements.REFERENCE_REQUIREMENT_CAP -> rTable.getIntByName("max_cap").toString()
|
|
Requirements.REFERENCE_REQUIREMENT_SQUAD_CAP -> rTable.getIntByName("max_squad_cap").toString()
|
|
Requirements.REFERENCE_REQUIREMENT_CUM_SQUAD_CAP -> rTable.getIntByName("max_cumulative_squad_cap").toString()
|
|
Requirements.REFERENCE_REQUIREMENT_STRUCTURE_RATIO -> rTable.getStringByName("required_structure_name") + ";" +
|
|
rTable.getIntByName("this_structure_count").toString()
|
|
else -> {
|
|
log.warn("Unknown requirement reference $ref at $fileName")
|
|
null
|
|
}
|
|
}
|
|
|
|
fun getBuildCost(cost: List<RgdData>?): BuildCost {
|
|
|
|
val costResources = cost?.getRgdTableByName("cost")
|
|
|
|
return BuildCost(
|
|
costResources?.getDoubleByName("requisition"),
|
|
costResources?.getDoubleByName("power"),
|
|
costResources?.getDoubleByName("population"),
|
|
costResources?.getDoubleByName("faith"),
|
|
costResources?.getDoubleByName("souls"),
|
|
cost?.getDoubleByName("time_seconds")?.toInt()
|
|
)
|
|
}
|
|
|
|
fun getResourceIncome(resourceExt: List<RgdData>?): ResourceIncome {
|
|
return ResourceIncome(
|
|
resourceExt?.getDoubleByName("faith_per_second")?.let { it * 10 },
|
|
resourceExt?.getDoubleByName("power_per_second")?.let { it * 10 },
|
|
resourceExt?.getDoubleByName("requisition_per_second")?.let { it * 10 },
|
|
)
|
|
}
|
|
|
|
|
|
fun getUiInfo(uiInfoRgdData: List<RgdData>, modDictionary: Map<Int, String>, modFolderData: String, mod: Mod, log: Logger, isOnOfAbility: Boolean = false): UiInfo {
|
|
val nameRef = uiInfoRgdData?.getStringByName("screen_name_id")?.replace("$", "")
|
|
val name = nameRef?.let { try { modDictionary[it.toInt()] } catch (e: Exception) { it } }
|
|
|
|
val descriptionRefs = uiInfoRgdData.getRgdTableByName("help_text_list")
|
|
?.mapNotNull{try {
|
|
(it.value as String).replace("$", "")
|
|
} catch (e: Exception) {
|
|
log.error("Error parsing ui help_text weapon $name", e)
|
|
null
|
|
}}
|
|
?.filter{it != "0" && it != "tables\\text_table.lua" && it != ""}
|
|
?.sortedBy { try { it.toInt() } catch (e: Exception) { 0 } }
|
|
|
|
val description = try {
|
|
descriptionRefs?.map { try { modDictionary[it.toInt()] } catch (e: Exception) { it } }?.joinToString ( "\n" )
|
|
} catch(e:Exception) {
|
|
log.warn("Error parsing ui description weapon $name", e)
|
|
null
|
|
}
|
|
|
|
val icon = try {
|
|
val iconPath = if (isOnOfAbility) {
|
|
uiInfoRgdData.getStringByName("icon_name") + "_off"
|
|
} else uiInfoRgdData.getStringByName("icon_name")
|
|
|
|
iconPath?.let { modAttribPathService.getIconPath(modFolderData, iconPath) }
|
|
?.let { iconsService.convertTgaToJpegImage(iconPath, it, mod.name) }
|
|
} catch (e: Exception) {
|
|
log.error("Error parsing ui icon path for $name", e)
|
|
null
|
|
}
|
|
|
|
return UiInfo(name, description, icon)
|
|
}
|
|
|
|
fun getAreaEffectData(areaEffectData: List<RgdData>): AreaEffect {
|
|
|
|
val areaEffectInformation = areaEffectData.getRgdTableByName("area_effect_information")
|
|
|
|
val areaType = areaEffectInformation?.getRgdTableByName("area_type")
|
|
?.getStringByName("\$REF")
|
|
?.replace("type_areaeffect\\tp_","")
|
|
?.replace(".lua","")
|
|
|
|
val filterType = areaEffectInformation?.getRgdTableByName("filter_type")
|
|
?.getStringByName("\$REF")
|
|
?.replace("type_areafilter\\tp_","")
|
|
?.replace(".lua","")
|
|
|
|
val cantHaveRadius = areaEffectInformation?.equals("area_effect_point") == true
|
|
val damageRadius = if(cantHaveRadius) 0.0 else areaEffectInformation?.getDoubleByName("radius") ?: 0.0
|
|
|
|
val throwData = areaEffectData.getRgdTableByName("throw_data")
|
|
val forceMin = throwData?.getDoubleByName("force_min") ?: 0.0
|
|
val forceMax = throwData?.getDoubleByName("force_max") ?: 0.0
|
|
|
|
val armourDamage = areaEffectData
|
|
.getRgdTableByName("weapon_damage")
|
|
?.getRgdTableByName("armour_damage")
|
|
val minDamage = armourDamage?.getDoubleByName("min_damage") ?: 0.0
|
|
val maxDamage = armourDamage?.getDoubleByName("max_damage") ?: 0.0
|
|
val minDamageValue = armourDamage?.getDoubleByName("min_damage_value") ?: 0.0
|
|
val moraleDamage = armourDamage?.getDoubleByName("morale_damage") ?: 0.0
|
|
|
|
|
|
|
|
val defaultArmourPiercing = armourDamage?.getDoubleByName("armour_piercing") ?: 0.0
|
|
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() ?: emptyMap()
|
|
|
|
|
|
|
|
return AreaEffect(
|
|
minDamage,
|
|
maxDamage,
|
|
damageRadius,
|
|
forceMin,
|
|
forceMax,
|
|
minDamageValue,
|
|
moraleDamage,
|
|
weaponDmgMap,
|
|
defaultArmourPiercing,
|
|
areaType,
|
|
filterType
|
|
)
|
|
}
|
|
|
|
fun getAbilities(modelData: List<RgdData>?, abilities: Set<Ability>): List<Ability> = modelData
|
|
?.getRgdTableByName("ability_ext")
|
|
?.getRgdTableByName("abilities")
|
|
?.mapNotNull { ability ->
|
|
if (ability.name.contains("ability_")) {
|
|
val abilityFileName = (ability.value as String?)?.let{
|
|
it.replace("abilities\\", "").replace(".lua", "").replace(".rgd", "")
|
|
}
|
|
abilities.find { it.filename?.replace(".rgd", "") == abilityFileName }
|
|
} else null
|
|
} ?: emptyList()
|
|
|
|
|
|
}
|
|
|