world map
This commit is contained in:
parent
190dfdd037
commit
eb269cc580
8 changed files with 264 additions and 8 deletions
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"embed"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
|
@ -47,11 +48,11 @@ func main() {
|
|||
if len(*f) > 0 {
|
||||
w, err := model.Parse(*f, nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
fmt.Println(err)
|
||||
} else {
|
||||
runtime.GC()
|
||||
world = w
|
||||
}
|
||||
|
||||
runtime.GC()
|
||||
world = w
|
||||
}
|
||||
|
||||
err = server.StartServer(config, world, static)
|
||||
|
|
|
@ -6,6 +6,8 @@ import (
|
|||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/robertjanetzko/LegendsBrowser2/backend/util"
|
||||
)
|
||||
|
||||
var LinkHf = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).hf(id)) }
|
||||
|
@ -30,6 +32,47 @@ var LinkMountain = func(w *DfWorld, id int) template.HTML { return template.HTML
|
|||
var LinkLandmass = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).landmass(id)) }
|
||||
var LinkRiver = func(w *DfWorld, id int) template.HTML { return template.HTML((&Context{World: w}).river(id)) }
|
||||
|
||||
var AddMapLandmass = func(w *DfWorld, id int) template.HTML {
|
||||
if x, ok := w.Landmasses[id]; ok {
|
||||
c1 := strings.Split(x.Coord1, ",")
|
||||
x1, _ := strconv.Atoi(c1[0])
|
||||
y1, _ := strconv.Atoi(c1[1])
|
||||
c2 := strings.Split(x.Coord2, ",")
|
||||
x2, _ := strconv.Atoi(c2[0])
|
||||
y2, _ := strconv.Atoi(c2[1])
|
||||
return template.HTML(fmt.Sprintf(`<script>addRegion('%s', %d, %d, %d, %d, '#FFF')</script>`, x.Name_, x1, y1, x2, y2))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var AddMapRegion = func(w *DfWorld, id int) template.HTML {
|
||||
if x, ok := w.Regions[id]; ok {
|
||||
r := "<script>"
|
||||
r += "var polygon = L.polygon(["
|
||||
r += strings.Join(util.Map(x.Outline(), func(c Coord) string { return fmt.Sprintf(`coord(%d,%d)`, c.X, c.Y-1) }), ",")
|
||||
r += "], { color : '#fff', opacity: 1, fillOpacity: 0, weight : 1 }).addTo(regionsLayer);\n"
|
||||
r += "attachTooltip(polygon, '" + x.Name_ + "');\n"
|
||||
|
||||
r += "polygon.on('mouseover', function (e) { this.setStyle({weight: 10}); });\n"
|
||||
r += "polygon.on('mouseout', function (e) { this.setStyle({ weight: 3}); });\n"
|
||||
|
||||
fillColor := "transparent"
|
||||
switch x.Evilness {
|
||||
case RegionEvilness_Evil:
|
||||
fillColor = "fuchsia"
|
||||
case RegionEvilness_Good:
|
||||
fillColor = "aqua"
|
||||
}
|
||||
if fillColor != "transparent" {
|
||||
r += "var evilPolygon = L.polygon(polygon.getLatLngs(), { color: 'transparent', opacity: 1, fillColor: '" + fillColor + "', fillOpacity: .3, interactive: false });\n"
|
||||
r += "evilPolygon.addTo(evilnessLayer);\n"
|
||||
}
|
||||
r += "</script>"
|
||||
return template.HTML(r)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var AddMapSite = func(w *DfWorld, id int) template.HTML {
|
||||
if site, ok := w.Sites[id]; ok {
|
||||
coords := strings.Split(site.Rectangle, ":")
|
||||
|
@ -45,6 +88,41 @@ var AddMapSite = func(w *DfWorld, id int) template.HTML {
|
|||
}
|
||||
}
|
||||
|
||||
var AddMapMountain = func(w *DfWorld, id int) template.HTML {
|
||||
if m, ok := w.MountainPeaks[id]; ok {
|
||||
c1 := strings.Split(m.Coords, ",")
|
||||
x, _ := strconv.Atoi(c1[0])
|
||||
y, _ := strconv.Atoi(c1[1])
|
||||
return template.HTML(fmt.Sprintf(`<script>addMountain('%s', %d, %d, '#666')</script>`, m.Name_, x, y))
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var AddMapWorldConstruction = func(w *DfWorld, id int) template.HTML {
|
||||
if x, ok := w.WorldConstructions[id]; ok {
|
||||
color := util.If(x.Type_ == WorldConstructionType_Tunnel, "#000", "#fff")
|
||||
line := x.Line()
|
||||
if len(line) == 1 {
|
||||
return template.HTML(fmt.Sprintf(`<script>addWc('%s', %d, %d, '%s')</script>`, x.Name_, line[0].X, line[0].Y, color))
|
||||
} else {
|
||||
r := "<script>"
|
||||
r += "var polyline = L.polyline(["
|
||||
r += strings.Join(util.Map(x.Line(), func(c Coord) string { return fmt.Sprintf(`coord(%d+0.5,%d-0.5)`, c.X, c.Y) }), ",")
|
||||
r += "], {color: '" + color + "', opacity: 1, weight: 3}).addTo(constructionsLayer);\n"
|
||||
r += "attachTooltip(polyline, '" + x.Name_ + "');\n"
|
||||
r += "polyline.on('mouseover', function (e) { this.setStyle({weight: 10}); });\n"
|
||||
r += "polyline.on('mouseout', function (e) { this.setStyle({ weight: 3}); });\n"
|
||||
r += "</script>"
|
||||
return template.HTML(r)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var AddMapRiver = func(w *DfWorld, id int) template.HTML {
|
||||
return ""
|
||||
}
|
||||
|
||||
var AndList = func(s []string) template.HTML { return template.HTML(andList(s)) }
|
||||
|
||||
func andList(list []string) string {
|
||||
|
|
|
@ -87,3 +87,115 @@ func (w *DfWorld) LoadDimensions() {
|
|||
w.Width, _ = strconv.Atoi(result[0][2])
|
||||
w.Height, _ = strconv.Atoi(result[0][1])
|
||||
}
|
||||
|
||||
type Coord struct {
|
||||
X, Y int
|
||||
}
|
||||
|
||||
func Coords(s string) []Coord {
|
||||
var coords []Coord
|
||||
for _, c := range strings.Split(s, "|") {
|
||||
if c == "" {
|
||||
continue
|
||||
}
|
||||
d := strings.Split(c, ",")
|
||||
x, _ := strconv.Atoi(d[0])
|
||||
y, _ := strconv.Atoi(d[1])
|
||||
coords = append(coords, Coord{X: x, Y: y})
|
||||
}
|
||||
return coords
|
||||
}
|
||||
|
||||
func maxCoords(coords []Coord) Coord {
|
||||
var max Coord
|
||||
for _, c := range coords {
|
||||
if c.X > max.X {
|
||||
max.X = c.X
|
||||
}
|
||||
if c.Y > max.Y {
|
||||
max.Y = c.Y
|
||||
}
|
||||
}
|
||||
return max
|
||||
}
|
||||
|
||||
func (r *Region) Outline() []Coord {
|
||||
var outline []Coord
|
||||
// if (cacheOutline != null)
|
||||
// return cacheOutline;
|
||||
|
||||
/* draw the region in a matrix */
|
||||
coords := Coords(r.Coords)
|
||||
max := maxCoords(coords)
|
||||
|
||||
var region = make([][]bool, max.X+3)
|
||||
for i := range region {
|
||||
region[i] = make([]bool, max.Y+3)
|
||||
}
|
||||
for _, c := range coords {
|
||||
region[c.X+1][c.Y+1] = true
|
||||
}
|
||||
|
||||
var curdir, prevdir rune
|
||||
curdir = 'n'
|
||||
if len(coords) == 1 || coords[0].X == coords[1].X-1 {
|
||||
curdir = 'e'
|
||||
}
|
||||
|
||||
x0 := coords[0].X + 1
|
||||
y0 := coords[0].Y + 1
|
||||
x := x0
|
||||
y := y0
|
||||
|
||||
/* follow the outline by keeping the right hand inside */
|
||||
Loop:
|
||||
for {
|
||||
if !(x != x0 || y != y0 || prevdir == 0) {
|
||||
break Loop
|
||||
}
|
||||
|
||||
prevdir = curdir
|
||||
switch {
|
||||
case curdir == 'n' && y > 1:
|
||||
y -= 1
|
||||
if region[x-1][y-1] {
|
||||
curdir = 'w'
|
||||
} else if !region[x][y-1] {
|
||||
curdir = 'e'
|
||||
}
|
||||
case curdir == 's' && y < max.Y+2:
|
||||
y += 1
|
||||
if region[x][y] {
|
||||
curdir = 'e'
|
||||
} else if !region[x-1][y] {
|
||||
curdir = 'w'
|
||||
}
|
||||
case curdir == 'w' && x > 1:
|
||||
x -= 1
|
||||
if region[x-1][y] {
|
||||
curdir = 's'
|
||||
} else if !region[x-1][y-1] {
|
||||
curdir = 'n'
|
||||
}
|
||||
case curdir == 'e' && x < max.X+2:
|
||||
x += 1
|
||||
if region[x][y-1] {
|
||||
curdir = 'n'
|
||||
} else if !region[x][y] {
|
||||
curdir = 's'
|
||||
}
|
||||
}
|
||||
if curdir != prevdir {
|
||||
/* change of direction: record point */
|
||||
outline = append(outline, Coord{X: x - 1, Y: y - 1})
|
||||
if len(outline) > 256*10 {
|
||||
break Loop
|
||||
}
|
||||
}
|
||||
}
|
||||
return outline
|
||||
}
|
||||
|
||||
func (x *WorldConstruction) Line() []Coord {
|
||||
return Coords(x.Coords)
|
||||
}
|
||||
|
|
|
@ -46,9 +46,10 @@ func (w *DfWorld) process() {
|
|||
}
|
||||
|
||||
// check events texts
|
||||
for _, e := range w.HistoricalEvents {
|
||||
e.Details.Html(&Context{World: w})
|
||||
}
|
||||
// for _, e := range w.HistoricalEvents {
|
||||
// e.Details.Html(&Context{World: w})
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
func (w *DfWorld) processEvents() {
|
||||
|
|
|
@ -124,6 +124,24 @@ func StartServer(config *Config, world *model.DfWorld, static embed.FS) error {
|
|||
srv.RegisterWorldResourcePage("/collection/{id}", "collection.html", func(id int) any { return srv.context.world.HistoricalEventCollections[id] })
|
||||
srv.RegisterWorldResourcePage("/popover/collection/{id}", "popoverCollection.html", func(id int) any { return srv.context.world.HistoricalEventCollections[id] })
|
||||
|
||||
srv.RegisterWorldPage("/worldmap", "worldMap.html", func(p Parms) any {
|
||||
return &struct {
|
||||
Landmasses map[int]*model.Landmass
|
||||
Regions map[int]*model.Region
|
||||
Sites map[int]*model.Site
|
||||
MountainPeaks map[int]*model.MountainPeak
|
||||
WorldConstructions map[int]*model.WorldConstruction
|
||||
Rivers []*model.River
|
||||
}{
|
||||
Landmasses: srv.context.world.Landmasses,
|
||||
Regions: srv.context.world.Regions,
|
||||
Sites: srv.context.world.Sites,
|
||||
MountainPeaks: srv.context.world.MountainPeaks,
|
||||
WorldConstructions: srv.context.world.WorldConstructions,
|
||||
Rivers: srv.context.world.Rivers,
|
||||
}
|
||||
})
|
||||
|
||||
srv.RegisterWorldPage("/", "index.html", func(p Parms) any {
|
||||
return &struct {
|
||||
Civilizations map[string][]*model.Entity
|
||||
|
|
|
@ -37,7 +37,6 @@ func (srv *DfServer) LoadTemplates() {
|
|||
"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) },
|
||||
"addSite": func(id int) template.HTML { return model.AddMapSite(srv.context.world, 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) },
|
||||
|
@ -53,6 +52,14 @@ func (srv *DfServer) LoadTemplates() {
|
|||
"landmass": func(id int) template.HTML { return model.LinkLandmass(srv.context.world, id) },
|
||||
"mountain": func(id int) template.HTML { return model.LinkMountain(srv.context.world, id) },
|
||||
"river": func(id int) template.HTML { return model.LinkRiver(srv.context.world, id) },
|
||||
|
||||
"addLandmass": func(id int) template.HTML { return model.AddMapLandmass(srv.context.world, id) },
|
||||
"addRegion": func(id int) template.HTML { return model.AddMapRegion(srv.context.world, id) },
|
||||
"addSite": func(id int) template.HTML { return model.AddMapSite(srv.context.world, id) },
|
||||
"addMountain": func(id int) template.HTML { return model.AddMapMountain(srv.context.world, id) },
|
||||
"addWorldConstruction": func(id int) template.HTML { return model.AddMapWorldConstruction(srv.context.world, id) },
|
||||
"addRiver": func(id int) template.HTML { return model.AddMapRiver(srv.context.world, id) },
|
||||
|
||||
"events": func(obj any) *model.EventList {
|
||||
return model.NewEventList(srv.context.world, obj)
|
||||
},
|
||||
|
|
|
@ -3,6 +3,11 @@ a {
|
|||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.leaflet-container {
|
||||
background: rgba(122, 122, 122, 0.1) !important;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.popover {
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
|
34
backend/templates/worldMap.html
Normal file
34
backend/templates/worldMap.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
{{template "layout.html" .}}
|
||||
|
||||
{{define "title"}}Legends Browser{{end}}
|
||||
|
||||
{{define "content"}}
|
||||
|
||||
<div id="map" style="width: 100%; height: 1000px"></div>
|
||||
{{initMap}}
|
||||
|
||||
{{- range .Landmasses }}
|
||||
{{ addLandmass .Id }}
|
||||
{{- end }}
|
||||
|
||||
{{- range .Regions }}
|
||||
{{ addRegion .Id }}
|
||||
{{- end }}
|
||||
|
||||
{{- range .Sites }}
|
||||
{{ addSite .Id }}
|
||||
{{- end }}
|
||||
|
||||
{{- range .MountainPeaks }}
|
||||
{{ addMountain .Id }}
|
||||
{{- end }}
|
||||
|
||||
{{- range .WorldConstructions }}
|
||||
{{ addWorldConstruction .Id }}
|
||||
{{- end }}
|
||||
|
||||
{{- range $id, $r := .Rivers }}
|
||||
{{ addRiver $id }}
|
||||
{{- end }}
|
||||
|
||||
{{- end }}
|
Loading…
Reference in a new issue