first pass on move/explore logic

This commit is contained in:
Sky Johnson 2025-08-13 18:19:54 -05:00
parent cb532efc39
commit 71245b1655
5 changed files with 120 additions and 5 deletions

61
internal/actions/move.go Normal file
View File

@ -0,0 +1,61 @@
package actions
import (
"dk/internal/control"
"dk/internal/towns"
"dk/internal/users"
"fmt"
)
type Direction int
const (
North Direction = iota
East
South
West
)
func (d Direction) String() string {
switch d {
case North:
return "North"
case East:
return "East"
case South:
return "South"
case West:
return "West"
default:
return "Unknown"
}
}
func Move(user *users.User, dir Direction) (string, int, int, error) {
control, err := control.Get()
if err != nil {
panic("Move: CONTROL ROW SHOULD EXIST")
}
newX, newY := user.X, user.Y
switch dir {
case North:
newY++
case East:
newX++
case South:
newY--
case West:
newX--
}
if !control.IsWithinWorldBounds(newX, newY) {
return user.Currently, user.X, user.Y, fmt.Errorf("You've hit the edge of the world.")
}
if towns.ExistsAt(newX, newY) {
return "In Town", newX, newY, nil
}
return "Exploring", newX, newY, nil
}

View File

@ -1,9 +1,11 @@
package routes package routes
import ( import (
"dk/internal/actions"
"dk/internal/middleware" "dk/internal/middleware"
"dk/internal/router" "dk/internal/router"
"dk/internal/template/components" "dk/internal/template/components"
"strconv"
) )
func Index(ctx router.Ctx, _ []string) { func Index(ctx router.Ctx, _ []string) {
@ -11,8 +13,43 @@ func Index(ctx router.Ctx, _ []string) {
if user != nil { if user != nil {
if user.Currently == "In Town" { if user.Currently == "In Town" {
ctx.Redirect("/town", 303) ctx.Redirect("/town", 303)
return
} }
} }
components.RenderPage(ctx, "", "intro.html", nil) components.RenderPage(ctx, "", "intro.html", nil)
} }
func Move(ctx router.Ctx, _ []string) {
user := middleware.GetCurrentUser(ctx)
dir, err := strconv.Atoi(string(ctx.PostArgs().Peek("direction")))
if err != nil {
ctx.SetContentType("text/plain")
ctx.SetBodyString("move form parsing error")
return
}
currently, newX, newY, err := actions.Move(user, actions.Direction(dir))
if err != nil {
ctx.SetContentType("text/plain")
ctx.SetBodyString("move error: " + err.Error())
return
}
user.Set("Currently", currently)
user.Set("X", newX)
user.Set("Y", newY)
user.Save()
if currently == "In Town" {
ctx.Redirect("/town", 303)
return
}
ctx.Redirect("/explore", 303)
}
func Explore(ctx router.Ctx, _ []string) {
ctx.SetContentType("text/plain")
ctx.SetBodyString("Exploring")
}

View File

@ -40,6 +40,8 @@ func Start(port string) error {
r.Use(middleware.CSRF(auth.Manager)) r.Use(middleware.CSRF(auth.Manager))
r.Get("/", routes.Index) r.Get("/", routes.Index)
r.Get("/explore", routes.Explore)
r.Post("/move", routes.Move)
routes.RegisterAuthRoutes(r) routes.RegisterAuthRoutes(r)
routes.RegisterTownRoutes(r) routes.RegisterTownRoutes(r)

View File

@ -196,6 +196,20 @@ func ByCoords(x, y int) (*Town, error) {
return town, nil return town, nil
} }
// ExistsAt checks for a town at the given coordinates, returning true/false
func ExistsAt(x, y int) bool {
var exists bool
query := `SELECT COUNT(*) > 0 FROM towns WHERE x = ? AND y = ? LIMIT 1`
err := database.Query(query, func(stmt *sqlite.Stmt) error {
exists = stmt.ColumnInt(0) > 0
return nil
}, x, y)
return err == nil && exists
}
// Retrieves towns within a certain distance from a point // Retrieves towns within a certain distance from a point
func ByDistance(fromX, fromY, maxDistance int) ([]*Town, error) { func ByDistance(fromX, fromY, maxDistance int) ([]*Town, error) {
var towns []*Town var towns []*Town

View File

@ -9,16 +9,17 @@
{/if} {/if}
</b></div> </b></div>
<div>{user.X}{if user.X < 0}W{else}E{/if}, {user.Y}{if user.Y < 0}N{else}S{/if}</div> <div>{user.X}{if user.X < 0}W{else}E{/if}, {user.Y}{if user.Y < 0}N{else}S{/if}</div>
<a href="javascript:open_map_popup()">View Map</a> <a href="javascript:open_map_popup()">View Map</a>
<form id="move-compass" action="/move" method="post" > <form id="move-compass" action="/move" method="post" >
<button id="north" name="direction" value="north">North</button> {csrf}
<button id="north" name="direction" value="1">North</button>
<div class="mid"> <div class="mid">
<button id="west" name="direction" value="west">West</button> <button id="west" name="direction" value="4">West</button>
<button id="east" name="direction" value="east">East</button> <button id="east" name="direction" value="2">East</button>
</div> </div>
<button id="south" name="direction" value="south">South</button> <button id="south" name="direction" value="3">South</button>
</form> </form>
</section> </section>