entity details

This commit is contained in:
Robert Janetzko 2022-05-05 14:55:57 +00:00
parent 093f7dacf9
commit e9cde0f17c
14 changed files with 260 additions and 51 deletions

View File

@ -460,7 +460,7 @@ func (f Field) EndAction(obj Object) string {
return ""
}
var entityRegex, _ = regexp.Compile("(civ|civ_id|enid|[^d]*entity(_id)?|^entity(_id)?|^source|^destination|^involved)(_?[0-9])?$")
var entityRegex, _ = regexp.Compile("(civ|civ_id|enid|(^|[^d])entity(_id)?|^entity(_id)?|^source|^destination|^involved)(_?[0-9])?$")
var hfRegex, _ = regexp.Compile("(hfid|hf_id|hist_figure_id|histfig_id|histfig|bodies|_hf)")
var artifactRegex, _ = regexp.Compile("(item(_id)?|artifact_id)$")
var siteRegex, _ = regexp.Compile("(site_id|site)[0-9]?$")

View File

@ -60,12 +60,32 @@
{
"Name": "Vampire",
"Type": "bool"
},
{
"Name": "Necromancer",
"Type": "bool"
},
{
"Name": "WerebeastSince",
"Type": "int"
},
{
"Name": "VampireSince",
"Type": "int"
},
{
"Name": "NecromancerSince",
"Type": "int"
}
],
"Entity": [
{
"Name": "Sites",
"Type": "[]int"
},
{
"Name": "Wars",
"Type": "[]*HistoricalEventCollection"
}
],
"Site": [

View File

@ -1,5 +1,5 @@
{
"LastPath": "/workspaces/legendsbrowser/inputs",
"LastFile": "/workspaces/legendsbrowser/inputs/Stalkmatches-00254-08-26-legends.xml",
"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
}

View File

@ -11,6 +11,7 @@ type Context struct {
World *DfWorld
HfId int
Story bool
Event *HistoricalEvent
}
func NewContext(w *DfWorld, ref any) *Context {
@ -24,6 +25,12 @@ func NewContext(w *DfWorld, ref any) *Context {
return c
}
func (c *Context) WithEvent(e *HistoricalEvent) *Context {
c2 := *c
c2.Event = e
return &c2
}
func (c *Context) hf(id int) string {
if c.HfId != -1 {
if c.HfId == id {
@ -33,7 +40,17 @@ func (c *Context) hf(id int) string {
}
}
if x, ok := c.World.HistoricalFigures[id]; ok {
return fmt.Sprintf(`the %s <a class="hf" href="/hf/%d">%s</a>`, x.Race+util.If(x.Deity, " deity", "")+util.If(x.Force, " force", ""), x.Id(), util.Title(x.Name()))
return hf(x)
}
return "UNKNOWN HISTORICAL FIGURE"
}
func (c *Context) hfUnrelated(id int) string {
if c.HfId != -1 && c.HfId == id {
return c.hfShort(id)
}
if x, ok := c.World.HistoricalFigures[id]; ok {
return hf(x)
}
return "UNKNOWN HISTORICAL FIGURE"
}
@ -59,11 +76,31 @@ func (c *Context) hfRelated(id, to int) string {
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(`the %s <a class="hf" href="/hf/%d">%s</a>`, x.Race+util.If(x.Deity, " deity", "")+util.If(x.Force, " force", ""), x.Id(), util.Title(x.Name()))
return hf(x)
}
return "UNKNOWN HISTORICAL FIGURE"
}
func hf(x *HistoricalFigure) string {
r := x.Race
if x.Deity {
r += " deity"
}
if x.Force {
r += " deity"
}
if x.Necromancer {
r += " necromancer"
}
if x.Werebeast {
r += " werebeast"
}
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()))
}
func (c *Context) hfList(ids []int) string {
return andList(util.Map(ids, func(id int) string { return c.hf(id) }))
}

View File

