This commit is contained in:
Robert Janetzko 2022-05-07 20:19:30 +00:00
parent e5cd5bd3c2
commit 6380871358
10 changed files with 117 additions and 18 deletions

View File

@ -85,6 +85,10 @@
{
"Name": "NecromancerSince",
"Type": "int"
},
{
"Name": "Kills",
"Type": "[]int"
}
],
"Entity": [

View File

@ -7,6 +7,7 @@ import (
"strings"
"github.com/robertjanetzko/LegendsBrowser2/backend/util"
"golang.org/x/exp/maps"
)
func (w *DfWorld) AllEventTypes() []string {
@ -63,6 +64,16 @@ func (w *DfWorld) SiteHistory(siteId int) []*HistoricalEvent {
return list
}
func (w *DfWorld) Races() []string {
races := make(map[string]bool)
for _, hf := range w.HistoricalFigures {
races[hf.Race] = true
}
list := maps.Keys(races)
sort.Strings(list)
return list
}
func (c *HistoricalEventCollection) Type() string {
if c.Details == nil {
return "unk"

View File

@ -19059,6 +19059,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
Kills []int `json:"kills" legend:"add" related:""` // Kills
Leader bool `json:"leader" legend:"add" related:""` // Leader
Necromancer bool `json:"necromancer" legend:"add" related:""` // Necromancer
NecromancerSince int `json:"necromancerSince" legend:"add" related:""` // NecromancerSince
@ -19182,6 +19183,7 @@ func (x *HistoricalFigure) MarshalJSON() ([]byte, error) {
d["sphere"] = x.Sphere
d["usedIdentityId"] = x.UsedIdentityId
d["vagueRelationship"] = x.VagueRelationship
d["kills"] = x.Kills
d["leader"] = x.Leader
d["necromancer"] = x.Necromancer
if x.NecromancerSince != -1 {

View File

@ -150,6 +150,10 @@ func (w *DfWorld) processEvents() {
id.HistfigId = hf.Id_
}
}
case *HistoricalEventHfDied:
if hf, ok := w.HistoricalFigures[d.SlayerHfid]; ok {
hf.Kills = append(hf.Kills, d.Hfid)
}
}
}
}

View File

@ -12,6 +12,7 @@ import (
"github.com/robertjanetzko/LegendsBrowser2/backend/model"
"github.com/robertjanetzko/LegendsBrowser2/backend/templates"
"github.com/robertjanetzko/LegendsBrowser2/backend/util"
"golang.org/x/exp/constraints"
)
type DfServerContext struct {
@ -119,6 +120,19 @@ func StartServer(config *Config, world *model.DfWorld, static embed.FS) error {
srv.RegisterWorldResourcePage("/identity/{id}", "identity.html", func(id int) any { return srv.context.world.Identities[id] })
srv.RegisterWorldResourcePage("/popover/identity/{id}", "popoverIdentity.html", func(id int) any { return srv.context.world.Identities[id] })
srv.RegisterWorldPage("/years", "years.html", func(p Parms) any {
return groupBy(srv.context.world.HistoricalEvents,
func(e *model.HistoricalEvent) int { return e.Year },
func(e *model.HistoricalEvent) bool { return true },
func(e *model.HistoricalEvent) int { return e.Id_ })
})
srv.RegisterWorldResourcePage("/year/{id}", "year.html", func(id int) any {
return util.FilterMap(srv.context.world.HistoricalEvents,
func(v *model.HistoricalEvent) bool { return v.Year == id },
func(a, b *model.HistoricalEvent) bool { return a.Id_ < b.Id_ },
)
})
srv.RegisterWorldPage("/events", "eventTypes.html", func(p Parms) any { return srv.context.world.AllEventTypes() })
srv.RegisterWorldPage("/events/{type}", "eventType.html", func(p Parms) any { return srv.context.world.EventsOfType(p["type"]) })
srv.RegisterWorldResourcePage("/event/{id}", "event.html", func(id int) any { return srv.context.world.HistoricalEvents[id] })
@ -236,7 +250,18 @@ func (srv *DfServer) searchHf(p Parms) any {
list = append(list, hf)
}
sort.Slice(list, func(i, j int) bool { return list[i].Name_ < list[j].Name_ })
switch p["sort"] {
case "race":
sort.Slice(list, func(i, j int) bool { return list[i].Race < list[j].Race })
case "birth":
sort.Slice(list, func(i, j int) bool { return list[i].BirthYear < list[j].BirthYear })
case "death":
sort.Slice(list, func(i, j int) bool { return list[i].DeathYear < list[j].DeathYear })
case "kills":
sort.Slice(list, func(i, j int) bool { return len(list[i].Kills) > len(list[j].Kills) })
default:
sort.Slice(list, func(i, j int) bool { return list[i].Name_ < list[j].Name_ })
}
return map[string]any{
"Params": p,
@ -288,8 +313,8 @@ func groupByType[K comparable, T namedTyped](input map[K]T) map[string][]T {
return groupBy(input, func(t T) string { return t.Type() }, func(t T) bool { return t.Name() != "" }, func(t T) string { return t.Name() })
}
func groupBy[K comparable, T any](input map[K]T, mapper func(T) string, filter func(T) bool, sortMapper func(T) string) map[string][]T {
output := make(map[string][]T)
func groupBy[K comparable, N comparable, T any, S constraints.Ordered](input map[K]T, mapper func(T) N, filter func(T) bool, sortMapper func(T) S) map[N][]T {
output := make(map[N][]T)
for _, v := range input {
k := mapper(v)

View File

@ -90,12 +90,14 @@ func (srv *DfServer) LoadTemplates() {
"html": func(value any) template.HTML {
return template.HTML(fmt.Sprint(value))
},
"bytes": func(s int64) string { return humanize.Bytes(uint64(s)) },
"first": util.FirstInMap,
"ifFirst": func(m any, k string, r string) string { return util.If(util.FirstInMap(m, k), r, "") },
"strip": util.Strip,
"string": util.String,
"capitalize": util.Capitalize,
"bytes": func(s int64) string { return humanize.Bytes(uint64(s)) },
"first": util.FirstInMap,
"ifFirst": func(m any, k string, r string) string { return util.If(util.FirstInMap(m, k), r, "") },
"strip": util.Strip,
"string": util.String,
"capitalize": util.Capitalize,
"add": func(a, b int) int { return a + b },
"breakYearColumn": func(c, m int) bool { return (c % ((m + 2) / 4)) == 0 },
}
srv.templates = templates.New(functions)
}

View File

@ -14,6 +14,7 @@
<th>Name</th>
<th>Race</th>
<th>Lived</th>
<th>Kills</th>
</tr>
{{- range .Hfs }}{{- if not (eq .Name "") }}
<tr>
@ -26,6 +27,7 @@
from {{ .BirthYear }} till {{ .DeathYear }}
{{- end }}
</td>
<td>{{ len .Kills }}</td>
</tr>
{{- end}}{{- end}}
</table>
@ -51,25 +53,26 @@
}}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">
<div class="select form-group mt-1 mb-3">
<select class="form-control" name="race">
<option class="text-muted" value="">Race</option>
<option value="black bear">black bear</option>
{{- range world.Races -}}
<option value="{{ . }}" {{if eq $.Params.race . }}selected{{end}}>{{ . }}</option>
{{- end -}}
</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>
<option value="name" {{if eq .Params.sort "name" }}selected{{end}}>Name</option>
<option value="race" {{if eq .Params.sort "race" }}selected{{end}}>Race</option>
<option value="birth" {{if eq .Params.sort "birth" }}selected{{end}}>Birth</option>
<option value="death" {{if eq .Params.sort "death" }}selected{{end}}>Death</option>
<option value="kills" {{if eq .Params.sort "kills" }}selected{{end}}>Kills</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Refresh</button>
<button type="submit" class="btn btn-primary mt-4">Refresh</button>
</form>
</div>
</div>

View File

@ -0,0 +1,12 @@
{{template "layout.html" .}}
{{define "title"}}Year {{(index . 0).Year}}{{end}}
{{define "content"}}
<h3>Year {{(index . 0).Year}}</h3>
<h5>Events</h5>
{{ template "events.html" events . }}
{{- end }}

View File

@ -0,0 +1,25 @@
{{template "layout.html" .}}
{{define "title"}}Years{{end}}
{{define "content"}}
<h3>Years</h3>
<div class="row">
<div class="col-md-3">
<ul>
{{ $c := 0}}
{{ range $y, $e := . }}
{{ $c = add $c 1 }}
{{ if breakYearColumn $c (len $) }}
</ul>
</div>
<div class="col-md-3">
<ul>
{{end}}
<li><a href="/year/{{ $y }}">Year {{ $y }}</a> ({{len $e}} events)</li>
{{ end }}
</ul>
</div>
</div>
{{- end }}

View File

@ -90,6 +90,17 @@ func Map[U, V any](list []U, mapper func(U) V) []V {
return newList
}
func FilterMap[K comparable, V any](input map[K]V, predicate func(V) bool, sorter func(V, V) bool) []V {
var list []V
for _, v := range input {
if predicate(v) {
list = append(list, v)
}
}
sort.Slice(list, func(i, j int) bool { return sorter(list[i], list[j]) })
return list
}
type Identifiable interface {
Id() int
}