structures, properties

This commit is contained in:
Robert Janetzko 2022-05-05 10:55:33 +00:00
parent 765a7cef2b
commit 093f7dacf9
20 changed files with 199 additions and 45 deletions

View file

@ -27,7 +27,8 @@
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"golang.Go",
"jinliming2.vscode-go-template"
"jinliming2.vscode-go-template",
"golang.go"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

View file

@ -8,7 +8,8 @@
"HistoricalEventDanceFormCreated.FormId": "danceForm",
"HistoricalEventMusicalFormCreated.FormId": "musicalForm",
"HistoricalEventPoeticFormCreated.FormId": "poeticForm",
"HistoricalEventHfReachSummit.MountainPeakId": "mountain"
"HistoricalEventHfReachSummit.MountainPeakId": "mountain",
"HistoricalEventBuildingProfileAcquired.StructureId": "structure"
},
"AdditionalFields": {
"DfWorld": [
@ -45,6 +46,10 @@
{
"Name": "SiteId",
"Type": "int"
},
{
"Name": "Ruin",
"Type": "bool"
}
],
"HistoricalFigure": [
@ -81,6 +86,12 @@
"Type": "HistoricalEventRelationshipRelationship"
}
],
"HistoricalEventBuildingProfileAcquired": [
{
"Name": "StructureId",
"Type": "int"
}
],
"HistoricalEventHfReachSummit": [
{
"Name": "MountainPeakId",
@ -128,6 +139,12 @@
"Name": "OccasionEventcol",
"Type": "int"
}
],
"WorldConstruction": [
{
"Name": "Parts",
"Type": "[]int"
}
]
}
}

View file

@ -12,5 +12,5 @@ buildMacOs:
genisoimage -D -V "LegendsBrowser" -no-pad -r -apple -o /tmp/build/uncompressed.dmg /tmp/build/macos
dmg dmg /tmp/build/uncompressed.dmg ../bin/LegendsBrowser.dmg
run:
cd backend && go run main.go
runLast:
go run main.go -c conf.json -l=true

5
backend/conf.json Normal file
View file

@ -0,0 +1,5 @@
{
"LastPath": "/workspaces/legendsbrowser/inputs",
"LastFile": "/workspaces/legendsbrowser/inputs/Stalkmatches-00254-08-26-legends.xml",
"DebugTemplates": true
}

View file

