diff --git a/data/dk.db b/data/dk.db index 11508ac..1616cbd 100644 Binary files a/data/dk.db and b/data/dk.db differ diff --git a/internal/components/asides.go b/internal/components/asides.go index 7c62a4e..e5cfd89 100644 --- a/internal/components/asides.go +++ b/internal/components/asides.go @@ -45,6 +45,7 @@ func RightAside(ctx sushi.Ctx) map[string]any { } user := ctx.GetCurrentUser().(*users.User) + data["_class"] = user.Class() data["_expprog"] = fmt.Sprintf("%.1f", user.ExpProgress()) diff --git a/internal/models/classes/classes.go b/internal/models/classes/class.go similarity index 64% rename from internal/models/classes/classes.go rename to internal/models/classes/class.go index 8e60112..67b0626 100644 --- a/internal/models/classes/classes.go +++ b/internal/models/classes/class.go @@ -6,7 +6,7 @@ import ( "strings" ) -type Classes struct { +type Class struct { ID int Name string Lore string @@ -20,8 +20,8 @@ type Classes struct { RateDEX int } -func New() *Classes { - return &Classes{ +func New() *Class { + return &Class{ BaseHP: 15, BaseMP: 10, BaseSTR: 1, @@ -33,7 +33,7 @@ func New() *Classes { } } -func (c *Classes) Validate() error { +func (c *Class) Validate() error { if strings.TrimSpace(c.Name) == "" { return fmt.Errorf("class name cannot be empty") } @@ -64,6 +64,30 @@ func (c *Classes) Validate() error { return nil } -func (c *Classes) Delete() error { +func (c *Class) Delete() error { return database.Exec("DELETE FROM classes WHERE id = %d", c.ID) } + +func (c *Class) Insert() error { + id, err := database.Insert("classes", c, "id") + if err != nil { + return err + } + c.ID = int(id) + return nil +} + +func Find(id int) (*Class, error) { + var class Class + err := database.Get(&class, "SELECT * FROM classes WHERE id = %d", id) + if err != nil { + return nil, fmt.Errorf("class with ID %d not found", id) + } + return &class, nil +} + +func All() ([]*Class, error) { + var classes []*Class + err := database.Select(&classes, "SELECT * FROM classes ORDER BY id DESC") + return classes, err +} diff --git a/internal/models/users/users.go b/internal/models/users/users.go index 5e6c621..da68bbe 100644 --- a/internal/models/users/users.go +++ b/internal/models/users/users.go @@ -9,6 +9,7 @@ import ( "dk/internal/database" "dk/internal/helpers" "dk/internal/helpers/exp" + "dk/internal/models/classes" ) // User represents a user in the game @@ -138,14 +139,6 @@ func Find(id int) (*User, error) { return &user, nil } -func GetByID(id int) *User { - user, err := Find(id) - if err != nil { - return nil - } - return user -} - func All() ([]*User, error) { var users []*User err := database.Select(&users, "SELECT * FROM users ORDER BY registered DESC, id DESC") @@ -328,3 +321,15 @@ func (u *User) ExpProgress() float64 { return float64(progressExp) / float64(nextLevelExp-currentLevelExp) * 100 } + +func (u *User) Class() *classes.Class { + class, err := classes.Find(u.ClassID) + if err != nil { + class, err = classes.Find(1) + if err != nil { + panic("There should always be at least one class") + } + return class + } + return class +} diff --git a/internal/routes/auth.go b/internal/routes/auth.go index c30e1ca..936d9ac 100644 --- a/internal/routes/auth.go +++ b/internal/routes/auth.go @@ -2,9 +2,11 @@ package routes import ( "fmt" + "slices" "strings" "dk/internal/components" + "dk/internal/models/classes" "dk/internal/models/users" sushi "git.sharkk.net/Sharkk/Sushi" @@ -86,10 +88,14 @@ func showRegister(ctx sushi.Ctx) { } sess.Delete("form_data") + allClasses, _ := classes.All() + slices.Reverse(allClasses) + components.RenderPage(ctx, "Register", "auth/register.html", map[string]any{ "username": username, "email": email, "error_message": sess.GetFlashMessage("error"), + "classes": allClasses, }) } @@ -99,6 +105,7 @@ func processRegister(ctx sushi.Ctx) { email := strings.TrimSpace(ctx.Form("email").String()) userPassword := ctx.Form("password").String() confirmPassword := ctx.Form("confirm_password").String() + classID := ctx.Form("class").Int() formData := map[string]string{ "username": username, @@ -125,13 +132,25 @@ func processRegister(ctx sushi.Ctx) { return } + // Ensure class ID exists (should always, unless someone modified the form) + class, err := classes.Find(classID) + if err != nil { + setFlashAndFormData(ctx, "Invalid class selected", formData) + ctx.Redirect("/register") + return + } + // Create new user user := users.New() user.Username = username user.Email = email user.Password = password.HashPassword(userPassword) - user.ClassID = 1 user.Auth = 1 + user.ClassID = classID + user.HP, user.MaxHP = class.BaseHP, class.BaseHP + user.MP, user.MaxMP = class.BaseMP, class.BaseMP + user.Strength = class.BaseSTR + user.Dexterity = class.BaseDEX // Validate before inserting if err := user.Validate(); err != nil { diff --git a/main.go b/main.go index 5d35311..9250e28 100644 --- a/main.go +++ b/main.go @@ -126,5 +126,9 @@ func start(port string) error { } func getUserByID(userID int) any { - return users.GetByID(userID) + user, err := users.Find(userID) + if err != nil { + panic(fmt.Sprintf("Error finding user ID %d", userID)) + } + return user } diff --git a/templates/auth/register.html b/templates/auth/register.html index 15a9d0c..a54d14b 100644 --- a/templates/auth/register.html +++ b/templates/auth/register.html @@ -30,12 +30,11 @@