additional fields, structures

This commit is contained in:
Robert Janetzko 2022-04-29 12:21:27 +00:00
parent 1387a2938e
commit e210a3e3dd
18 changed files with 317 additions and 63 deletions

View File

@ -151,6 +151,17 @@ func CreateMetadata(a *AnalyzeData) (*Metadata, error) {
} }
} }
additional := make(map[string]Field)
if afs, ok := a.Overwrites.AdditionalFields[typeNames[k]]; ok {
for _, add := range afs {
additional[add.Name] = Field{
Name: add.Name,
Type: add.Type,
Legend: "add",
}
}
}
objects[typeNames[k]] = Object{ objects[typeNames[k]] = Object{
Name: typeNames[k], Name: typeNames[k],
Id: a.Fields[k+PATH_SEPARATOR+"id"] != nil, Id: a.Fields[k+PATH_SEPARATOR+"id"] != nil,
@ -160,6 +171,7 @@ func CreateMetadata(a *AnalyzeData) (*Metadata, error) {
SubTypeOf: getSubtypeOf(k), SubTypeOf: getSubtypeOf(k),
SubType: getSubtype(k), SubType: getSubtype(k),
Fields: objFields, Fields: objFields,
Additional: additional,
} }
} }
} }

View File

@ -15,6 +15,7 @@ type Object struct {
SubTypeOf *string `json:"subtypeof,omitempty"` SubTypeOf *string `json:"subtypeof,omitempty"`
SubType *string `json:"subtype,omitempty"` SubType *string `json:"subtype,omitempty"`
Fields map[string]Field `json:"fields"` Fields map[string]Field `json:"fields"`
Additional map[string]Field `json:"additional"`
} }
type Subtype struct { type Subtype struct {

View File

@ -102,6 +102,9 @@ type {{ $obj.Name }} struct {
{{- if not (not $obj.SubTypes) }} {{- if not (not $obj.SubTypes) }}
Details {{ $obj.Name }}Details Details {{ $obj.Name }}Details
{{- end }} {{- end }}
{{- range $fname, $field := $obj.Additional }}
{{ $field.TypeLine }} // {{ $fname }}
{{- end }}
} }
func New{{ $obj.Name }}() *{{ $obj.Name }} { func New{{ $obj.Name }}() *{{ $obj.Name }} {

View File

@ -53,6 +53,7 @@ func NewFieldData() *FieldData {
type AnalyzeData struct { type AnalyzeData struct {
Fields map[string]*FieldData Fields map[string]*FieldData
SubTypes map[string]*map[string]*Subtype SubTypes map[string]*map[string]*Subtype
Overwrites *Overwrites
} }
func NewAnalyzeData() *AnalyzeData { func NewAnalyzeData() *AnalyzeData {
@ -78,6 +79,16 @@ func LoadAnalyzeData() (*AnalyzeData, error) {
a := NewAnalyzeData() a := NewAnalyzeData()
json.Unmarshal(data, a) json.Unmarshal(data, a)
data, err = ioutil.ReadFile("overwrites.json")
if err != nil {
return nil, err
}
overwrites := &Overwrites{}
json.Unmarshal(data, overwrites)
a.Overwrites = overwrites
return a, nil return a, nil
} }
@ -120,8 +131,14 @@ type AnalyzeContext struct {
overwrites *Overwrites overwrites *Overwrites
} }
type AdditionalField struct {
Name string
Type string
}
type Overwrites struct { type Overwrites struct {
ForceEnum map[string]bool ForceEnum map[string]bool
AdditionalFields map[string][]AdditionalField
} }
func analyze(file string, a *AnalyzeData) error { func analyze(file string, a *AnalyzeData) error {

View File

@ -2,5 +2,13 @@
"ForceEnum": { "ForceEnum": {
"df_world|historical_events|historical_event+HfDied|cause": true, "df_world|historical_events|historical_event+HfDied|cause": true,
"df_world|historical_events|historical_event+HfDied|death_cause": true "df_world|historical_events|historical_event+HfDied|death_cause": true
},
"AdditionalFields": {
"Structure": [
{
"Name": "SiteId",
"Type": "int"
}
]
} }
} }

View File

@ -112,7 +112,7 @@ func (c *Context) site(id int, prefix string) string {
func (c *Context) structure(siteId, structureId int) string { func (c *Context) structure(siteId, structureId int) string {
if x, ok := c.World.Sites[siteId]; ok { if x, ok := c.World.Sites[siteId]; ok {
if y, ok := x.Structures[structureId]; ok { if y, ok := x.Structures[structureId]; ok {
return fmt.Sprintf(`<a class="structure" href="/site/%d/structure/%d">%s</a>`, siteId, structureId, util.Title(y.Name())) return fmt.Sprintf(`<a class="structure" href="/site/%d/structure/%d"><i class="%s fa-xs"></i>&nbsp;%s</a>`, siteId, structureId, y.Icon(), util.Title(y.Name()))
} }
} }
return "UNKNOWN STRUCTURE" return "UNKNOWN STRUCTURE"

View File

@ -144,6 +144,10 @@ func (s *Site) Type() string {
return s.Type_.String() return s.Type_.String()
} }
func (s *Structure) Type() string {
return s.Type_.String()
}
func (w *WorldConstruction) Type() string { func (w *WorldConstruction) Type() string {
return w.Type_.String() return w.Type_.String()
} }

View File

@ -10,6 +10,9 @@ import (
var LinkHf = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).hf(id)) } var LinkHf = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).hf(id)) }
var LinkEntity = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).entity(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, "")) } var LinkSite = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).site(id, "")) }
var LinkStructure = func(w *DfWorld, siteId, id int) template.HTML {
return template.HTML((&Context{World: w}).structure(siteId, id))
}
var LinkRegion = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).region(id)) } var LinkRegion = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).region(id)) }
var LinkWorldConstruction = func(w *DfWorld, id int) template.HTML { var LinkWorldConstruction = func(w *DfWorld, id int) template.HTML {
return template.HTML((&Context{World: w}).worldConstruction(id)) return template.HTML((&Context{World: w}).worldConstruction(id))

View File

@ -64,6 +64,36 @@ func (x *Site) Icon() string {
return "" return ""
} }
func (x *Structure) Icon() string {
switch x.Type_ {
case StructureType_CountingHouse:
return "fa-solid fa-coins"
case StructureType_Dungeon:
return "fa-solid fa-dungeon"
case StructureType_Guildhall:
return "fa-solid fa-wrench"
case StructureType_InnTavern:
return "fa-solid fa-utensils"
case StructureType_Keep:
return "fa-brands fa-fort-awesome"
case StructureType_Library:
return "fa-solid fa-book"
case StructureType_Market:
return "fa-solid fa-store"
case StructureType_MeadHall:
return "fa-solid fa-warehouse"
case StructureType_Temple:
return "fa-solid fa-landmark-dome"
case StructureType_Tomb:
return "fa-solid fa-circle-stop"
case StructureType_Tower:
return "fa-solid fa-chess-rook"
case StructureType_UnderworldSpire:
return "fa-solid fa-monument"
}
return ""
}
func (x *WorldConstruction) Icon() string { func (x *WorldConstruction) Icon() string {
switch x.Type_ { switch x.Type_ {
case WorldConstructionType_Bridge: case WorldConstructionType_Bridge:

View File

@ -19033,6 +19033,7 @@ type Structure struct {
Subtype StructureSubtype `json:"subtype" legend:"base"` // subtype Subtype StructureSubtype `json:"subtype" legend:"base"` // subtype
Type_ StructureType `json:"type" legend:"both"` // type Type_ StructureType `json:"type" legend:"both"` // type
WorshipHfid int `json:"worshipHfid" legend:"base"` // worship_hfid WorshipHfid int `json:"worshipHfid" legend:"base"` // worship_hfid
SiteId int `json:"siteId" legend:"add"` // SiteId
} }
func NewStructure() *Structure { func NewStructure() *Structure {

View File

@ -143,9 +143,7 @@ BaseLoop:
} }
ioutil.WriteFile("same.json", same, 0644) ioutil.WriteFile("same.json", same, 0644)
for _, e := range world.HistoricalEvents { world.Process()
e.Details.Html(&Context{World: world})
}
return world, nil return world, nil
} }

16
backend/model/process.go Normal file
View File

@ -0,0 +1,16 @@
package model
func (w *DfWorld) Process() {
// set site in structure
for _, site := range w.Sites {
for _, structure := range site.Structures {
structure.SiteId = site.Id_
}
}
// check events texts
for _, e := range w.HistoricalEvents {
e.Details.Html(&Context{World: w})
}
}

View File

@ -54,6 +54,11 @@ func StartServer(world *model.DfWorld, static embed.FS) {
srv.RegisterWorldPage("/sites", "sites.html", func(p Parms) any { return grouped(srv.context.world.Sites) }) srv.RegisterWorldPage("/sites", "sites.html", func(p Parms) any { return grouped(srv.context.world.Sites) })
srv.RegisterWorldResourcePage("/site/{id}", "site.html", func(id int) any { return srv.context.world.Sites[id] }) srv.RegisterWorldResourcePage("/site/{id}", "site.html", func(id int) any { return srv.context.world.Sites[id] })
srv.RegisterWorldPage("/structures", "structures.html", func(p Parms) any {
return flatGrouped(srv.context.world.Sites, func(s *model.Site) []*model.Structure { return util.Values(s.Structures) })
})
srv.RegisterWorldResourcePage("/structure/{id}", "site.html", func(id int) any { return srv.context.world.Sites[id/100].Structures[id%100] })
srv.RegisterWorldPage("/worldconstructions", "worldconstructions.html", func(p Parms) any { return grouped(srv.context.world.WorldConstructions) }) srv.RegisterWorldPage("/worldconstructions", "worldconstructions.html", func(p Parms) any { return grouped(srv.context.world.WorldConstructions) })
srv.RegisterWorldResourcePage("/worldconstruction/{id}", "worldconstruction.html", func(id int) any { return srv.context.world.WorldConstructions[id] }) srv.RegisterWorldResourcePage("/worldconstruction/{id}", "worldconstruction.html", func(id int) any { return srv.context.world.WorldConstructions[id] })
@ -261,7 +266,26 @@ type namedTyped interface {
model.Typed model.Typed
} }
func grouped[T namedTyped](input map[int]T) map[string][]T { func flatGrouped[K comparable, U any, V namedTyped](input map[K]U, mapper func(U) []V) map[string][]V {
output := make(map[string][]V)
for _, x := range input {
for _, v := range mapper(x) {
k := v.Type()
if v.Name() != "" {
output[k] = append(output[k], v)
}
}
}
for _, v := range output {
sort.Slice(v, func(i, j int) bool { return v[i].Name() < v[j].Name() })
}
return output
}
func grouped[K comparable, T namedTyped](input map[K]T) map[string][]T {
output := make(map[string][]T) output := make(map[string][]T)
for _, v := range input { for _, v := range input {

View File

@ -29,6 +29,7 @@ func (srv *DfServer) LoadTemplates() {
"getEntity": func(id int) *model.Entity { return srv.context.world.Entities[id] }, "getEntity": func(id int) *model.Entity { return srv.context.world.Entities[id] },
"site": func(id int) template.HTML { return model.LinkSite(srv.context.world, id) }, "site": func(id int) template.HTML { return model.LinkSite(srv.context.world, id) },
"getSite": func(id int) *model.Site { return srv.context.world.Sites[id] }, "getSite": func(id int) *model.Site { return srv.context.world.Sites[id] },
"structure": func(siteId, id int) template.HTML { return model.LinkStructure(srv.context.world, siteId, id) },
"region": func(id int) template.HTML { return model.LinkRegion(srv.context.world, id) }, "region": func(id int) template.HTML { return model.LinkRegion(srv.context.world, id) },
"getRegion": func(id int) *model.Region { return srv.context.world.Regions[id] }, "getRegion": func(id int) *model.Region { return srv.context.world.Regions[id] },
"worldconstruction": func(id int) template.HTML { return model.LinkWorldConstruction(srv.context.world, id) }, "worldconstruction": func(id int) template.HTML { return model.LinkWorldConstruction(srv.context.world, id) },

View File

@ -3,13 +3,30 @@
{{define "title"}}{{ title .Name }}{{end}} {{define "title"}}{{ title .Name }}{{end}}
{{define "content"}} {{define "content"}}
<h1>{{ title .Name }}</h1> <h3>{{ title .Name }}</h3>
{{ .Race }} (*{{ .BirthYear }}{{ if ge .DeathYear 0 }} †{{ .DeathYear }}{{ end }}) {{if .Female }}
<i class="fa-solid fa-venus fa-xs"></i>
{{else}}
<i class="fa-solid fa-mars fa-xs"></i>
{{end}} {{end}}
{{ .Race }} (*{{ .BirthYear }}{{ if ge .DeathYear 0 }} †{{ .DeathYear }}{{ end }})
{{- if or (ne 0 (len .EntityFormerPositionLink)) (ne 0 (len .EntityPositionLink)) }} <div class="row mt-3">
<h3>Positions</h3> <div class="col-4">
<ul> {{- if ne 0 (len .SiteLink) }}
<h5>Sites</h5>
<ul>
{{- range $i := .SiteLink }}
<li>
{{ site $i.SiteId }} ({{ $i.LinkType }})
</li>
{{- end }}
</ul>
{{- end }}
{{- if or (ne 0 (len .EntityFormerPositionLink)) (ne 0 (len .EntityPositionLink)) }}
<h5>Positions</h5>
<ul>
{{- range $i := .EntityFormerPositionLink }} {{- range $i := .EntityFormerPositionLink }}
<li> <li>
{{ ((getEntity $i.EntityId).Position $i.PositionProfileId).Name }} of {{ entity $i.EntityId }} ({{ {{ ((getEntity $i.EntityId).Position $i.PositionProfileId).Name }} of {{ entity $i.EntityId }} ({{
@ -21,33 +38,96 @@
of {{ entity $i.EntityId }} of {{ entity $i.EntityId }}
</li> </li>
{{- end }} {{- end }}
</ul> </ul>
{{- end }} {{- end }}
</div>
{{- if ne 0 (len .HfLink) }} {{- if ne 0 (len .HfLink) }}
<h3>Related Figures</h3> <div class="col-4">
<ul> <h5>Related Figures</h5>
<ul>
{{- range $i := .HfLink }} {{- range $i := .HfLink }}
<li> <li>
{{ hf $i.Hfid }} ({{ $i.LinkType }}) {{ hf $i.Hfid }} ({{ $i.LinkType }})
</li> </li>
{{- end }} {{- end }}
</ul> </ul>
{{- end }} </div>
{{- end }}
{{- if ne 0 (len .EntityLink) }} {{- if ne 0 (len .EntityLink) }}
<h3>Related Entities</h3> <div class="col-4">
<ul> <h5>Related Entities</h5>
<ul>
{{- range $i := .EntityLink }} {{- range $i := .EntityLink }}
<li> <li>
{{ entity $i.EntityId }} ({{ $i.LinkType }}) {{ entity $i.EntityId }} ({{ $i.LinkType }})
</li> </li>
{{- end }} {{- end }}
</ul> </ul>
{{- end }} </div>
{{- end }}
</div>
<h3>Events</h3> <div class="row">
{{- if ne 0 (len .EntityReputation) }}
<div class="col-4">
<h5>Entity Reputations</h5>
<ul>
{{- range $i := .EntityReputation }}
<li>
{{ entity $i.EntityId }}
<ul>
{{if gt .UnsolvedMurders 0}}<li>Unsolved Murders: {{.UnsolvedMurders}}</li>{{end}}
{{if gt .FirstAgelessYear 0}}<li>First Suspected Ageless Year: {{.FirstAgelessYear}}</li>{{end}}
</ul>
</li>
{{- end }}
</ul>
</div>
{{- end }}
{{- if ne 0 (len .VagueRelationship) }}
<div class="col-4">
<h5>Relationships</h5>
<ul>
{{- range $i := .VagueRelationship }}
<li>
{{ hf $i.Hfid }} (TODO)
</li>
{{- end }}
</ul>
</div>
{{- end }}
{{- if ne 0 (len .IntrigueActor) }}
<div class="col-8">
<h5>Intrigue Actors</h5>
<ul>
{{- range $i := .IntrigueActor }}
<li>
{{if ne .EntityId -1}}{{entity .EntityId}}{{else}}{{ hf .Hfid }}{{end}} - {{.Role}} - {{.Strategy}}
</li>
{{- end }}
</ul>
</div>
{{- end }}
{{- if ne 0 (len .IntriguePlot) }}
<div class="col-4">
<h5>Intrigue Plots</h5>
<ul>
{{- range $i := .IntriguePlot }}
<li>
{{ .Type_ }}{{if .OnHold}} (on hold){{end}}
</li>
{{- end }}
</ul>
</div>
{{- end }}
</div>
<h5>Events</h5>
{{ template "events.html" events . }} {{ template "events.html" events . }}
{{ json . }} {{ json . }}
{{end}}

View File

@ -0,0 +1,23 @@
{{if ge .RepHero 0}}<li>Hero: $r.repHero</li>{{end}}
{{if ge .RepViolent 0}}<li>Violent: $r.repViolent</li>{{end}}
{{if ge .RepPsychopath 0}}<li>Psychopath: $r.repPsychopath</li>{{end}}
{{if ge .RepEnemyFighter 0}}<li>Enemy Fighter: $r.repEnemyFighter</li>{{end}}
{{if ge .RepFriendlyFighter 0}}<li>Enemy Fighter: $r.repEnemyFighter</li>{{end}}
{{if ge .RepKiller 0}}<li>Killer: $r.repKiller</li>{{end}}
{{if ge .RepMurderer 0}}<li>Murderer: $r.repMurderer</li>{{end}}
{{if ge .RepPoet 0}}<li>Poet: $r.repPoet</li>{{end}}
{{if ge .RepBard 0}}<li>Bard: $r.repBard</li>{{end}}
{{if ge .RepDancer 0}}<li>Dancer: $r.repDancer</li>{{end}}
{{if ge .RepStoryteller 0}}<li>Storyteller: $r.repStoryteller</li>{{end}}
{{if ge .RepTreasureHunter 0}}<li>Treasure Hunter: $r.repTreasureHunter</li>{{end}}
{{if ge .RepPreacher 0}}<li>Preacher: $r.repPreacher</li>{{end}}
{{if ge .RepBrigand 0}}<li>Brigand: $r.repBrigand</li>{{end}}
{{if ge .RepIntruder 0}}<li>Intruder: $r.repIntruder</li>{{end}}
{{if ge .RepMonster 0}}<li>Monster: $r.repMonster</li>{{end}}
{{if ge .RepThief 0}}<li>Thief: $r.repThief</li>{{end}}
{{if ge .RepHatedGroup 0}}<li>Member of Hated Group: $r.repHatedGroup</li>{{end}}
{{if ge .RepRespectedGroup 0}}<li>Member of Respected Group: $r.repRespectedGroup</li>{{end}}
{{if ge .RepHunter 0}}<li>Hunter: $r.repHunter</li>{{end}}
{{if ge .RepLoyalSoldier 0}}<li>Loyal Soldier: $r.repLoyalSoldier</li>{{end}}
{{if ge .RepComrade 0}}<li>Comrade: $r.repComrade</li>{{end}}
{{if ge .RepBully 0}}<li>Bully: $r.repBully</li>{{end}}

View File

@ -3,10 +3,10 @@
{{define "title"}}{{ title .Name }}{{end}} {{define "title"}}{{ title .Name }}{{end}}
{{define "content"}} {{define "content"}}
<h1>{{ title .Name }}</h1> <h3>{{ title .Name }}</h3>
{{ .Type_ }}
<h3>Events</h3>
<h5 class="mt-3">Events</h5>
{{ template "events.html" events . }} {{ template "events.html" events . }}
<p>{{ json . }}</p> <p>{{ json . }}</p>

View File

@ -0,0 +1,33 @@
{{template "layout.html" .}}
{{define "title"}}Structures{{end}}
{{define "content"}}
<h3>Structures</h3>
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
{{- range $t, $v := .}}
<button class="nav-link{{ ifFirst $ $t " active" }}" data-bs-toggle="tab" data-bs-target="#nav-{{kebab $t}}" type="button"
role="tab">{{$t}} ({{ len $v }})</button>
{{- end}}
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
{{- range $t, $v := . }}
<div class="tab-pane{{ ifFirst $ $t " active" }}" id="nav-{{kebab $t}}" role="tabpanel" aria-labelledby="nav-home-tab">
<table>
<tr>
<th width="100%">Name</th>
</tr>
{{- range $v }}{{- if not (eq .Name "") }}
<tr>
<td>{{ structure .SiteId .Id }}</td>
</tr>
{{- end}}{{- end}}
</table>
</div>
{{- end}}
</div>
{{- end }}