@ -20,7 +20,8 @@ var static embed.FS
func main() {
f := flag.String("f", "", "open a file")
p := flag.Bool("p", false, "start profiling")
d := flag.Bool("d", false, "debug templates")
c := flag.String("c", "", "config file")
l := flag.Bool("l", false, "open last file")
flag.Parse()
if *p {
@ -30,10 +31,19 @@ func main() {
}()
}
templates.DebugTemplates = *d
config, err := server.LoadConfig(*c)
if err != nil {
log.Fatal(err)
}
templates.DebugTemplates = config.DebugTemplates
var world *model.DfWorld
if *l {
*f = config.LastFile
}
if len(*f) > 0 {
w, err := model.Parse(*f, nil)
if err != nil {
@ -44,7 +54,7 @@ func main() {
world = w
}
err := server.StartServer(world, static)
err = server.StartServer(config, world, static)
if err != nil {
log.Fatal(err)
}

View file

@ -115,7 +115,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" href="/site/%d"><i class="%s fa-xs"></i> %s</a>`, prefix, x.Id(), x.Icon(), util.Title(x.Name()))
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 "UNKNOWN SITE"
}
@ -123,7 +123,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" href="/site/%d/structure/%d"><i class="%s fa-xs"></i> %s</a>`, siteId, structureId, y.Icon(), util.Title(y.Name()))
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 "UNKNOWN STRUCTURE"

View file

@ -407,8 +407,17 @@ func (x *HistoricalEventBodyAbused) Html(c *Context) string {
}
func (x *HistoricalEventBuildingProfileAcquired) Html(c *Context) string {
return util.If(x.AcquirerEnid != -1, c.entity(x.AcquirerEnid), c.hf(x.AcquirerHfid)) +
util.If(x.PurchasedUnowned, " purchased ", " inherited ") +
mode := " acquired "
switch {
case x.PurchasedUnowned:
mode = " purchased "
case x.RebuiltRuined:
mode = " rebuilt "
case x.Inherited:
mode = " iinherited "
}
return util.If(x.AcquirerEnid != -1, c.entity(x.AcquirerEnid), c.hf(x.AcquirerHfid)) + mode +
c.property(x.SiteId, x.BuildingProfileId) + c.site(x.SiteId, " in") +
util.If(x.LastOwnerHfid != -1, " formerly owned by "+c.hfRelated(x.LastOwnerHfid, x.AcquirerHfid), "")
}

View file

@ -5245,14 +5245,15 @@ func (x *HistoricalEventBodyAbused) MarshalJSON() ([]byte, error) {
}
type HistoricalEventBuildingProfileAcquired struct {
AcquirerEnid int `json:"acquirerEnid" legend:"base" related:""` // acquirer_enid
AcquirerHfid int `json:"acquirerHfid" legend:"base" related:""` // acquirer_hfid
BuildingProfileId int `json:"buildingProfileId" legend:"base" related:""` // building_profile_id
Inherited bool `json:"inherited" legend:"base" related:""` // inherited
LastOwnerHfid int `json:"lastOwnerHfid" legend:"base" related:""` // last_owner_hfid
PurchasedUnowned bool `json:"purchasedUnowned" legend:"base" related:""` // purchased_unowned
RebuiltRuined bool `json:"rebuiltRuined" legend:"base" related:""` // rebuilt_ruined
SiteId int `json:"siteId" legend:"base" related:""` // site_id
AcquirerEnid int `json:"acquirerEnid" legend:"base" related:""` // acquirer_enid
AcquirerHfid int `json:"acquirerHfid" legend:"base" related:""` // acquirer_hfid
BuildingProfileId int `json:"buildingProfileId" legend:"base" related:""` // building_profile_id
Inherited bool `json:"inherited" legend:"base" related:""` // inherited
LastOwnerHfid int `json:"lastOwnerHfid" legend:"base" related:""` // last_owner_hfid
PurchasedUnowned bool `json:"purchasedUnowned" legend:"base" related:""` // purchased_unowned
RebuiltRuined bool `json:"rebuiltRuined" legend:"base" related:""` // rebuilt_ruined
SiteId int `json:"siteId" legend:"base" related:""` // site_id
StructureId int `json:"structureId" legend:"add" related:"structure"` // StructureId
}
func NewHistoricalEventBuildingProfileAcquired() *HistoricalEventBuildingProfileAcquired {
@ -5262,6 +5263,7 @@ func NewHistoricalEventBuildingProfileAcquired() *HistoricalEventBuildingProfile
BuildingProfileId: -1,
LastOwnerHfid: -1,
SiteId: -1,
StructureId: -1,
}
}
func (x *HistoricalEventBuildingProfileAcquired) Type() string { return "building profile acquired" }
@ -5274,7 +5276,7 @@ func (x *HistoricalEventBuildingProfileAcquired) RelatedToHf(id int) bool {
func (x *HistoricalEventBuildingProfileAcquired) RelatedToArtifact(id int) bool { return false }
func (x *HistoricalEventBuildingProfileAcquired) RelatedToSite(id int) bool { return x.SiteId == id }
func (x *HistoricalEventBuildingProfileAcquired) RelatedToStructure(siteId, id int) bool {
return false
return x.RelatedToSite(siteId) && (x.StructureId == id)
}
func (x *HistoricalEventBuildingProfileAcquired) RelatedToRegion(id int) bool { return false }
func (x *HistoricalEventBuildingProfileAcquired) RelatedToWorldConstruction(id int) bool {
@ -5309,6 +5311,9 @@ func (x *HistoricalEventBuildingProfileAcquired) MarshalJSON() ([]byte, error) {
if x.SiteId != -1 {
d["siteId"] = x.SiteId
}
if x.StructureId != -1 {
d["structureId"] = x.StructureId
}
return json.Marshal(d)
}
@ -21447,6 +21452,7 @@ type Structure struct {
Subtype StructureSubtype `json:"subtype" legend:"base" related:""` // subtype
Type_ StructureType `json:"type" legend:"both" related:""` // type
WorshipHfid int `json:"worshipHfid" legend:"base" related:""` // worship_hfid
Ruin bool `json:"ruin" legend:"add" related:""` // Ruin
SiteId int `json:"siteId" legend:"add" related:""` // SiteId
}
@ -21542,6 +21548,7 @@ func (x *Structure) MarshalJSON() ([]byte, error) {
if x.WorshipHfid != -1 {
d["worshipHfid"] = x.WorshipHfid
}
d["ruin"] = x.Ruin
if x.SiteId != -1 {
d["siteId"] = x.SiteId
}
@ -21708,6 +21715,7 @@ type WorldConstruction struct {
Id_ int `json:"id" legend:"plus" related:""` // id
Name_ string `json:"name" legend:"plus" related:""` // name
Type_ WorldConstructionType `json:"type" legend:"plus" related:""` // type
Parts []int `json:"parts" legend:"add" related:""` // Parts
}
func NewWorldConstruction() *WorldConstruction {
@ -21732,6 +21740,7 @@ func (x *WorldConstruction) MarshalJSON() ([]byte, error) {
if x.Type_ != 0 {
d["type"] = x.Type_
}
d["parts"] = x.Parts
return json.Marshal(d)
}

View file

@ -39,6 +39,7 @@ func (w *DfWorld) processEvents() {
case *HistoricalEventCreatedSite:
w.addEntitySite(d.CivId, d.SiteId)
w.addEntitySite(d.SiteCivId, d.SiteId)
w.Sites[d.SiteId].Ruin = false
case *HistoricalEventDestroyedSite:
w.addEntitySite(d.DefenderCivId, d.SiteId)
w.addEntitySite(d.SiteCivId, d.SiteId)
@ -48,6 +49,7 @@ func (w *DfWorld) processEvents() {
w.addEntitySite(d.SiteCivId, d.SiteId)
w.addEntitySite(d.DefenderCivId, d.SiteId)
w.addEntitySite(d.NewSiteCivId, d.SiteId)
w.Sites[d.SiteId].Ruin = false
case *HistoricalEventHfDestroyedSite:
w.addEntitySite(d.SiteCivId, d.SiteId)
w.addEntitySite(d.DefenderCivId, d.SiteId)
@ -74,6 +76,31 @@ func (w *DfWorld) processEvents() {
case *HistoricalEventHfReachSummit:
id, _, _ := util.FindInMap(w.MountainPeaks, func(m *MountainPeak) bool { return m.Coords == d.Coords })
d.MountainPeakId = id
case *HistoricalEventCreatedWorldConstruction:
if master, ok := w.WorldConstructions[d.MasterWcid]; ok {
master.Parts = append(master.Parts, d.Wcid)
}
case *HistoricalEventBuildingProfileAcquired:
if site, ok := w.Sites[d.SiteId]; ok {
if property, ok := site.SiteProperties[d.BuildingProfileId]; ok {
if structure, ok := site.Structures[property.StructureId]; ok {
structure.Ruin = false
}
d.StructureId = property.StructureId
}
}
case *HistoricalEventRazedStructure:
if site, ok := w.Sites[d.SiteId]; ok {
if structure, ok := site.Structures[d.StructureId]; ok {
structure.Ruin = true
}
}
case *HistoricalEventReplacedStructure:
if site, ok := w.Sites[d.SiteId]; ok {
if structure, ok := site.Structures[d.OldAbId]; ok {
structure.Ruin = true
}
}
}
}
}

View file

@ -9,14 +9,20 @@ import (
)
type Config struct {
LastPath string
LastFile string
path string
LastPath string
LastFile string
DebugTemplates bool `json:"DebugTemplates,omitempty"`
}
func LoadConfig() (*Config, error) {
path, err := configPath()
if err != nil {
return nil, err
func LoadConfig(path string) (*Config, error) {
var err error
if path == "" {
path, err = configPath()
if err != nil {
return nil, err
}
}
data, err := ioutil.ReadFile(path)
@ -29,7 +35,7 @@ func LoadConfig() (*Config, error) {
return nil, err
}
return &Config{LastPath: home}, nil
return &Config{LastPath: home, path: path}, nil
} else {
return nil, err
}
@ -37,13 +43,20 @@ func LoadConfig() (*Config, error) {
c := &Config{}
json.Unmarshal(data, c)
c.path = path
return c, nil
}
func (c *Config) Save() error {
path, err := configPath()
if err != nil {
return err
var err error
path := c.path
if path == "" {
path, err = configPath()
if err != nil {
return err
}
}
file, err := json.MarshalIndent(c, "", " ")

View file

@ -89,6 +89,9 @@ func (h loadHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
return
} else {
h.server.context.config.LastFile = p.Current
h.server.context.config.Save()
h.server.context.isLoading = true
h.server.context.world = nil
go loadWorld(h.server, p.Current)

View file

@ -28,12 +28,7 @@ type DfServer struct {
context *DfServerContext
}
func StartServer(world *model.DfWorld, static embed.FS) error {
config, err := LoadConfig()
if err != nil {
return err
}
func StartServer(config *Config, world *model.DfWorld, static embed.FS) error {
srv := &DfServer{
router: mux.NewRouter().StrictSlash(true),
context: &DfServerContext{

View file

@ -39,8 +39,8 @@ func (srv *DfServer) LoadTemplates() {
"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) },
"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) },
"getWorldconstruction": func(id int) *model.WorldConstruction { return srv.context.world.WorldConstructions[id] },
"worldConstruction": func(id int) template.HTML { return model.LinkWorldConstruction(srv.context.world, id) },
"getWorldConstruction": func(id int) *model.WorldConstruction { return srv.context.world.WorldConstructions[id] },
"artifact": func(id int) template.HTML { return model.LinkArtifact(srv.context.world, id) },
"getArtifact": func(id int) *model.Artifact { return srv.context.world.Artifacts[id] },
"danceForm": func(id int) template.HTML { return model.LinkDanceForm(srv.context.world, id) },

View file

@ -34,6 +34,14 @@ td.object {
color: #bbb;
}
.site.ruin {
color: #b4a675;
}
.structure.ruin {
color: #94702a;
}
.worldconstruction {
color: #777777;
}

View file

@ -1 +1 @@
{{ .Type }} in {{ site .SiteId }}
{{ .Type }}{{if .Ruin}} (ruin){{end}} in {{ site .SiteId }}

View file

@ -58,7 +58,7 @@
<div class="col-4">
<h5>WorldConstructions</h5>
<ul>
{{range .WorldConstructions}}<li>{{ worldconstruction .Id }}</li>{{end}}
{{range .WorldConstructions}}<li>{{ worldConstruction .Id }}</li>{{end}}
</ul>
</div>
{{- end}}

View file

@ -4,7 +4,53 @@
{{define "content"}}
<h3>{{ title .Name }}</h3>
{{ .Type_ }}
<p>{{ .Type_ }}</p>
<nav>
<div class="nav nav-tabs" id="nav-tab" role="tablist">
{{- if gt (len .Structures) 0 }}
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#nav-structures" type="button" role="tab">Structures</button>
{{- end}}
{{- if gt (len .SiteProperties) 0 }}
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#nav-site-properties" type="button" role="tab">Properties</button>
{{- end}}
</div>
</nav>
<div class="tab-content" id="nav-tabContent">
{{- if gt (len .Structures) 0 }}
<div class="tab-pane active" id="nav-structures" role="tabpanel">
<table class="table table-hover table-sm table-borderless object-table">
<tr>
<th>Name</th>
<th width="100%">Type</th>
</tr>
{{- range .Structures }}
<tr>
<td>{{ structure $.Id .Id }}</td>
<td>{{ .Type }}</td>
</tr>
{{- end}}
</table>
</div>
{{- end}}
{{- if gt (len .SiteProperties) 0 }}
<div class="tab-pane" id="nav-site-properties" role="tabpanel">
<table class="table table-hover table-sm table-borderless object-table">
<tr>
<th>Type</th>
<th width="100%">Name or Owner</th>
</tr>
{{- range .SiteProperties }}
<tr>
<td>{{ if ne .StructureId -1 }}{{ structure $.Id .StructureId }}{{else}}{{ .Type_ }}{{end}}</td>
<td>{{ if ne .OwnerHfid -1 }}{{ hf .OwnerHfid }}{{else}}no
owner{{ end }}</td>
</tr>
{{- end}}
</table>
</div>
{{- end}}
</div>
<h5 class="mt-3">Events</h5>
{{ template "events.html" events . }}

View file

@ -19,12 +19,14 @@
<table class="table table-hover table-sm table-borderless object-table">
<tr>
<th width="100%">Name</th>
<th>Size</th>
<th>Structures</th>
<th>Properties</th>
</tr>
{{- range $v }}{{- if not (eq .Name "") }}
<tr>
<td>{{ site .Id }}</td>
<td></td>
<td>{{ len .Structures }}</td>
<td>{{ len .SiteProperties }}</td>
</tr>
{{- end}}{{- end}}
</table>

View file

@ -5,8 +5,17 @@
{{define "content"}}
<h3>{{ title .Name }}</h3>
<p>{{ .Type }}</p>
<h5>Events</h5>
{{- if gt (len .Parts) 0 }}
<h5>Parts</h5>
<ul>
{{- range .Parts }}
<li>{{ worldConstruction . }}</li>
{{- end }}
</ul>
{{- end }}
<h5>Events</h5>
{{ template "events.html" events . }}
<p>{{ json . }}</p>

View file

@ -23,7 +23,7 @@
</tr>
{{- range $v }}{{- if not (eq .Name "") }}
<tr>
<td>{{ worldconstruction .Id }}</td>
<td>{{ worldConstruction .Id }}</td>
<td></td>
</tr>
{{- end}}{{- end}}