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;
}
&#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 {
}
}
}

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/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 = "<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(),
"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 := "<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{
"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,
})
}

View File

@ -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 {

View File

@ -5,24 +5,24 @@
<li>Level: {user.Level}</li>
<li>Exp: {user.Exp}</li>
<li>Gold: {user.Gold}</li>
<li>HP: {user.HP}</li>
<li>MP: {user.MP}</li>
<li>TP: {user.TP}</li>
<li>HP: {user.HP}/{user.MaxHP}</li>
<li>MP: {user.MP}/{user.MaxMP}</li>
<li>TP: {user.TP}/{user.MaxTP}</li>
</ul>
<div id="statbars">
<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>
</div>
<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>
</div>
<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>
</div>
@ -30,7 +30,6 @@
<a href="javascript:open_char_popup()">Extended Stats</a>
</section>
<br>
<section>
<div class="title"><img src="/assets/images/button_inventory.gif" alt="Inventory" title="Inventory"></div>