From cb532efc399384e80a3b77c2cad87d38c101e360 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Wed, 13 Aug 2025 16:39:29 -0500 Subject: [PATCH] finish map buying --- assets/dk.css | 8 +-- internal/routes/town.go | 89 ++++++++++++++++++++++++++++- templates/town/maps.html | 119 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 7 deletions(-) create mode 100644 templates/town/maps.html diff --git a/assets/dk.css b/assets/dk.css index a08761a..a6c0206 100644 --- a/assets/dk.css +++ b/assets/dk.css @@ -32,7 +32,7 @@ h3 { font-size: 1.4rem; font-weight: bold; } h4 { font-size: 1.1rem; font-weight: bold; } div#container { - width: 90vw; + max-width: 1024px; display: flex; flex-direction: column; margin: 0px auto; @@ -357,13 +357,9 @@ table { } } -table.item-shop { +table.shop { width: 80%; margin: 0px auto; - - td:first-child { - width: fit-content; - } } div.modal { diff --git a/internal/routes/town.go b/internal/routes/town.go index 799bd10..296ecd4 100644 --- a/internal/routes/town.go +++ b/internal/routes/town.go @@ -14,6 +14,17 @@ import ( "strconv" ) +// Map acts as a representation of owned/unowned maps in the town stores. +type Map struct { + ID int + Name string + Cost int + Owned bool + X int + Y int + TP int +} + func RegisterTownRoutes(r *router.Router) { group := r.Group("/town") group.Use(middleware.RequireAuth()) @@ -21,9 +32,11 @@ func RegisterTownRoutes(r *router.Router) { group.Get("/", showTown) group.Get("/inn", showInn) - group.Get("/shop", showShop) group.WithMiddleware(middleware.CSRF(auth.Manager)).Post("/inn", rest) + group.Get("/shop", showShop) group.Get("/shop/buy/:id", buyItem) + group.Get("/maps", showMaps) + group.Get("/maps/buy/:id", buyMap) } func showTown(ctx router.Ctx, _ []string) { @@ -133,3 +146,77 @@ func buyItem(ctx router.Ctx, params []string) { ctx.Redirect("/town/shop", 302) } + +func showMaps(ctx router.Ctx, _ []string) { + var errorHTML string + if flash := auth.GetFlashMessage(ctx); flash != nil { + errorHTML = `
` + flash.Message + "
" + } + + town := ctx.UserValue("town").(*towns.Town) + user := ctx.UserValue("user").(*users.User) + + maplist := helpers.NewOrderedMap[int, Map]() + towns, _ := towns.All() + var mapped []int + if user.Towns != "" { + mapped = user.GetTownIDs() + } + for _, town := range towns { + var owned bool + if mapped != nil && slices.Contains(mapped, town.ID) { + owned = true + } else { + owned = false + } + + maplist.Set(town.ID, Map{ + ID: town.ID, + Name: town.Name, + Cost: town.MapCost, + Owned: owned, + X: town.X, + Y: town.Y, + TP: town.TPCost, + }) + } + + components.RenderPage(ctx, town.Name+" Maps", "town/maps.html", map[string]any{ + "town": town, + "maplist": maplist.ToSlice(), + "error_message": errorHTML, + }) +} + +func buyMap(ctx router.Ctx, params []string) { + id, err := strconv.Atoi(params[0]) + if err != nil { + auth.SetFlashMessage(ctx, "error", "Error purchasing map; "+err.Error()) + ctx.Redirect("/town/maps", 302) + return + } + + mapped, err := towns.Find(id) + if err != nil { + auth.SetFlashMessage(ctx, "error", "Error purchasing map; "+err.Error()) + ctx.Redirect("/town/maps", 302) + return + } + + user := ctx.UserValue("user").(*users.User) + if user.Gold < mapped.MapCost { + auth.SetFlashMessage(ctx, "error", "You don't have enough gold to buy the map to "+mapped.Name) + ctx.Redirect("/town/maps", 302) + return + } + + user.Set("Gold", user.Gold-mapped.MapCost) + if user.Towns == "" { + user.Set("Towns", params[0]) + } else { + user.Set("Towns", user.Towns+","+params[0]) + } + user.Save() + + ctx.Redirect("/town/maps", 302) +} diff --git a/templates/town/maps.html b/templates/town/maps.html new file mode 100644 index 0000000..4fbe26a --- /dev/null +++ b/templates/town/maps.html @@ -0,0 +1,119 @@ +{include "layout.html"} + +{block "content"} +
+

{town.Name} Maps

+ {error_message} +
+

Buying maps will put the town in your Travel To box, and it won't cost you as many TP to get there.

+

Click a town name to purchase its map.

+
+ +
+ + {for map in maplist} + + + + + {/for} +
+ {if map.Owned == false} + {if user.Gold >= map.Cost} + {map.Name} + {else} + {map.Name} + {/if} + {else} + {map.Name} + {/if} + + {if map.Owned == false} + {if user.Gold >= map.Cost} + {map.Cost}G + {else} + {map.Cost}G (can't afford) + {/if} + {else} + {map.X}, {map.Y}
+ TP Cost: {map.TP} + {/if} +
+
+ +
+

If you've changed your mind, you may also return back to town.

+
+ + +
+{/block} + +{block "scripts"} + +{/block}