clean up aside components - add magiclist and townlist

This commit is contained in:
Sky Johnson 2025-08-12 09:13:41 -05:00
parent f0756c79b6
commit 6968e8822c
5 changed files with 154 additions and 69 deletions

View File

@ -290,9 +290,21 @@ div#statbars {
background-color: white; background-color: white;
} }
&#hp > div.bar { &#hp {
background: #56ab2f; & > div.bar {
background: linear-gradient(to left, #a8e063, #56ab2f); 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 { &#mp > div.bar {
@ -305,9 +317,5 @@ div#statbars {
background: linear-gradient(to right, #757f9a, #d7dde8); background: linear-gradient(to right, #757f9a, #d7dde8);
} }
} }
& > label {
}
} }
} }

View File

@ -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, ",")
}

View File

@ -4,32 +4,23 @@ import (
"dk/internal/helpers" "dk/internal/helpers"
"dk/internal/middleware" "dk/internal/middleware"
"dk/internal/router" "dk/internal/router"
"dk/internal/spells"
"dk/internal/template" "dk/internal/template"
"dk/internal/towns" "dk/internal/towns"
"dk/internal/users"
) )
// LeftAside generates the left sidebar content // LeftAside generates the left sidebar content
func LeftAside(ctx router.Ctx) string { func LeftAside(ctx router.Ctx) string {
if !middleware.IsAuthenticated(ctx) { user := middleware.GetCurrentUser(ctx)
if user == nil {
return "" return ""
} }
leftSideTmpl, err := template.Cache.Load("leftside.html") tmpl, err := template.Cache.Load("leftside.html")
if err != nil { if err != nil {
return "leftside failed to load?" 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" cardinalX := "E"
if user.X < 0 { if user.X < 0 {
cardinalX = "W" cardinalX = "W"
@ -46,18 +37,32 @@ func LeftAside(ctx router.Ctx) string {
if err != nil { if err != nil {
townname = "error finding town" townname = "error finding town"
} }
townname = "<b>In " + town.Name + "</b>" townname = "<div class=\"mb-05\"><b>In " + town.Name + "</b></div>"
} }
leftSideData := map[string]any{ townlist := ""
townIDs := user.GetTownIDs()
if len(townIDs) > 0 {
townlist = "<i>Teleport to:</i><br>"
for _, id := range townIDs {
town, err := towns.Find(id)
if err != nil {
continue
}
townlist += `<a href="#">` + town.Name + "</a><br>"
}
} else {
townlist = "<i>No town maps</i>"
}
return tmpl.RenderNamed(map[string]any{
"user": user.ToMap(), "user": user.ToMap(),
"cardinalX": cardinalX, "cardinalX": cardinalX,
"cardinalY": cardinalY, "cardinalY": cardinalY,
"townname": townname, "townname": townname,
"townlist": "@TODO", "townlist": townlist,
} })
return leftSideTmpl.RenderNamed(leftSideData)
} }
// RightAside generates the right sidebar content // 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) mpPct := helpers.ClampPct(float64(user.MP), float64(user.MaxMP), 0, 100)
tpPct := helpers.ClampPct(float64(user.TP), float64(user.MaxTP), 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 := "<i>No weapon</i>"
if user.WeaponName != "" {
weaponName = user.WeaponName
}
armorName := "<i>No armor</i>"
if user.ArmorName != "" {
armorName = user.ArmorName
}
shieldName := "<i>No shield</i>"
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 += `<a href="#">` + spell.Name + "</a>"
}
}
} else {
magicList = "<i>No healing spells known</i>"
}
return tmpl.RenderNamed(map[string]any{ return tmpl.RenderNamed(map[string]any{
"user": user.ToMap(), "user": user.ToMap(),
"hppct": hpPct, "hppct": hpPct,
"mppct": mpPct, "hpcolor": hpColor,
"tppct": tpPct, "mppct": mpPct,
"tppct": tpPct,
"weaponname": weaponName,
"armorname": armorName,
"shieldname": shieldName,
"slot1name": slot1Name,
"slot2name": slot2Name,
"slot3name": slot3Name,
"magiclist": magicList,
}) })
} }

View File

