Class skill injection now points to authored entries
This commit is contained in:
+46
-16
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user