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 modifiers: List<ModifierDto>,
|
||||||
val requirements: RequirementDto?,
|
val requirements: RequirementDto?,
|
||||||
val hotkey: String?,
|
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.RequirementDto
|
||||||
import com.dowstats.data.dto.controllers.WeaponDto
|
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.dto.controllers.WeaponShortDto
|
||||||
import com.dowstats.data.entities.ability.Ability
|
import com.dowstats.data.entities.ability.Ability
|
||||||
import com.dowstats.data.entities.sergant.SergeantWeapon
|
import com.dowstats.data.entities.sergant.SergeantWeapon
|
||||||
@ -107,7 +108,7 @@ class Weapon {
|
|||||||
@OneToMany(mappedBy="weapon", cascade = [(CascadeType.ALL)])
|
@OneToMany(mappedBy="weapon", cascade = [(CascadeType.ALL)])
|
||||||
var weaponPiercings: List<WeaponArmorPiercing> = listOf()
|
var weaponPiercings: List<WeaponArmorPiercing> = listOf()
|
||||||
|
|
||||||
fun toDto(requirementDto: RequirementDto?) = WeaponDto(
|
fun toDto(requirementDto: RequirementDto?, researches: List<WeaponResearchDto>) = WeaponDto(
|
||||||
id!!,
|
id!!,
|
||||||
filename!!,
|
filename!!,
|
||||||
name,
|
name,
|
||||||
@ -140,6 +141,7 @@ class Weapon {
|
|||||||
weaponModifiers.map { mod -> mod.toDto().copy(maxLifeTime = mod.maxLifeTime) },
|
weaponModifiers.map { mod -> mod.toDto().copy(maxLifeTime = mod.maxLifeTime) },
|
||||||
requirementDto,
|
requirementDto,
|
||||||
uiHotkeyName,
|
uiHotkeyName,
|
||||||
|
researches,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun toShortDto() = WeaponShortDto(
|
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(
|
class WeaponService @Autowired constructor(
|
||||||
val weaponRepository: WeaponRepository,
|
val weaponRepository: WeaponRepository,
|
||||||
val requirementsMappingComponent: RequirementsMappingComponent,
|
val requirementsMappingComponent: RequirementsMappingComponent,
|
||||||
|
val weaponResearchEffectMappingComponent: WeaponResearchEffectMappingComponent,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getWeaponDto(id: Long, modId: Long): WeaponDto {
|
fun getWeaponDto(id: Long, modId: Long): WeaponDto {
|
||||||
@ -16,7 +17,8 @@ class WeaponService @Autowired constructor(
|
|||||||
val requirements = requirementsMappingComponent
|
val requirements = requirementsMappingComponent
|
||||||
.getRequirements(weapon.weaponRequirements.toList(),
|
.getRequirements(weapon.weaponRequirements.toList(),
|
||||||
modId)
|
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": {
|
"include": {
|
||||||
"file": "db/0.0.6/schema/jump_requirements.json"
|
"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 rgdService = RgdService()
|
||||||
|
|
||||||
val prevVersion = "wanila2.8.0"
|
val prevVersion = "wanila2.9.1"
|
||||||
val currentVersion = "wanila"
|
val currentVersion = "wanila"
|
||||||
|
|
||||||
val spaceMarinesPath = "space_marines"
|
val spaceMarinesPath = "space_marines"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user