@ -44,8 +44,8 @@ func (x *HistoricalEventAddHfEntityLink) Html(c *Context) string {
}
func (x *HistoricalEventAddHfHfLink) Html(c *Context) string {
h := c.hf(x.Hfid)
t := c.hf(x.HfidTarget)
h := c.hfUnrelated(x.Hfid)
t := c.hfUnrelated(x.HfidTarget)
switch x.LinkType {
case HistoricalEventAddHfHfLinkLinkType_Apprentice:
return h + " became the master of " + t
@ -2056,7 +2056,7 @@ func (x *HistoricalEventRemoveHfEntityLink) Html(c *Context) string {
}
func (x *HistoricalEventRemoveHfHfLink) Html(c *Context) string {
return c.hf(x.Hfid) + " divorced " + c.hfRelated(x.HfidTarget, x.Hfid)
return c.hfUnrelated(x.Hfid) + " divorced " + c.hfUnrelated(x.HfidTarget)
}
func (x *HistoricalEventRemoveHfSiteLink) Html(c *Context) string {

View File

@ -9,6 +9,7 @@ import (
)
var LinkHf = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).hf(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, "")) }
var LinkStructure = func(w *DfWorld, siteId, id int) template.HTML {

View File

@ -1975,22 +1975,23 @@ func (s EntityWeapon) MarshalJSON() ([]byte, error) {
}
type Entity struct {
Child []int `json:"child" legend:"plus" related:""` // child
Claims string `json:"claims" legend:"plus" related:""` // claims
EntityLink []*EntityEntityLink `json:"entityLink" legend:"plus" related:""` // entity_link
EntityPosition []*EntityPosition `json:"entityPosition" legend:"plus" related:""` // entity_position
EntityPositionAssignment []*EntityPositionAssignment `json:"entityPositionAssignment" legend:"plus" related:""` // entity_position_assignment
HistfigId []int `json:"histfigId" legend:"plus" related:""` // histfig_id
Honor []*Honor `json:"honor" legend:"base" related:""` // honor
Id_ int `json:"id" legend:"both" related:""` // id
Name_ string `json:"name" legend:"base" related:""` // name
Occasion []*Occasion `json:"occasion" legend:"plus" related:""` // occasion
Profession EntityProfession `json:"profession" legend:"plus" related:""` // profession
Race string `json:"race" legend:"plus" related:""` // race
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
Sites []int `json:"sites" legend:"add" related:""` // Sites
Child []int `json:"child" legend:"plus" related:""` // child
Claims string `json:"claims" legend:"plus" related:""` // claims
EntityLink []*EntityEntityLink `json:"entityLink" legend:"plus" related:""` // entity_link
EntityPosition []*EntityPosition `json:"entityPosition" legend:"plus" related:""` // entity_position
EntityPositionAssignment []*EntityPositionAssignment `json:"entityPositionAssignment" legend:"plus" related:""` // entity_position_assignment
HistfigId []int `json:"histfigId" legend:"plus" related:""` // histfig_id
Honor []*Honor `json:"honor" legend:"base" related:""` // honor
Id_ int `json:"id" legend:"both" related:""` // id
Name_ string `json:"name" legend:"base" related:""` // name
Occasion []*Occasion `json:"occasion" legend:"plus" related:""` // occasion
Profession EntityProfession `json:"profession" legend:"plus" related:""` // profession
Race string `json:"race" legend:"plus" related:""` // race
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
Sites []int `json:"sites" legend:"add" related:""` // Sites
Wars []*HistoricalEventCollection `json:"wars" legend:"add" related:""` // Wars
}
func NewEntity() *Entity {
@ -2029,6 +2030,7 @@ func (x *Entity) MarshalJSON() ([]byte, error) {
d["weapon"] = x.Weapon
d["worshipId"] = x.WorshipId
d["sites"] = x.Sites
d["wars"] = x.Wars
return json.Marshal(d)
}
@ -4818,10 +4820,8 @@ func NewHistoricalEventAssumeIdentity() *HistoricalEventAssumeIdentity {
TricksterHfid: -1,
}
}
func (x *HistoricalEventAssumeIdentity) Type() string { return "assume identity" }
func (x *HistoricalEventAssumeIdentity) RelatedToEntity(id int) bool {
return x.IdentityId == id || x.TargetEnid == id
}
func (x *HistoricalEventAssumeIdentity) Type() string { return "assume identity" }
func (x *HistoricalEventAssumeIdentity) RelatedToEntity(id int) bool { return x.TargetEnid == id }
func (x *HistoricalEventAssumeIdentity) RelatedToHf(id int) bool { return x.TricksterHfid == id }
func (x *HistoricalEventAssumeIdentity) RelatedToArtifact(id int) bool { return false }
func (x *HistoricalEventAssumeIdentity) RelatedToSite(id int) bool { return false }
@ -9064,7 +9064,7 @@ func NewHistoricalEventFailedIntrigueCorruption() *HistoricalEventFailedIntrigue
}
func (x *HistoricalEventFailedIntrigueCorruption) Type() string { return "failed intrigue corruption" }
func (x *HistoricalEventFailedIntrigueCorruption) RelatedToEntity(id int) bool {
return x.CorruptorIdentity == id || x.RelevantEntityId == id || x.TargetIdentity == id
return x.RelevantEntityId == id
}
func (x *HistoricalEventFailedIntrigueCorruption) RelatedToHf(id int) bool {
return x.CorruptorHfid == id || x.LureHfid == id || x.TargetHfid == id
@ -12879,7 +12879,7 @@ func (x *HistoricalEventHfsFormedIntrigueRelationship) Type() string {
return "hfs formed intrigue relationship"
}
func (x *HistoricalEventHfsFormedIntrigueRelationship) RelatedToEntity(id int) bool {
return x.CorruptorIdentity == id || x.RelevantEntityId == id || x.TargetIdentity == id
return x.RelevantEntityId == id
}
func (x *HistoricalEventHfsFormedIntrigueRelationship) RelatedToHf(id int) bool {
return x.CorruptorHfid == id || x.LureHfid == id || x.TargetHfid == id
@ -13086,9 +13086,7 @@ func NewHistoricalEventHfsFormedReputationRelationship() *HistoricalEventHfsForm
func (x *HistoricalEventHfsFormedReputationRelationship) Type() string {
return "hfs formed reputation relationship"
}
func (x *HistoricalEventHfsFormedReputationRelationship) RelatedToEntity(id int) bool {
return x.IdentityId1 == id || x.IdentityId2 == id
}
func (x *HistoricalEventHfsFormedReputationRelationship) RelatedToEntity(id int) bool { return false }
func (x *HistoricalEventHfsFormedReputationRelationship) RelatedToHf(id int) bool {
return x.Hfid1 == id || x.Hfid2 == id
}
@ -18902,8 +18900,12 @@ 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
Necromancer bool `json:"necromancer" legend:"add" related:""` // Necromancer
NecromancerSince int `json:"necromancerSince" legend:"add" related:""` // NecromancerSince
Vampire bool `json:"vampire" legend:"add" related:""` // Vampire
VampireSince int `json:"vampireSince" legend:"add" related:""` // VampireSince
Werebeast bool `json:"werebeast" legend:"add" related:""` // Werebeast
WerebeastSince int `json:"werebeastSince" legend:"add" related:""` // WerebeastSince
}
func NewHistoricalFigure() *HistoricalFigure {
@ -18918,6 +18920,9 @@ func NewHistoricalFigure() *HistoricalFigure {
EntPopId: -1,
Id_: -1,
Sex: -1,
NecromancerSince: -1,
VampireSince: -1,
WerebeastSince: -1,
}
}
func (x *HistoricalFigure) Id() int { return x.Id_ }
@ -19017,8 +19022,18 @@ func (x *HistoricalFigure) MarshalJSON() ([]byte, error) {
d["sphere"] = x.Sphere
d["usedIdentityId"] = x.UsedIdentityId
d["vagueRelationship"] = x.VagueRelationship
d["necromancer"] = x.Necromancer
if x.NecromancerSince != -1 {
d["necromancerSince"] = x.NecromancerSince
}
d["vampire"] = x.Vampire
if x.VampireSince != -1 {
d["vampireSince"] = x.VampireSince
}
d["werebeast"] = x.Werebeast
if x.WerebeastSince != -1 {
d["werebeastSince"] = x.WerebeastSince
}
return json.Marshal(d)
}

View File

@ -1,6 +1,7 @@
package model
import (
"sort"
"strings"
"github.com/robertjanetzko/LegendsBrowser2/backend/util"
@ -19,6 +20,15 @@ func (w *DfWorld) process() {
w.processEvents()
w.processCollections()
w.processHistoricalFigures()
for _, e := range w.Entities {
idx := slices.Index(e.Child, e.Id_)
if idx != -1 {
e.Child = append(e.Child[:idx], e.Child[idx+1:]...)
}
sort.Slice(e.Wars, func(i, j int) bool { return e.Wars[i].Id_ < e.Wars[j].Id_ })
}
// check events texts
for _, e := range w.HistoricalEvents {
@ -32,9 +42,16 @@ func (w *DfWorld) processEvents() {
case *HistoricalEventHfDoesInteraction:
if strings.HasPrefix(d.Interaction, "DEITY_CURSE_WEREBEAST_") {
w.HistoricalFigures[d.TargetHfid].Werebeast = true
w.HistoricalFigures[d.TargetHfid].WerebeastSince = e.Year
}
if strings.HasPrefix(d.Interaction, "DEITY_CURSE_VAMPIRE_") {
w.HistoricalFigures[d.TargetHfid].Vampire = true
w.HistoricalFigures[d.TargetHfid].VampireSince = e.Year
}
case *HistoricalEventHfLearnsSecret:
if strings.HasPrefix(d.Interaction, "SECRET_") {
w.HistoricalFigures[d.StudentHfid].Necromancer = true
w.HistoricalFigures[d.StudentHfid].NecromancerSince = e.Year
}
case *HistoricalEventCreatedSite:
w.addEntitySite(d.CivId, d.SiteId)
@ -174,6 +191,13 @@ func (w *DfWorld) processCollections() {
}
}
}
case *HistoricalEventCollectionWar:
if e, ok := w.Entities[cd.AggressorEntId]; ok {
e.Wars = append(e.Wars, col)
}
if e, ok := w.Entities[cd.DefenderEntId]; ok {
e.Wars = append(e.Wars, col)
}
}
}
}
@ -202,3 +226,19 @@ func (w *DfWorld) addRelationshipEvents() {
}
}
}
func (w *DfWorld) processHistoricalFigures() {
// for _, hf := range w.HistoricalFigures {
// for _, i := range hf.ActiveInteraction {
// if strings.HasPrefix(i, "DEITY_CURSE_WEREBEAST_") {
// hf.Werebeast = true
// }
// if strings.HasPrefix(i, "DEITY_CURSE_VAMPIRE_") {
// hf.Vampire = true
// }
// if strings.HasPrefix(i, "SECRET_") {
// hf.Necromancer = true
// }
// }
// }
}

