diff --git a/assets/dk.css b/assets/dk.css index ed8341d..3060155 100644 --- a/assets/dk.css +++ b/assets/dk.css @@ -290,9 +290,21 @@ div#statbars { background-color: white; } - &#hp > div.bar { - background: #56ab2f; - background: linear-gradient(to left, #a8e063, #56ab2f); + &#hp { + & > div.bar { + background: #56ab2f; + background: linear-gradient(to left, #a8e063, #56ab2f); + } + + &.warning > div.bar { + background: #F2994A; + background: linear-gradient(to left, #F2C94C, #F2994A); + } + + &.danger > div.bar { + background: #cb2d3e; + background: linear-gradient(to left, #ef473a, #cb2d3e); + } } &#mp > div.bar { @@ -305,9 +317,5 @@ div#statbars { background: linear-gradient(to right, #757f9a, #d7dde8); } } - - & > label { - - } } } \ No newline at end of file diff --git a/internal/helpers/convert.go b/internal/helpers/convert.go new file mode 100644 index 0000000..833a265 --- /dev/null +++ b/internal/helpers/convert.go @@ -0,0 +1,28 @@ +package helpers + +import ( + "strconv" + "strings" +) + +// StringToInts converts comma-delimited string to int slice +func StringToInts(s string) []int { + if s == "" { + return []int{} + } + parts := strings.Split(s, ",") + ints := make([]int, len(parts)) + for i, part := range parts { + ints[i], _ = strconv.Atoi(part) + } + return ints +} + +// IntToString converts int slice to comma-delimited string +func IntsToString(ints []int) string { + strs := make([]string, len(ints)) + for i, num := range ints { + strs[i] = strconv.Itoa(num) + } + return strings.Join(strs, ",") +} diff --git a/internal/template/components/asides.go b/internal/template/components/asides.go index b1cb18c..20cb225 100644 --- a/internal/template/components/asides.go +++ b/internal/template/components/asides.go @@ -4,32 +4,23 @@ import ( "dk/internal/helpers" "dk/internal/middleware" "dk/internal/router" + "dk/internal/spells" "dk/internal/template" "dk/internal/towns" - "dk/internal/users" ) // LeftAside generates the left sidebar content func LeftAside(ctx router.Ctx) string { - if !middleware.IsAuthenticated(ctx) { + user := middleware.GetCurrentUser(ctx) + if user == nil { return "" } - leftSideTmpl, err := template.Cache.Load("leftside.html") + tmpl, err := template.Cache.Load("leftside.html") if err != nil { return "leftside failed to load?" } - currentUser := middleware.GetCurrentUser(ctx) - if currentUser == nil { - return "no currentUser?" - } - - user, err := users.Find(currentUser.ID) - if err != nil { - return "user not found?" - } - cardinalX := "E" if user.X < 0 { cardinalX = "W" @@ -46,18 +37,32 @@ func LeftAside(ctx router.Ctx) string { if err != nil { townname = "error finding town" } - townname = "In " + town.Name + "" + townname = "
In " + town.Name + "
" } - leftSideData := map[string]any{ + townlist := "" + townIDs := user.GetTownIDs() + if len(townIDs) > 0 { + townlist = "Teleport to:
" + for _, id := range townIDs { + town, err := towns.Find(id) + if err != nil { + continue + } + + townlist += `` + town.Name + "
" + } + } else { + townlist = "No town maps" + } + + return tmpl.RenderNamed(map[string]any{ "user": user.ToMap(), "cardinalX": cardinalX, "cardinalY": cardinalY, "townname": townname, - "townlist": "@TODO", - } - - return leftSideTmpl.RenderNamed(leftSideData) + "townlist": townlist, + }) } // RightAside generates the right sidebar content @@ -76,10 +81,72 @@ func RightAside(ctx router.Ctx) string { mpPct := helpers.ClampPct(float64(user.MP), float64(user.MaxMP), 0, 100) tpPct := helpers.ClampPct(float64(user.TP), float64(user.MaxTP), 0, 100) + hpColor := "" + if hpPct < 35 { + hpColor = "danger" + } else if hpPct < 75 { + hpColor = "warning" + } + + weaponName := "No weapon" + if user.WeaponName != "" { + weaponName = user.WeaponName + } + + armorName := "No armor" + if user.ArmorName != "" { + armorName = user.ArmorName + } + + shieldName := "No shield" + if user.ShieldName != "" { + shieldName = user.ShieldName + } + + slot1Name := "" + if user.Slot1Name != "" { + slot1Name = user.Slot1Name + } + + slot2Name := "" + if user.Slot2Name != "" { + slot2Name = user.Slot2Name + } + + slot3Name := "" + if user.Slot3Name != "" { + slot3Name = user.Slot3Name + } + + magicList := "" + list := user.GetSpellIDs() + if len(list) > 0 { + for i := range list { + spell, err := spells.Find(i) + if err != nil { + continue + } + + if spell.IsHealing() { + magicList += `` + spell.Name + "" + } + } + } else { + magicList = "No healing spells known" + } + return tmpl.RenderNamed(map[string]any{ - "user": user.ToMap(), - "hppct": hpPct, - "mppct": mpPct, - "tppct": tpPct, + "user": user.ToMap(), + "hppct": hpPct, + "hpcolor": hpColor, + "mppct": mpPct, + "tppct": tpPct, + "weaponname": weaponName, + "armorname": armorName, + "shieldname": shieldName, + "slot1name": slot1Name, + "slot2name": slot2Name, + "slot3name": slot3Name, + "magiclist": magicList, }) } diff --git a/internal/users/users.go b/internal/users/users.go index dc78107..f6a80a2 100644 --- a/internal/users/users.go +++ b/internal/users/users.go @@ -2,10 +2,11 @@ package users import ( "fmt" - "strings" + "slices" "time" "dk/internal/database" + "dk/internal/helpers" "dk/internal/helpers/scanner" "zombiezen.com/go/sqlite" @@ -271,7 +272,7 @@ func (u *User) IsAdmin() bool { } func (u *User) IsModerator() bool { - return u.Auth >= 2 + return u.Auth >= 3 } func (u *User) IsFighting() bool { @@ -282,46 +283,28 @@ func (u *User) IsAlive() bool { return u.HP > 0 } -func (u *User) GetSpellIDs() []string { - if u.Spells == "" { - return []string{} - } - return strings.Split(u.Spells, ",") +func (u *User) GetSpellIDs() []int { + return helpers.StringToInts(u.Spells) } -func (u *User) SetSpellIDs(spells []string) { - u.Set("Spells", strings.Join(spells, ",")) +func (u *User) SetSpellIDs(spells []int) { + u.Set("Spells", helpers.IntsToString(spells)) } -func (u *User) HasSpell(spellID string) bool { - spells := u.GetSpellIDs() - for _, spell := range spells { - if strings.TrimSpace(spell) == spellID { - return true - } - } - return false +func (u *User) HasSpell(spellID int) bool { + return slices.Contains(u.GetSpellIDs(), spellID) } -func (u *User) GetTownIDs() []string { - if u.Towns == "" { - return []string{} - } - return strings.Split(u.Towns, ",") +func (u *User) GetTownIDs() []int { + return helpers.StringToInts(u.Towns) } -func (u *User) SetTownIDs(towns []string) { - u.Set("Towns", strings.Join(towns, ",")) +func (u *User) SetTownIDs(towns []int) { + u.Set("Towns", helpers.IntsToString(towns)) } -func (u *User) HasVisitedTown(townID string) bool { - towns := u.GetTownIDs() - for _, town := range towns { - if strings.TrimSpace(town) == townID { - return true - } - } - return false +func (u *User) HasTownMap(townID int) bool { + return slices.Contains(u.GetTownIDs(), townID) } func (u *User) GetEquipment() map[string]any { diff --git a/templates/rightside.html b/templates/rightside.html index fd4d75a..bf2bacc 100644 --- a/templates/rightside.html +++ b/templates/rightside.html @@ -5,24 +5,24 @@
  • Level: {user.Level}
  • Exp: {user.Exp}
  • Gold: {user.Gold}
  • -
  • HP: {user.HP}
  • -
  • MP: {user.MP}
  • -
  • TP: {user.TP}
  • +
  • HP: {user.HP}/{user.MaxHP}
  • +
  • MP: {user.MP}/{user.MaxMP}
  • +
  • TP: {user.TP}/{user.MaxTP}
  • -
    +
    -
    +
    -
    +
    @@ -30,7 +30,6 @@ Extended Stats -
    Inventory