@ -2,10 +2,11 @@ package users
import ( import (
"fmt" "fmt"
"strings" "slices"
"time" "time"
"dk/internal/database" "dk/internal/database"
"dk/internal/helpers"
"dk/internal/helpers/scanner" "dk/internal/helpers/scanner"
"zombiezen.com/go/sqlite" "zombiezen.com/go/sqlite"
@ -271,7 +272,7 @@ func (u *User) IsAdmin() bool {
} }
func (u *User) IsModerator() bool { func (u *User) IsModerator() bool {
return u.Auth >= 2 return u.Auth >= 3
} }
func (u *User) IsFighting() bool { func (u *User) IsFighting() bool {
@ -282,46 +283,28 @@ func (u *User) IsAlive() bool {
return u.HP > 0 return u.HP > 0
} }
func (u *User) GetSpellIDs() []string { func (u *User) GetSpellIDs() []int {
if u.Spells == "" { return helpers.StringToInts(u.Spells)
return []string{}
}
return strings.Split(u.Spells, ",")
} }
func (u *User) SetSpellIDs(spells []string) { func (u *User) SetSpellIDs(spells []int) {
u.Set("Spells", strings.Join(spells, ",")) u.Set("Spells", helpers.IntsToString(spells))
} }
func (u *User) HasSpell(spellID string) bool { func (u *User) HasSpell(spellID int) bool {
spells := u.GetSpellIDs() return slices.Contains(u.GetSpellIDs(), spellID)
for _, spell := range spells {
if strings.TrimSpace(spell) == spellID {
return true
}
}
return false
} }
func (u *User) GetTownIDs() []string { func (u *User) GetTownIDs() []int {
if u.Towns == "" { return helpers.StringToInts(u.Towns)
return []string{}
}
return strings.Split(u.Towns, ",")
} }
func (u *User) SetTownIDs(towns []string) { func (u *User) SetTownIDs(towns []int) {
u.Set("Towns", strings.Join(towns, ",")) u.Set("Towns", helpers.IntsToString(towns))
} }
func (u *User) HasVisitedTown(townID string) bool { func (u *User) HasTownMap(townID int) bool {
towns := u.GetTownIDs() return slices.Contains(u.GetTownIDs(), townID)
for _, town := range towns {
if strings.TrimSpace(town) == townID {
return true
}
}
return false
} }
func (u *User) GetEquipment() map[string]any { func (u *User) GetEquipment() map[string]any {

View File

@ -5,24 +5,24 @@
<li>Level: {user.Level}</li> <li>Level: {user.Level}</li>
<li>Exp: {user.Exp}</li> <li>Exp: {user.Exp}</li>
<li>Gold: {user.Gold}</li> <li>Gold: {user.Gold}</li>
<li>HP: {user.HP}</li> <li>HP: {user.HP}/{user.MaxHP}</li>
<li>MP: {user.MP}</li> <li>MP: {user.MP}/{user.MaxMP}</li>
<li>TP: {user.TP}</li> <li>TP: {user.TP}/{user.MaxTP}</li>
</ul> </ul>
<div id="statbars"> <div id="statbars">
<div class="stat"> <div class="stat">
<div id="hp" class="container"><div class="bar" style="height: {hppct}%"></div></div> <div id="hp" class="container {hpcolor}"><div class="bar" style="height: {hppct}%;"></div></div>
<label>HP</label> <label>HP</label>
</div> </div>
<div class="stat"> <div class="stat">
<div id="mp" class="container"><div class="bar" style="height: {mppct}%"></div></div> <div id="mp" class="container"><div class="bar" style="height: {mppct}%;"></div></div>
<label>MP</label> <label>MP</label>
</div> </div>
<div class="stat"> <div class="stat">
<div id="tp" class="container"><div class="bar" style="height: {tppct}%"></div></div> <div id="tp" class="container"><div class="bar" style="height: {tppct}%;"></div></div>
<label>TP</label> <label>TP</label>
</div> </div>
@ -30,7 +30,6 @@
<a href="javascript:open_char_popup()">Extended Stats</a> <a href="javascript:open_char_popup()">Extended Stats</a>
</section> </section>
<br>
<section> <section>
<div class="title"><img src="/assets/images/button_inventory.gif" alt="Inventory" title="Inventory"></div> <div class="title"><img src="/assets/images/button_inventory.gif" alt="Inventory" title="Inventory"></div>