feat(inventory-go): weapon_types multi-select filter by skill (melee/missile/war/void)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
29d400f86a
commit
b4bee24773
2 changed files with 111 additions and 9 deletions
|
|
@ -191,7 +191,7 @@ func (s *Server) runSearch(ctx context.Context, q url.Values) (map[string]any, e
|
|||
case qBool(q, "jewelry_only"):
|
||||
conds = append(conds, "object_class = 4")
|
||||
case qBool(q, "weapon_only"):
|
||||
conds = append(conds, weaponTypeClause(q.Get("weapon_type")))
|
||||
conds = append(conds, weaponOnlyClause(q))
|
||||
case qBool(q, "clothing_only"):
|
||||
conds = append(conds, "(object_class = 3 AND name NOT ILIKE '%cloak%' AND name NOT ILIKE '%robe%' AND name NOT ILIKE '%pallium%' AND name NOT ILIKE '%armet%' AND (name ILIKE '%shirt%' OR name ILIKE '%pants%' OR name ILIKE '%breeches%' OR name ILIKE '%baggy%' OR name ILIKE '%tunic%'))")
|
||||
}
|
||||
|
|
@ -543,24 +543,36 @@ func underwearCTEWhere(q map[string][]string) string {
|
|||
}
|
||||
|
||||
func weaponTypeClause(wt string) string {
|
||||
exists := func(skill int) string {
|
||||
meleeSkill := func(skill int) string {
|
||||
return fmt.Sprintf("(object_class = 1 AND EXISTS (SELECT 1 FROM item_raw_data wrd WHERE wrd.item_id = db_item_id AND (wrd.int_values->>'218103840')::int = %d))", skill)
|
||||
}
|
||||
missileMastery := func(mastery int) string {
|
||||
return fmt.Sprintf("(object_class = 9 AND EXISTS (SELECT 1 FROM item_raw_data wrd WHERE wrd.item_id = db_item_id AND (wrd.int_values->>'218103840')::int = 47 AND (wrd.int_values->>'353')::int = %d))", mastery)
|
||||
}
|
||||
casterSkill := func(skill int) string {
|
||||
return fmt.Sprintf("(object_class = 31 AND EXISTS (SELECT 1 FROM item_raw_data wrd WHERE wrd.item_id = db_item_id AND (wrd.int_values->>'159')::int = %d))", skill)
|
||||
}
|
||||
switch strings.ToLower(wt) {
|
||||
case "heavy":
|
||||
return exists(44)
|
||||
return meleeSkill(44)
|
||||
case "light":
|
||||
return exists(45)
|
||||
return meleeSkill(45)
|
||||
case "finesse":
|
||||
return exists(46)
|
||||
return meleeSkill(46)
|
||||
case "two_handed":
|
||||
return exists(41)
|
||||
return meleeSkill(41)
|
||||
case "missile":
|
||||
return "(object_class = 9 AND EXISTS (SELECT 1 FROM item_raw_data wrd WHERE wrd.item_id = db_item_id AND (wrd.int_values->>'218103840')::int = 47))"
|
||||
case "bow":
|
||||
return "(object_class = 9 AND name ILIKE '%bow%' AND name NOT ILIKE '%crossbow%')"
|
||||
return missileMastery(8)
|
||||
case "crossbow":
|
||||
return "(object_class = 9 AND name ILIKE '%crossbow%')"
|
||||
return missileMastery(9)
|
||||
case "thrown":
|
||||
return "(object_class = 9 AND (name ILIKE '%atlatl%' OR name ILIKE '%throwing%' OR name ILIKE '%javelin%' OR name ILIKE '%shuriken%' OR name ILIKE '%dart%' OR name ILIKE '%slingshot%'))"
|
||||
return missileMastery(10)
|
||||
case "war":
|
||||
return casterSkill(34)
|
||||
case "void":
|
||||
return casterSkill(43)
|
||||
case "caster":
|
||||
return "object_class = 31"
|
||||
default:
|
||||
|
|
@ -568,6 +580,34 @@ func weaponTypeClause(wt string) string {
|
|||
}
|
||||
}
|
||||
|
||||
// weaponOnlyClause builds the WHERE fragment for weapon_only searches: an OR of
|
||||
// the per-type clauses named in weapon_types (CSV) plus the legacy single
|
||||
// weapon_type. Empty selection = all weapons. Types are deduped.
|
||||
func weaponOnlyClause(q url.Values) string {
|
||||
var types []string
|
||||
types = append(types, splitNonEmpty(q.Get("weapon_types"))...)
|
||||
if wt := strings.TrimSpace(q.Get("weapon_type")); wt != "" {
|
||||
types = append(types, wt)
|
||||
}
|
||||
seen := map[string]bool{}
|
||||
var clauses []string
|
||||
for _, t := range types {
|
||||
key := strings.ToLower(strings.TrimSpace(t))
|
||||
if key == "" || seen[key] {
|
||||
continue
|
||||
}
|
||||
seen[key] = true
|
||||
clauses = append(clauses, weaponTypeClause(key))
|
||||
}
|
||||
if len(clauses) == 0 {
|
||||
return "object_class IN (1, 9, 31)"
|
||||
}
|
||||
if len(clauses) == 1 {
|
||||
return clauses[0]
|
||||
}
|
||||
return "(" + strings.Join(clauses, " OR ") + ")"
|
||||
}
|
||||
|
||||
func slotNameClause(name string, ab *argBuilder) string {
|
||||
switch strings.ToLower(name) {
|
||||
case "ring":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue