hf search
This commit is contained in:
parent
e9cde0f17c
commit
b63c76f48c
|
@ -7,3 +7,4 @@ legendsbrowser
|
|||
.DS_Store
|
||||
bin
|
||||
/inputs/*
|
||||
/inputs2/*
|
|
@ -53,6 +53,10 @@
|
|||
}
|
||||
],
|
||||
"HistoricalFigure": [
|
||||
{
|
||||
"Name": "Leader",
|
||||
"Type": "bool"
|
||||
},
|
||||
{
|
||||
"Name": "Werebeast",
|
||||
"Type": "bool"
|
||||
|
@ -79,6 +83,10 @@
|
|||
}
|
||||
],
|
||||
"Entity": [
|
||||
{
|
||||
"Name": "Leaders",
|
||||
"Type": "[]*EntityLeader"
|
||||
},
|
||||
{
|
||||
"Name": "Sites",
|
||||
"Type": "[]int"
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
resources/frontend/*
|
||||
same.json
|
||||
conf.json
|
||||
_conf.json
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"LastPath": "/workspaces/legendsbrowser/inputs/legends-Runlance-01510-01-01",
|
||||
"LastFile": "/workspaces/legendsbrowser/inputs/legends-Runlance-01510-01-01/Runlance-01510-01-01-legends.xml",
|
||||
"DebugTemplates": true
|
||||
}
|
|
@ -57,7 +57,7 @@ func (c *Context) hfUnrelated(id int) string {
|
|||
|
||||
func (c *Context) hfShort(id int) string {
|
||||
if x, ok := c.World.HistoricalFigures[id]; ok {
|
||||
return fmt.Sprintf(`<a class="hf" href="/hf/%d">%s</a>`, x.Id(), util.Title(x.FirstName()))
|
||||
return fmt.Sprintf(`<a class="hf" href="/hf/%d">%s%s</a>`, x.Id(), hfIcon(x), util.Title(x.FirstName()))
|
||||
}
|
||||
return "UNKNOWN HISTORICAL FIGURE"
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ func (c *Context) hfRelated(id, to int) string {
|
|||
if x, ok := c.World.HistoricalFigures[id]; ok {
|
||||
if t, ok := c.World.HistoricalFigures[to]; ok {
|
||||
if y, ok := util.Find(t.HfLink, func(l *HfLink) bool { return l.Hfid == id }); ok {
|
||||
return fmt.Sprintf(`%s %s <a class="hf" href="/hf/%d">%s</a>`, t.PossesivePronoun(), y.LinkType, x.Id(), util.Title(x.Name()))
|
||||
return fmt.Sprintf(`%s %s <a class="hf" href="/hf/%d">%s%s</a>`, t.PossesivePronoun(), y.LinkType, x.Id(), hfIcon(x), util.Title(x.Name()))
|
||||
}
|
||||
}
|
||||
return hf(x)
|
||||
|
@ -81,6 +81,14 @@ func (c *Context) hfRelated(id, to int) string {
|
|||
return "UNKNOWN HISTORICAL FIGURE"
|
||||
}
|
||||
|
||||
func hfIcon(x *HistoricalFigure) string {
|
||||
switch {
|
||||
case x.Leader:
|
||||
return `<i class="fa-solid fa-crown fa-xs"></i> `
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func hf(x *HistoricalFigure) string {
|
||||
r := x.Race
|
||||
if x.Deity {
|
||||
|
@ -98,7 +106,7 @@ func hf(x *HistoricalFigure) string {
|
|||
if x.Vampire {
|
||||
r += " vampire"
|
||||
}
|
||||
return fmt.Sprintf(`the %s <a class="hf" href="/hf/%d">%s</a>`, r, x.Id(), util.Title(x.Name()))
|
||||
return fmt.Sprintf(`the %s <a class="hf" href="/hf/%d">%s%s</a>`, r, x.Id(), hfIcon(x), util.Title(x.Name()))
|
||||
}
|
||||
|
||||
func (c *Context) hfList(ids []int) string {
|
||||
|
@ -152,7 +160,7 @@ func (c *Context) siteStructure(siteId, structureId int, prefix string) string {
|
|||
|
||||
func (c *Context) site(id int, prefix string) string {
|
||||
if x, ok := c.World.Sites[id]; ok {
|
||||
return fmt.Sprintf(`%s <a class="site%s" href="/site/%d"><i class="%s fa-xs"></i> %s</a>`, prefix, util.If(x.Ruin, " ruin", ""), x.Id(), x.Icon(), util.Title(x.Name()))
|
||||
return fmt.Sprintf(`%s <a class="site" href="/site/%d"><i class="%s fa-xs%s"></i> %s</a>`, prefix, x.Id(), x.Icon(), util.If(x.Ruin, " ruin", ""), util.Title(x.Name()))
|
||||
}
|
||||
return "UNKNOWN SITE"
|
||||
}
|
||||
|
@ -160,7 +168,7 @@ func (c *Context) site(id int, prefix string) string {
|
|||
func (c *Context) structure(siteId, structureId int) string {
|
||||
if x, ok := c.World.Sites[siteId]; ok {
|
||||
if y, ok := x.Structures[structureId]; ok {
|
||||
return fmt.Sprintf(`<a class="structure%s" href="/site/%d/structure/%d"><i class="%s fa-xs"></i> %s</a>`, util.If(y.Ruin, " ruin", ""), siteId, structureId, y.Icon(), util.Title(y.Name()))
|
||||
return fmt.Sprintf(`<a class="structure" href="/site/%d/structure/%d"><i class="%s fa-xs%s"></i> %s</a>`, siteId, structureId, y.Icon(), util.If(y.Ruin, " ruin", ""), util.Title(y.Name()))
|
||||
}
|
||||
}
|
||||
return "UNKNOWN STRUCTURE"
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
)
|
||||
|
||||
var LinkHf = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).hf(id)) }
|
||||
var LinkHfShort = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).hfShort(id)) }
|
||||
var LinkHfList = func(w *DfWorld, id []int) template.HTML { return template.HTML((&Context{World: w}).hfList(id)) }
|
||||
var LinkEntity = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).entity(id)) }
|
||||
var LinkSite = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).site(id, "")) }
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/robertjanetzko/LegendsBrowser2/backend/util"
|
||||
)
|
||||
|
||||
type EntityLeader struct {
|
||||
Hf *HistoricalFigure
|
||||
StartYear int
|
||||
EndYear int
|
||||
}
|
||||
|
||||
func (w *DfWorld) LoadHistory() {
|
||||
w.LoadDimensions()
|
||||
|
||||
path := strings.ReplaceAll(w.FilePath, "-legends.xml", "-world_history.txt")
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
leaderRegEx := regexp.MustCompile(` \[\*\] (.+?) \(.*?Reign Began: (-?\d+)\)`)
|
||||
results := regexp.MustCompile(`\n([^ ].*?), [^\n]+(?:\n [^\n]+)*`).FindAllStringSubmatch(util.ConvertCp473(data), -1)
|
||||
for _, result := range results {
|
||||
if _, civ, ok := util.FindInMap(w.Entities, nameMatches[*Entity](result[1])); ok {
|
||||
leaders := leaderRegEx.FindAllStringSubmatch(result[0], -1)
|
||||
var last *EntityLeader
|
||||
for _, leader := range leaders {
|
||||
year, _ := strconv.Atoi(leader[2])
|
||||
l := &EntityLeader{StartYear: year, EndYear: -1}
|
||||
if _, hf, ok := util.FindInMap(w.HistoricalFigures, nameMatches[*HistoricalFigure](leader[1])); ok {
|
||||
hf.Leader = true
|
||||
l.Hf = hf
|
||||
civ.Leaders = append(civ.Leaders, l)
|
||||
}
|
||||
if last != nil {
|
||||
last.EndYear = year
|
||||
}
|
||||
last = l
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func nameMatches[T Named](name string) func(T) bool {
|
||||
name = strings.ToLower(name)
|
||||
return func(t T) bool { return t.Name() == name }
|
||||
}
|
|
@ -74,17 +74,13 @@ func (w *DfWorld) LoadDimensions() {
|
|||
}
|
||||
|
||||
fmt.Println("Found Worldgen", path)
|
||||
|
||||
content, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
text := string(content)
|
||||
fmt.Println(text)
|
||||
|
||||
r := regexp.MustCompile(`\[DIM:(\d+):(\d+)\]`)
|
||||
result := r.FindAllStringSubmatch(text, 1)
|
||||
result := r.FindAllStringSubmatch(string(content), 1)
|
||||
if result == nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1990,6 +1990,7 @@ type Entity struct {
|
|||
Type_ EntityType `json:"type" legend:"plus" related:""` // type
|
||||
Weapon []EntityWeapon `json:"weapon" legend:"plus" related:""` // weapon
|
||||
WorshipId []int `json:"worshipId" legend:"plus" related:""` // worship_id
|
||||
Leaders []*EntityLeader `json:"leaders" legend:"add" related:""` // Leaders
|
||||
Sites []int `json:"sites" legend:"add" related:""` // Sites
|
||||
Wars []*HistoricalEventCollection `json:"wars" legend:"add" related:""` // Wars
|
||||
}
|
||||
|
@ -2029,6 +2030,7 @@ func (x *Entity) MarshalJSON() ([]byte, error) {
|
|||
}
|
||||
d["weapon"] = x.Weapon
|
||||
d["worshipId"] = x.WorshipId
|
||||
d["leaders"] = x.Leaders
|
||||
d["sites"] = x.Sites
|
||||
d["wars"] = x.Wars
|
||||
return json.Marshal(d)
|
||||
|
@ -18900,6 +18902,7 @@ type HistoricalFigure struct {
|
|||
Sphere []string `json:"sphere" legend:"base" related:""` // sphere
|
||||
UsedIdentityId []int `json:"usedIdentityId" legend:"base" related:""` // used_identity_id
|
||||
VagueRelationship []*VagueRelationship `json:"vagueRelationship" legend:"base" related:""` // vague_relationship
|
||||
Leader bool `json:"leader" legend:"add" related:""` // Leader
|
||||
Necromancer bool `json:"necromancer" legend:"add" related:""` // Necromancer
|
||||
NecromancerSince int `json:"necromancerSince" legend:"add" related:""` // NecromancerSince
|
||||
Vampire bool `json:"vampire" legend:"add" related:""` // Vampire
|
||||
|
@ -19022,6 +19025,7 @@ func (x *HistoricalFigure) MarshalJSON() ([]byte, error) {
|
|||
d["sphere"] = x.Sphere
|
||||
d["usedIdentityId"] = x.UsedIdentityId
|
||||
d["vagueRelationship"] = x.VagueRelationship
|
||||
d["leader"] = x.Leader
|
||||
d["necromancer"] = x.Necromancer
|
||||
if x.NecromancerSince != -1 {
|
||||
d["necromancerSince"] = x.NecromancerSince
|
||||
|
|
|
@ -143,6 +143,7 @@ BaseLoop:
|
|||
// ioutil.WriteFile("same.json", same, 0644)
|
||||
|
||||
world.LoadMap()
|
||||
world.LoadHistory()
|
||||
|
||||
world.process()
|
||||
|
||||
|
|
|
@ -18,7 +18,12 @@ func (srv *DfServer) RegisterWorldPage(path string, template string, accessor fu
|
|||
return
|
||||
}
|
||||
|
||||
data := accessor(mux.Vars(r))
|
||||
params := mux.Vars(r)
|
||||
for k, v := range r.URL.Query() {
|
||||
params[k] = v[0]
|
||||
}
|
||||
|
||||
data := accessor(params)
|
||||
if data == nil || (reflect.ValueOf(data).Kind() == reflect.Ptr && reflect.ValueOf(data).IsNil()) {
|
||||
srv.notFound(w)
|
||||
return
|
||||
|
|
|
@ -106,6 +106,7 @@ func StartServer(config *Config, world *model.DfWorld, static embed.FS) error {
|
|||
srv.RegisterWorldResourcePage("/writtencontent/{id}", "writtencontent.html", func(id int) any { return srv.context.world.WrittenContents[id] })
|
||||
srv.RegisterWorldResourcePage("/popover/writtencontent/{id}", "popoverWrittencontent.html", func(id int) any { return srv.context.world.WrittenContents[id] })
|
||||
|
||||
srv.RegisterWorldPage("/hfs", "hfs.html", srv.searchHf)
|
||||
srv.RegisterWorldResourcePage("/hf/{id}", "hf.html", func(id int) any { return srv.context.world.HistoricalFigures[id] })
|
||||
srv.RegisterWorldResourcePage("/popover/hf/{id}", "popoverHf.html", func(id int) any { return srv.context.world.HistoricalFigures[id] })
|
||||
|
||||
|
@ -172,6 +173,48 @@ func (srv *DfServer) findStructure(p Parms) any {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (srv *DfServer) searchHf(p Parms) any {
|
||||
var list []*model.HistoricalFigure
|
||||
|
||||
for _, hf := range srv.context.world.HistoricalFigures {
|
||||
if p["leader"] == "1" && !hf.Leader {
|
||||
continue
|
||||
}
|
||||
if p["deity"] == "1" && !hf.Deity {
|
||||
continue
|
||||
}
|
||||
if p["force"] == "1" && !hf.Force {
|
||||
continue
|
||||
}
|
||||
if p["vampire"] == "1" && !hf.Vampire {
|
||||
continue
|
||||
}
|
||||
if p["werebeast"] == "1" && !hf.Werebeast {
|
||||
continue
|
||||
}
|
||||
if p["necromancer"] == "1" && !hf.Necromancer {
|
||||
continue
|
||||
}
|
||||
if p["alive"] == "1" && hf.DeathYear != -1 {
|
||||
continue
|
||||
}
|
||||
if p["ghost"] == "1" && false { // TODO ghost
|
||||
continue
|
||||
}
|
||||
if p["adventurer"] == "1" && !hf.Adventurer {
|
||||
continue
|
||||
}
|
||||
list = append(list, hf)
|
||||
}
|
||||
|
||||
sort.Slice(list, func(i, j int) bool { return list[i].Name_ < list[j].Name_ })
|
||||
|
||||
return map[string]any{
|
||||
"Params": p,
|
||||
"Hfs": list,
|
||||
}
|
||||
}
|
||||
|
||||
func (srv *DfServer) notFound(w http.ResponseWriter) {
|
||||
err := srv.templates.Render(w, "notFound.html", nil)
|
||||
if err != nil {
|
||||
|
|
|
@ -30,6 +30,7 @@ func (srv *DfServer) LoadTemplates() {
|
|||
srv.context.world.Width, srv.context.world.Height))
|
||||
},
|
||||
"hf": func(id int) template.HTML { return model.LinkHf(srv.context.world, id) },
|
||||
"hfShort": func(id int) template.HTML { return model.LinkHfShort(srv.context.world, id) },
|
||||
"getHf": func(id int) *model.HistoricalFigure { return srv.context.world.HistoricalFigures[id] },
|
||||
"hfList": func(ids []int) template.HTML { return model.LinkHfList(srv.context.world, ids) },
|
||||
"entity": func(id int) template.HTML { return model.LinkEntity(srv.context.world, id) },
|
||||
|
|
|
@ -13,8 +13,11 @@
|
|||
|
||||
<nav>
|
||||
<div class="nav nav-tabs" id="nav-tab" role="tablist">
|
||||
{{- if gt (len .Leaders) 0 }}
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#nav-leaders" type="button" role="tab">Sites</button>
|
||||
{{- end}}
|
||||
{{- if gt (len .Sites) 0 }}
|
||||
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#nav-sites" type="button" role="tab">Sites</button>
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#nav-sites" type="button" role="tab">Sites</button>
|
||||
{{- end}}
|
||||
{{- if gt (len .HistfigId) 0 }}
|
||||
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#nav-members" type="button" role="tab">Members</button>
|
||||
|
@ -28,8 +31,31 @@
|
|||
</div>
|
||||
</nav>
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
{{- if gt (len .Leaders) 0 }}
|
||||
<div class="tab-pane active" id="nav-leaders" role="tabpanel">
|
||||
<table class="table table-hover table-sm table-borderless object-table">
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th width="100%">Name</th>
|
||||
</tr>
|
||||
{{- range .Leaders }}
|
||||
<tr>
|
||||
<td>
|
||||
{{- if eq .EndYear -1 }}
|
||||
since {{ .StartYear }}
|
||||
{{- else }}
|
||||
from {{ .StartYear }} till {{ .EndYear }}
|
||||
{{- end }}
|
||||
</td>
|
||||
<td>
|
||||
{{ hf .Hf.Id }}</td>
|
||||
</tr>
|
||||
{{- end}}
|
||||
</table>
|
||||
</div>
|
||||
{{- end}}
|
||||
{{- if gt (len .Sites) 0 }}
|
||||
<div class="tab-pane active" id="nav-sites" role="tabpanel">
|
||||
<div class="tab-pane" id="nav-sites" role="tabpanel">
|
||||
<table class="table table-hover table-sm table-borderless">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
|
|
|
@ -10,10 +10,14 @@
|
|||
<i class="fa-solid fa-mars fa-xs"></i>
|
||||
{{end}}
|
||||
{{ .Race }}
|
||||
{{ if .Deity}}deity{{end}}
|
||||
{{ if .Force}}force{{end}}
|
||||
{{ if .Vampire}}vampire{{end}}
|
||||
{{ if .Werebeast}}werebeast{{end}}
|
||||
{{ if .Necromancer}}necromancer{{end}}
|
||||
{{ if not (or .Deity .Force)}}
|
||||
(*{{ .BirthYear }}{{ if ge .DeathYear 0 }} †{{ .DeathYear }}{{ end }})
|
||||
{{ end }}
|
||||
|
||||
<div class="row mt-3">
|
||||
<div class="col-4">
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
{{template "layout.html" .}}
|
||||
|
||||
{{define "title"}}Historical Figures{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
<h3>Historical Figures</h3>
|
||||
|
||||
{{ json .Params }}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-10">
|
||||
<table class="table table-hover table-sm table-borderless object-table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Race</th>
|
||||
<th>Lived</th>
|
||||
</tr>
|
||||
{{- range .Hfs }}{{- if not (eq .Name "") }}
|
||||
<tr>
|
||||
<td><a class="hf" href="/hf/{{.Id}}">{{ title .Name }}</a></td>
|
||||
<td>{{ .Race }}</td>
|
||||
<td>
|
||||
{{- if eq .DeathYear -1 }}
|
||||
from {{ .BirthYear }} till now
|
||||
{{- else }}
|
||||
from {{ .BirthYear }} till {{ .DeathYear }}
|
||||
{{- end }}
|
||||
</td>
|
||||
</tr>
|
||||
{{- end}}{{- end}}
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<h5>Filter</h5>
|
||||
<form action="/hfs" method="GET">
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="leader" value="1" {{if eq .Params.leader "1"
|
||||
}}checked{{end}}> Leader</label></div>
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="deity" value="1" {{if eq .Params.deity "1"
|
||||
}}checked{{end}}> Deity</label></div>
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="force" value="1" {{if eq .Params.force "1"
|
||||
}}checked{{end}}> Force</label></div>
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="vampire" value="1" {{if eq .Params.vampire "1"
|
||||
}}checked{{end}}> Vampire</label></div>
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="werebeast" value="1" {{if eq .Params.werebeast "1"
|
||||
}}checked{{end}}> Werebeast</label></div>
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="necromancer" value="1" {{if eq .Params.necromancer "1"
|
||||
}}checked{{end}}> Necromancer</label></div>
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="alive" value="1" {{if eq .Params.alive "1"
|
||||
}}checked{{end}}> Alive</label></div>
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="ghost" value="1" {{if eq .Params.ghost "1"
|
||||
}}checked{{end}}> Ghost</label></div>
|
||||
<div class="checkbox"><label><input class="filter" type="checkbox" name="adventurer" value="1" {{if eq .Params.adventurer "1"
|
||||
}}checked{{end}}> Adventurer</label></div>
|
||||
<div class="select form-group">
|
||||
<select class="form-control" name="race">
|
||||
<option class="text-muted" value="">Race</option>
|
||||
<option value="black bear">black bear</option>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
<h4>Sorting</h4>
|
||||
<div class="select form-group">
|
||||
<select class="form-control" name="sort">
|
||||
<option value="">Default</option>
|
||||
<option value="name">Name</option>
|
||||
<option value="race">Race</option>
|
||||
<option value="birth">Birth</option>
|
||||
<option value="death">Death</option>
|
||||
<option value="kills">Kills</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Refresh</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{- end }}
|
|
@ -3,7 +3,15 @@
|
|||
{{else}}
|
||||
<i class="fa-solid fa-mars fa-xs"></i>
|
||||
{{end}}
|
||||
{{ .Race }} (*{{ .BirthYear }}{{ if ge .DeathYear 0 }} †{{ .DeathYear }}{{ end }})
|
||||
{{ .Race }}
|
||||
{{ if .Deity}}deity{{end}}
|
||||
{{ if .Force}}force{{end}}
|
||||
{{ if .Vampire}}vampire{{end}}
|
||||
{{ if .Werebeast}}werebeast{{end}}
|
||||
{{ if .Necromancer}}necromancer{{end}}
|
||||
{{ if not (or .Deity .Force)}}
|
||||
(*{{ .BirthYear }}{{ if ge .DeathYear 0 }} †{{ .DeathYear }}{{ end }})
|
||||
{{ end }}
|
||||
|
||||
{{- if or (ne 0 (len .EntityFormerPositionLink)) (ne 0 (len .EntityPositionLink)) }}
|
||||
<ul class="mb-0">
|
||||
|
|
Loading…
Reference in New Issue