Add researches support
This commit is contained in:
parent
74bfa790a7
commit
2d941bd29c
2
pom.xml
2
pom.xml
@ -15,7 +15,7 @@
|
|||||||
<description>Down of war wiki</description>
|
<description>Down of war wiki</description>
|
||||||
<properties>
|
<properties>
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<kotlin.version>1.8.22</kotlin.version>
|
<kotlin.version>2.2.0</kotlin.version>
|
||||||
<spring.version>3.3.1</spring.version>
|
<spring.version>3.3.1</spring.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|||||||
@ -4,4 +4,13 @@ object Metadata {
|
|||||||
|
|
||||||
const val USER_ROLE = "USER"
|
const val USER_ROLE = "USER"
|
||||||
|
|
||||||
|
object Requirements {
|
||||||
|
val REFERENCE_REQUIREMENT_POP = "requirements\\required_total_pop.lua"
|
||||||
|
val REFERENCE_REQUIREMENT_ADDON = "requirements\\local_required_addon.lua"
|
||||||
|
val REFERENCE_GLOBAL_REQUIREMENT_ADDON = "requirements\\global_required_addon.lua"
|
||||||
|
val REFERENCE_REQUIREMENT_STRUCTURE_EITHER = "requirements\\required_structure_either.lua"
|
||||||
|
val REFERENCE_REQUIREMENT_STRUCTURE = "requirements\\required_structure.lua"
|
||||||
|
val REFERENCE_REQUIREMENT_RESEARCH = "requirements\\required_research.lua"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
13
src/main/kotlin/com/dowstats/data/dto/AreaEffect.kt
Normal file
13
src/main/kotlin/com/dowstats/data/dto/AreaEffect.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package com.dowstats.data.dto
|
||||||
|
|
||||||
|
data class AreaEffect(
|
||||||
|
val minDamage: Double,
|
||||||
|
val maxDamage: Double,
|
||||||
|
val damageRadius: Double,
|
||||||
|
val throwForceMin: Double,
|
||||||
|
val throwForceMax: Double,
|
||||||
|
val minDamageValue: Double,
|
||||||
|
val moraleDamage: Double,
|
||||||
|
val weaponDmgMap: Map<String, Double>,
|
||||||
|
val defaultArmorPiercing: Double,
|
||||||
|
)
|
||||||
7
src/main/kotlin/com/dowstats/data/dto/ResourceIncome.kt
Normal file
7
src/main/kotlin/com/dowstats/data/dto/ResourceIncome.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package com.dowstats.data.dto
|
||||||
|
|
||||||
|
data class ResourceIncome(
|
||||||
|
val faith: Double?,
|
||||||
|
val power: Double?,
|
||||||
|
val requisition: Double?,
|
||||||
|
)
|
||||||
7
src/main/kotlin/com/dowstats/data/dto/UiInfo.kt
Normal file
7
src/main/kotlin/com/dowstats/data/dto/UiInfo.kt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package com.dowstats.data.dto
|
||||||
|
|
||||||
|
data class UiInfo (
|
||||||
|
val name: String?,
|
||||||
|
val description: String?,
|
||||||
|
val iconPath: String?,
|
||||||
|
)
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package com.dowstats.data.dto.controllers
|
||||||
|
|
||||||
|
import com.dowstats.data.entities.Building
|
||||||
|
import com.dowstats.data.entities.DowUnit
|
||||||
|
import com.dowstats.data.entities.Sergeant
|
||||||
|
import com.dowstats.data.entities.Weapon
|
||||||
|
|
||||||
|
|
||||||
|
data class EntityCompressDto(
|
||||||
|
val name: String?,
|
||||||
|
val icon: String?,
|
||||||
|
val id: Long,
|
||||||
|
val filename: String?,
|
||||||
|
)
|
||||||
|
|
||||||
|
object EntityCompressDtoObject {
|
||||||
|
fun Sergeant.compressDto(): EntityCompressDto =
|
||||||
|
EntityCompressDto(
|
||||||
|
this.name,
|
||||||
|
this.icon,
|
||||||
|
this.id!!,
|
||||||
|
this.filename
|
||||||
|
)
|
||||||
|
|
||||||
|
fun DowUnit.compressDto(): EntityCompressDto =
|
||||||
|
EntityCompressDto(
|
||||||
|
this.name,
|
||||||
|
this.icon,
|
||||||
|
this.id!!,
|
||||||
|
this.filenameSquad + ";" + this.filenameUnit
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Building.compressDto(): EntityCompressDto =
|
||||||
|
EntityCompressDto(
|
||||||
|
this.name,
|
||||||
|
this.icon,
|
||||||
|
this.id!!,
|
||||||
|
this.filename
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Weapon.compressDto(): EntityCompressDto =
|
||||||
|
EntityCompressDto(
|
||||||
|
this.name,
|
||||||
|
this.icon,
|
||||||
|
this.id!!,
|
||||||
|
this.filename
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
package com.dowstats.data.dto.controllers.building
|
package com.dowstats.data.dto.controllers
|
||||||
|
|
||||||
data class AddonModifierDto (
|
data class ModifierDto (
|
||||||
val id: Long,
|
val id: Long,
|
||||||
val reference: String?,
|
val reference: String?,
|
||||||
val usageType: String?,
|
val usageType: String?,
|
||||||
val value: Double?,
|
val value: Double?,
|
||||||
|
val target: String? = null,
|
||||||
)
|
)
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package com.dowstats.data.dto.controllers
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.building.BuildingAddonShortDto
|
||||||
|
import com.dowstats.data.dto.controllers.building.BuildingShortDto
|
||||||
|
import com.dowstats.data.dto.controllers.research.ResearchShortDto
|
||||||
|
|
||||||
|
data class RequirementDto (
|
||||||
|
val requirementBuildings: Set<BuildingShortDto>,
|
||||||
|
val requirementBuildingsEither: Set<BuildingShortDto>,
|
||||||
|
val requirementResearches: Set<RequirementResearchDto>,
|
||||||
|
val requireAddon: BuildingAddonShortDto?,
|
||||||
|
val requirementsGlobalAddons: Set<BuildingAddonShortDto>?,
|
||||||
|
val requiredTotalPop: Int?,
|
||||||
|
val replaceWhenDone: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class RequirementResearchDto(
|
||||||
|
val researchShortDto: ResearchShortDto,
|
||||||
|
val researchMustNotBeComplete: Boolean,
|
||||||
|
)
|
||||||
@ -1,5 +1,7 @@
|
|||||||
package com.dowstats.data.dto.controllers
|
package com.dowstats.data.dto.controllers
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.research.ResearchShortDto
|
||||||
|
|
||||||
|
|
||||||
data class SergeantDto(
|
data class SergeantDto(
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
@ -27,4 +29,5 @@ data class SergeantDto(
|
|||||||
val detectRadius: Int?,
|
val detectRadius: Int?,
|
||||||
val icon: String?,
|
val icon: String?,
|
||||||
val weapons: List<WeaponSlotDto>?,
|
val weapons: List<WeaponSlotDto>?,
|
||||||
|
val affectedResearches: Set<ResearchShortDto>,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
package com.dowstats.data.dto.controllers
|
||||||
|
|
||||||
|
data class SergeantUnitShortDto(
|
||||||
|
val id: Long?,
|
||||||
|
val filename: String,
|
||||||
|
val name: String?,
|
||||||
|
val icon: String?,
|
||||||
|
val unit: EntityCompressDto
|
||||||
|
)
|
||||||
@ -1,5 +1,7 @@
|
|||||||
package com.dowstats.data.dto.controllers
|
package com.dowstats.data.dto.controllers
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.research.ResearchShortDto
|
||||||
|
|
||||||
|
|
||||||
data class UnitFullDto(
|
data class UnitFullDto(
|
||||||
val id: Long,
|
val id: Long,
|
||||||
@ -35,17 +37,19 @@ data class UnitFullDto(
|
|||||||
val moveSpeed: Int?,
|
val moveSpeed: Int?,
|
||||||
val sightRadius: Int?,
|
val sightRadius: Int?,
|
||||||
val detectRadius: Int?,
|
val detectRadius: Int?,
|
||||||
val reinforceCostRequisition: Int?,
|
val reinforceCostRequisition: Double?,
|
||||||
val reinforceCostPower: Int?,
|
val reinforceCostPower: Double?,
|
||||||
val reinforceCostPopulation: Int?,
|
val reinforceCostPopulation: Double?,
|
||||||
val reinforceCostFaith: Int?,
|
val reinforceCostFaith: Double?,
|
||||||
val reinforceCostSouls: Int?,
|
val reinforceCostSouls: Double?,
|
||||||
val reinforceTime: Int?,
|
val reinforceTime: Int?,
|
||||||
val repairMax: Int?,
|
val repairMax: Int?,
|
||||||
val repairSpeed: Int?,
|
val repairSpeed: Int?,
|
||||||
|
val repairCostPercent: Int?,
|
||||||
val maxSergeants: Int?,
|
val maxSergeants: Int?,
|
||||||
val icon: String?,
|
val icon: String?,
|
||||||
val modId: Long,
|
val modId: Long,
|
||||||
val sergeants: Set<SergeantDto>?,
|
val sergeants: Set<SergeantDto>?,
|
||||||
val weapons: Set<WeaponSlotDto>?,
|
val weapons: Set<WeaponSlotDto>?,
|
||||||
|
val affectedResearches: Set<ResearchShortDto>,
|
||||||
)
|
)
|
||||||
@ -1,12 +1,14 @@
|
|||||||
package com.dowstats.data.dto.controllers
|
package com.dowstats.data.dto.controllers
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.research.ResearchShortDto
|
||||||
|
|
||||||
data class WeaponDto(
|
data class WeaponDto(
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
val filename: String,
|
val filename: String,
|
||||||
val name: String?,
|
val name: String?,
|
||||||
val description: String?,
|
val description: String?,
|
||||||
val costRequisition: Int?,
|
val costRequisition: Double?,
|
||||||
val costPower: Int?,
|
val costPower: Double?,
|
||||||
val costTimeSeconds: Int?,
|
val costTimeSeconds: Int?,
|
||||||
val accuracy: Double?,
|
val accuracy: Double?,
|
||||||
val reloadTime: Double?,
|
val reloadTime: Double?,
|
||||||
@ -27,5 +29,6 @@ data class WeaponDto(
|
|||||||
val icon: String?,
|
val icon: String?,
|
||||||
val haveEquipButton: Boolean,
|
val haveEquipButton: Boolean,
|
||||||
val modId: Long?,
|
val modId: Long?,
|
||||||
val weaponArmorPiercing: List<WeaponArmorPiercingDto>
|
val weaponArmorPiercing: List<WeaponArmorPiercingDto>,
|
||||||
|
val affectedResearches: Set<ResearchShortDto>,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.dowstats.data.dto.controllers
|
||||||
|
|
||||||
|
data class WeaponUnitShortDto(
|
||||||
|
val id: Long?,
|
||||||
|
val filename: String,
|
||||||
|
val name: String?,
|
||||||
|
val units: Set<EntityCompressDto>,
|
||||||
|
val sergeants: Set<SergeantUnitShortDto>,
|
||||||
|
val buildings: Set<EntityCompressDto>
|
||||||
|
)
|
||||||
@ -1,10 +0,0 @@
|
|||||||
package com.dowstats.data.dto.controllers.building
|
|
||||||
|
|
||||||
data class AddonRequirementDto (
|
|
||||||
val requirementBuildings: List<BuildingShortDto>,
|
|
||||||
val requirementBuildingsEither: List<BuildingShortDto>,
|
|
||||||
val requireAddon: BuildingAddonShortDto?,
|
|
||||||
val replaceWhenDone: Boolean,
|
|
||||||
val requirementsGlobalAddons: List<BuildingAddonShortDto>?,
|
|
||||||
val requiredTotalPop: Int?,
|
|
||||||
)
|
|
||||||
@ -1,5 +1,8 @@
|
|||||||
package com.dowstats.data.dto.controllers.building
|
package com.dowstats.data.dto.controllers.building
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.ModifierDto
|
||||||
|
import com.dowstats.data.dto.controllers.RequirementDto
|
||||||
|
|
||||||
data class BuildingAddonDto(
|
data class BuildingAddonDto(
|
||||||
val id: Long?,
|
val id: Long?,
|
||||||
val name: String?,
|
val name: String?,
|
||||||
@ -11,8 +14,8 @@ data class BuildingAddonDto(
|
|||||||
val addonCostFaith: Double?,
|
val addonCostFaith: Double?,
|
||||||
val addonCostSouls: Double?,
|
val addonCostSouls: Double?,
|
||||||
val addonCostTime: Int?,
|
val addonCostTime: Int?,
|
||||||
val addonModifiers: Set<AddonModifierDto>,
|
val addonModifiers: Set<ModifierDto>,
|
||||||
val addonRequirement: AddonRequirementDto?,
|
val addonRequirement: RequirementDto?,
|
||||||
val icon: String?,
|
val icon: String?,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,8 @@ import com.dowstats.data.dto.controllers.ArmorTypeDto
|
|||||||
import com.dowstats.data.dto.controllers.RaceDto
|
import com.dowstats.data.dto.controllers.RaceDto
|
||||||
import com.dowstats.data.dto.controllers.UnitShortDto
|
import com.dowstats.data.dto.controllers.UnitShortDto
|
||||||
import com.dowstats.data.dto.controllers.WeaponSlotDto
|
import com.dowstats.data.dto.controllers.WeaponSlotDto
|
||||||
import com.dowstats.data.entities.DowUnit
|
import com.dowstats.data.dto.controllers.research.ResearchDto
|
||||||
|
import com.dowstats.data.dto.controllers.research.ResearchShortDto
|
||||||
|
|
||||||
data class BuildingFullDto(
|
data class BuildingFullDto(
|
||||||
var id: Long?,
|
var id: Long?,
|
||||||
@ -32,6 +33,8 @@ data class BuildingFullDto(
|
|||||||
var icon: String?,
|
var icon: String?,
|
||||||
var modId: Long?,
|
var modId: Long?,
|
||||||
var addons: Set<BuildingAddonDto>?,
|
var addons: Set<BuildingAddonDto>?,
|
||||||
|
var researches: List<ResearchDto>?,
|
||||||
val units: Set<UnitShortDto>,
|
val units: Set<UnitShortDto>,
|
||||||
val weapons: Set<WeaponSlotDto>?,
|
val weapons: Set<WeaponSlotDto>?,
|
||||||
|
val affectedResearches: Set<ResearchShortDto>,
|
||||||
)
|
)
|
||||||
|
|||||||
@ -12,6 +12,7 @@ data class BuildingShortDto(
|
|||||||
val name: String,
|
val name: String,
|
||||||
val icon: String,
|
val icon: String,
|
||||||
val id: Long,
|
val id: Long,
|
||||||
|
val filename: String,
|
||||||
val units: Set<UnitShortDto>,
|
val units: Set<UnitShortDto>,
|
||||||
val armourTypeName: String,
|
val armourTypeName: String,
|
||||||
val canDetect: Boolean,
|
val canDetect: Boolean,
|
||||||
|
|||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.dowstats.data.dto.controllers.research
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.*
|
||||||
|
|
||||||
|
|
||||||
|
data class ResearchDto(
|
||||||
|
val id: Long?,
|
||||||
|
val name: String?,
|
||||||
|
val description: String?,
|
||||||
|
val filename: String?,
|
||||||
|
val costRequisition: Double?,
|
||||||
|
val costPower: Double?,
|
||||||
|
val costFaith: Double?,
|
||||||
|
val costSouls: Double?,
|
||||||
|
val costTime: Int?,
|
||||||
|
val modifiers: List<ModifierDto>,
|
||||||
|
val requirements: RequirementDto?,
|
||||||
|
val affectedUnits: Set<EntityCompressDto>,
|
||||||
|
val affectedSergeants: Set<SergeantUnitShortDto>,
|
||||||
|
val affectedBuildings: Set<EntityCompressDto>,
|
||||||
|
val affectedWeapons: Set<WeaponUnitShortDto>,
|
||||||
|
val icon: String?,
|
||||||
|
val modId: Long?,
|
||||||
|
)
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
package com.dowstats.data.dto.controllers.research
|
||||||
|
|
||||||
|
data class ResearchShortDto(
|
||||||
|
val id: Long?,
|
||||||
|
val name: String?,
|
||||||
|
val icon: String?,
|
||||||
|
val buildingId: Long?,
|
||||||
|
)
|
||||||
@ -1,32 +0,0 @@
|
|||||||
package com.dowstats.data.entities
|
|
||||||
|
|
||||||
import com.dowstats.data.dto.controllers.building.AddonRequirementDto
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
|
||||||
import jakarta.persistence.*
|
|
||||||
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "addon_requirements")
|
|
||||||
class AddonRequirements {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
||||||
var id: Long? = null
|
|
||||||
|
|
||||||
@ManyToOne
|
|
||||||
@JoinColumn(name = "addon_id", nullable = false)
|
|
||||||
@JsonIgnore
|
|
||||||
var addon: BuildingAddon? = null
|
|
||||||
var reference: String? = null
|
|
||||||
var replaceWhenDone: Boolean = false
|
|
||||||
var value: String? = null
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
val REFERENCE_REQUIREMENT_POP = "requirements\\required_total_pop.lua"
|
|
||||||
val REFERENCE_REQUIREMENT_ADDON = "requirements\\local_required_addon.lua"
|
|
||||||
val REFERENCE_GLOBAL_REQUIREMENT_ADDON = "requirements\\global_required_addon.lua"
|
|
||||||
val REFERENCE_REQUIREMENT_STRUCTURE_EITHER = "requirements\\required_structure_either.lua"
|
|
||||||
val REFERENCE_REQUIREMENT_STRUCTURE = "requirements\\required_structure.lua"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,10 +1,12 @@
|
|||||||
package com.dowstats.data.entities
|
package com.dowstats.data.entities
|
||||||
|
|
||||||
import com.dowstats.data.dto.controllers.UnitShortDto
|
|
||||||
import com.dowstats.data.dto.controllers.building.BuildingAddonDto
|
import com.dowstats.data.dto.controllers.building.BuildingAddonDto
|
||||||
import com.dowstats.data.dto.controllers.building.BuildingFullDto
|
import com.dowstats.data.dto.controllers.building.BuildingFullDto
|
||||||
|
import com.dowstats.data.dto.controllers.research.ResearchDto
|
||||||
import com.dowstats.data.entities.DowUnitObject.toUnitDto
|
import com.dowstats.data.entities.DowUnitObject.toUnitDto
|
||||||
import com.dowstats.data.entities.Weapon.HardpointPosition
|
import com.dowstats.data.entities.Weapon.HardpointPosition
|
||||||
|
import com.dowstats.data.entities.addon.BuildingAddon
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
import jakarta.persistence.*
|
import jakarta.persistence.*
|
||||||
|
|
||||||
|
|
||||||
@ -16,7 +18,7 @@ class Building {
|
|||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
var id: Long? = null
|
var id: Long? = null
|
||||||
|
|
||||||
var canBuild: Boolean = true
|
var canBuild: Boolean? = true
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "race_id", nullable = false)
|
@JoinColumn(name = "race_id", nullable = false)
|
||||||
@ -63,10 +65,22 @@ class Building {
|
|||||||
inverseJoinColumns = [JoinColumn(name = "unit_id")])
|
inverseJoinColumns = [JoinColumn(name = "unit_id")])
|
||||||
var units: MutableSet<DowUnit>? = null
|
var units: MutableSet<DowUnit>? = null
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "buildings_researches",
|
||||||
|
joinColumns = [JoinColumn(name = "building_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "research_id")])
|
||||||
|
var researches: MutableSet<Research>? = null
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "researches_affected_buildings",
|
||||||
|
joinColumns = [JoinColumn(name = "building_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "research_id")])
|
||||||
|
var affectedResearches: MutableSet<Research> = mutableSetOf()
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
var weaponHardpoints: MutableSet<HardpointPosition> = mutableSetOf()
|
var weaponHardpoints: MutableSet<HardpointPosition> = mutableSetOf()
|
||||||
|
|
||||||
fun toDto(buildingAddons: Set<BuildingAddonDto>?): BuildingFullDto =
|
fun toDto(buildingAddons: Set<BuildingAddonDto>?, researches: List<ResearchDto>?): BuildingFullDto =
|
||||||
BuildingFullDto(
|
BuildingFullDto(
|
||||||
id!!,
|
id!!,
|
||||||
race?.toDto(),
|
race?.toDto(),
|
||||||
@ -93,8 +107,10 @@ class Building {
|
|||||||
icon,
|
icon,
|
||||||
modId!!,
|
modId!!,
|
||||||
buildingAddons,
|
buildingAddons,
|
||||||
|
researches,
|
||||||
units?.toList()?.toUnitDto() ?: emptySet(),
|
units?.toList()?.toUnitDto() ?: emptySet(),
|
||||||
weapons?.map { it.toWeaponSlotDto() }?.toSet(),
|
weapons?.map { it.toWeaponSlotDto() }?.toSet(),
|
||||||
|
affectedResearches.map { it.toResearchShortDto() }.toSet(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.dowstats.data.entities
|
|||||||
|
|
||||||
import com.dowstats.data.dto.controllers.UnitFullDto
|
import com.dowstats.data.dto.controllers.UnitFullDto
|
||||||
import com.dowstats.data.dto.controllers.UnitShortDto
|
import com.dowstats.data.dto.controllers.UnitShortDto
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
import jakarta.persistence.*
|
import jakarta.persistence.*
|
||||||
|
|
||||||
|
|
||||||
@ -30,7 +31,8 @@ class DowUnit {
|
|||||||
|
|
||||||
var name: String? = null
|
var name: String? = null
|
||||||
var description: String? = null
|
var description: String? = null
|
||||||
var filename: String? = null
|
var filenameSquad: String? = null
|
||||||
|
var filenameUnit: String? = null
|
||||||
var buildCostRequisition: Double? = null
|
var buildCostRequisition: Double? = null
|
||||||
var buildCostPower: Double? = null
|
var buildCostPower: Double? = null
|
||||||
var buildCostPopulation: Double? = null
|
var buildCostPopulation: Double? = null
|
||||||
@ -57,11 +59,11 @@ class DowUnit {
|
|||||||
var moveSpeed: Int? = null
|
var moveSpeed: Int? = null
|
||||||
var sightRadius: Int? = null
|
var sightRadius: Int? = null
|
||||||
var detectRadius: Int? = null
|
var detectRadius: Int? = null
|
||||||
var reinforceCostRequisition: Int? = null
|
var reinforceCostRequisition: Double? = null
|
||||||
var reinforceCostPower: Int? = null
|
var reinforceCostPower: Double? = null
|
||||||
var reinforceCostPopulation: Int? = null
|
var reinforceCostPopulation: Double? = null
|
||||||
var reinforceCostFaith: Int? = null
|
var reinforceCostFaith: Double? = null
|
||||||
var reinforceCostSouls: Int? = null
|
var reinforceCostSouls: Double? = null
|
||||||
var reinforceTime: Int? = null
|
var reinforceTime: Int? = null
|
||||||
var maxSergeants: Int? = null
|
var maxSergeants: Int? = null
|
||||||
var faithIncome: Double? = null
|
var faithIncome: Double? = null
|
||||||
@ -76,6 +78,11 @@ class DowUnit {
|
|||||||
@OneToMany(mappedBy = "unit", cascade = [CascadeType.ALL])
|
@OneToMany(mappedBy = "unit", cascade = [CascadeType.ALL])
|
||||||
var weapons: MutableSet<UnitWeapon>? = null
|
var weapons: MutableSet<UnitWeapon>? = null
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "researches_affected_units",
|
||||||
|
joinColumns = [JoinColumn(name = "unit_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "research_id")])
|
||||||
|
var affectedResearches: MutableSet<Research> = mutableSetOf()
|
||||||
|
|
||||||
|
|
||||||
fun toDto(): UnitFullDto =
|
fun toDto(): UnitFullDto =
|
||||||
@ -86,7 +93,7 @@ class DowUnit {
|
|||||||
armorType2?.toDto(),
|
armorType2?.toDto(),
|
||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
filename!!,
|
filenameSquad!!,
|
||||||
buildCostRequisition,
|
buildCostRequisition,
|
||||||
buildCostPower,
|
buildCostPower,
|
||||||
buildCostPopulation,
|
buildCostPopulation,
|
||||||
@ -121,34 +128,24 @@ class DowUnit {
|
|||||||
reinforceTime,
|
reinforceTime,
|
||||||
repairMax,
|
repairMax,
|
||||||
repairSpeed,
|
repairSpeed,
|
||||||
|
repairCostPercent,
|
||||||
maxSergeants,
|
maxSergeants,
|
||||||
icon,
|
icon,
|
||||||
modId!!,
|
modId!!,
|
||||||
sergeants?.map { it.toDto() }?.toSet(),
|
sergeants?.map { it.toDto() }?.toSet(),
|
||||||
weapons?.map { it.toWeaponSlotDto() }?.toSet()
|
weapons?.map { it.toWeaponSlotDto() }?.toSet(),
|
||||||
|
affectedResearches.map { it.toResearchShortDto() }.toSet(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
object DowUnitObject {
|
object DowUnitObject {
|
||||||
fun List<DowUnit>.toUnitDto(): Set<UnitShortDto> =
|
fun List<DowUnit>.toUnitDto(): Set<UnitShortDto> =
|
||||||
this.mapNotNull {
|
this.mapNotNull {
|
||||||
val name = it.name ?: it.filename
|
val name = it.name ?: it.filenameSquad
|
||||||
val icon = it.icon
|
val icon = it.icon
|
||||||
if (name == null || icon == null) null else UnitShortDto(name, icon, it.id!!,
|
if (name == null || icon == null) null else UnitShortDto(name, icon, it.id!!,
|
||||||
it.armorType?.name!!,
|
it.armorType?.name!!,
|
||||||
(it.detectRadius ?: 0) > 0)
|
(it.detectRadius ?: 0) > 0)
|
||||||
}.toSet()
|
}.toSet()
|
||||||
|
|
||||||
fun List<DowUnit>.filterCompanyUnits(): List<DowUnit> =
|
|
||||||
this.filter {
|
|
||||||
it.filename?.contains("_sp.") != true
|
|
||||||
&& it.filename?.contains("_sp_") != true
|
|
||||||
&& it.filename?.contains("sp_eldar_") != true
|
|
||||||
&& it.filename?.contains("_dxp3.") != true
|
|
||||||
&& it.filename?.contains("_dxp3_") != true
|
|
||||||
&& it.filename?.contains("_nis.") != true
|
|
||||||
&& it.filename?.contains("_exarch_council.") != true
|
|
||||||
&& it.filename?.contains("_dark_reapers_base.") != true
|
|
||||||
&& it.filename?.contains("tau_squad_slave_murdered") != true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.dowstats.data.entities
|
||||||
|
|
||||||
|
import jakarta.persistence.GeneratedValue
|
||||||
|
import jakarta.persistence.GenerationType
|
||||||
|
import jakarta.persistence.Id
|
||||||
|
import jakarta.persistence.MappedSuperclass
|
||||||
|
|
||||||
|
@MappedSuperclass
|
||||||
|
open class RequirementBase {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
var id: Long? = null
|
||||||
|
|
||||||
|
var reference: String? = null
|
||||||
|
var value: String? = null
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ package com.dowstats.data.entities
|
|||||||
|
|
||||||
import com.dowstats.data.dto.controllers.SergeantDto
|
import com.dowstats.data.dto.controllers.SergeantDto
|
||||||
import com.dowstats.data.entities.Weapon.HardpointPosition
|
import com.dowstats.data.entities.Weapon.HardpointPosition
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
import jakarta.persistence.*
|
import jakarta.persistence.*
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ class Sergeant {
|
|||||||
|
|
||||||
var name: String? = null
|
var name: String? = null
|
||||||
var description: String? = null
|
var description: String? = null
|
||||||
var filename: String? = null
|
var filename: String = ""
|
||||||
var buildCostRequisition: Double? = null
|
var buildCostRequisition: Double? = null
|
||||||
var buildCostPower: Double? = null
|
var buildCostPower: Double? = null
|
||||||
var buildCostPopulation: Double? = null
|
var buildCostPopulation: Double? = null
|
||||||
@ -49,6 +50,8 @@ class Sergeant {
|
|||||||
var powerIncome: Double? = null
|
var powerIncome: Double? = null
|
||||||
var requisitionIncome: Double? = null
|
var requisitionIncome: Double? = null
|
||||||
|
|
||||||
|
var modId: Long? = null
|
||||||
|
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
var weaponHardpoints: MutableSet<HardpointPosition> = mutableSetOf()
|
var weaponHardpoints: MutableSet<HardpointPosition> = mutableSetOf()
|
||||||
@ -56,6 +59,12 @@ class Sergeant {
|
|||||||
@OneToMany(mappedBy = "sergeant", cascade = [CascadeType.ALL])
|
@OneToMany(mappedBy = "sergeant", cascade = [CascadeType.ALL])
|
||||||
var weapons: MutableSet<SergeantWeapon>? = null
|
var weapons: MutableSet<SergeantWeapon>? = null
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "researches_affected_sergeants",
|
||||||
|
joinColumns = [JoinColumn(name = "sergeant_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "research_id")])
|
||||||
|
var affectedResearches: MutableSet<Research> = mutableSetOf()
|
||||||
|
|
||||||
fun toDto(): SergeantDto =
|
fun toDto(): SergeantDto =
|
||||||
SergeantDto(
|
SergeantDto(
|
||||||
id!!,
|
id!!,
|
||||||
@ -82,6 +91,7 @@ class Sergeant {
|
|||||||
sightRadius,
|
sightRadius,
|
||||||
detectRadius,
|
detectRadius,
|
||||||
icon,
|
icon,
|
||||||
weapons?.map { it.toWeaponSlotDto() }
|
weapons?.map { it.toWeaponSlotDto() },
|
||||||
|
affectedResearches.map { it.toResearchShortDto() }.toSet()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package com.dowstats.data.entities
|
package com.dowstats.data.entities
|
||||||
|
|
||||||
import com.dowstats.data.dto.controllers.WeaponDto
|
import com.dowstats.data.dto.controllers.WeaponDto
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
import jakarta.persistence.*
|
import jakarta.persistence.*
|
||||||
|
|
||||||
|
|
||||||
@ -14,8 +15,8 @@ class Weapon {
|
|||||||
var filename: String? = null
|
var filename: String? = null
|
||||||
var name: String? = null
|
var name: String? = null
|
||||||
var description: String? = null
|
var description: String? = null
|
||||||
var costRequisition: Int? = null
|
var costRequisition: Double? = null
|
||||||
var costPower: Int? = null
|
var costPower: Double? = null
|
||||||
var costTimeSeconds: Int? = null
|
var costTimeSeconds: Int? = null
|
||||||
var accuracy: Double? = null
|
var accuracy: Double? = null
|
||||||
var reloadTime: Double? = null
|
var reloadTime: Double? = null
|
||||||
@ -37,6 +38,21 @@ class Weapon {
|
|||||||
var haveEquipButton: Boolean = true
|
var haveEquipButton: Boolean = true
|
||||||
var modId: Long? = null
|
var modId: Long? = null
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "researches_affected_weapons",
|
||||||
|
joinColumns = [JoinColumn(name = "weapon_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "research_id")])
|
||||||
|
var affectedResearches: MutableSet<Research> = mutableSetOf()
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "weapon", cascade = [CascadeType.ALL])
|
||||||
|
var unitsUse: MutableSet<UnitWeapon>? = null
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "weapon", cascade = [CascadeType.ALL])
|
||||||
|
var sergeantsUse: MutableSet<SergeantWeapon>? = null
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "weapon", cascade = [CascadeType.ALL])
|
||||||
|
var buildingUse: MutableSet<BuildingWeapon>? = null
|
||||||
|
|
||||||
// for many-to-many persistance
|
// for many-to-many persistance
|
||||||
data class HardpointPosition(val weaponId: Long, val hardpoint: Int, val order: Int)
|
data class HardpointPosition(val weaponId: Long, val hardpoint: Int, val order: Int)
|
||||||
|
|
||||||
@ -71,6 +87,7 @@ class Weapon {
|
|||||||
icon,
|
icon,
|
||||||
haveEquipButton,
|
haveEquipButton,
|
||||||
modId,
|
modId,
|
||||||
weaponPiercings.map { it.toDto() }
|
weaponPiercings.map { it.toDto() },
|
||||||
|
affectedResearches.map { it.toResearchShortDto() }.toSet(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package com.dowstats.data.entities
|
package com.dowstats.data.entities.addon
|
||||||
|
|
||||||
import com.dowstats.data.dto.controllers.building.AddonModifierDto
|
import com.dowstats.data.dto.controllers.ModifierDto
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
import jakarta.persistence.*
|
import jakarta.persistence.*
|
||||||
|
|
||||||
@ -22,12 +22,12 @@ class AddonModifiers {
|
|||||||
var usageType: String? = null
|
var usageType: String? = null
|
||||||
var value: Double? = null
|
var value: Double? = null
|
||||||
|
|
||||||
fun toDto(): AddonModifierDto {
|
fun toDto(): ModifierDto {
|
||||||
return AddonModifierDto(
|
return ModifierDto(
|
||||||
id = id!!,
|
id = id!!,
|
||||||
reference = reference,
|
reference = reference,
|
||||||
usageType = usageType,
|
usageType = usageType,
|
||||||
value = value
|
value = value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.dowstats.data.entities.addon
|
||||||
|
|
||||||
|
import com.dowstats.data.entities.RequirementBase
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
|
import jakarta.persistence.*
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "addon_requirements")
|
||||||
|
class AddonRequirements: RequirementBase() {
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "addon_id", nullable = false)
|
||||||
|
@JsonIgnore
|
||||||
|
var addon: BuildingAddon? = null
|
||||||
|
var replaceWhenDone: Boolean = false
|
||||||
|
}
|
||||||
@ -1,8 +1,9 @@
|
|||||||
package com.dowstats.data.entities
|
package com.dowstats.data.entities.addon
|
||||||
|
|
||||||
import com.dowstats.data.dto.controllers.building.AddonRequirementDto
|
import com.dowstats.data.dto.controllers.RequirementDto
|
||||||
import com.dowstats.data.dto.controllers.building.BuildingAddonDto
|
import com.dowstats.data.dto.controllers.building.BuildingAddonDto
|
||||||
import com.dowstats.data.dto.controllers.building.BuildingAddonShortDto
|
import com.dowstats.data.dto.controllers.building.BuildingAddonShortDto
|
||||||
|
import com.dowstats.data.entities.Building
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
import jakarta.persistence.*
|
import jakarta.persistence.*
|
||||||
|
|
||||||
@ -39,7 +40,7 @@ class BuildingAddon {
|
|||||||
var icon: String? = null
|
var icon: String? = null
|
||||||
var modId: Long? = null
|
var modId: Long? = null
|
||||||
|
|
||||||
fun toDto(addonRequirementDto: AddonRequirementDto?): BuildingAddonDto = BuildingAddonDto(
|
fun toDto(addonRequirementDto: RequirementDto?): BuildingAddonDto = BuildingAddonDto(
|
||||||
id = id,
|
id = id,
|
||||||
name = name,
|
name = name,
|
||||||
description = description,
|
description = description,
|
||||||
137
src/main/kotlin/com/dowstats/data/entities/research/Research.kt
Normal file
137
src/main/kotlin/com/dowstats/data/entities/research/Research.kt
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
package com.dowstats.data.entities.research
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.EntityCompressDtoObject.compressDto
|
||||||
|
import com.dowstats.data.dto.controllers.ModifierDto
|
||||||
|
import com.dowstats.data.dto.controllers.RequirementDto
|
||||||
|
import com.dowstats.data.dto.controllers.SergeantUnitShortDto
|
||||||
|
import com.dowstats.data.dto.controllers.WeaponUnitShortDto
|
||||||
|
import com.dowstats.data.dto.controllers.research.ResearchDto
|
||||||
|
import com.dowstats.data.dto.controllers.research.ResearchShortDto
|
||||||
|
import com.dowstats.data.entities.Building
|
||||||
|
import com.dowstats.data.entities.DowUnit
|
||||||
|
import com.dowstats.data.entities.Sergeant
|
||||||
|
import com.dowstats.data.entities.Weapon
|
||||||
|
import jakarta.persistence.*
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "researches")
|
||||||
|
class Research {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
var id: Long? = null
|
||||||
|
|
||||||
|
var name: String? = null
|
||||||
|
var description: String? = null
|
||||||
|
var filename: String? = null
|
||||||
|
var costRequisition: Double? = null
|
||||||
|
var costPower: Double? = null
|
||||||
|
var costFaith: Double? = null
|
||||||
|
var costSouls: Double? = null
|
||||||
|
var costTime: Int? = null
|
||||||
|
var icon: String? = null
|
||||||
|
var modId: Long? = null
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "research", cascade = [CascadeType.ALL])
|
||||||
|
var researchModifiers: MutableSet<ResearchModifiers> = mutableSetOf()
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "research", cascade = [CascadeType.ALL])
|
||||||
|
var addonRequirements: MutableSet<ResearchRequirements> = mutableSetOf()
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "researches_affected_units",
|
||||||
|
joinColumns = [JoinColumn(name = "research_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "unit_id")])
|
||||||
|
var affectedUnits: MutableSet<DowUnit> = mutableSetOf()
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "researches_affected_sergeants",
|
||||||
|
joinColumns = [JoinColumn(name = "research_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "sergeant_id")])
|
||||||
|
var affectedSergeants: MutableSet<Sergeant> = mutableSetOf()
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "researches_affected_buildings",
|
||||||
|
joinColumns = [JoinColumn(name = "research_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "building_id")])
|
||||||
|
var affectedBuildings: MutableSet<Building> = mutableSetOf()
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "researches_affected_weapons",
|
||||||
|
joinColumns = [JoinColumn(name = "research_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "weapon_id")])
|
||||||
|
var affectedWeapons: MutableSet<Weapon> = mutableSetOf()
|
||||||
|
|
||||||
|
@ManyToMany
|
||||||
|
@JoinTable(name = "buildings_researches",
|
||||||
|
joinColumns = [JoinColumn(name = "research_id")],
|
||||||
|
inverseJoinColumns = [JoinColumn(name = "building_id")])
|
||||||
|
var buildings: MutableSet<Building>? = null
|
||||||
|
|
||||||
|
fun toResearchShortDto(): ResearchShortDto = ResearchShortDto(
|
||||||
|
id = id!!,
|
||||||
|
name = name,
|
||||||
|
icon = icon,
|
||||||
|
buildings?.firstOrNull()?.id
|
||||||
|
)
|
||||||
|
|
||||||
|
fun toResearchDto(requirements: RequirementDto?): ResearchDto = ResearchDto(
|
||||||
|
id = id!!,
|
||||||
|
name = name,
|
||||||
|
icon = icon,
|
||||||
|
filename = filename,
|
||||||
|
description = description,
|
||||||
|
costRequisition = costRequisition,
|
||||||
|
costPower = costPower,
|
||||||
|
costFaith = costFaith,
|
||||||
|
costSouls = costSouls,
|
||||||
|
costTime = costTime,
|
||||||
|
modifiers = researchModifiers.map {
|
||||||
|
ModifierDto(
|
||||||
|
it.id!!,
|
||||||
|
it.reference,
|
||||||
|
it.usageType,
|
||||||
|
it.value,
|
||||||
|
it.target,
|
||||||
|
)
|
||||||
|
}.sortedBy { it.target },
|
||||||
|
requirements = requirements,
|
||||||
|
affectedUnits = affectedUnits.map { it.compressDto() }.toSet(),
|
||||||
|
affectedSergeants = affectedSergeants.map {
|
||||||
|
SergeantUnitShortDto(
|
||||||
|
it.id!!,
|
||||||
|
it.filename!!,
|
||||||
|
it.name,
|
||||||
|
it.icon,
|
||||||
|
it.unit!!.compressDto()
|
||||||
|
)
|
||||||
|
}.toSet(),
|
||||||
|
affectedBuildings = affectedBuildings.map { it.compressDto() }.toSet(),
|
||||||
|
affectedWeapons = affectedWeapons.mapNotNull {
|
||||||
|
if(it.unitsUse!!.isEmpty() && it.sergeantsUse!!.isEmpty() && it.buildingUse!!.isEmpty()) {
|
||||||
|
null
|
||||||
|
} else
|
||||||
|
WeaponUnitShortDto(
|
||||||
|
it.id!!,
|
||||||
|
it.filename!!,
|
||||||
|
it.name,
|
||||||
|
it.unitsUse?.mapNotNull {
|
||||||
|
it.unit?.compressDto()
|
||||||
|
}?.toSet() ?: emptySet(),
|
||||||
|
it.sergeantsUse?.map {
|
||||||
|
SergeantUnitShortDto(
|
||||||
|
it.sergeant!!.id!!,
|
||||||
|
it.sergeant!!.filename!!,
|
||||||
|
it.sergeant!!.name,
|
||||||
|
it.sergeant!!.icon,
|
||||||
|
it.sergeant!!.unit!!.compressDto()
|
||||||
|
)
|
||||||
|
}?.toSet() ?: emptySet(),
|
||||||
|
it.buildingUse?.map { it.building!!.compressDto() }?.toSet() ?: emptySet()
|
||||||
|
)
|
||||||
|
}.toSet(),
|
||||||
|
modId = modId,
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.dowstats.data.entities.research
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.ModifierDto
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
|
import jakarta.persistence.*
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "research_modifiers")
|
||||||
|
class ResearchModifiers {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
var id: Long? = null
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "research_id", nullable = false)
|
||||||
|
@JsonIgnore
|
||||||
|
var research: Research? = null
|
||||||
|
|
||||||
|
var reference: String? = null
|
||||||
|
var target: String? = null
|
||||||
|
var usageType: String? = null
|
||||||
|
var value: Double? = null
|
||||||
|
|
||||||
|
fun toDto(): ModifierDto {
|
||||||
|
return ModifierDto(
|
||||||
|
id = id!!,
|
||||||
|
reference = reference,
|
||||||
|
usageType = usageType,
|
||||||
|
value = value,
|
||||||
|
target = target,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package com.dowstats.data.entities.research
|
||||||
|
|
||||||
|
import com.dowstats.data.entities.RequirementBase
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore
|
||||||
|
import jakarta.persistence.*
|
||||||
|
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "research_requirements")
|
||||||
|
class ResearchRequirements : RequirementBase() {
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "research_id", nullable = false)
|
||||||
|
@JsonIgnore
|
||||||
|
var research: Research? = null
|
||||||
|
}
|
||||||
@ -1,10 +1,6 @@
|
|||||||
package com.dowstats.data.repositories
|
package com.dowstats.data.repositories
|
||||||
|
|
||||||
import com.dowstats.data.entities.Building
|
import com.dowstats.data.entities.addon.BuildingAddon
|
||||||
import com.dowstats.data.entities.BuildingAddon
|
|
||||||
import com.dowstats.data.entities.DowUnit
|
|
||||||
import com.dowstats.data.entities.Race
|
|
||||||
import org.springframework.data.jpa.repository.Query
|
|
||||||
import org.springframework.data.repository.CrudRepository
|
import org.springframework.data.repository.CrudRepository
|
||||||
|
|
||||||
interface AddonRepository : CrudRepository<BuildingAddon, Long>{
|
interface AddonRepository : CrudRepository<BuildingAddon, Long>{
|
||||||
|
|||||||
@ -13,4 +13,10 @@ interface ModRepository : CrudRepository<Mod, Long>{
|
|||||||
""", nativeQuery = true)
|
""", nativeQuery = true)
|
||||||
@Modifying
|
@Modifying
|
||||||
fun clearModData(modId: Long)
|
fun clearModData(modId: Long)
|
||||||
|
|
||||||
|
@Query("""
|
||||||
|
CALL delete_campaign_entities(:modId)
|
||||||
|
""", nativeQuery = true)
|
||||||
|
@Modifying
|
||||||
|
fun removeCampaignEntities(modId: Long)
|
||||||
}
|
}
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package com.dowstats.data.repositories
|
||||||
|
|
||||||
|
import com.dowstats.data.entities.DowUnit
|
||||||
|
import com.dowstats.data.entities.Weapon
|
||||||
|
import com.dowstats.data.entities.addon.BuildingAddon
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
|
import org.springframework.data.repository.*
|
||||||
|
|
||||||
|
interface ResearchRepository : CrudRepository<Research, Long>{
|
||||||
|
fun deleteAllByModId(modId: Long)
|
||||||
|
fun findAllByModId(modId: Long): List<Research>
|
||||||
|
fun findFirstByModIdAndFilename(modId: Long, fileName: String): Research?
|
||||||
|
}
|
||||||
@ -1,6 +1,9 @@
|
|||||||
package com.dowstats.data.repositories
|
package com.dowstats.data.repositories
|
||||||
|
|
||||||
import com.dowstats.data.entities.Sergeant
|
import com.dowstats.data.entities.Sergeant
|
||||||
|
import com.dowstats.data.entities.Weapon
|
||||||
import org.springframework.data.repository.CrudRepository
|
import org.springframework.data.repository.CrudRepository
|
||||||
|
|
||||||
interface SergeantRepository : CrudRepository<Sergeant, Long>
|
interface SergeantRepository : CrudRepository<Sergeant, Long>{
|
||||||
|
fun findAllByModId(modId: Long): List<Sergeant>
|
||||||
|
}
|
||||||
@ -18,7 +18,5 @@ interface UnitRepository : CrudRepository<DowUnit, Long> {
|
|||||||
""")
|
""")
|
||||||
fun findByModIdAndRace(modId: Long, race: Race?): List<DowUnit>
|
fun findByModIdAndRace(modId: Long, race: Race?): List<DowUnit>
|
||||||
|
|
||||||
fun findByFilenameAndRaceAndModId(fileName: String, race: Race, modId: Long): DowUnit?
|
|
||||||
|
|
||||||
fun deleteAllByModIdAndRaceId(modId: Long, raceId: String)
|
fun deleteAllByModIdAndRaceId(modId: Long, raceId: String)
|
||||||
}
|
}
|
||||||
@ -2,8 +2,10 @@ package com.dowstats.data.repositories
|
|||||||
|
|
||||||
import com.dowstats.data.entities.DowUnit
|
import com.dowstats.data.entities.DowUnit
|
||||||
import com.dowstats.data.entities.Weapon
|
import com.dowstats.data.entities.Weapon
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
import org.springframework.data.repository.*
|
import org.springframework.data.repository.*
|
||||||
|
|
||||||
interface WeaponRepository : CrudRepository<Weapon, Long>{
|
interface WeaponRepository : CrudRepository<Weapon, Long>{
|
||||||
fun deleteAllByModId(modId: Long)
|
fun deleteAllByModId(modId: Long)
|
||||||
|
fun findAllByModId(modId: Long): List<Weapon>
|
||||||
}
|
}
|
||||||
@ -0,0 +1,44 @@
|
|||||||
|
package com.dowstats.service.datamaps
|
||||||
|
|
||||||
|
import com.dowstats.data.dto.controllers.building.BuildingShortDto
|
||||||
|
import com.dowstats.data.entities.Building
|
||||||
|
import com.dowstats.data.entities.DowUnitObject.toUnitDto
|
||||||
|
|
||||||
|
object CommonMapping {
|
||||||
|
fun List<Building>.toBuildingShortDto(): List<BuildingShortDto> =
|
||||||
|
this
|
||||||
|
.sortedWith(compareBy<Building> { it.units?.isEmpty() }.thenBy{ it.buildCostRequisition?.let { 0 - it } })
|
||||||
|
.mapNotNull {
|
||||||
|
val name = it.name ?: it.filename?.replace(".rgd", "")?.replace("_", " ")
|
||||||
|
val icon = it.icon
|
||||||
|
if (name == null || icon == null) null else BuildingShortDto(
|
||||||
|
name, icon, it.id!!,
|
||||||
|
it.filename!!,
|
||||||
|
it.units?.toList()?.toUnitDto() ?: emptySet(),
|
||||||
|
it.armorType?.name!!,
|
||||||
|
(it.detectRadius ?: 0) > 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isNotCompanyEntity(fileName: String): Boolean =
|
||||||
|
!fileName.contains("_dxp3.") &&
|
||||||
|
!fileName.contains("_dxp3_") &&
|
||||||
|
!fileName.contains("sp_eldar_") &&
|
||||||
|
!fileName.contains("_sp_") &&
|
||||||
|
!fileName.contains("_sp.") &&
|
||||||
|
!fileName.contains("_nis.") &&
|
||||||
|
!fileName.contains("_interface_relay.") &&
|
||||||
|
!fileName.contains("necron_tunnel.rgd") &&
|
||||||
|
!fileName.contains("_exarch_council.") &&
|
||||||
|
!fileName.contains("_dark_reapers_base.") &&
|
||||||
|
!fileName.contains("eldar_deep_strike_building.rgd") &&
|
||||||
|
!fileName.contains("ork_deep_strike_building.rgd") &&
|
||||||
|
!fileName.contains("_caravel_ai.rgd") &&
|
||||||
|
!fileName.contains("sisters_tanktrap_ai.rgd") &&
|
||||||
|
!fileName.contains("sisters_hq_ktgm.rgd") &&
|
||||||
|
!fileName.contains("tau_squad_slave_murdered") &&
|
||||||
|
!fileName.contains("single_player_only") &&
|
||||||
|
!fileName.contains("space_marine_drop_pod_building.rgd")
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,147 +1,68 @@
|
|||||||
package com.dowstats.service.datamaps
|
package com.dowstats.service.datamaps
|
||||||
|
|
||||||
import com.dowstats.data.dto.controllers.building.AddonRequirementDto
|
import com.dowstats.Metadata.Requirements
|
||||||
import com.dowstats.data.dto.controllers.building.BuildingFullDto
|
import com.dowstats.data.dto.controllers.building.BuildingFullDto
|
||||||
import com.dowstats.data.dto.controllers.building.BuildingShortDto
|
|
||||||
import com.dowstats.data.dto.controllers.building.RaceBuildings
|
import com.dowstats.data.dto.controllers.building.RaceBuildings
|
||||||
import com.dowstats.data.entities.AddonRequirements
|
|
||||||
import com.dowstats.data.entities.Building
|
import com.dowstats.data.entities.Building
|
||||||
import com.dowstats.data.entities.DowUnitObject.filterCompanyUnits
|
|
||||||
import com.dowstats.data.entities.DowUnitObject.toUnitDto
|
|
||||||
import com.dowstats.data.repositories.AddonRepository
|
|
||||||
import com.dowstats.data.repositories.BuildingRepository
|
import com.dowstats.data.repositories.BuildingRepository
|
||||||
import com.dowstats.data.repositories.RaceRepository
|
import com.dowstats.data.repositories.RaceRepository
|
||||||
|
import com.dowstats.service.datamaps.CommonMapping.isNotCompanyEntity
|
||||||
|
import com.dowstats.service.datamaps.CommonMapping.toBuildingShortDto
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class DowBuildingMappingService @Autowired constructor(
|
class DowBuildingMappingService @Autowired constructor(
|
||||||
val buildingRepository: BuildingRepository,
|
val buildingRepository: BuildingRepository,
|
||||||
val addonRepository: AddonRepository,
|
val requirementsMappingComponent: RequirementsMappingComponent,
|
||||||
val raceRepository: RaceRepository
|
val raceRepository: RaceRepository
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun findBuildingsByMod(modId: Long): List<RaceBuildings> {
|
fun findBuildingsByMod(modId: Long): List<RaceBuildings> {
|
||||||
return getAllBuildings(modId).groupBy { it.race }.mapNotNull { raceUnits ->
|
return getAllBuildings(modId).groupBy { it.race }.mapNotNull { raceUnits ->
|
||||||
RaceBuildings(raceUnits.key?.toDto() ?: throw Exception("Race is null"), raceUnits.value.toBuildingDto())
|
RaceBuildings(raceUnits.key?.toDto() ?: throw Exception("Race is null"), raceUnits.value.toBuildingShortDto())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findBuildingsByModAndRace(modId: Long, race: String): RaceBuildings {
|
fun findBuildingsByModAndRace(modId: Long, race: String): RaceBuildings {
|
||||||
val buildings = getAllBuildings(modId, race)
|
val buildings = getAllBuildings(modId, race)
|
||||||
val raceEntity = race.let { raceRepository.findById(race) ?: throw Exception("Race $race not found") }
|
val raceEntity = race.let { raceRepository.findById(race) ?: throw Exception("Race $race not found") }
|
||||||
return RaceBuildings(raceEntity.toDto(), buildings.toBuildingDto())
|
return RaceBuildings(raceEntity.toDto(), buildings.toBuildingShortDto())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mapToDto(building: Building): BuildingFullDto {
|
fun mapToDto(building: Building): BuildingFullDto {
|
||||||
|
|
||||||
val buildingAddons = building.addons?.map { addon ->
|
val buildingAddons = building.addons?.map { addon ->
|
||||||
|
|
||||||
val requirements = addon.addonRequirements
|
val replaceWhenDone = addon.addonRequirements?.find { it.reference == Requirements.REFERENCE_REQUIREMENT_ADDON }?.replaceWhenDone ?: false
|
||||||
|
val requirement = requirementsMappingComponent
|
||||||
val requireCap =
|
.getRequirements(addon.addonRequirements?.toList() ?: emptyList(),
|
||||||
requirements?.find { it.reference == AddonRequirements.REFERENCE_REQUIREMENT_POP }?.value?.toDouble()
|
building.modId!!,
|
||||||
?.toInt()
|
building.addons?.toList() ?: emptyList()
|
||||||
|
|
||||||
val requirementAddon =
|
|
||||||
requirements?.find { it.reference == AddonRequirements.REFERENCE_REQUIREMENT_ADDON }?.value?.let {
|
|
||||||
building.addons?.find { addon -> addon.filename == it.split("\\").last().replace(".lua", ".rgd") }
|
|
||||||
}
|
|
||||||
|
|
||||||
val replaceWhenDone = requirements?.find { it.reference == AddonRequirements.REFERENCE_REQUIREMENT_ADDON }?.replaceWhenDone ?: false
|
|
||||||
|
|
||||||
val requirementAddonGlobal =
|
|
||||||
requirements?.filter { it.reference == AddonRequirements.REFERENCE_GLOBAL_REQUIREMENT_ADDON }
|
|
||||||
?.mapNotNull { rgra ->
|
|
||||||
val addonFileName = rgra.value?.split("\\")?.last()?.replace(".lua", ".rgd")
|
|
||||||
addonFileName?.let {
|
|
||||||
addonRepository.findFirstByModIdAndFilename(
|
|
||||||
building.modId!!,
|
|
||||||
it.split("\\").last().replace(".lua", ".rgd")
|
|
||||||
)?.toShortDto()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val requirementBuildings =
|
|
||||||
requirements?.filter { it.reference == AddonRequirements.REFERENCE_REQUIREMENT_STRUCTURE }?.mapNotNull {
|
|
||||||
val buildingFileName = it.value?.split("\\")?.last()?.replace(".lua", ".rgd")
|
|
||||||
buildingFileName?.let {
|
|
||||||
buildingRepository.findByModIdAndFilename(building.modId!!, buildingFileName)
|
|
||||||
}
|
|
||||||
}?.filter { it.id != building.id }?.distinct()?.toBuildingDto()
|
|
||||||
|
|
||||||
val requirementBuildingsEither =
|
|
||||||
requirements?.find { it.reference == AddonRequirements.REFERENCE_REQUIREMENT_STRUCTURE_EITHER }?.let {
|
|
||||||
it.value?.split(";")?.mapNotNull { bPath ->
|
|
||||||
buildingRepository.findByModIdAndFilename(
|
|
||||||
building.modId!!,
|
|
||||||
bPath.split("\\").last().replace(".lua", ".rgd")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}?.toBuildingDto()
|
|
||||||
|
|
||||||
val addonRequirement = if (requireCap != null ||
|
|
||||||
requirementAddon != null ||
|
|
||||||
(requirementBuildings?.size ?: 0) > 0 ||
|
|
||||||
(requirementBuildingsEither?.size ?: 0) > 0 ||
|
|
||||||
(requirementAddonGlobal?.size ?: 0) > 0
|
|
||||||
) {
|
|
||||||
AddonRequirementDto(
|
|
||||||
requirementBuildings ?: emptyList(),
|
|
||||||
requirementBuildingsEither ?: emptyList(),
|
|
||||||
requirementAddon?.toShortDto(),
|
|
||||||
replaceWhenDone,
|
|
||||||
requirementAddonGlobal,
|
|
||||||
requireCap
|
|
||||||
)
|
)
|
||||||
} else null
|
|
||||||
|
|
||||||
addon.toDto(addonRequirement)
|
addon.toDto(requirement?.copy(
|
||||||
|
replaceWhenDone = replaceWhenDone,
|
||||||
|
requirementBuildings = requirement.requirementBuildings.filter { it.id != building.id }.toSet())
|
||||||
|
)
|
||||||
}?.sortedBy { it.name }?.toSet()
|
}?.sortedBy { it.name }?.toSet()
|
||||||
|
|
||||||
return building.toDto(buildingAddons)
|
val researches = building.researches?.map {research ->
|
||||||
|
val requiremens = requirementsMappingComponent
|
||||||
|
.getRequirements(research.addonRequirements.toList() ?: emptyList(),
|
||||||
|
building.modId!!,
|
||||||
|
building.addons?.toList() ?: emptyList()
|
||||||
|
)
|
||||||
|
research.toResearchDto(requiremens)
|
||||||
|
}?.sortedBy { it.name }
|
||||||
|
|
||||||
|
return building.toDto(buildingAddons, researches)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun List<Building>.toBuildingDto(): List<BuildingShortDto> =
|
|
||||||
this
|
|
||||||
.sortedWith(compareBy<Building> { it.units?.isEmpty() }.thenBy{ it.buildCostRequisition?.let { 0 - it } })
|
|
||||||
.mapNotNull {
|
|
||||||
val name = it.name ?: it.filename?.replace(".rgd", "")?.replace("_", " ")
|
|
||||||
val icon = it.icon
|
|
||||||
if (name == null || icon == null) null else BuildingShortDto(
|
|
||||||
name, icon, it.id!!,
|
|
||||||
it.units?.toList()?.filterCompanyUnits()?.toUnitDto() ?: emptySet(),
|
|
||||||
it.armorType?.name!!,
|
|
||||||
(it.detectRadius ?: 0) > 0
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getAllBuildings(modId: Long, race: String? = null): List<Building> {
|
private fun getAllBuildings(modId: Long, race: String? = null): List<Building> {
|
||||||
val raceEntity = race?.let { raceRepository.findById(race) ?: throw Exception("Race $race not found") }
|
val raceEntity = race?.let { raceRepository.findById(race) ?: throw Exception("Race $race not found") }
|
||||||
return filterCompanyUnits(buildingRepository.findByModIdAndRace(modId, raceEntity))
|
return buildingRepository.findByModIdAndRace(modId, raceEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun filterCompanyUnits(buildings: List<Building>): List<Building> =
|
|
||||||
buildings.filter {
|
|
||||||
it.filename?.contains("_sp.") != true
|
|
||||||
&& it.filename?.contains("_sp_") != true
|
|
||||||
&& it.filename?.contains("sp_eldar_") != true
|
|
||||||
&& it.filename?.contains("_dxp3.") != true
|
|
||||||
&& it.filename?.contains("_dxp3_") != true
|
|
||||||
&& it.filename?.contains("_nis.") != true
|
|
||||||
&& it.filename?.contains("_interface_relay.") != true
|
|
||||||
&& it.filename?.contains("necron_tunnel.rgd") != true
|
|
||||||
&& it.filename?.contains("_exarch_council.") != true
|
|
||||||
&& it.filename?.contains("_dark_reapers_base.") != true
|
|
||||||
&& it.filename?.contains("eldar_deep_strike_building.rgd") != true
|
|
||||||
&& it.filename?.contains("ork_deep_strike_building.rgd") != true
|
|
||||||
&& it.filename?.contains("_caravel_ai.rgd") != true
|
|
||||||
&& it.filename?.contains("sisters_tanktrap_ai.rgd") != true
|
|
||||||
&& it.filename?.contains("sisters_hq_ktgm.rgd") != true
|
|
||||||
&& it.filename?.contains("tau_squad_slave_murdered") != true
|
|
||||||
&& it.filename?.contains("single_player_only") != true
|
|
||||||
&& it.filename?.contains("space_marine_drop_pod_building.rgd") != true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,9 +1,7 @@
|
|||||||
package com.dowstats.service.datamaps
|
package com.dowstats.service.datamaps
|
||||||
|
|
||||||
import com.dowstats.data.dto.controllers.RaceUnits
|
import com.dowstats.data.dto.controllers.RaceUnits
|
||||||
import com.dowstats.data.dto.controllers.UnitShortDto
|
|
||||||
import com.dowstats.data.entities.DowUnit
|
import com.dowstats.data.entities.DowUnit
|
||||||
import com.dowstats.data.entities.DowUnitObject.filterCompanyUnits
|
|
||||||
import com.dowstats.data.entities.DowUnitObject.toUnitDto
|
import com.dowstats.data.entities.DowUnitObject.toUnitDto
|
||||||
import com.dowstats.data.entities.Race
|
import com.dowstats.data.entities.Race
|
||||||
import com.dowstats.data.repositories.RaceRepository
|
import com.dowstats.data.repositories.RaceRepository
|
||||||
@ -40,7 +38,7 @@ class DowUnitMappingService @Autowired constructor(
|
|||||||
.toUnitDto()
|
.toUnitDto()
|
||||||
|
|
||||||
val support = units.filter {
|
val support = units.filter {
|
||||||
it.capInfantry?.let { it == 0 } ?: false && it.reinforceCostPopulation?.let { it == 0 } ?: true &&
|
it.capInfantry?.let { it == 0 } ?: false && it.reinforceCostPopulation?.let { it == 0.0 } ?: true &&
|
||||||
it.capSupport?.let { it == 0 } ?: false
|
it.capSupport?.let { it == 0 } ?: false
|
||||||
}
|
}
|
||||||
.toUnitDto()
|
.toUnitDto()
|
||||||
@ -51,7 +49,7 @@ class DowUnitMappingService @Autowired constructor(
|
|||||||
|
|
||||||
private fun getAllUnits(modId: Long, race: String? = null): List<DowUnit> {
|
private fun getAllUnits(modId: Long, race: String? = null): List<DowUnit> {
|
||||||
val raceEntity = race?.let{ raceRepository.findById(race) ?: throw Exception("Race $race not found") }
|
val raceEntity = race?.let{ raceRepository.findById(race) ?: throw Exception("Race $race not found") }
|
||||||
return unitRepository.findByModIdAndRace(modId, raceEntity).filterCompanyUnits()
|
return unitRepository.findByModIdAndRace(modId, raceEntity)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
package com.dowstats.service.datamaps
|
||||||
|
|
||||||
|
import com.dowstats.Metadata.Requirements
|
||||||
|
import com.dowstats.data.dto.controllers.RequirementDto
|
||||||
|
import com.dowstats.data.dto.controllers.RequirementResearchDto
|
||||||
|
import com.dowstats.data.entities.RequirementBase
|
||||||
|
import com.dowstats.data.entities.addon.BuildingAddon
|
||||||
|
import com.dowstats.data.repositories.AddonRepository
|
||||||
|
import com.dowstats.data.repositories.BuildingRepository
|
||||||
|
import com.dowstats.data.repositories.ResearchRepository
|
||||||
|
import com.dowstats.service.datamaps.CommonMapping.toBuildingShortDto
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
|
||||||
|
@Component
|
||||||
|
class RequirementsMappingComponent(
|
||||||
|
val addonRepository: AddonRepository,
|
||||||
|
val buildingRepository: BuildingRepository,
|
||||||
|
val researchRepository: ResearchRepository,
|
||||||
|
) {
|
||||||
|
fun getRequirements(requirements : List<RequirementBase>, modId: Long, thisBuildingAddons: List<BuildingAddon> = emptyList()) : RequirementDto? {
|
||||||
|
|
||||||
|
val requireCap =
|
||||||
|
requirements.find { it.reference == Requirements.REFERENCE_REQUIREMENT_POP }?.value?.toDouble()
|
||||||
|
?.toInt()
|
||||||
|
|
||||||
|
val requirementAddon =
|
||||||
|
requirements.find { it.reference == Requirements.REFERENCE_REQUIREMENT_ADDON }?.value?.let {
|
||||||
|
thisBuildingAddons.find { addon -> addon.filename == it.split("\\").last().replace(".lua", ".rgd") }
|
||||||
|
}?.toShortDto()
|
||||||
|
|
||||||
|
|
||||||
|
val requirementAddonGlobal =
|
||||||
|
requirements.filter { it.reference == Requirements.REFERENCE_GLOBAL_REQUIREMENT_ADDON }
|
||||||
|
.mapNotNull { rgra ->
|
||||||
|
val addonFileName = rgra.value?.split("\\")?.last()?.replace(".lua", ".rgd")
|
||||||
|
addonFileName?.let {
|
||||||
|
addonRepository.findFirstByModIdAndFilename(
|
||||||
|
modId,
|
||||||
|
it.split("\\").last().replace(".lua", ".rgd")
|
||||||
|
)?.toShortDto()
|
||||||
|
}
|
||||||
|
}.toSet()
|
||||||
|
|
||||||
|
val requirementBuildings =
|
||||||
|
requirements.filter { it.reference == Requirements.REFERENCE_REQUIREMENT_STRUCTURE }.mapNotNull {
|
||||||
|
val buildingFileName = it.value?.split("\\")?.last()?.replace(".lua", ".rgd")
|
||||||
|
buildingFileName?.let {
|
||||||
|
buildingRepository.findByModIdAndFilename(modId, buildingFileName)
|
||||||
|
}
|
||||||
|
}.distinct().toBuildingShortDto().toSet()
|
||||||
|
|
||||||
|
val requirementBuildingsEither =
|
||||||
|
requirements.find { it.reference == Requirements.REFERENCE_REQUIREMENT_STRUCTURE_EITHER }?.let {
|
||||||
|
it.value?.split(";")?.mapNotNull { bPath ->
|
||||||
|
buildingRepository.findByModIdAndFilename(
|
||||||
|
modId,
|
||||||
|
bPath.split("\\").last().replace(".lua", ".rgd")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}?.toBuildingShortDto()?.toSet() ?: emptySet()
|
||||||
|
|
||||||
|
val requirementResearches =
|
||||||
|
requirements.filter { it.reference == Requirements.REFERENCE_REQUIREMENT_RESEARCH }.mapNotNull {
|
||||||
|
val research = it.value?.split(";")?.first()
|
||||||
|
val mustNotBeCompleteStr = it.value?.split(";")?.last()
|
||||||
|
val researchFileName = research?.split("\\")?.last()?.replace(".lua", ".rgd")?.let {
|
||||||
|
if(it.endsWith(".rgd")) it else "$it.rgd"
|
||||||
|
}
|
||||||
|
researchFileName?.let {
|
||||||
|
researchRepository.findFirstByModIdAndFilename(modId, researchFileName)
|
||||||
|
}?.toResearchShortDto()?.let {
|
||||||
|
val mustNotBeComplete = mustNotBeCompleteStr == "true"
|
||||||
|
RequirementResearchDto(it, mustNotBeComplete)
|
||||||
|
}
|
||||||
|
}.toSet()
|
||||||
|
|
||||||
|
return if (requireCap != null ||
|
||||||
|
requirementAddon != null ||
|
||||||
|
requirementBuildings.isNotEmpty() ||
|
||||||
|
requirementBuildingsEither.isNotEmpty() ||
|
||||||
|
requirementResearches.isNotEmpty() ||
|
||||||
|
requirementAddonGlobal.isNotEmpty()
|
||||||
|
) {
|
||||||
|
RequirementDto(
|
||||||
|
requirementBuildings,
|
||||||
|
requirementBuildingsEither,
|
||||||
|
requirementResearches,
|
||||||
|
requirementAddon,
|
||||||
|
requirementAddonGlobal,
|
||||||
|
requireCap
|
||||||
|
)
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
package com.dowstats.service.postparsing
|
||||||
|
|
||||||
|
import com.dowstats.configuration.StorageConfig
|
||||||
|
import com.dowstats.data.entities.*
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
|
import com.dowstats.data.repositories.*
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.Path
|
||||||
|
import javax.imageio.ImageIO
|
||||||
|
import kotlin.io.path.exists
|
||||||
|
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class PostParsingService @Autowired constructor(
|
||||||
|
val researchRepository: ResearchRepository,
|
||||||
|
val unitRepository: UnitRepository,
|
||||||
|
val sergeantRepository: SergeantRepository,
|
||||||
|
val buildingRepository: BuildingRepository,
|
||||||
|
val weaponRepository: WeaponRepository,
|
||||||
|
) {
|
||||||
|
|
||||||
|
val log = LoggerFactory.getLogger(PostParsingService::class.java)
|
||||||
|
|
||||||
|
fun bindResearch(mod: Mod) {
|
||||||
|
try {
|
||||||
|
val modId = mod.id!!
|
||||||
|
val researches = researchRepository.findAllByModId(modId)
|
||||||
|
val units = unitRepository.findByModIdAndRace(modId, null)
|
||||||
|
val sergeants = sergeantRepository.findAllByModId(modId)
|
||||||
|
val buildings = buildingRepository.findByModIdAndRace(modId, null)
|
||||||
|
val weapons = weaponRepository.findAllByModId(modId)
|
||||||
|
|
||||||
|
bindResearchUnits(units, researches)
|
||||||
|
bindResearchSergeants(sergeants, researches)
|
||||||
|
bindResearchBuildings(buildings, researches)
|
||||||
|
bindResearchWeapons(weapons, researches)
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
log.warn("Error occurred during bind researches", e)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindResearchUnits(units: List<DowUnit>, researches: List<Research>) {
|
||||||
|
|
||||||
|
val unitsWithBindings: List<DowUnit> = researches.flatMap { research ->
|
||||||
|
research.researchModifiers.mapNotNull { modifier ->
|
||||||
|
units.find {
|
||||||
|
it.filenameSquad?.replace(".rgd", "") == modifier.target ||
|
||||||
|
it.filenameUnit?.replace(".rgd", "") == modifier.target
|
||||||
|
}
|
||||||
|
?.let {
|
||||||
|
it.affectedResearches.add(research)
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unitRepository.saveAll(unitsWithBindings)
|
||||||
|
log.info("Successfully bind researches to units")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindResearchSergeants(sergeants: List<Sergeant>, researches: List<Research>) {
|
||||||
|
|
||||||
|
val sergeantsWithBindings: List<Sergeant> = researches.flatMap { research ->
|
||||||
|
research.researchModifiers.mapNotNull { modifier ->
|
||||||
|
sergeants.find { it.filename.replace(".rgd", "") == modifier.target }?.let {
|
||||||
|
it.affectedResearches.add(research)
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sergeantRepository.saveAll(sergeantsWithBindings)
|
||||||
|
log.info("Successfully bind researches to sergeants")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindResearchBuildings(buildings: List<Building>, researches: List<Research>) {
|
||||||
|
|
||||||
|
val buildingsWithBindings: List<Building> = researches.flatMap { research ->
|
||||||
|
research.researchModifiers.mapNotNull { modifier ->
|
||||||
|
buildings.find { it.filename?.replace(".rgd", "") == modifier.target }?.let {
|
||||||
|
it.affectedResearches.add(research)
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buildingRepository.saveAll(buildingsWithBindings)
|
||||||
|
log.info("Successfully bind researches to buildings")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindResearchWeapons(weapons: List<Weapon>, researches: List<Research>) {
|
||||||
|
|
||||||
|
val weaponsWithBindings: List<Weapon> = researches.flatMap { research ->
|
||||||
|
research.researchModifiers.mapNotNull { modifier ->
|
||||||
|
weapons.find { it.filename?.replace(".rgd", "") == modifier.target }?.let {
|
||||||
|
it.affectedResearches.add(research)
|
||||||
|
it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
weaponRepository.saveAll(weaponsWithBindings)
|
||||||
|
log.info("Successfully bind researches to weapons")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,9 @@
|
|||||||
package com.dowstats.service.w40k
|
package com.dowstats.service.w40k
|
||||||
|
|
||||||
import com.dowstats.data.dto.BuildCost
|
|
||||||
import com.dowstats.data.entities.*
|
import com.dowstats.data.entities.*
|
||||||
|
import com.dowstats.data.entities.addon.AddonModifiers
|
||||||
|
import com.dowstats.data.entities.addon.AddonRequirements
|
||||||
|
import com.dowstats.data.entities.addon.BuildingAddon
|
||||||
import com.dowstats.data.rgd.RgdData
|
import com.dowstats.data.rgd.RgdData
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getBooleanByName
|
import com.dowstats.data.rgd.RgdDataUtil.getBooleanByName
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
|
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
|
||||||
@ -10,23 +12,13 @@ import com.dowstats.data.rgd.RgdDataUtil.getStringByName
|
|||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Path
|
|
||||||
import kotlin.io.path.exists
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class BuildingAddonRgdExtractService @Autowired constructor(
|
class BuildingAddonRgdExtractService @Autowired constructor(
|
||||||
private val modAttribPathService: ModAttribPathService,
|
private val commonParseRgdService: CommonParseRgdService,
|
||||||
private val iconsService: IconsService,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val log = LoggerFactory.getLogger(BuildingAddonRgdExtractService::class.java)
|
val log = LoggerFactory.getLogger(BuildingAddonRgdExtractService::class.java)
|
||||||
|
|
||||||
data class AddonTexts(
|
|
||||||
val name: String?,
|
|
||||||
val description: String?,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun extractToAddonEntity(
|
fun extractToAddonEntity(
|
||||||
fileName: String,
|
fileName: String,
|
||||||
modDictionary: Map<Int, String>,
|
modDictionary: Map<Int, String>,
|
||||||
@ -37,14 +29,16 @@ class BuildingAddonRgdExtractService @Autowired constructor(
|
|||||||
): BuildingAddon {
|
): BuildingAddon {
|
||||||
|
|
||||||
val addon = BuildingAddon()
|
val addon = BuildingAddon()
|
||||||
|
|
||||||
val nameAndDescription = getAddonNameAndDescription(addonRgdData, modDictionary)
|
|
||||||
addon.name = nameAndDescription.name
|
|
||||||
addon.description = nameAndDescription.description
|
|
||||||
addon.building = building
|
addon.building = building
|
||||||
|
|
||||||
|
val uiInfoRgd = addonRgdData.getRgdTableByName("ui_info") ?: throw Exception("Could not find ui_info at $fileName")
|
||||||
|
val uiInfo = commonParseRgdService.getUiInfo(uiInfoRgd, modDictionary, modFolderData, mod, log)
|
||||||
|
addon.name = uiInfo.name
|
||||||
|
addon.description = uiInfo.description
|
||||||
|
addon.icon = uiInfo.iconPath
|
||||||
addon.filename = fileName
|
addon.filename = fileName
|
||||||
|
|
||||||
val buildCost = getAddonCost(addonRgdData)
|
val buildCost = commonParseRgdService.getBuildCost(addonRgdData.getRgdTableByName("time_cost"))
|
||||||
addon.addonCostRequisition = buildCost.requisition
|
addon.addonCostRequisition = buildCost.requisition
|
||||||
addon.addonCostPower = buildCost.power
|
addon.addonCostPower = buildCost.power
|
||||||
addon.addonCostPopulation = buildCost.population
|
addon.addonCostPopulation = buildCost.population
|
||||||
@ -54,8 +48,6 @@ class BuildingAddonRgdExtractService @Autowired constructor(
|
|||||||
addon.addonModifiers = getAddonModifiers(addon, addonRgdData).toMutableSet()
|
addon.addonModifiers = getAddonModifiers(addon, addonRgdData).toMutableSet()
|
||||||
addon.addonRequirements = getAddonRequirements(addon, addonRgdData).toMutableSet()
|
addon.addonRequirements = getAddonRequirements(addon, addonRgdData).toMutableSet()
|
||||||
|
|
||||||
val addonIcon = convertIconAndReturnPath(addonRgdData, modFolderData, mod.name)
|
|
||||||
addon.icon = addonIcon
|
|
||||||
addon.modId = mod.id
|
addon.modId = mod.id
|
||||||
|
|
||||||
return addon
|
return addon
|
||||||
@ -88,82 +80,11 @@ class BuildingAddonRgdExtractService @Autowired constructor(
|
|||||||
it.addon = addon
|
it.addon = addon
|
||||||
it.reference = rTable.getStringByName("\$REF")
|
it.reference = rTable.getStringByName("\$REF")
|
||||||
it.replaceWhenDone = rTable.getBooleanByName("replace_when_done") == true
|
it.replaceWhenDone = rTable.getBooleanByName("replace_when_done") == true
|
||||||
it.value = when(it.reference){
|
it.value = commonParseRgdService.getRequirementReference(it.reference, rTable, addon.filename!!, log)
|
||||||
AddonRequirements.REFERENCE_REQUIREMENT_POP -> rTable.getDoubleByName("population_required").toString()
|
|
||||||
AddonRequirements.REFERENCE_REQUIREMENT_ADDON -> rTable.getStringByName("addon_name")
|
|
||||||
AddonRequirements.REFERENCE_GLOBAL_REQUIREMENT_ADDON -> rTable.getStringByName("global_addon_name")
|
|
||||||
AddonRequirements.REFERENCE_REQUIREMENT_STRUCTURE_EITHER -> rTable.getStringByName("structure_name_or") + ";" + rTable.getStringByName("structure_name_either")
|
|
||||||
AddonRequirements.REFERENCE_REQUIREMENT_STRUCTURE -> rTable.getStringByName("structure_name")
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else null
|
} else null
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getAddonCost(addonData: List<RgdData>): BuildCost {
|
|
||||||
|
|
||||||
val cost = addonData.getRgdTableByName("time_cost")
|
|
||||||
|
|
||||||
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()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAddonNameAndDescription(addonData: List<RgdData>, modDictionary: Map<Int, String>): AddonTexts {
|
|
||||||
val uiInfo = addonData.getRgdTableByName("ui_info")
|
|
||||||
|
|
||||||
val nameRef = uiInfo?.getStringByName("screen_name_id")?.replace("$", "")
|
|
||||||
val name = nameRef?.let {
|
|
||||||
try {
|
|
||||||
modDictionary[it.toInt()]
|
|
||||||
} catch (e: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val descriptionRefs = uiInfo?.getRgdTableByName("help_text_list")
|
|
||||||
?.map { (it.value as String).replace("$", "") }
|
|
||||||
?.filter { it != "0" && it != "tables\\text_table.lua" && it != "" }
|
|
||||||
?.sortedBy {
|
|
||||||
try {
|
|
||||||
it.toInt()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val description = try {
|
|
||||||
descriptionRefs?.map { modDictionary[it.toInt()] }?.joinToString("\n")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
log.warn("Error parsing ui description", e)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
return AddonTexts(name, description)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun convertIconAndReturnPath(
|
|
||||||
buildingData: List<RgdData>,
|
|
||||||
modFolderData: String,
|
|
||||||
modName: String?
|
|
||||||
): String? {
|
|
||||||
val iconPathInMod = buildingData
|
|
||||||
.getRgdTableByName("ui_info")
|
|
||||||
?.getStringByName("icon_name")
|
|
||||||
|
|
||||||
return iconPathInMod?.let { modAttribPathService.getIconPath(modFolderData, iconPathInMod) }
|
|
||||||
?.let { iconsService.convertTgaToJpegImage(iconPathInMod, it, modName) }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,21 @@
|
|||||||
package com.dowstats.service.w40k
|
package com.dowstats.service.w40k
|
||||||
|
|
||||||
import com.dowstats.data.dto.BuildCost
|
|
||||||
import com.dowstats.data.dto.BuildingDataToSave
|
import com.dowstats.data.dto.BuildingDataToSave
|
||||||
import com.dowstats.data.entities.*
|
import com.dowstats.data.entities.*
|
||||||
import com.dowstats.data.repositories.UnitRepository
|
import com.dowstats.data.entities.research.Research
|
||||||
import com.dowstats.data.rgd.RgdData
|
import com.dowstats.data.rgd.RgdData
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
|
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getIntByName
|
import com.dowstats.data.rgd.RgdDataUtil.getIntByName
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
|
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
|
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
|
||||||
import com.dowstats.service.w40k.UnitRgdExtractService.ResourceIncome
|
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Path
|
|
||||||
import kotlin.io.path.exists
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class BuildingRgdExtractService @Autowired constructor(
|
class BuildingRgdExtractService @Autowired constructor(
|
||||||
private val modAttribPathService: ModAttribPathService,
|
|
||||||
private val iconsService: IconsService,
|
|
||||||
private val addonRgdExtractService: BuildingAddonRgdExtractService,
|
private val addonRgdExtractService: BuildingAddonRgdExtractService,
|
||||||
|
private val commonParseRgdService: CommonParseRgdService,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val log = LoggerFactory.getLogger(BuildingRgdExtractService::class.java)
|
val log = LoggerFactory.getLogger(BuildingRgdExtractService::class.java)
|
||||||
@ -39,16 +33,12 @@ class BuildingRgdExtractService @Autowired constructor(
|
|||||||
val weaponFilename: String,
|
val weaponFilename: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class BuildingTexts(
|
|
||||||
val name: String?,
|
|
||||||
val description: String?,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun extractToBuildingEntity(
|
fun extractToBuildingEntity(
|
||||||
fileName: String,
|
fileName: String,
|
||||||
modDictionary: Map<Int, String>,
|
modDictionary: Map<Int, String>,
|
||||||
buildingData: List<RgdData>,
|
buildingData: List<RgdData>,
|
||||||
weapons: Set<Weapon>,
|
weapons: Set<Weapon>,
|
||||||
|
researches: Set<Research>,
|
||||||
units: List<DowUnit>,
|
units: List<DowUnit>,
|
||||||
race: Race,
|
race: Race,
|
||||||
modFolderData: String,
|
modFolderData: String,
|
||||||
@ -63,13 +53,16 @@ class BuildingRgdExtractService @Autowired constructor(
|
|||||||
building.race = race
|
building.race = race
|
||||||
building.armorType = getBuildingArmourType(buildingData, armorTypes, "type_armour") ?: throw Exception("Cant get armor type")
|
building.armorType = getBuildingArmourType(buildingData, armorTypes, "type_armour") ?: throw Exception("Cant get armor type")
|
||||||
building.armorType2 = getBuildingArmourType(buildingData, armorTypes, "type_armour_2")
|
building.armorType2 = getBuildingArmourType(buildingData, armorTypes, "type_armour_2")
|
||||||
|
|
||||||
val nameAndDescription = getBuildingNameAndDescription(buildingData, modDictionary)
|
|
||||||
building.name = nameAndDescription.name
|
|
||||||
building.description = nameAndDescription.description
|
|
||||||
building.filename = fileName
|
building.filename = fileName
|
||||||
|
|
||||||
val buildCost = getBuildCost(buildingData)
|
val buildingUiInfo = buildingData.getRgdTableByName("ui_ext")
|
||||||
|
?.getRgdTableByName("ui_info") ?: throw Exception("Could not find ui_info at $fileName")
|
||||||
|
val buildingUiData = commonParseRgdService.getUiInfo(buildingUiInfo, modDictionary, modFolderData, mod, log)
|
||||||
|
building.name = buildingUiData.name
|
||||||
|
building.description = buildingUiData.description
|
||||||
|
building.icon = buildingUiData.iconPath
|
||||||
|
|
||||||
|
val buildCost = commonParseRgdService.getBuildCost(buildingData.getRgdTableByName("cost_ext")?.getRgdTableByName("time_cost"))
|
||||||
building.buildCostRequisition = buildCost.requisition
|
building.buildCostRequisition = buildCost.requisition
|
||||||
building.buildCostPower = buildCost.power
|
building.buildCostPower = buildCost.power
|
||||||
building.buildCostPopulation = buildCost.population
|
building.buildCostPopulation = buildCost.population
|
||||||
@ -77,7 +70,7 @@ class BuildingRgdExtractService @Autowired constructor(
|
|||||||
building.buildCostSouls = buildCost.souls
|
building.buildCostSouls = buildCost.souls
|
||||||
building.buildCostTime = buildCost.time
|
building.buildCostTime = buildCost.time
|
||||||
|
|
||||||
val incomeData = getResource(buildingData)
|
val incomeData = commonParseRgdService.getResourceIncome(buildingData.getRgdTableByName("resource_ext"))
|
||||||
building.faithIncome = incomeData.faith
|
building.faithIncome = incomeData.faith
|
||||||
building.powerIncome = incomeData.power
|
building.powerIncome = incomeData.power
|
||||||
building.requisitionIncome = incomeData.requisition
|
building.requisitionIncome = incomeData.requisition
|
||||||
@ -94,6 +87,7 @@ class BuildingRgdExtractService @Autowired constructor(
|
|||||||
building.repairMax = healthData.maxRepaires
|
building.repairMax = healthData.maxRepaires
|
||||||
|
|
||||||
building.units = getUnits(buildingData, units).toMutableSet()
|
building.units = getUnits(buildingData, units).toMutableSet()
|
||||||
|
building.researches = getResearches(buildingData, researches).toMutableSet()
|
||||||
|
|
||||||
val addons = getAddons(buildingData)
|
val addons = getAddons(buildingData)
|
||||||
building.addons = addons?.mapNotNull {addonFileName ->
|
building.addons = addons?.mapNotNull {addonFileName ->
|
||||||
@ -106,8 +100,6 @@ class BuildingRgdExtractService @Autowired constructor(
|
|||||||
}
|
}
|
||||||
}?.toMutableSet()
|
}?.toMutableSet()
|
||||||
|
|
||||||
val buildingIcon = convertIconAndReturnPath(buildingData, modFolderData, mod.name)
|
|
||||||
building.icon = buildingIcon
|
|
||||||
|
|
||||||
val buildingWeapons = getBuildingWeapon(buildingData)?.mapNotNull { weaponData ->
|
val buildingWeapons = getBuildingWeapon(buildingData)?.mapNotNull { weaponData ->
|
||||||
weapons.find {
|
weapons.find {
|
||||||
@ -135,54 +127,6 @@ class BuildingRgdExtractService @Autowired constructor(
|
|||||||
return armorTypes.find { it.id == armorType?.replace("type_armour\\tp_", "")?.replace(".lua", "") }
|
return armorTypes.find { it.id == armorType?.replace("type_armour\\tp_", "")?.replace(".lua", "") }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getBuildCost(buildingData: List<RgdData>): BuildCost {
|
|
||||||
|
|
||||||
val cost = buildingData.getRgdTableByName("cost_ext")
|
|
||||||
?.getRgdTableByName("time_cost")
|
|
||||||
|
|
||||||
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()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getResource(buildingData: List<RgdData>): ResourceIncome {
|
|
||||||
val resourceExt = buildingData.getRgdTableByName("resource_ext")
|
|
||||||
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 },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getBuildingNameAndDescription(buildingData: List<RgdData>, modDictionary: Map<Int, String>): BuildingTexts {
|
|
||||||
val uiInfo = buildingData.getRgdTableByName("ui_ext")
|
|
||||||
?.getRgdTableByName("ui_info")
|
|
||||||
|
|
||||||
val nameRef = uiInfo?.getStringByName("screen_name_id")?.replace("$", "")
|
|
||||||
val name = nameRef?.let { try{modDictionary[it.toInt()]} catch (e: Exception) { null } }
|
|
||||||
|
|
||||||
val descriptionRefs = uiInfo?.getRgdTableByName("help_text_list")
|
|
||||||
?.map{(it.value as String).replace("$", "")}
|
|
||||||
?.filter{it != "0" && it != "tables\\text_table.lua" && it != ""}
|
|
||||||
?.sortedBy { try { it.toInt() } catch (e: Exception) { 0 } }
|
|
||||||
|
|
||||||
val description = try {
|
|
||||||
descriptionRefs?.map { modDictionary[it.toInt()] }?.joinToString ( "\n" )
|
|
||||||
} catch(e:Exception) {
|
|
||||||
log.warn("Error parsing ui description", e)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
return BuildingTexts(name, description)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getHealthData(buildingData: List<RgdData>): HealthData {
|
private fun getHealthData(buildingData: List<RgdData>): HealthData {
|
||||||
val healthExt = buildingData.getRgdTableByName("health_ext")
|
val healthExt = buildingData.getRgdTableByName("health_ext")
|
||||||
return HealthData(
|
return HealthData(
|
||||||
@ -225,17 +169,6 @@ class BuildingRgdExtractService @Autowired constructor(
|
|||||||
}?.flatten()
|
}?.flatten()
|
||||||
|
|
||||||
|
|
||||||
private fun convertIconAndReturnPath(buildingData: List<RgdData>, modFolderData: String, modName: String?): String? {
|
|
||||||
val iconPathInMod = buildingData
|
|
||||||
.getRgdTableByName("ui_ext")
|
|
||||||
?.getRgdTableByName("ui_info")
|
|
||||||
?.getStringByName("icon_name")
|
|
||||||
|
|
||||||
return iconPathInMod?.let { modAttribPathService.getIconPath(modFolderData, iconPathInMod) }
|
|
||||||
?.let { iconsService.convertTgaToJpegImage(iconPathInMod, it, modName) }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getAddons(buildingData: List<RgdData>): List<String>? = buildingData
|
private fun getAddons(buildingData: List<RgdData>): List<String>? = buildingData
|
||||||
.getRgdTableByName("addon_ext")
|
.getRgdTableByName("addon_ext")
|
||||||
?.getRgdTableByName("addons")
|
?.getRgdTableByName("addons")
|
||||||
@ -254,10 +187,19 @@ class BuildingRgdExtractService @Autowired constructor(
|
|||||||
?.mapNotNull { unit ->
|
?.mapNotNull { unit ->
|
||||||
if (unit.name.contains("squad_")) {
|
if (unit.name.contains("squad_")) {
|
||||||
val fileName = unit.value.toString().split("\\").last().replace(".lua", ".rgd")
|
val fileName = unit.value.toString().split("\\").last().replace(".lua", ".rgd")
|
||||||
units.find { it.filename == fileName }
|
units.find { it.filenameSquad == fileName }
|
||||||
} else null
|
} else null
|
||||||
} ?: emptyList()
|
} ?: emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getResearches(buildingData: List<RgdData>, researches: Set<Research>): List<Research> {
|
||||||
|
return buildingData.getRgdTableByName("research_ext")
|
||||||
|
?.getRgdTableByName("research_table")
|
||||||
|
?.mapNotNull { research ->
|
||||||
|
if (research.name.contains("research_")) {
|
||||||
|
val fileName = research.value.toString().split("\\").last().replace(".lua", "")
|
||||||
|
researches.find { it.filename?.replace(".rgd", "") == fileName }
|
||||||
|
} else null
|
||||||
|
} ?: emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,137 @@
|
|||||||
|
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.rgd.RgdData
|
||||||
|
import com.dowstats.data.rgd.RgdDataUtil.getBooleanByName
|
||||||
|
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
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): UiInfo {
|
||||||
|
val nameRef = uiInfoRgdData?.getStringByName("screen_name_id")?.replace("$", "")
|
||||||
|
val name = nameRef?.let { try { modDictionary[it.toInt()] } catch (e: Exception) { null } }
|
||||||
|
|
||||||
|
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) { "" } }?.joinToString ( "\n" )
|
||||||
|
} catch(e:Exception) {
|
||||||
|
log.warn("Error parsing ui description weapon $name", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
val icon = try {
|
||||||
|
val iconPath = 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 weapon $name", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
return UiInfo(name, description, icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getAreaEffectData(weaponData: List<RgdData>): AreaEffect {
|
||||||
|
val areaEffect = weaponData.getRgdTableByName("area_effect")
|
||||||
|
|
||||||
|
val areaEffectInformation = areaEffect?.getRgdTableByName("area_effect_information")
|
||||||
|
val cantHaveRadius = areaEffectInformation?.getRgdTableByName("area_type")?.getStringByName("\$REF")?.contains("tp_area_effect_point") == true
|
||||||
|
val damageRadius = if(cantHaveRadius) 0.0 else areaEffectInformation?.getDoubleByName("radius") ?: 0.0
|
||||||
|
|
||||||
|
val throwData = areaEffect?.getRgdTableByName("throw_data")
|
||||||
|
val forceMin = throwData?.getDoubleByName("force_min") ?: 0.0
|
||||||
|
val forceMax = throwData?.getDoubleByName("force_max") ?: 0.0
|
||||||
|
|
||||||
|
val armourDamage = areaEffect
|
||||||
|
?.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)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -43,6 +43,7 @@ class IconsService @Autowired constructor(
|
|||||||
null
|
null
|
||||||
} else {
|
} else {
|
||||||
pathToSave.replace("${storageConfig.iconsStorage.replace("/", File.separator)}${File.separator}", "")
|
pathToSave.replace("${storageConfig.iconsStorage.replace("/", File.separator)}${File.separator}", "")
|
||||||
|
.replace("${File.separator}${File.separator}","${File.separator}")
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.warn("Can't convert icon $iconPathInMod", e)
|
log.warn("Can't convert icon $iconPathInMod", e)
|
||||||
|
|||||||
@ -26,6 +26,9 @@ class ModAttribPathService @Autowired constructor(
|
|||||||
fun getWeaponAttribsPath(modFolderData: String): String =
|
fun getWeaponAttribsPath(modFolderData: String): String =
|
||||||
"$modFolderData${File.separator}attrib${File.separator}weapon"
|
"$modFolderData${File.separator}attrib${File.separator}weapon"
|
||||||
|
|
||||||
|
fun getResearchAttribsPath(modFolderData: String): String =
|
||||||
|
"$modFolderData${File.separator}attrib${File.separator}research"
|
||||||
|
|
||||||
fun getAddonAttribsPath(modFolderData: String): String =
|
fun getAddonAttribsPath(modFolderData: String): String =
|
||||||
"$modFolderData${File.separator}attrib${File.separator}addons"
|
"$modFolderData${File.separator}attrib${File.separator}addons"
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
package com.dowstats.service.w40k
|
package com.dowstats.service.w40k
|
||||||
|
|
||||||
import com.dowstats.data.entities.*
|
import com.dowstats.data.entities.*
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
import com.dowstats.data.repositories.*
|
import com.dowstats.data.repositories.*
|
||||||
import com.dowstats.data.rgd.RgdData
|
import com.dowstats.data.rgd.RgdData
|
||||||
|
import com.dowstats.service.postparsing.PostParsingService
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
@ -17,6 +19,7 @@ import kotlin.io.path.name
|
|||||||
class ModParserService @Autowired constructor(
|
class ModParserService @Autowired constructor(
|
||||||
val rgdParserService: RgdParserService,
|
val rgdParserService: RgdParserService,
|
||||||
val unitRgdExtractService: UnitRgdExtractService,
|
val unitRgdExtractService: UnitRgdExtractService,
|
||||||
|
val researchRgdExtractService: ResearchRgdExtractService,
|
||||||
val raceRepository: RaceRepository,
|
val raceRepository: RaceRepository,
|
||||||
val armorTypeRepository: ArmorTypeRepository,
|
val armorTypeRepository: ArmorTypeRepository,
|
||||||
val unitRepository: UnitRepository,
|
val unitRepository: UnitRepository,
|
||||||
@ -26,6 +29,9 @@ class ModParserService @Autowired constructor(
|
|||||||
val modAttribPathService: ModAttribPathService,
|
val modAttribPathService: ModAttribPathService,
|
||||||
val buildingRepository: BuildingRepository,
|
val buildingRepository: BuildingRepository,
|
||||||
val buildingExtractService: BuildingRgdExtractService,
|
val buildingExtractService: BuildingRgdExtractService,
|
||||||
|
val postParsingService: PostParsingService,
|
||||||
|
private val researchRepository: ResearchRepository,
|
||||||
|
private val modRepository: ModRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val defaultDictionary: MutableMap<Int, String> = mutableMapOf()
|
val defaultDictionary: MutableMap<Int, String> = mutableMapOf()
|
||||||
@ -56,6 +62,7 @@ class ModParserService @Autowired constructor(
|
|||||||
fun parseModFilesAndSaveToDb(mod: Mod) {
|
fun parseModFilesAndSaveToDb(mod: Mod) {
|
||||||
|
|
||||||
log.info("Start parse mod files ${mod.technicalName}:${mod.version}")
|
log.info("Start parse mod files ${mod.technicalName}:${mod.version}")
|
||||||
|
modRepository.clearModData(mod.id!!)
|
||||||
|
|
||||||
val modFolderData = modAttribPathService.getModFolderData(mod.technicalName!!, mod.version!!)
|
val modFolderData = modAttribPathService.getModFolderData(mod.technicalName!!, mod.version!!)
|
||||||
val racesList = Files.walk(Path(modAttribPathService.getSbpsAttribsFolderPath(modFolderData)), 1)
|
val racesList = Files.walk(Path(modAttribPathService.getSbpsAttribsFolderPath(modFolderData)), 1)
|
||||||
@ -78,9 +85,14 @@ class ModParserService @Autowired constructor(
|
|||||||
val enrichedModDictionary = defaultDictionary + modDictionary
|
val enrichedModDictionary = defaultDictionary + modDictionary
|
||||||
|
|
||||||
val weapons = saveWeapons(modFolderData, mod, armorTypes, enrichedModDictionary)
|
val weapons = saveWeapons(modFolderData, mod, armorTypes, enrichedModDictionary)
|
||||||
|
val researches = saveResearches(modFolderData, mod, enrichedModDictionary)
|
||||||
saveUnits(modFolderData, weapons, racesList, armorTypes, mod, enrichedModDictionary)
|
saveUnits(modFolderData, weapons, racesList, armorTypes, mod, enrichedModDictionary)
|
||||||
|
saveBuildings(modFolderData, weapons, researches, racesList, armorTypes, mod, enrichedModDictionary)
|
||||||
|
|
||||||
|
modRepository.removeCampaignEntities(mod.id!!)
|
||||||
|
postParsingService.bindResearch(mod)
|
||||||
|
log.info("Complete parse mod ${mod.technicalName}:${mod.version}")
|
||||||
|
|
||||||
saveBuildings(modFolderData, weapons, racesList, armorTypes, mod, enrichedModDictionary)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +122,49 @@ class ModParserService @Autowired constructor(
|
|||||||
return modDictionary
|
return modDictionary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun saveResearches(
|
||||||
|
modFolderData: String,
|
||||||
|
mod: Mod,
|
||||||
|
modDictionary: Map<Int, String>
|
||||||
|
): Set<Research> {
|
||||||
|
|
||||||
|
val classicRgdDataResearches =
|
||||||
|
rgdParserService.parseFolderToRgdFiles(
|
||||||
|
modAttribPathService.getResearchAttribsPath(
|
||||||
|
modAttribPathService.pathToWanilaData,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
val modRgdDataResearches =
|
||||||
|
rgdParserService.parseFolderToRgdFiles(
|
||||||
|
modAttribPathService.getResearchAttribsPath(
|
||||||
|
modFolderData,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
val researchesFull = classicRgdDataResearches + modRgdDataResearches
|
||||||
|
|
||||||
|
val researches = researchesFull.mapNotNull { researchData ->
|
||||||
|
try {
|
||||||
|
researchRgdExtractService.extractToResearchEntity(
|
||||||
|
researchData.key,
|
||||||
|
modDictionary,
|
||||||
|
researchData.value,
|
||||||
|
modFolderData,
|
||||||
|
mod,
|
||||||
|
)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
log.error("Can't extract ${researchData.key}", e)
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return try {
|
||||||
|
researchRepository.saveAll(researches).toSet()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun saveUnits(
|
private fun saveUnits(
|
||||||
modFolderData: String,
|
modFolderData: String,
|
||||||
weapons: Set<Weapon>,
|
weapons: Set<Weapon>,
|
||||||
@ -173,6 +228,7 @@ class ModParserService @Autowired constructor(
|
|||||||
try {
|
try {
|
||||||
unitRgdExtractService.extractToUnitEntity(
|
unitRgdExtractService.extractToUnitEntity(
|
||||||
squadRgdData.key,
|
squadRgdData.key,
|
||||||
|
baseUnitName,
|
||||||
modDictionary,
|
modDictionary,
|
||||||
squadRgdData.value,
|
squadRgdData.value,
|
||||||
unitRgdData,
|
unitRgdData,
|
||||||
@ -230,6 +286,7 @@ class ModParserService @Autowired constructor(
|
|||||||
sergeantRepository.save(sergeant)
|
sergeantRepository.save(sergeant)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
log.error("Cant save unit ${unitDataToSave.unit.name}", e)
|
||||||
throw e
|
throw e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -239,6 +296,7 @@ class ModParserService @Autowired constructor(
|
|||||||
private fun saveBuildings(
|
private fun saveBuildings(
|
||||||
modFolderData: String,
|
modFolderData: String,
|
||||||
weapons: Set<Weapon>,
|
weapons: Set<Weapon>,
|
||||||
|
researches: Set<Research>,
|
||||||
racesList: List<String>,
|
racesList: List<String>,
|
||||||
armorTypes: Set<ArmorType>,
|
armorTypes: Set<ArmorType>,
|
||||||
mod: Mod, modDictionary: Map<Int, String>
|
mod: Mod, modDictionary: Map<Int, String>
|
||||||
@ -282,6 +340,7 @@ class ModParserService @Autowired constructor(
|
|||||||
modDictionary,
|
modDictionary,
|
||||||
structure.value,
|
structure.value,
|
||||||
weapons,
|
weapons,
|
||||||
|
researches,
|
||||||
raceUnits,
|
raceUnits,
|
||||||
race,
|
race,
|
||||||
modFolderData,
|
modFolderData,
|
||||||
@ -356,4 +415,6 @@ class ModParserService @Autowired constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
package com.dowstats.service.w40k
|
||||||
|
|
||||||
|
import com.dowstats.data.entities.*
|
||||||
|
import com.dowstats.data.entities.research.Research
|
||||||
|
import com.dowstats.data.entities.research.ResearchModifiers
|
||||||
|
import com.dowstats.data.entities.research.ResearchRequirements
|
||||||
|
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 org.slf4j.LoggerFactory
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
@Service
|
||||||
|
class ResearchRgdExtractService @Autowired constructor(
|
||||||
|
private val commonParseRgdService: CommonParseRgdService,
|
||||||
|
) {
|
||||||
|
|
||||||
|
val log = LoggerFactory.getLogger(ResearchRgdExtractService::class.java)
|
||||||
|
|
||||||
|
fun extractToResearchEntity(
|
||||||
|
fileName: String,
|
||||||
|
modDictionary: Map<Int, String>,
|
||||||
|
researchData: List<RgdData>,
|
||||||
|
modFolderData: String,
|
||||||
|
mod: Mod,
|
||||||
|
): Research {
|
||||||
|
|
||||||
|
val research = Research()
|
||||||
|
research.filename = fileName
|
||||||
|
|
||||||
|
val uiInfo = researchData.getRgdTableByName("ui_info") ?: throw Exception("Could not find ui_info at $fileName")
|
||||||
|
val researchUiInfo = commonParseRgdService.getUiInfo(uiInfo, modDictionary, modFolderData, mod, log)
|
||||||
|
research.name = researchUiInfo.name
|
||||||
|
research.description = researchUiInfo.description
|
||||||
|
research.icon = researchUiInfo.iconPath
|
||||||
|
|
||||||
|
val cost = commonParseRgdService.getBuildCost(researchData.getRgdTableByName("time_cost"))
|
||||||
|
|
||||||
|
research.costRequisition = cost.requisition
|
||||||
|
research.costPower = cost.power
|
||||||
|
research.costFaith = cost.faith
|
||||||
|
research.costSouls = cost.souls
|
||||||
|
research.costTime = cost.time
|
||||||
|
research.researchModifiers = getResearchModifiers(research, researchData).toMutableSet()
|
||||||
|
research.addonRequirements = getResearchRequirements(research, researchData).toMutableSet()
|
||||||
|
|
||||||
|
research.modId = mod.id
|
||||||
|
|
||||||
|
return research
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getResearchModifiers(research: Research, researchData: List<RgdData>): List<ResearchModifiers> {
|
||||||
|
val modifiers = researchData.getRgdTableByName("modifiers")
|
||||||
|
return modifiers?.mapNotNull { m ->
|
||||||
|
if (m.name.contains("modifier_")) {
|
||||||
|
val mTable = m.value as List<RgdData>
|
||||||
|
if (mTable.getStringByName("\$REF") == "modifiers\\no_modifier.lua") null else {
|
||||||
|
ResearchModifiers().also {
|
||||||
|
it.research = research
|
||||||
|
it.reference = mTable.getStringByName("\$REF")
|
||||||
|
it.usageType = mTable.getRgdTableByName("usage_type")?.getStringByName("\$REF")
|
||||||
|
it.target = mTable.getStringByName("target_type_name")
|
||||||
|
it.value = mTable.getDoubleByName("value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else null
|
||||||
|
} ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getResearchRequirements(research: Research, researchData: List<RgdData>): List<ResearchRequirements> {
|
||||||
|
val requirements = researchData.getRgdTableByName("requirements")
|
||||||
|
return requirements?.mapNotNull { r ->
|
||||||
|
if (r.name.contains("required_")) {
|
||||||
|
val rTable = r.value as List<RgdData>
|
||||||
|
if (rTable.getStringByName("\$REF") == "requirements\\required_none.lua") null else {
|
||||||
|
ResearchRequirements().also {
|
||||||
|
it.research = research
|
||||||
|
it.reference = rTable.getStringByName("\$REF")
|
||||||
|
it.value = commonParseRgdService.getRequirementReference(it.reference, rTable, research.filename!!, log)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else null
|
||||||
|
} ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -13,7 +13,7 @@ import java.nio.ByteBuffer
|
|||||||
class RgdParserService @Autowired constructor(
|
class RgdParserService @Autowired constructor(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val log = LoggerFactory.getLogger(WeaponRgdExtractService::class.java)
|
val log = LoggerFactory.getLogger(RgdParserService::class.java)
|
||||||
|
|
||||||
val zeroByte: Byte = 0
|
val zeroByte: Byte = 0
|
||||||
|
|
||||||
|
|||||||
@ -7,18 +7,13 @@ import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
|
|||||||
import com.dowstats.data.rgd.RgdDataUtil.getIntByName
|
import com.dowstats.data.rgd.RgdDataUtil.getIntByName
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
|
import com.dowstats.data.rgd.RgdDataUtil.getRgdTableByName
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
|
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
|
||||||
import com.dowstats.service.w40k.UnitRgdExtractService.ResourceIncome
|
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Path
|
|
||||||
import kotlin.io.path.exists
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class SergeantRgdExtractService @Autowired constructor(
|
class SergeantRgdExtractService @Autowired constructor(
|
||||||
private val modAttribPathService: ModAttribPathService,
|
private val commonParseRgdService: CommonParseRgdService,
|
||||||
private val iconsService: IconsService,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val log = LoggerFactory.getLogger(SergeantRgdExtractService::class.java)
|
val log = LoggerFactory.getLogger(SergeantRgdExtractService::class.java)
|
||||||
@ -42,11 +37,6 @@ class SergeantRgdExtractService @Autowired constructor(
|
|||||||
val upTime: Double?,
|
val upTime: Double?,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class SquadTexts(
|
|
||||||
val name: String?,
|
|
||||||
val description: String?,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun extractToSergeantEntity(
|
fun extractToSergeantEntity(
|
||||||
fileName: String,
|
fileName: String,
|
||||||
modDictionary: Map<Int, String>,
|
modDictionary: Map<Int, String>,
|
||||||
@ -69,19 +59,23 @@ class SergeantRgdExtractService @Autowired constructor(
|
|||||||
|
|
||||||
sergeant.armorType = getUnitArmorType(sergeantData, armorTypes, "type_armour") ?: throw Exception("Cant get armor type")
|
sergeant.armorType = getUnitArmorType(sergeantData, armorTypes, "type_armour") ?: throw Exception("Cant get armor type")
|
||||||
sergeant.armorType2 = getUnitArmorType(sergeantData, armorTypes, "type_armour_2")
|
sergeant.armorType2 = getUnitArmorType(sergeantData, armorTypes, "type_armour_2")
|
||||||
|
|
||||||
val nameAndDescription = getSergeantNameAndDescription(sergeantData, modDictionary)
|
|
||||||
sergeant.name = nameAndDescription.name
|
|
||||||
sergeant.description = nameAndDescription.description
|
|
||||||
sergeant.filename = fileName
|
sergeant.filename = fileName
|
||||||
|
|
||||||
|
val sergeantUiRgd = sergeantData.getRgdTableByName("ui_ext")
|
||||||
|
?.getRgdTableByName("ui_info") ?: throw Exception("Could not find ui_info at $fileName")
|
||||||
|
val sergeantUiInfo = commonParseRgdService.getUiInfo(sergeantUiRgd, modDictionary, modFolderData, mod, log)
|
||||||
|
sergeant.name = sergeantUiInfo.name
|
||||||
|
sergeant.description = sergeantUiInfo.description
|
||||||
|
sergeant.icon = sergeantUiInfo.iconPath
|
||||||
|
|
||||||
|
|
||||||
val healthData = getHealthAndMoraleDeathPenaltyData(sergeantData)
|
val healthData = getHealthAndMoraleDeathPenaltyData(sergeantData)
|
||||||
sergeant.health = healthData.hitpoints?.toInt()
|
sergeant.health = healthData.hitpoints?.toInt()
|
||||||
sergeant.armour = healthData.armour
|
sergeant.armour = healthData.armour
|
||||||
sergeant.healthRegeneration = healthData.regeneration
|
sergeant.healthRegeneration = healthData.regeneration
|
||||||
sergeant.moraleDeathPenalty = healthData.moraleDeathPenalty?.toInt()
|
sergeant.moraleDeathPenalty = healthData.moraleDeathPenalty?.toInt()
|
||||||
|
|
||||||
val incomeData = getResource(sergeantData)
|
val incomeData = commonParseRgdService.getResourceIncome(sergeantData.getRgdTableByName("resource_ext"))
|
||||||
sergeant.faithIncome = incomeData.faith
|
sergeant.faithIncome = incomeData.faith
|
||||||
sergeant.powerIncome = incomeData.power
|
sergeant.powerIncome = incomeData.power
|
||||||
sergeant.requisitionIncome = incomeData.requisition
|
sergeant.requisitionIncome = incomeData.requisition
|
||||||
@ -93,8 +87,7 @@ class SergeantRgdExtractService @Autowired constructor(
|
|||||||
sergeant.mass = massData.mass
|
sergeant.mass = massData.mass
|
||||||
sergeant.upTime = massData.upTime
|
sergeant.upTime = massData.upTime
|
||||||
|
|
||||||
val unitIcon = convertSergeantIconAndReturnPath(sergeantData, modFolderData, mod.name)
|
sergeant.modId = mod.id!!
|
||||||
sergeant.icon = unitIcon
|
|
||||||
|
|
||||||
val sergeantWeapons = getSergeantWeapons(sergeantData)?.mapNotNull { weaponData ->
|
val sergeantWeapons = getSergeantWeapons(sergeantData)?.mapNotNull { weaponData ->
|
||||||
weapons.find {
|
weapons.find {
|
||||||
@ -119,29 +112,6 @@ class SergeantRgdExtractService @Autowired constructor(
|
|||||||
return armorTypes.find { it.id == armorType?.replace("type_armour\\tp_", "")?.replace(".lua", "") }
|
return armorTypes.find { it.id == armorType?.replace("type_armour\\tp_", "")?.replace(".lua", "") }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getSergeantNameAndDescription(sergeantData: List<RgdData>, modDictionary: Map<Int, String>): SquadTexts {
|
|
||||||
val uiInfo = sergeantData.getRgdTableByName("ui_ext")
|
|
||||||
?.getRgdTableByName("ui_info")
|
|
||||||
|
|
||||||
|
|
||||||
val nameRef = uiInfo?.getStringByName("screen_name_id")?.replace("$", "")
|
|
||||||
val name = nameRef?.let { try{modDictionary[it.toInt()]} catch (e: Exception) { null } }
|
|
||||||
|
|
||||||
val descriptionRefs = uiInfo?.getRgdTableByName("help_text_list")
|
|
||||||
?.map{(it.value as String).replace("$", "")}
|
|
||||||
?.filter{it != "0" && it != "tables\\text_table.lua" && it != ""}
|
|
||||||
?.sortedBy { try { it.toInt() } catch (e: Exception) { 0 } }
|
|
||||||
|
|
||||||
val description = try {
|
|
||||||
descriptionRefs?.map { modDictionary[it.toInt()] }?.joinToString ( "\n" )
|
|
||||||
} catch(e:Exception) {
|
|
||||||
log.warn("Error parsing ui description", e)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
return SquadTexts(name, description)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getHealthAndMoraleDeathPenaltyData(unitData: List<RgdData>): HealthAndMoraleDeathData {
|
private fun getHealthAndMoraleDeathPenaltyData(unitData: List<RgdData>): HealthAndMoraleDeathData {
|
||||||
val healthExt = unitData.getRgdTableByName("health_ext")
|
val healthExt = unitData.getRgdTableByName("health_ext")
|
||||||
@ -153,14 +123,6 @@ class SergeantRgdExtractService @Autowired constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getResource(sergeantData: List<RgdData>): ResourceIncome {
|
|
||||||
val resourceExt = sergeantData.getRgdTableByName("resource_ext")
|
|
||||||
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 },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getMassData(unitData: List<RgdData>): MassData {
|
private fun getMassData(unitData: List<RgdData>): MassData {
|
||||||
val massDataRgd = unitData
|
val massDataRgd = unitData
|
||||||
@ -201,14 +163,4 @@ class SergeantRgdExtractService @Autowired constructor(
|
|||||||
} else null
|
} else null
|
||||||
}?.flatten()
|
}?.flatten()
|
||||||
|
|
||||||
private fun convertSergeantIconAndReturnPath(sergeantData: List<RgdData>, modFolderData: String, modName: String?): String? {
|
|
||||||
val iconPathInMod = sergeantData
|
|
||||||
.getRgdTableByName("ui_ext")
|
|
||||||
?.getRgdTableByName("ui_info")
|
|
||||||
?.getStringByName("icon_name")
|
|
||||||
|
|
||||||
return iconPathInMod?.let { modAttribPathService.getIconPath(modFolderData, iconPathInMod) }
|
|
||||||
?.let { iconsService.convertTgaToJpegImage(iconPathInMod, it, modName) }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,8 +16,7 @@ import org.springframework.stereotype.Service
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
class UnitRgdExtractService @Autowired constructor(
|
class UnitRgdExtractService @Autowired constructor(
|
||||||
private val modAttribPathService: ModAttribPathService,
|
private val commonParseRgdService: CommonParseRgdService,
|
||||||
private val iconsService: IconsService,
|
|
||||||
private val sergeantRgdExtractService: SergeantRgdExtractService,
|
private val sergeantRgdExtractService: SergeantRgdExtractService,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -36,12 +35,6 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
val percentCost: Int?,
|
val percentCost: Int?,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class ResourceIncome(
|
|
||||||
val faith: Double?,
|
|
||||||
val power: Double?,
|
|
||||||
val requisition: Double?,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class MoraleData(
|
data class MoraleData(
|
||||||
val max: Double?,
|
val max: Double?,
|
||||||
val broken: Double?,
|
val broken: Double?,
|
||||||
@ -58,13 +51,10 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
val upTime: Double?,
|
val upTime: Double?,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class UnitTexts(
|
|
||||||
val name: String?,
|
|
||||||
val description: String?,
|
|
||||||
)
|
|
||||||
|
|
||||||
fun extractToUnitEntity(
|
fun extractToUnitEntity(
|
||||||
fileName: String,
|
fileNameSquad: String,
|
||||||
|
fileNameUnit: String,
|
||||||
modDictionary: Map<Int, String>,
|
modDictionary: Map<Int, String>,
|
||||||
squadData: List<RgdData>,
|
squadData: List<RgdData>,
|
||||||
unitData: List<RgdData>,
|
unitData: List<RgdData>,
|
||||||
@ -84,10 +74,14 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
unit.armorType = getUnitArmorType(unitData, armorTypes, "type_armour") ?: throw Exception("Cant get armor type")
|
unit.armorType = getUnitArmorType(unitData, armorTypes, "type_armour") ?: throw Exception("Cant get armor type")
|
||||||
unit.armorType2 = getUnitArmorType(unitData, armorTypes, "type_armour_2")
|
unit.armorType2 = getUnitArmorType(unitData, armorTypes, "type_armour_2")
|
||||||
|
|
||||||
val nameAndDescription = getUnitNameAndDescription(squadData, modDictionary)
|
val squadUiInfo = squadData.getRgdTableByName("squad_ui_ext")
|
||||||
unit.name = nameAndDescription.name
|
?.getRgdTableByName("ui_info") ?: throw Exception("Could not find ui_info at $fileNameSquad")
|
||||||
unit.description = nameAndDescription.description
|
val squadUiData = commonParseRgdService.getUiInfo(squadUiInfo, modDictionary, modFolderData, mod, log)
|
||||||
unit.filename = fileName
|
unit.name = squadUiData.name
|
||||||
|
unit.description = squadUiData.description
|
||||||
|
unit.icon = squadUiData.iconPath
|
||||||
|
unit.filenameSquad = fileNameSquad
|
||||||
|
unit.filenameUnit = fileNameUnit
|
||||||
|
|
||||||
val buildCost = getBuildCost(unitData, squadData)
|
val buildCost = getBuildCost(unitData, squadData)
|
||||||
unit.buildCostRequisition = buildCost.requisition
|
unit.buildCostRequisition = buildCost.requisition
|
||||||
@ -117,7 +111,7 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
unit.repairSpeed = repairData.healthPerSecond
|
unit.repairSpeed = repairData.healthPerSecond
|
||||||
unit.repairCostPercent = repairData.percentCost
|
unit.repairCostPercent = repairData.percentCost
|
||||||
|
|
||||||
val incomeData = getResource(unitData)
|
val incomeData = commonParseRgdService.getResourceIncome(unitData.getRgdTableByName("resource_ext"))
|
||||||
unit.faithIncome = incomeData.faith
|
unit.faithIncome = incomeData.faith
|
||||||
unit.powerIncome = incomeData.power
|
unit.powerIncome = incomeData.power
|
||||||
unit.requisitionIncome = incomeData.requisition
|
unit.requisitionIncome = incomeData.requisition
|
||||||
@ -135,14 +129,14 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
unit.mass = massData.mass
|
unit.mass = massData.mass
|
||||||
unit.upTime = massData.upTime
|
unit.upTime = massData.upTime
|
||||||
|
|
||||||
val reinforceData = getReinforceRgdData(squadData)
|
val reinforceCostRgdData = getReinforceCostRgdData(squadData)
|
||||||
val reinforceCostData = reinforceData?.getRgdTableByName("cost")
|
val reinforceCostData = commonParseRgdService.getBuildCost(reinforceCostRgdData)
|
||||||
unit.reinforceCostRequisition = getReinforceRequisition(reinforceCostData)
|
unit.reinforceCostRequisition = reinforceCostData.requisition
|
||||||
unit.reinforceCostPower = getReinforcePower(reinforceCostData)
|
unit.reinforceCostPower = reinforceCostData.power
|
||||||
unit.reinforceCostPopulation = getReinforcePopulation(reinforceCostData)
|
unit.reinforceCostPopulation = reinforceCostData.population
|
||||||
unit.reinforceCostFaith = getReinforceFaith(reinforceCostData)
|
unit.reinforceCostFaith = reinforceCostData.faith
|
||||||
unit.reinforceCostSouls = getReinforceSouls(reinforceCostData)
|
unit.reinforceCostSouls = reinforceCostData.souls
|
||||||
unit.reinforceTime = getReinforceTime(reinforceData)
|
unit.reinforceTime = reinforceCostData.time
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -167,8 +161,6 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
|
|
||||||
unit.maxSergeants = sergeantsData.second
|
unit.maxSergeants = sergeantsData.second
|
||||||
|
|
||||||
val unitIcon = convertIconAndReturnPath(mod.name, squadData, modFolderData)
|
|
||||||
unit.icon = unitIcon
|
|
||||||
|
|
||||||
val unitWeapons = getUnitWeapons(unitData, weapons)
|
val unitWeapons = getUnitWeapons(unitData, weapons)
|
||||||
|
|
||||||
@ -201,11 +193,7 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
|
|
||||||
private fun getBuildCost(unitData: List<RgdData>, squadData: List<RgdData>): BuildCost {
|
private fun getBuildCost(unitData: List<RgdData>, squadData: List<RgdData>): BuildCost {
|
||||||
|
|
||||||
val cost = unitData.getRgdTableByName("cost_ext")
|
val cost = commonParseRgdService.getBuildCost(unitData.getRgdTableByName("cost_ext")?.getRgdTableByName("time_cost"))
|
||||||
?.getRgdTableByName("time_cost")
|
|
||||||
|
|
||||||
val costResources = cost
|
|
||||||
?.getRgdTableByName("cost")
|
|
||||||
|
|
||||||
val minSquadSize = squadData.getRgdTableByName("squad_loadout_ext")
|
val minSquadSize = squadData.getRgdTableByName("squad_loadout_ext")
|
||||||
?.getDoubleByName("unit_min")?.toInt()
|
?.getDoubleByName("unit_min")?.toInt()
|
||||||
@ -214,45 +202,15 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
cost?.let { it * (minSquadSize ?: 1) }
|
cost?.let { it * (minSquadSize ?: 1) }
|
||||||
|
|
||||||
return BuildCost(
|
return BuildCost(
|
||||||
getCost(costResources?.getDoubleByName("requisition")),
|
getCost(cost.requisition),
|
||||||
getCost(costResources?.getDoubleByName("power")),
|
getCost(cost.power),
|
||||||
getCost(costResources?.getDoubleByName("population")),
|
getCost(cost.population),
|
||||||
getCost(costResources?.getDoubleByName("faith")),
|
getCost(cost.faith),
|
||||||
getCost(costResources?.getDoubleByName("souls")),
|
getCost(cost.souls),
|
||||||
getCost(cost?.getDoubleByName("time_seconds"))?.toInt()
|
getCost(cost.time?.toDouble())?.toInt()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getUnitNameAndDescription(squadData: List<RgdData>, modDictionary: Map<Int, String>): UnitTexts {
|
|
||||||
val uiInfo = squadData.getRgdTableByName("squad_ui_ext")
|
|
||||||
?.getRgdTableByName("ui_info")
|
|
||||||
|
|
||||||
|
|
||||||
val nameRef = uiInfo?.getStringByName("screen_name_id")?.replace("$", "")
|
|
||||||
val name = nameRef?.let {
|
|
||||||
try {
|
|
||||||
modDictionary[it.toInt()]
|
|
||||||
} catch (e: Exception) {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val descriptionRefs = uiInfo?.getRgdTableByName("help_text_list")
|
|
||||||
?.map { (it.value as String).replace("$", "") }
|
|
||||||
?.filter { it != "0" && it != "tables\\text_table.lua" && it != "" && it.toIntOrNull() != null }
|
|
||||||
?.sortedBy { it.toInt() }
|
|
||||||
|
|
||||||
val description = try {
|
|
||||||
descriptionRefs?.map {
|
|
||||||
modDictionary[it.toInt()] }?.joinToString("\n")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
log.warn("Error parsing ui description", e)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
return UnitTexts(name, description)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getSquadCap(squadData: List<RgdData>): Pair<Double?, Double?> {
|
private fun getSquadCap(squadData: List<RgdData>): Pair<Double?, Double?> {
|
||||||
|
|
||||||
@ -307,14 +265,6 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getResource(unitData: List<RgdData>): ResourceIncome {
|
|
||||||
val resourceExt = unitData.getRgdTableByName("resource_ext")
|
|
||||||
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 },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getMoraleData(squadData: List<RgdData>): MoraleData {
|
private fun getMoraleData(squadData: List<RgdData>): MoraleData {
|
||||||
val moraleData = squadData.getRgdTableByName("squad_morale_ext")
|
val moraleData = squadData.getRgdTableByName("squad_morale_ext")
|
||||||
@ -346,28 +296,10 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
.getRgdTableByName("sight_ext")
|
.getRgdTableByName("sight_ext")
|
||||||
?.getDoubleByName("keen_sight_radius")
|
?.getDoubleByName("keen_sight_radius")
|
||||||
|
|
||||||
private fun getReinforceRgdData(squadData: List<RgdData>): List<RgdData>? = squadData
|
private fun getReinforceCostRgdData(squadData: List<RgdData>): List<RgdData>? = squadData
|
||||||
.getRgdTableByName("squad_reinforce_ext")
|
.getRgdTableByName("squad_reinforce_ext")
|
||||||
?.getRgdTableByName("cost")
|
?.getRgdTableByName("cost")
|
||||||
|
|
||||||
private fun getReinforceRequisition(reinforceData: List<RgdData>?): Int? = reinforceData
|
|
||||||
?.getIntByName("requisition")
|
|
||||||
|
|
||||||
private fun getReinforcePower(reinforceData: List<RgdData>?): Int? = reinforceData
|
|
||||||
?.getIntByName("power")
|
|
||||||
|
|
||||||
private fun getReinforcePopulation(reinforceData: List<RgdData>?): Int? = reinforceData
|
|
||||||
?.getIntByName("population")
|
|
||||||
|
|
||||||
private fun getReinforceFaith(reinforceData: List<RgdData>?): Int? = reinforceData
|
|
||||||
?.getIntByName("faith")
|
|
||||||
|
|
||||||
private fun getReinforceSouls(reinforceData: List<RgdData>?): Int? = reinforceData
|
|
||||||
?.getIntByName("souls")
|
|
||||||
|
|
||||||
private fun getReinforceTime(reinforceData: List<RgdData>?): Int? = reinforceData
|
|
||||||
?.getIntByName("time_seconds")
|
|
||||||
|
|
||||||
private fun getUnitWeapons(reinforceData: List<RgdData>?, weapons: Set<Weapon>): List<WeaponsData>? = reinforceData
|
private fun getUnitWeapons(reinforceData: List<RgdData>?, weapons: Set<Weapon>): List<WeaponsData>? = reinforceData
|
||||||
?.getRgdTableByName("combat_ext")
|
?.getRgdTableByName("combat_ext")
|
||||||
?.getRgdTableByName("hardpoints")
|
?.getRgdTableByName("hardpoints")
|
||||||
@ -382,9 +314,9 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
it.mapNotNull { weapon ->
|
it.mapNotNull { weapon ->
|
||||||
(weapon.value as? List<RgdData>)?.getStringByName("weapon")?.let {
|
(weapon.value as? List<RgdData>)?.getStringByName("weapon")?.let {
|
||||||
if (it != "") {
|
if (it != "") {
|
||||||
val weaponFileName = it.replace("weapon\\", "").replace(".lua", ".rgd")
|
val weaponFileName = it.replace("weapon\\", "").replace(".lua", "")
|
||||||
val weaponEntity = weapons.find {
|
val weaponEntity = weapons.find {
|
||||||
it.filename == weaponFileName
|
it.filename?.replace(".rgd", "") == weaponFileName
|
||||||
}
|
}
|
||||||
if(weaponEntity == null){
|
if(weaponEntity == null){
|
||||||
log.warn("Can't find weapon $weaponFileName")
|
log.warn("Can't find weapon $weaponFileName")
|
||||||
@ -418,19 +350,9 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
|
|
||||||
if (sergeantLeaderFilePath == null || sergeantLeaderFilePath == "") null else {
|
if (sergeantLeaderFilePath == null || sergeantLeaderFilePath == "") null else {
|
||||||
|
|
||||||
val cost = sergeantRgdTable.getRgdTableByName("cost_time")
|
|
||||||
val costResources = cost?.getRgdTableByName("cost")
|
|
||||||
|
|
||||||
SergeantData(
|
SergeantData(
|
||||||
sergeantLeaderFilePath,
|
sergeantLeaderFilePath,
|
||||||
BuildCost(
|
commonParseRgdService.getBuildCost(sergeantRgdTable.getRgdTableByName("cost_time"))
|
||||||
costResources?.getDoubleByName("requisition"),
|
|
||||||
costResources?.getDoubleByName("power"),
|
|
||||||
costResources?.getDoubleByName("population"),
|
|
||||||
costResources?.getDoubleByName("faith"),
|
|
||||||
costResources?.getDoubleByName("souls"),
|
|
||||||
cost?.getIntByName("time_seconds"),
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else null
|
} else null
|
||||||
@ -438,15 +360,4 @@ class UnitRgdExtractService @Autowired constructor(
|
|||||||
|
|
||||||
return Pair(sergeantsData, maxSergeants)
|
return Pair(sergeantsData, maxSergeants)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertIconAndReturnPath(modName: String?, squadData: List<RgdData>, modFolderData: String): String? {
|
|
||||||
val iconPathInMod = squadData
|
|
||||||
.getRgdTableByName("squad_ui_ext")
|
|
||||||
?.getRgdTableByName("ui_info")
|
|
||||||
?.getStringByName("icon_name")
|
|
||||||
|
|
||||||
return iconPathInMod?.let { modAttribPathService.getIconPath(modFolderData, iconPathInMod) }
|
|
||||||
?.let { iconsService.convertTgaToJpegImage(iconPathInMod, it, modName) }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,69 +4,40 @@ import com.dowstats.data.entities.ArmorType
|
|||||||
import com.dowstats.data.entities.Mod
|
import com.dowstats.data.entities.Mod
|
||||||
import com.dowstats.data.entities.Weapon
|
import com.dowstats.data.entities.Weapon
|
||||||
import com.dowstats.data.entities.WeaponArmorPiercing
|
import com.dowstats.data.entities.WeaponArmorPiercing
|
||||||
import com.dowstats.data.repositories.ArmorTypeRepository
|
|
||||||
import com.dowstats.data.rgd.RgdData
|
import com.dowstats.data.rgd.RgdData
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getBooleanByName
|
import com.dowstats.data.rgd.RgdDataUtil.getBooleanByName
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getDoubleByName
|
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.getRgdTableByName
|
||||||
import com.dowstats.data.rgd.RgdDataUtil.getStringByName
|
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import java.io.File
|
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.nio.file.Path
|
|
||||||
import kotlin.io.path.exists
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class WeaponRgdExtractService @Autowired constructor(
|
class WeaponRgdExtractService @Autowired constructor(
|
||||||
private val armorTypeRepository: ArmorTypeRepository,
|
private val commonParseRgdService: CommonParseRgdService,
|
||||||
private val iconsService: IconsService,
|
|
||||||
private val modAttribPathService: ModAttribPathService,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val log = LoggerFactory.getLogger(WeaponRgdExtractService::class.java)
|
val log = LoggerFactory.getLogger(WeaponRgdExtractService::class.java)
|
||||||
|
|
||||||
data class BuildCost(
|
|
||||||
val requisition: Int?,
|
|
||||||
val power: Int?,
|
|
||||||
val seconds: Int?
|
|
||||||
)
|
|
||||||
|
|
||||||
data class AreaEffectData(
|
|
||||||
val minDamage: Double,
|
|
||||||
val maxDamage: Double,
|
|
||||||
val damageRadius: Double,
|
|
||||||
val throwForceMin: Double,
|
|
||||||
val throwForceMax: Double,
|
|
||||||
val minDamageValue: Double,
|
|
||||||
val moraleDamage: Double,
|
|
||||||
val armourPiercing: List<WeaponArmorPiercing>,
|
|
||||||
)
|
|
||||||
|
|
||||||
data class WeaponUiInfo(
|
|
||||||
val name: String?,
|
|
||||||
val description: String?,
|
|
||||||
val iconPath: String?,
|
|
||||||
val haveEquipButton: Boolean
|
|
||||||
)
|
|
||||||
|
|
||||||
fun extractToWeaponEntity(weaponFileName: String, weaponData: List<RgdData>, mod: Mod, armorTypes: Set<ArmorType>, modFolderData: String, modDictionary: Map<Int, String>): Weapon? {
|
fun extractToWeaponEntity(weaponFileName: String, weaponData: List<RgdData>, mod: Mod, armorTypes: Set<ArmorType>, modFolderData: String, modDictionary: Map<Int, String>): Weapon? {
|
||||||
|
|
||||||
val weapon = Weapon()
|
val weapon = Weapon()
|
||||||
|
|
||||||
weapon.filename = weaponFileName
|
weapon.filename = weaponFileName
|
||||||
val weaponUiData = getWeaponNameAndDescription(weaponData, modDictionary, modFolderData, mod)
|
|
||||||
|
val weaponUiInfo = weaponData.getRgdTableByName("ui_info") ?: throw Exception("Could not find ui_info at $weaponFileName")
|
||||||
|
val weaponUiData = commonParseRgdService.getUiInfo(weaponUiInfo, modDictionary, modFolderData, mod, log)
|
||||||
weapon.name = weaponUiData.name
|
weapon.name = weaponUiData.name
|
||||||
weapon.icon = weaponUiData.iconPath
|
weapon.icon = weaponUiData.iconPath
|
||||||
weapon.description = weaponUiData.description
|
weapon.description = weaponUiData.description
|
||||||
weapon.haveEquipButton = weaponUiData.haveEquipButton
|
weapon.haveEquipButton = weaponUiInfo.getBooleanByName("no_button")?.let { !it } ?: false
|
||||||
|
|
||||||
val cost = getCost(weaponData)
|
val cost = commonParseRgdService.getBuildCost(weaponData.getRgdTableByName("cost"))
|
||||||
weapon.costRequisition = cost.requisition ?: 0
|
weapon.costRequisition = cost.requisition ?: 0.0
|
||||||
weapon.costPower = cost.power ?: 0
|
weapon.costPower = cost.power ?: 0.0
|
||||||
weapon.costTimeSeconds = cost.seconds ?: 0
|
weapon.costTimeSeconds = cost.time ?: 0
|
||||||
weapon.accuracy = weaponData.getDoubleByName("accuracy") ?: 1.0
|
weapon.accuracy = weaponData.getDoubleByName("accuracy") ?: 1.0
|
||||||
weapon.accuracyReductionMoving = weaponData.getDoubleByName("accuracy_reduction_when_moving")
|
weapon.accuracyReductionMoving = weaponData.getDoubleByName("accuracy_reduction_when_moving")
|
||||||
weapon.minRange = weaponData.getDoubleByName("min_range")
|
weapon.minRange = weaponData.getDoubleByName("min_range")
|
||||||
@ -79,14 +50,24 @@ class WeaponRgdExtractService @Autowired constructor(
|
|||||||
weapon.canAttackGround = weaponData.getBooleanByName("can_attack_ground_units") ?: true
|
weapon.canAttackGround = weaponData.getBooleanByName("can_attack_ground_units") ?: true
|
||||||
|
|
||||||
|
|
||||||
val areaEffectData = getAreaEffectData(weaponData, armorTypes, weapon)
|
val areaEffectData = commonParseRgdService.getAreaEffectData(weaponData)
|
||||||
|
|
||||||
|
val armoursPiercing = armorTypes.map {
|
||||||
|
val weaponArmourPiercing = WeaponArmorPiercing()
|
||||||
|
weaponArmourPiercing.weapon = weapon
|
||||||
|
weaponArmourPiercing.armorType = it
|
||||||
|
val piercingValue = (areaEffectData.weaponDmgMap[it.id] ?: areaEffectData.defaultArmorPiercing).toBigDecimal()
|
||||||
|
weaponArmourPiercing.piercingValue = piercingValue.let {pv -> if(pv <= BigDecimal(100)) pv else BigDecimal(100) }
|
||||||
|
weaponArmourPiercing
|
||||||
|
}
|
||||||
|
|
||||||
weapon.minDamageValue = areaEffectData.minDamageValue
|
weapon.minDamageValue = areaEffectData.minDamageValue
|
||||||
weapon.minDamage = areaEffectData.minDamage
|
weapon.minDamage = areaEffectData.minDamage
|
||||||
weapon.maxDamage = areaEffectData.maxDamage
|
weapon.maxDamage = areaEffectData.maxDamage
|
||||||
weapon.throwForceMin = areaEffectData.throwForceMin
|
weapon.throwForceMin = areaEffectData.throwForceMin
|
||||||
weapon.throwForceMax = areaEffectData.throwForceMax
|
weapon.throwForceMax = areaEffectData.throwForceMax
|
||||||
weapon.moraleDamage = areaEffectData.moraleDamage
|
weapon.moraleDamage = areaEffectData.moraleDamage
|
||||||
weapon.weaponPiercings = areaEffectData.armourPiercing
|
weapon.weaponPiercings = armoursPiercing
|
||||||
weapon.damageRadius = areaEffectData.damageRadius
|
weapon.damageRadius = areaEffectData.damageRadius
|
||||||
weapon.modId = mod.id
|
weapon.modId = mod.id
|
||||||
|
|
||||||
@ -95,94 +76,5 @@ class WeaponRgdExtractService @Autowired constructor(
|
|||||||
} else weapon
|
} else weapon
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCost(weaponData: List<RgdData>): BuildCost {
|
|
||||||
val costTable = weaponData.getRgdTableByName("cost")
|
|
||||||
val costTime = costTable?.getIntByName("time_seconds")
|
|
||||||
val costCost = costTable?.getRgdTableByName("cost")
|
|
||||||
val power = costCost?.getIntByName("power")
|
|
||||||
val requisition = costCost?.getIntByName("requisition")
|
|
||||||
return BuildCost(requisition, power, costTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAreaEffectData(weaponData: List<RgdData>, armorTypes: Set<ArmorType>, thisWeapon: Weapon): AreaEffectData {
|
|
||||||
val areaEffect = weaponData.getRgdTableByName("area_effect")
|
|
||||||
|
|
||||||
val areaEffectInformation = areaEffect?.getRgdTableByName("area_effect_information")
|
|
||||||
val cantHaveRadius = areaEffectInformation?.getRgdTableByName("area_type")?.getStringByName("\$REF")?.contains("tp_area_effect_point") == true
|
|
||||||
val damageRadius = if(cantHaveRadius) 0.0 else areaEffectInformation?.getDoubleByName("radius") ?: 0.0
|
|
||||||
|
|
||||||
val throwData = areaEffect?.getRgdTableByName("throw_data")
|
|
||||||
val forceMin = throwData?.getDoubleByName("force_min") ?: 0.0
|
|
||||||
val forceMax = throwData?.getDoubleByName("force_max") ?: 0.0
|
|
||||||
|
|
||||||
val armourDamage = areaEffect
|
|
||||||
?.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")
|
|
||||||
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()
|
|
||||||
|
|
||||||
val armoursPiercing = armorTypes.map {
|
|
||||||
val weaponArmourPiercing = WeaponArmorPiercing()
|
|
||||||
weaponArmourPiercing.weapon = thisWeapon
|
|
||||||
weaponArmourPiercing.armorType = it
|
|
||||||
val piercingValue = (weaponDmgMap[it.id] ?: defaultArmourPiercing)?.toBigDecimal()
|
|
||||||
weaponArmourPiercing.piercingValue = piercingValue?.let {pv -> if(pv <= BigDecimal(100)) pv else BigDecimal(100) }
|
|
||||||
weaponArmourPiercing
|
|
||||||
}
|
|
||||||
|
|
||||||
return AreaEffectData(minDamage, maxDamage, damageRadius, forceMin, forceMax, minDamageValue, moraleDamage, armoursPiercing)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getWeaponNameAndDescription(weaponData: List<RgdData>, modDictionary: Map<Int, String>, modFolderData: String, mod: Mod): WeaponUiInfo {
|
|
||||||
val weaponUiInfo = weaponData.getRgdTableByName("ui_info")
|
|
||||||
|
|
||||||
val nameRef = weaponUiInfo?.getStringByName("screen_name_id")?.replace("$", "")
|
|
||||||
val name = nameRef?.let { try { modDictionary[it.toInt()] } catch (e: Exception) { null } }
|
|
||||||
|
|
||||||
val descriptionRefs = weaponUiInfo?.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) { "" } }?.joinToString ( "\n" )
|
|
||||||
} catch(e:Exception) {
|
|
||||||
log.warn("Error parsing ui description weapon $name", e)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val icon = try {
|
|
||||||
val iconPath = weaponUiInfo?.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 weapon $name", e)
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
val haveUpgradeButton = weaponUiInfo?.getBooleanByName("no_button")?.let { !it } ?: false
|
|
||||||
|
|
||||||
return WeaponUiInfo(name, description, icon, haveUpgradeButton)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
65
src/main/resources/db/0.0.3/data/armor_types.json
Normal file
65
src/main/resources/db/0.0.3/data/armor_types.json
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Update armor type names",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"update": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "name",
|
||||||
|
"value": "Infantry H.Med."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tableName": "armor_types",
|
||||||
|
"where": "name='Infantry Heavy Medium'"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"update": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "name",
|
||||||
|
"value": "Infantry H.High"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tableName": "armor_types",
|
||||||
|
"where": "name='Infantry Heavy High'"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"update": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "name",
|
||||||
|
"value": "Infantry Com."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tableName": "armor_types",
|
||||||
|
"where": "name='Commander'"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"update": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "name",
|
||||||
|
"value": "Vehicle Air"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tableName": "armor_types",
|
||||||
|
"where": "name='Air'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
CREATE OR REPLACE PROCEDURE delete_campaign_entities(mod_id_p bigint)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
DELETE FROM units WHERE mod_id = mod_id_p AND (fileName_squad LIKE '%\_dxp3.%' OR fileName_squad LIKE '%\_dxp3.%' OR fileName_squad LIKE '%sp\_eldar\_%' OR fileName_squad LIKE '%\_sp\_%' OR fileName_squad LIKE '%\_sp.%' OR fileName_squad LIKE '%\_nis.%' OR fileName_squad LIKE '%\_interface\_relay.%' OR fileName_squad LIKE '%necron\_tunnel.rgd%' OR fileName_squad LIKE '%\_exarch\_council.%' OR fileName_squad LIKE '%\_dark\_reapers\_base.%' OR fileName_squad LIKE '%eldar\_deep\_strike\_building.rgd%' OR fileName_squad LIKE '%ork\_deep\_strike\_building.rgd%' OR fileName_squad LIKE '%\_caravel\_ai.rgd%' OR fileName_squad LIKE '%sisters\_tanktrap\_ai.rgd%' OR fileName_squad LIKE '%sisters\_hq\_ktgm.rgd%' OR fileName_squad LIKE '%tau\_squad\_slave\_murdered%' OR fileName_squad LIKE '%single\_player\_only%' OR fileName_squad LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR fileName_squad LIKE '%advance\_sp%' OR fileName_squad LIKE '%\_no\_limit.rgd%');
|
||||||
|
DELETE FROM buildings WHERE mod_id = mod_id_p AND (filename LIKE '%\_dxp3.%' OR filename LIKE '%\_dxp3.%' OR filename LIKE '%sp\_eldar\_%' OR filename LIKE '%\_sp\_%' OR filename LIKE '%\_sp.%' OR filename LIKE '%\_nis.%' OR filename LIKE '%\_interface\_relay.%' OR filename LIKE '%necron\_tunnel.rgd%' OR filename LIKE '%\_exarch\_council.%' OR filename LIKE '%\_dark\_reapers\_base.%' OR filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR filename LIKE '%ork\_deep\_strike\_building.rgd%' OR filename LIKE '%\_caravel\_ai.rgd%' OR filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR filename LIKE '%sisters\_hq\_ktgm.rgd%' OR filename LIKE '%tau\_squad\_slave\_murdered%' OR filename LIKE '%single\_player\_only%' OR filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR filename LIKE '%advance\_sp%' OR filename LIKE '%night\_lords\_hq\_aep%' OR filename LIKE '%\_ktgm.rgd%' OR filename LIKE '%salamander\_hq\_aep.rgd%' OR filename LIKE '%\_no\_limit.rgd%');
|
||||||
|
DELETE FROM weapons WHERE mod_id = mod_id_p AND (filename LIKE '%\_dxp3.%' OR filename LIKE '%\_dxp3.%' OR filename LIKE '%sp\_eldar\_%' OR filename LIKE '%\_sp\_%' OR filename LIKE '%\_sp.%' OR filename LIKE '%\_nis.%' OR filename LIKE '%\_interface\_relay.%' OR filename LIKE '%necron\_tunnel.rgd%' OR filename LIKE '%\_exarch\_council.%' OR filename LIKE '%\_dark\_reapers\_base.%' OR filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR filename LIKE '%ork\_deep\_strike\_building.rgd%' OR filename LIKE '%\_caravel\_ai.rgd%' OR filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR filename LIKE '%sisters\_hq\_ktgm.rgd%' OR filename LIKE '%tau\_squad\_slave\_murdered%' OR filename LIKE '%single\_player\_only%' OR filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR filename LIKE '%advance\_sp%');
|
||||||
|
DELETE FROM researches WHERE mod_id = mod_id_p AND (filename LIKE '%\_dxp3.%' OR filename LIKE '%\_dxp3.%' OR filename LIKE '%sp\_eldar\_%' OR filename LIKE '%\_sp\_%' OR filename LIKE '%\_sp.%' OR filename LIKE '%\_nis.%' OR filename LIKE '%\_interface\_relay.%' OR filename LIKE '%necron\_tunnel.rgd%' OR filename LIKE '%\_exarch\_council.%' OR filename LIKE '%\_dark\_reapers\_base.%' OR filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR filename LIKE '%ork\_deep\_strike\_building.rgd%' OR filename LIKE '%\_caravel\_ai.rgd%' OR filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR filename LIKE '%sisters\_hq\_ktgm.rgd%' OR filename LIKE '%tau\_squad\_slave\_murdered%' OR filename LIKE '%single\_player\_only%' OR filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR filename LIKE '%advance\_sp%');
|
||||||
|
DELETE FROM research_modifiers USING researches WHERE researches.mod_id = 3 AND researches.id = research_id AND (target LIKE '%\_dxp3%' OR target LIKE '%\_dxp3%' OR target LIKE '%sp\_eldar\_%' OR target LIKE '%\_sp\_%' OR target LIKE '%\_sp.%' OR target LIKE '%\_nis.%' OR target LIKE '%\_interface\_relay.%' OR target LIKE '%necron\_tunnel.rgd%' OR target LIKE '%\_exarch\_council.%' OR target LIKE '%\_dark\_reapers\_base.%' OR target LIKE '%eldar\_deep\_strike\_building.rgd%' OR target LIKE '%ork\_deep\_strike\_building.rgd%' OR target LIKE '%\_caravel\_ai.rgd%' OR target LIKE '%sisters\_tanktrap\_ai.rgd%' OR target LIKE '%sisters\_hq\_ktgm.rgd%' OR target LIKE '%tau\_squad\_slave\_murdered%' OR target LIKE '%single\_player\_only%' OR target LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR target LIKE '%advance\_sp%');
|
||||||
|
DELETE FROM building_addons USING buildings WHERE buildings.mod_id = 3 AND buildings.id = building_addons.building_id AND (building_addons.filename LIKE '%\_dxp3%' OR building_addons.filename LIKE '%\_dxp3%' OR building_addons.filename LIKE '%sp\_eldar\_%' OR building_addons.filename LIKE '%\_sp\_%' OR building_addons.filename LIKE '%\_sp.%' OR building_addons.filename LIKE '%\_nis.%' OR building_addons.filename LIKE '%\_interface\_relay.%' OR building_addons.filename LIKE '%necron\_tunnel.rgd%' OR building_addons.filename LIKE '%\_exarch\_council.%' OR building_addons.filename LIKE '%\_dark\_reapers\_base.%' OR building_addons.filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR building_addons.filename LIKE '%ork\_deep\_strike\_building.rgd%' OR building_addons.filename LIKE '%\_caravel\_ai.rgd%' OR building_addons.filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR building_addons.filename LIKE '%sisters\_hq\_ktgm.rgd%' OR building_addons.filename LIKE '%tau\_squad\_slave\_murdered%' OR building_addons.filename LIKE '%single\_player\_only%' OR building_addons.filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR building_addons.filename LIKE '%advance\_sp%' OR building_addons.filename LIKE '%addon\_necron\_hq\_3%');
|
||||||
|
DELETE FROM abilities WHERE mod_id = mod_id_p AND (filename LIKE '%\_dxp3.%' OR filename LIKE '%\_dxp3.%' OR filename LIKE '%sp\_eldar\_%' OR filename LIKE '%\_sp\_%' OR filename LIKE '%\_sp.%' OR filename LIKE '%\_nis.%' OR filename LIKE '%\_interface\_relay.%' OR filename LIKE '%necron\_tunnel.rgd%' OR filename LIKE '%\_exarch\_council.%' OR filename LIKE '%\_dark\_reapers\_base.%' OR filename LIKE '%eldar\_deep\_strike\_building.rgd%' OR filename LIKE '%ork\_deep\_strike\_building.rgd%' OR filename LIKE '%\_caravel\_ai.rgd%' OR filename LIKE '%sisters\_tanktrap\_ai.rgd%' OR filename LIKE '%sisters\_hq\_ktgm.rgd%' OR filename LIKE '%tau\_squad\_slave\_murdered%' OR filename LIKE '%single\_player\_only%' OR filename LIKE '%space\_marine\_drop\_pod\_building.rgd%' OR filename LIKE '%advance\_sp%');
|
||||||
|
$$;
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
CREATE OR REPLACE PROCEDURE delete_mod_data(mod_id_p bigint)
|
||||||
|
LANGUAGE SQL
|
||||||
|
AS $$
|
||||||
|
DELETE FROM units WHERE mod_id = mod_id_p;
|
||||||
|
DELETE FROM buildings WHERE mod_id = mod_id_p;
|
||||||
|
DELETE FROM weapons WHERE mod_id = mod_id_p;
|
||||||
|
DELETE FROM researches WHERE mod_id = mod_id_p;
|
||||||
|
DELETE FROM abilities WHERE mod_id = mod_id_p;
|
||||||
|
$$;
|
||||||
94
src/main/resources/db/0.0.3/schema/abilities.json
Normal file
94
src/main/resources/db/0.0.3/schema/abilities.json
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add abilities table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "abilities",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "int",
|
||||||
|
"autoIncrement": true,
|
||||||
|
"constraints": {
|
||||||
|
"primaryKey": true,
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "filename",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(255)"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "varchar(5000)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_requisition",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_power",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_faith",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_souls",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "icon",
|
||||||
|
"type": "varchar(128)"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "mod_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "mod_id",
|
||||||
|
"baseTableName": "abilities",
|
||||||
|
"constraintName": "fk_abilities_mods",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "mods"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
66
src/main/resources/db/0.0.3/schema/buildings_researches.json
Normal file
66
src/main/resources/db/0.0.3/schema/buildings_researches.json
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add buildings_researches table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "buildings_researches",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "building_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "research_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addUniqueConstraint": {
|
||||||
|
"columnNames": "building_id, research_id",
|
||||||
|
"constraintName": "uc_buildings_researches_research_id_building_id",
|
||||||
|
"tableName": "buildings_researches"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "building_id",
|
||||||
|
"baseTableName": "buildings_researches",
|
||||||
|
"constraintName": "fk_buildings_buildings_researches",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "buildings",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "research_id",
|
||||||
|
"baseTableName": "buildings_researches",
|
||||||
|
"constraintName": "fk_researches_buildings_researches",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "researches",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
69
src/main/resources/db/0.0.3/schema/research_modifiers.json
Normal file
69
src/main/resources/db/0.0.3/schema/research_modifiers.json
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add research_modifiers table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "research_modifiers",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "int",
|
||||||
|
"autoIncrement": true,
|
||||||
|
"constraints": {
|
||||||
|
"primaryKey": true,
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "reference",
|
||||||
|
"type": "varchar(255)"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "usage_type",
|
||||||
|
"type": "varchar(255)"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "target",
|
||||||
|
"type": "varchar(255)"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "research_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "research_id",
|
||||||
|
"baseTableName": "research_modifiers",
|
||||||
|
"constraintName": "fk_researches_research_modifiers",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "researches",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add research_requirements table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "research_requirements",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "int",
|
||||||
|
"autoIncrement": true,
|
||||||
|
"constraints": {
|
||||||
|
"primaryKey": true,
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "reference",
|
||||||
|
"type": "varchar(255)"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "value",
|
||||||
|
"type": "varchar(255)"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "research_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "research_id",
|
||||||
|
"baseTableName": "research_requirements",
|
||||||
|
"constraintName": "fk_research_requirements_researches",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "researches",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
99
src/main/resources/db/0.0.3/schema/researches.json
Normal file
99
src/main/resources/db/0.0.3/schema/researches.json
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add researches table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "researches",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "int",
|
||||||
|
"autoIncrement": true,
|
||||||
|
"constraints": {
|
||||||
|
"primaryKey": true,
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "filename",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(4096)"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "description",
|
||||||
|
"type": "varchar(5000)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_requisition",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_power",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_faith",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_souls",
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "cost_time",
|
||||||
|
"type": "int"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"column": {
|
||||||
|
"name": "mod_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "icon",
|
||||||
|
"type": "varchar(128)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "mod_id",
|
||||||
|
"baseTableName": "researches",
|
||||||
|
"constraintName": "fk_researches_mods",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "mods"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add researches_affected_buildings table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "researches_affected_buildings",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "research_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "building_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addUniqueConstraint": {
|
||||||
|
"columnNames": "research_id, building_id",
|
||||||
|
"constraintName": "uc_researches_affected_buildings_research_id_building_id",
|
||||||
|
"tableName": "researches_affected_buildings"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "research_id",
|
||||||
|
"baseTableName": "researches_affected_buildings",
|
||||||
|
"constraintName": "fk_researches_researches_affected_buildings",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "researches",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "building_id",
|
||||||
|
"baseTableName": "researches_affected_buildings",
|
||||||
|
"constraintName": "fk_buildings_researches_affected_buildings",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "buildings",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add researches_affected_sergeants table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "researches_affected_sergeants",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "research_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "sergeant_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addUniqueConstraint": {
|
||||||
|
"columnNames": "research_id, sergeant_id",
|
||||||
|
"constraintName": "uc_researches_affected_sergeants_research_id_sergeant_id",
|
||||||
|
"tableName": "researches_affected_sergeants"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "research_id",
|
||||||
|
"baseTableName": "researches_affected_sergeants",
|
||||||
|
"constraintName": "fk_researches_researches_affected_sergeants",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "researches",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "sergeant_id",
|
||||||
|
"baseTableName": "researches_affected_sergeants",
|
||||||
|
"constraintName": "fk_sergeants_researches_affected_sergeants",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "sergeants",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add researches_affected_units table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "researches_affected_units",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "research_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "unit_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addUniqueConstraint": {
|
||||||
|
"columnNames": "research_id, unit_id",
|
||||||
|
"constraintName": "uc_researches_affected_units_research_id_unit_id",
|
||||||
|
"tableName": "researches_affected_units"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "research_id",
|
||||||
|
"baseTableName": "researches_affected_units",
|
||||||
|
"constraintName": "fk_researches_researches_affected_units",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "researches",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "unit_id",
|
||||||
|
"baseTableName": "researches_affected_units",
|
||||||
|
"constraintName": "fk_units_researches_affected_units",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "units",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add researches_affected_weapons table",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"createTable": {
|
||||||
|
"tableName": "researches_affected_weapons",
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "research_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "weapon_id",
|
||||||
|
"type": "int",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addUniqueConstraint": {
|
||||||
|
"columnNames": "research_id, weapon_id",
|
||||||
|
"constraintName": "uc_researches_affected_weapons_research_id_weapon_id",
|
||||||
|
"tableName": "researches_affected_weapons"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "research_id",
|
||||||
|
"baseTableName": "researches_affected_weapons",
|
||||||
|
"constraintName": "fk_researches_researches_affected_weapons",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "researches",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"addForeignKeyConstraint":
|
||||||
|
{
|
||||||
|
"baseColumnNames": "weapon_id",
|
||||||
|
"baseTableName": "researches_affected_weapons",
|
||||||
|
"constraintName": "fk_weapons_researches_affected_weapons",
|
||||||
|
"referencedColumnNames": "id",
|
||||||
|
"referencedTableName": "weapons",
|
||||||
|
"onDelete": "CASCADE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
25
src/main/resources/db/0.0.3/schema/sergeants.json
Normal file
25
src/main/resources/db/0.0.3/schema/sergeants.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add mod_id column to sergeants",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"addColumn": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "mod_id",
|
||||||
|
"type": "int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tableName": "sergeants"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
36
src/main/resources/db/0.0.3/schema/units.json
Normal file
36
src/main/resources/db/0.0.3/schema/units.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"databaseChangeLog": [
|
||||||
|
{
|
||||||
|
"changeSet": {
|
||||||
|
"id": "Add filename_unit column to unit and rename filename to filename_squad",
|
||||||
|
"author": "anibus",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"addColumn": {
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"column": {
|
||||||
|
"name": "filename_unit",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"value": "",
|
||||||
|
"constraints": {
|
||||||
|
"nullable": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tableName": "units"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"renameColumn": {
|
||||||
|
"newColumnName": "filename_squad",
|
||||||
|
"oldColumnName": "filename",
|
||||||
|
"tableName": "units"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -107,6 +107,67 @@
|
|||||||
"include": {
|
"include": {
|
||||||
"file": "db/0.0.2/data/armor_types.json"
|
"file": "db/0.0.2/data/armor_types.json"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/researches.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/research_requirements.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/research_modifiers.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/abilities.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/buildings_researches.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/researches_affected_units.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/researches_affected_sergeants.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/researches_affected_buildings.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/researches_affected_weapons.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/procedures/delete_mod_data_procedure.sql"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/units.json"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/data/armor_types.json"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/procedures/delete_campaign_entities.sql"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"include": {
|
||||||
|
"file": "db/0.0.3/schema/sergeants.json"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,33 +18,6 @@ class BuildingRgdExtractServiceTest {
|
|||||||
val iconService = mockk<IconsService>()
|
val iconService = mockk<IconsService>()
|
||||||
val addonRgdExtractService = mockk<BuildingAddonRgdExtractService>()
|
val addonRgdExtractService = mockk<BuildingAddonRgdExtractService>()
|
||||||
|
|
||||||
val buildingRgdExtractService = BuildingRgdExtractService(modAttribPathService, iconService, addonRgdExtractService)
|
|
||||||
|
|
||||||
val rgdService = RgdParserService()
|
val rgdService = RgdParserService()
|
||||||
|
|
||||||
@Test
|
|
||||||
fun `Should correct parse building`() {
|
|
||||||
|
|
||||||
val buildingRgdFile = File("src/test/resources/rgd/waagh_banner/ork_waagh_banner.rgd")
|
|
||||||
|
|
||||||
val rgdData = rgdService.parseRgdFileStream(DataInputStream(buildingRgdFile.inputStream()))
|
|
||||||
|
|
||||||
val res = buildingRgdExtractService.extractToBuildingEntity("Waagh banner", emptyMap(), rgdData, emptySet(), "orks", "/modFolder", Mod(), listOf(
|
|
||||||
Race().also {
|
|
||||||
it.id = "orks"
|
|
||||||
it.name = "Орки"
|
|
||||||
}
|
|
||||||
), listOf(
|
|
||||||
ArmorType().also {
|
|
||||||
it.id = "building_low"
|
|
||||||
it.name = "Лёгкие здания"
|
|
||||||
}
|
|
||||||
),
|
|
||||||
emptyMap())
|
|
||||||
|
|
||||||
assertEquals(170.toDouble(), res.building.buildCostRequisition)
|
|
||||||
assertEquals(emptySet(), res.buildingWeapons)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user