Add on/off weapon research dps and params tables feature
This commit is contained in:
parent
51bf0cdff1
commit
97ea7313b8
@ -0,0 +1,11 @@
|
||||
package com.dowstats.data.dto.controllers
|
||||
|
||||
/**
|
||||
* Описывает как исследование влияет на конкретное поле оружия
|
||||
* (урон, точность, перезарядка и т.д.).
|
||||
*/
|
||||
data class ResearchEffectDto(
|
||||
val field: String,
|
||||
val usageType: String?,
|
||||
val modifierValue: Double?,
|
||||
)
|
||||
@ -36,4 +36,5 @@ data class WeaponDto(
|
||||
val modifiers: List<ModifierDto>,
|
||||
val requirements: RequirementDto?,
|
||||
val hotkey: String?,
|
||||
val researches: List<WeaponResearchDto>,
|
||||
)
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
package com.dowstats.data.dto.controllers
|
||||
|
||||
import com.dowstats.data.dto.controllers.research.ResearchShortDto
|
||||
|
||||
/**
|
||||
* Описывает влияние конкретного исследования (research) на оружие:
|
||||
* список эффектов по полям оружия (урон, точность, перезарядка и т.д.).
|
||||
*/
|
||||
data class WeaponResearchDto(
|
||||
val research: ResearchShortDto,
|
||||
val researchRequired: List<ResearchShortDto> = emptyList(),
|
||||
val effects: List<ResearchEffectDto>,
|
||||
)
|
||||
@ -2,6 +2,7 @@ package com.dowstats.data.entities.weapon
|
||||
|
||||
import com.dowstats.data.dto.controllers.RequirementDto
|
||||
import com.dowstats.data.dto.controllers.WeaponDto
|
||||
import com.dowstats.data.dto.controllers.WeaponResearchDto
|
||||
import com.dowstats.data.dto.controllers.WeaponShortDto
|
||||
import com.dowstats.data.entities.ability.Ability
|
||||
import com.dowstats.data.entities.sergant.SergeantWeapon
|
||||
@ -107,7 +108,7 @@ class Weapon {
|
||||
@OneToMany(mappedBy="weapon", cascade = [(CascadeType.ALL)])
|
||||
var weaponPiercings: List<WeaponArmorPiercing> = listOf()
|
||||
|
||||
fun toDto(requirementDto: RequirementDto?) = WeaponDto(
|
||||
fun toDto(requirementDto: RequirementDto?, researches: List<WeaponResearchDto>) = WeaponDto(
|
||||
id!!,
|
||||
filename!!,
|
||||
name,
|
||||
@ -140,6 +141,7 @@ class Weapon {
|
||||
weaponModifiers.map { mod -> mod.toDto().copy(maxLifeTime = mod.maxLifeTime) },
|
||||
requirementDto,
|
||||
uiHotkeyName,
|
||||
researches,
|
||||
)
|
||||
|
||||
fun toShortDto() = WeaponShortDto(
|
||||
|
||||
@ -0,0 +1,117 @@
|
||||
package com.dowstats.service.datamaps
|
||||
|
||||
import com.dowstats.Metadata.Requirements
|
||||
import com.dowstats.data.dto.controllers.ResearchEffectDto
|
||||
import com.dowstats.data.dto.controllers.WeaponResearchDto
|
||||
import com.dowstats.data.dto.controllers.research.ResearchShortDto
|
||||
import com.dowstats.data.entities.research.Research
|
||||
import com.dowstats.data.entities.weapon.Weapon
|
||||
import com.dowstats.data.repositories.ResearchRepository
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
/**
|
||||
* Builds detailed information about how researches affect a weapon's fields.
|
||||
* Maps research modifier references to weapon fields.
|
||||
*/
|
||||
@Component
|
||||
class WeaponResearchEffectMappingComponent(
|
||||
val researchRepository: ResearchRepository,
|
||||
) {
|
||||
|
||||
/**
|
||||
* Mapping from modifier reference name (without modifiers prefix and .lua suffix)
|
||||
* to the corresponding weapon field name.
|
||||
*/
|
||||
private val referenceToField: Map<String, String> = mapOf(
|
||||
"accuracy_moving_reduction_weapon_modifier" to "accuracyReductionMoving",
|
||||
"accuracy_ranged_weapon_modifier" to "accuracy",
|
||||
"accuracy_weapon_modifier" to "accuracy",
|
||||
"armour_piercing_weapon_modifier" to "armourPiercing",
|
||||
"max_damage_weapon_modifier" to "maxDamage",
|
||||
"max_range_weapon_modifier" to "maxRange",
|
||||
"min_damage_weapon_modifier" to "minDamage",
|
||||
"reload_time_weapon_modifier" to "reloadTime",
|
||||
"setup_time_weapon_modifier" to "setupTime",
|
||||
)
|
||||
|
||||
/**
|
||||
* Builds a list of WeaponResearchDto for a given weapon,
|
||||
* describing how each affecting research modifies the weapon's fields.
|
||||
*/
|
||||
fun buildEffects(weapon: Weapon): List<WeaponResearchDto> {
|
||||
val weaponTarget = weapon.filename?.replace(".rgd", "") ?: return emptyList()
|
||||
|
||||
return weapon.affectedResearches.mapNotNull { research ->
|
||||
val effects = research.researchModifiers
|
||||
.filter { modifier ->
|
||||
modifier.target == weaponTarget && modifier.reference != null
|
||||
}
|
||||
.mapNotNull { modifier ->
|
||||
val refName = extractRefName(modifier.reference!!)
|
||||
val field = referenceToField[refName] ?: return@mapNotNull null
|
||||
|
||||
ResearchEffectDto(
|
||||
field = field,
|
||||
usageType = modifier.usageType,
|
||||
modifierValue = modifier.value,
|
||||
)
|
||||
}
|
||||
|
||||
if (effects.isEmpty()) return@mapNotNull null
|
||||
|
||||
WeaponResearchDto(
|
||||
research = research.toResearchShortDto(),
|
||||
researchRequired = getRequiredResearches(research),
|
||||
effects = effects,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns researches required by the given research (its prerequisites).
|
||||
* Handles both "required_research" (excluding "must not be complete" ones,
|
||||
* since they are mutually exclusive rather than required)
|
||||
* and "required_research_either" requirements.
|
||||
*/
|
||||
private fun getRequiredResearches(research: Research): List<ResearchShortDto> {
|
||||
val modId = research.modId ?: return emptyList()
|
||||
|
||||
val required = research.researchRequirements
|
||||
.filter { it.reference?.getPureReference() == Requirements.REFERENCE_REQUIREMENT_RESEARCH }
|
||||
.filter { it.value?.split(";")?.last() != "true" }
|
||||
.mapNotNull { req ->
|
||||
req.value?.split(";")?.first()
|
||||
?.replace(".lua", ".rgd")
|
||||
?.replace("research\\", "")
|
||||
?.let { if (it.endsWith(".rgd")) it else "$it.rgd" }
|
||||
?.let { researchRepository.findFirstByModIdAndFilename(modId, it)?.toResearchShortDto() }
|
||||
}
|
||||
|
||||
val requiredEither = research.researchRequirements
|
||||
.filter { it.reference?.getPureReference() == Requirements.REFERENCE_REQUIRED_RESEARCH_EITHER }
|
||||
.flatMap { req ->
|
||||
req.value?.split(";").orEmpty().mapNotNull { r ->
|
||||
val researchFileName = r.split("\\").last().replace(".lua", ".rgd").let { resFile ->
|
||||
if (resFile.endsWith(".rgd")) resFile else "$resFile.rgd"
|
||||
}
|
||||
researchRepository.findFirstByModIdAndFilename(modId, researchFileName)?.toResearchShortDto()
|
||||
}
|
||||
}
|
||||
|
||||
return (required + requiredEither).distinct()
|
||||
}
|
||||
|
||||
private fun String.getPureReference(): String =
|
||||
this.split("\\").last()
|
||||
.replace(".lua", "")
|
||||
.replace(".rgd", "")
|
||||
|
||||
/**
|
||||
* Extracts the short modifier name from a full reference path.
|
||||
* e.g. modifiers/max_damage_weapon_modifier.lua -> max_damage_weapon_modifier
|
||||
*/
|
||||
private fun extractRefName(reference: String): String =
|
||||
reference.split("\\").first()
|
||||
.replace(".lua", "")
|
||||
.replace(".rgd", "")
|
||||
}
|
||||
@ -9,6 +9,7 @@ import org.springframework.stereotype.Service
|
||||
class WeaponService @Autowired constructor(
|
||||
val weaponRepository: WeaponRepository,
|
||||
val requirementsMappingComponent: RequirementsMappingComponent,
|
||||
val weaponResearchEffectMappingComponent: WeaponResearchEffectMappingComponent,
|
||||
) {
|
||||
|
||||
fun getWeaponDto(id: Long, modId: Long): WeaponDto {
|
||||
@ -16,7 +17,8 @@ class WeaponService @Autowired constructor(
|
||||
val requirements = requirementsMappingComponent
|
||||
.getRequirements(weapon.weaponRequirements.toList(),
|
||||
modId)
|
||||
return weapon.toDto(requirements)
|
||||
val researches = weaponResearchEffectMappingComponent.buildEffects(weapon)
|
||||
return weapon.toDto(requirements, researches)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
{
|
||||
"databaseChangeLog": [
|
||||
{
|
||||
"changeSet": {
|
||||
"id": "Add index on mod_id and filename to researches",
|
||||
"author": "anibus",
|
||||
"changes": [
|
||||
{
|
||||
"createIndex": {
|
||||
"indexName": "idx_researches_mod_id_filename",
|
||||
"tableName": "researches",
|
||||
"columns": [
|
||||
{
|
||||
"column": {
|
||||
"name": "mod_id"
|
||||
}
|
||||
},
|
||||
{
|
||||
"column": {
|
||||
"name": "filename"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -476,6 +476,11 @@
|
||||
"include": {
|
||||
"file": "db/0.0.6/schema/jump_requirements.json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"include": {
|
||||
"file": "db/0.0.6/schema/add_index_to_researches.json"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ class ModDiffPrinterScript {
|
||||
|
||||
val rgdService = RgdService()
|
||||
|
||||
val prevVersion = "wanila2.8.0"
|
||||
val prevVersion = "wanila2.9.1"
|
||||
val currentVersion = "wanila"
|
||||
|
||||
val spaceMarinesPath = "space_marines"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user