Closing gaps and cleaning house
This commit is contained in:
+159
-14
@@ -747,6 +747,14 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
|
||||
lockAdded := 0
|
||||
lockPruned := 0
|
||||
retiredKeys := map[string]struct{}{}
|
||||
featFamilyAliases := generatedFamilyAliases{}
|
||||
if dataset.Name == "feat" {
|
||||
var err error
|
||||
featFamilyAliases, err = collectGeneratedFamilyAliases(dataset.GeneratedDir)
|
||||
if err != nil {
|
||||
return nativeCollectedDataset{}, err
|
||||
}
|
||||
}
|
||||
|
||||
for key, rowID := range lockData {
|
||||
if rowID <= baseBoundaryID {
|
||||
@@ -834,7 +842,7 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
|
||||
if parsedID == lockedID {
|
||||
return override, nil
|
||||
}
|
||||
if dataset.Name == "feat" && generatedCanonicalLockCanMove(rawKey, parsedID, lockData) {
|
||||
if dataset.Name == "feat" && generatedCanonicalLockCanMove(rawKey, parsedID, lockData, featFamilyAliases) {
|
||||
delete(lockData, rawKey)
|
||||
lockModified = true
|
||||
return override, nil
|
||||
@@ -847,7 +855,7 @@ func collectBaseDataset(dataset nativeDataset) (nativeCollectedDataset, error) {
|
||||
}
|
||||
for lockedKey, lockedID := range lockData {
|
||||
if lockedKey != key && lockedID == rowID {
|
||||
if dataset.Name == "feat" && generatedAliasLockForKey(key, lockedKey) {
|
||||
if dataset.Name == "feat" && generatedAliasLockForKey(key, lockedKey, featFamilyAliases) {
|
||||
delete(lockData, lockedKey)
|
||||
lockModified = true
|
||||
continue
|
||||
@@ -2396,8 +2404,48 @@ func generatedFamilyPrereqKey(ctx *featGeneratedContext, sourceRow map[string]an
|
||||
return featKey, true
|
||||
}
|
||||
|
||||
func generatedFamilyLegacyAliases(familyKey string) []string {
|
||||
switch familyKey {
|
||||
type generatedFamilyAliases map[string][]string
|
||||
|
||||
func collectGeneratedFamilyAliases(generatedDir string) (generatedFamilyAliases, error) {
|
||||
aliases := generatedFamilyAliases{}
|
||||
if generatedDir == "" {
|
||||
return aliases, nil
|
||||
}
|
||||
paths, err := collectModulePaths(generatedDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, path := range paths {
|
||||
obj, err := loadJSONObject(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !isFamilyExpansionObject(obj) {
|
||||
continue
|
||||
}
|
||||
spec, err := parseFamilyExpansionSpec(path, obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(spec.LegacyFamilyKeys) > 0 {
|
||||
aliases[spec.FamilyKey] = spec.LegacyFamilyKeys
|
||||
}
|
||||
}
|
||||
return aliases, nil
|
||||
}
|
||||
|
||||
func configuredGeneratedFamilyLegacyAliases(familyKey string, aliases generatedFamilyAliases) []string {
|
||||
normalized := normalizeKeyIdentity(familyKey)
|
||||
for configuredFamilyKey, configured := range aliases {
|
||||
if normalizeKeyIdentity(configuredFamilyKey) == normalized && len(configured) > 0 {
|
||||
return configured
|
||||
}
|
||||
}
|
||||
return compatibilityGeneratedFamilyLegacyAliases(familyKey)
|
||||
}
|
||||
|
||||
func compatibilityGeneratedFamilyLegacyAliases(familyKey string) []string {
|
||||
switch normalizeKeyIdentity(familyKey) {
|
||||
case "skillfocus":
|
||||
return []string{"skillfocus"}
|
||||
case "greaterskillfocus":
|
||||
@@ -2413,18 +2461,94 @@ func generatedFamilyLegacyAliases(familyKey string) []string {
|
||||
}
|
||||
}
|
||||
|
||||
func generatedAliasLockForKey(canonicalKey, lockedKey string) bool {
|
||||
func knownGeneratedFamilyKeys(aliases generatedFamilyAliases) []string {
|
||||
seen := map[string]struct{}{}
|
||||
keys := make([]string, 0, 32)
|
||||
add := func(key string) {
|
||||
key = strings.TrimSpace(key)
|
||||
if key == "" {
|
||||
return
|
||||
}
|
||||
if _, ok := seen[key]; ok {
|
||||
return
|
||||
}
|
||||
seen[key] = struct{}{}
|
||||
keys = append(keys, key)
|
||||
}
|
||||
for _, key := range []string{
|
||||
"greater_weapon_specialization",
|
||||
"epic_weapon_specialization",
|
||||
"greaterweaponspecialization",
|
||||
"epicweaponspecialization",
|
||||
"overwhelming_critical",
|
||||
"epic_overwhelming_critical",
|
||||
"overwhelmingcritical",
|
||||
"epicoverwhelmingcritical",
|
||||
"greater_weapon_focus",
|
||||
"epic_weapon_focus",
|
||||
"greaterweaponfocus",
|
||||
"epicweaponfocus",
|
||||
"greater_skill_focus",
|
||||
"epic_skill_focus",
|
||||
"greaterskillfocus",
|
||||
"epicskillfocus",
|
||||
"weapon_specialization",
|
||||
"weaponspecialization",
|
||||
"improved_critical",
|
||||
"improvedcritical",
|
||||
"weapon_of_choice",
|
||||
"weaponofchoice",
|
||||
"weapon_focus",
|
||||
"weaponfocus",
|
||||
"skill_focus",
|
||||
"skillfocus",
|
||||
} {
|
||||
add(key)
|
||||
}
|
||||
for familyKey, legacyKeys := range aliases {
|
||||
add(familyKey)
|
||||
for _, legacyKey := range legacyKeys {
|
||||
add(legacyKey)
|
||||
}
|
||||
}
|
||||
slices.SortFunc(keys, func(a, b string) int {
|
||||
if len(a) == len(b) {
|
||||
return strings.Compare(a, b)
|
||||
}
|
||||
return len(b) - len(a)
|
||||
})
|
||||
return keys
|
||||
}
|
||||
|
||||
func splitKnownGeneratedFamilyIdentity(text string, aliases generatedFamilyAliases) familyIdentity {
|
||||
text = strings.TrimPrefix(strings.TrimSpace(text), "feat:")
|
||||
for _, parent := range knownGeneratedFamilyKeys(aliases) {
|
||||
if text == parent {
|
||||
return familyIdentity{Parent: parent}
|
||||
}
|
||||
prefix := parent + "_"
|
||||
if strings.HasPrefix(text, prefix) {
|
||||
return familyIdentity{
|
||||
Parent: parent,
|
||||
Child: strings.TrimPrefix(text, prefix),
|
||||
}
|
||||
}
|
||||
}
|
||||
return splitFamilyExpansionIdentity(text)
|
||||
}
|
||||
|
||||
func generatedAliasLockForKey(canonicalKey, lockedKey string, aliases generatedFamilyAliases) bool {
|
||||
canonicalKey = strings.TrimPrefix(strings.TrimSpace(canonicalKey), "feat:")
|
||||
lockedKey = strings.TrimPrefix(strings.TrimSpace(lockedKey), "feat:")
|
||||
if canonicalKey == "" || lockedKey == "" {
|
||||
return false
|
||||
}
|
||||
identity := splitFamilyExpansionIdentity(canonicalKey)
|
||||
identity := splitKnownGeneratedFamilyIdentity(canonicalKey, aliases)
|
||||
if identity.Parent == "" || identity.Child == "" {
|
||||
return false
|
||||
}
|
||||
legacyChildren := legacyFamilyChildAliases(identity.Parent, identity.Child)
|
||||
for _, alias := range generatedFamilyLegacyAliases(identity.Parent) {
|
||||
for _, alias := range configuredGeneratedFamilyLegacyAliases(identity.Parent, aliases) {
|
||||
prefix := alias + "_"
|
||||
if !strings.HasPrefix(lockedKey, prefix) {
|
||||
continue
|
||||
@@ -2439,18 +2563,38 @@ func generatedAliasLockForKey(canonicalKey, lockedKey string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func generatedCanonicalLockCanMove(canonicalKey string, rowID int, lockData map[string]int) bool {
|
||||
func generatedCanonicalLockCanMove(canonicalKey string, rowID int, lockData map[string]int, aliases generatedFamilyAliases) bool {
|
||||
if rowID <= 0 {
|
||||
return false
|
||||
}
|
||||
for lockedKey, lockedID := range lockData {
|
||||
if lockedID == rowID && generatedAliasLockForKey(canonicalKey, lockedKey) {
|
||||
if lockedID == rowID && generatedAliasLockForKey(canonicalKey, lockedKey, aliases) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *featGeneratedContext) generatedFamilyAliases() generatedFamilyAliases {
|
||||
aliases := generatedFamilyAliases{}
|
||||
for familyKey, spec := range c.familySpecs {
|
||||
if len(spec.LegacyFamilyKeys) > 0 {
|
||||
aliases[familyKey] = spec.LegacyFamilyKeys
|
||||
}
|
||||
}
|
||||
return aliases
|
||||
}
|
||||
|
||||
func (c *featGeneratedContext) generatedFamilyLegacyAliases(familyKey string) []string {
|
||||
normalized := normalizeKeyIdentity(familyKey)
|
||||
for specFamilyKey, spec := range c.familySpecs {
|
||||
if normalizeKeyIdentity(specFamilyKey) == normalized && len(spec.LegacyFamilyKeys) > 0 {
|
||||
return spec.LegacyFamilyKeys
|
||||
}
|
||||
}
|
||||
return compatibilityGeneratedFamilyLegacyAliases(familyKey)
|
||||
}
|
||||
|
||||
func (c *featGeneratedContext) generatedFeatKeyForID(familyKey string, rowID int) (string, bool) {
|
||||
if rowID <= 0 {
|
||||
return "", false
|
||||
@@ -2467,7 +2611,7 @@ func (c *featGeneratedContext) generatedFeatKeyForID(familyKey string, rowID int
|
||||
return best, true
|
||||
}
|
||||
}
|
||||
for _, alias := range generatedFamilyLegacyAliases(familyKey) {
|
||||
for _, alias := range c.generatedFamilyLegacyAliases(familyKey) {
|
||||
for _, candidates := range []map[string]int{c.lockData, c.supplementalID} {
|
||||
matches := make([]string, 0)
|
||||
prefix := "feat:" + alias + "_"
|
||||
@@ -2489,7 +2633,7 @@ func (c *featGeneratedContext) generatedFeatKeyForID(familyKey string, rowID int
|
||||
func (c *featGeneratedContext) generatedFeatKeyFromLegacyAlias(familyKey, sourceSlug string) (string, int, bool) {
|
||||
targets := legacyFamilyChildAliases(familyKey, sourceSlug)
|
||||
canonicalKey := c.preferredGeneratedFeatKey(familyKey, sourceSlug)
|
||||
for _, alias := range generatedFamilyLegacyAliases(familyKey) {
|
||||
for _, alias := range c.generatedFamilyLegacyAliases(familyKey) {
|
||||
for _, candidates := range []map[string]int{c.lockData, c.supplementalID} {
|
||||
prefix := "feat:" + alias + "_"
|
||||
for _, target := range targets {
|
||||
@@ -2510,7 +2654,8 @@ func (c *featGeneratedContext) generatedFeatKeyFromLegacyAlias(familyKey, source
|
||||
|
||||
func legacyFamilyChildAliases(familyKey, sourceSlug string) []string {
|
||||
aliases := []string{}
|
||||
if familyKey != "greaterskillfocus" && familyKey != "skillfocus" {
|
||||
normalizedFamilyKey := normalizeKeyIdentity(familyKey)
|
||||
if normalizedFamilyKey != "greaterskillfocus" && normalizedFamilyKey != "skillfocus" {
|
||||
return []string{sourceSlug}
|
||||
}
|
||||
switch normalizeKeyIdentity(sourceSlug) {
|
||||
@@ -2539,12 +2684,12 @@ func legacyFamilyChildAliases(familyKey, sourceSlug string) []string {
|
||||
|
||||
func (c *featGeneratedContext) generatedFeatKeyFromCanonicalAlias(canonicalKey string) (string, int, bool) {
|
||||
stripped := strings.TrimPrefix(strings.TrimSpace(canonicalKey), "feat:")
|
||||
identity := splitFamilyExpansionIdentity(stripped)
|
||||
identity := splitKnownGeneratedFamilyIdentity(stripped, c.generatedFamilyAliases())
|
||||
if identity.Parent == "" || identity.Child == "" {
|
||||
return "", 0, false
|
||||
}
|
||||
legacyChildren := legacyFamilyChildAliases(identity.Parent, identity.Child)
|
||||
for _, alias := range generatedFamilyLegacyAliases(identity.Parent) {
|
||||
for _, alias := range c.generatedFamilyLegacyAliases(identity.Parent) {
|
||||
for _, legacyChild := range legacyChildren {
|
||||
if _, rowID, ok := c.featKeyForFamilyChild(alias, legacyChild); ok {
|
||||
return "feat:" + identity.Parent + "_" + identity.Child, rowID, true
|
||||
|
||||
Reference in New Issue
Block a user