View File

@ -31,6 +31,7 @@ func (srv *DfServer) LoadTemplates() {
},
"hf": func(id int) template.HTML { return model.LinkHf(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) },
"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) },

View File

@ -3,22 +3,110 @@
{{define "title"}}{{ title .Name }}{{end}}
{{define "content"}}
<h1>{{ title .Name }}</h1>
{{ .Race }} {{ .Type }}
<h5>Sites</h5>
<table>
{{- range .Sites }}
<tr>
<td class="object" style="vertical-align: top;"> {{ site . }}</td>
<td> {{ template "events.html" events (history .) }}</td>
</tr>
<h3>{{ title .Name }}</h3>
<p>
{{ .Race }} {{ .Type }}
{{- if gt (len .WorshipId) 0 }}
centered around the worship of {{ hfList .WorshipId }}
{{- end }}
</table>
{{- if ne 0 (len .Sites) }}
{{- end }}
</p>
<h3>Events</h3>
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
{{- 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>
{{- 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>
{{- end}}
{{- if gt (len .Child) 0 }}
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#nav-children" type="button" role="tab">Groups</button>
{{- end}}
{{- if gt (len .Wars) 0 }}
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#nav-wars" type="button" role="tab">Wars</button>
{{- end}}
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
{{- if gt (len .Sites) 0 }}
<div class="tab-pane active" id="nav-sites" role="tabpanel">
<table class="table table-hover table-sm table-borderless">
<tr>
<th>Name</th>
<th width="100%">History</th>
</tr>
{{- range .Sites }}
<tr>
<td class="object" style="vertical-align: top;"> {{ site . }}</td>
<td> {{ template "events.html" events (history .) }}</td>
</tr>
{{- end}}
</table>
</div>
{{- end}}
{{- if gt (len .HistfigId) 0 }}
<div class="tab-pane" id="nav-members" role="tabpanel">
<table class="table table-hover table-sm table-borderless object-table">
<tr>
<th width="100%">Type</th>
</tr>
{{- range .HistfigId }}
<tr>
<td>{{ hf .}}</td>
</tr>
{{- end}}
</table>
</div>
{{- end}}
{{- if gt (len .Child) 0 }}
<div class="tab-pane" id="nav-children" role="tabpanel">
<table class="table table-hover table-sm table-borderless object-table">
<tr>
<th width="100%">Type</th>
</tr>
{{- range .Child }}
<tr>
<td>{{ entity .}}</td>
</tr>
{{- end}}
</table>
</div>
{{- end}}
{{- if gt (len .Wars) 0 }}
<div class="tab-pane" id="nav-wars" role="tabpanel">
<table class="table table-hover table-sm table-borderless object-table">
<tr>
<th>Year</th>
<th>Name</th>
<th width="100%">Enemy</th>
</tr>
{{- range .Wars }}
<tr>
<td>
{{- if eq .StartYear .EndYear}}
In {{ .StartYear }}
{{- else if eq .EndYear -1 }}
Since {{ .StartYear }}
{{- else }}
From {{ .StartYear }} till {{ .EndYear }}
{{- end }}
</td>
<td>{{ collection .Id}}</td>
<td>
{{- if eq $.Id .Details.AggressorEntId}}
attacking {{ entity .Details.DefenderEntId }}
{{- else }}
defending against {{ entity .Details.AggressorEntId }}
{{- end}}
</td>
</tr>
{{- end}}
</table>
</div>
{{- end}}
</div>
<h5>Events</h5>
{{ template "events.html" events . }}

View File

@ -2,7 +2,7 @@
{{- range $event := .Events }}
<li>
[{{ $event.Id }}] In {{ time $event.Year $event.Seconds72 }},
{{ html ($event.Details.Html $.Context) }}
{{ html ($event.Details.Html ($.Context.WithEvent $event)) }}
{{ if ne .Collection -1 }} <a class="collection" href="/collection/{{.Collection}}"><i
class="fa-solid fa-magnifying-glass fa-xs"></i></a>{{end}}
{{ json $event.Details }}

View File

@ -9,7 +9,11 @@
{{else}}
<i class="fa-solid fa-mars fa-xs"></i>
{{end}}
{{ .Race }} (*{{ .BirthYear }}{{ if ge .DeathYear 0 }} †{{ .DeathYear }}{{ end }})
{{ .Race }}
{{ if .Vampire}}vampire{{end}}
{{ if .Werebeast}}werebeast{{end}}
{{ if .Necromancer}}necromancer{{end}}
(*{{ .BirthYear }}{{ if ge .DeathYear 0 }} †{{ .DeathYear }}{{ end }})
<div class="row mt-3">
<div class="col-4">

View File

@ -1 +1,4 @@
{{ .Race }} {{ .Type }}
{{ .Race }} {{ .Type }}
{{- if gt (len .WorshipId) 0 }}
centered around the worship of {{ hfList .WorshipId }}
{{- end }}

View File

@ -27,7 +27,7 @@
{{- range .Structures }}
<tr>
<td>{{ structure $.Id .Id }}</td>
<td>{{ .Type }}</td>
<td>{{ .Type }}{{if .Ruin}} (ruin){{end}}</td>
</tr>
{{- end}}
</table>