Class skill injection now points to authored entries

This commit is contained in:
2026-05-14 09:29:55 +02:00
parent 18066ee0dd
commit d61ab33aa4
2 changed files with 69 additions and 16 deletions
+46 -16
View File
@@ -2466,6 +2466,38 @@ func normalizeKeyIdentity(text string) string {
return text
}
func resolveCanonicalDatasetKey(key string, keyToID map[string]int) string {
key = strings.TrimSpace(key)
if key == "" {
return key
}
if _, ok := keyToID[key]; ok {
return key
}
prefix, suffix, ok := strings.Cut(key, ":")
if !ok || prefix == "" || suffix == "" {
return key
}
normalizedSuffix := normalizeKeyIdentity(suffix)
match := ""
for candidate := range keyToID {
candidatePrefix, candidateSuffix, ok := strings.Cut(candidate, ":")
if !ok || candidatePrefix != prefix {
continue
}
if normalizeKeyIdentity(candidateSuffix) != normalizedSuffix {
continue
}
if match == "" || candidate < match {
match = candidate
}
}
if match != "" {
return match
}
return key
}
func affinityTitleFromKey(featKey, skillName string) string {
if strings.HasPrefix(featKey, "feat:partialskillaffinity") {
return fmt.Sprintf("Partial Skill Affinity (%s)", skillName)
@@ -2652,8 +2684,8 @@ var (
{"FeatIndex": map[string]any{"id": "feat:horsemenu"}, "List": "3", "GrantedOnLevel": "1", "OnMenu": "1"},
}
classFeatClassSkillShorthandRows = []map[string]any{
{"FeatIndex": map[string]any{"id": "masterfeats:skillfocus", "filter": "classskills"}, "List": "1", "GrantedOnLevel": "-1", "OnMenu": "0"},
{"FeatIndex": map[string]any{"id": "masterfeats:greaterskillfocus", "filter": "classskills"}, "List": "1", "GrantedOnLevel": "12", "OnMenu": "0"},
{"FeatIndex": map[string]any{"id": "masterfeats:skill_focus", "filter": "classskills"}, "List": "1", "GrantedOnLevel": "-1", "OnMenu": "0"},
{"FeatIndex": map[string]any{"id": "masterfeats:greater_skill_focus", "filter": "classskills"}, "List": "1", "GrantedOnLevel": "12", "OnMenu": "0"},
}
)
@@ -2743,7 +2775,7 @@ func expandClassesFeatRow(row map[string]any, keyToID map[string]int, rowByKey m
}
return []map[string]any{cloned}, nil
case strings.HasPrefix(refKey, "masterfeats:"):
masterfeatKey := refKey
masterfeatKey := resolveCanonicalDatasetKey(refKey, keyToID)
children, err := expandMasterfeatChildren(masterfeatKey, row, keyToID, rowByKey, classKey)
if err != nil {
return nil, err
@@ -2786,6 +2818,7 @@ func expandClassesFeatRow(row map[string]any, keyToID map[string]int, rowByKey m
}
func expandMasterfeatChildren(masterfeatKey string, row map[string]any, keyToID map[string]int, rowByKey map[string]map[string]any, classKey string) ([]map[string]any, error) {
masterfeatKey = resolveCanonicalDatasetKey(masterfeatKey, keyToID)
if _, ok := keyToID[masterfeatKey]; !ok {
return nil, fmt.Errorf("unknown masterfeat reference %q", masterfeatKey)
}
@@ -2844,10 +2877,11 @@ func classFeatExpansionCanUseFeat(featRow map[string]any, classKey string, keyTo
}
func rowRefersToKey(value any, targetKey string, keyToID map[string]int) bool {
targetKey = resolveCanonicalDatasetKey(targetKey, keyToID)
targetID, hasTargetID := keyToID[targetKey]
switch typed := value.(type) {
case string:
text := strings.TrimSpace(typed)
text := resolveCanonicalDatasetKey(strings.TrimSpace(typed), keyToID)
if text == "" || text == nullValue || text == "****" {
return false
}
@@ -2878,6 +2912,7 @@ func rowRefersToKey(value any, targetKey string, keyToID map[string]int) bool {
}
func rowReferencesMasterfeat(row map[string]any, masterfeatKey string, keyToID map[string]int) bool {
masterfeatKey = resolveCanonicalDatasetKey(masterfeatKey, keyToID)
masterID, ok := keyToID[masterfeatKey]
if !ok {
return false
@@ -2895,6 +2930,7 @@ func rowReferencesMasterfeat(row map[string]any, masterfeatKey string, keyToID m
return int(typed) == masterID
case map[string]any:
if id, ok := typed["id"].(string); ok {
id = resolveCanonicalDatasetKey(id, keyToID)
if id == masterfeatKey {
return true
}
@@ -3369,6 +3405,12 @@ func shouldPreserveLiteralFeatIDObject(row map[string]any, field, refID string)
func shouldPreserveFeatMinLevelClass(row map[string]any) bool {
rowKey, _ := row["key"].(string)
if prefix, suffix, ok := strings.Cut(strings.TrimSpace(rowKey), ":"); ok && prefix == "masterfeats" {
switch normalizeKeyIdentity(suffix) {
case "weaponfocus", "weaponspecialization", "greaterweaponfocus", "greaterweaponspecialization", "improvedcritical", "overwhelmingcritical":
return true
}
}
switch {
case strings.HasPrefix(rowKey, "feat:weaponfocus_"):
return true
@@ -3386,18 +3428,6 @@ func shouldPreserveFeatMinLevelClass(row map[string]any) bool {
return true
case strings.HasPrefix(rowKey, "feat:epicweaponspecialization_"):
return true
case rowKey == "masterfeats:weaponfocus":
return true
case rowKey == "masterfeats:weaponspecialization":
return true
case rowKey == "masterfeats:greaterweaponfocus":
return true
case rowKey == "masterfeats:greaterweaponspecialization":
return true
case rowKey == "masterfeats:improvedcritical":
return true
case rowKey == "masterfeats:overwhelmingcritical":
return true
default:
return false
}