Skip to content

Commit 06317f0

Browse files
authored
Update mob and item list functionality (#351)
* Added in Getters for Screen width and height to apply default values if no screen information has been received and cast the native uint32 to int as that is the downstream type that is used. * Added templates/layout.go and the shared DynamicList function as part of a larger refactor * Modifed mob and item list to use DynamicList for rendering of results as well as fixing sort by tolowering the names * Added a message if no items are returned * added tests
1 parent c514515 commit 06317f0

File tree

5 files changed

+172
-63
lines changed

5 files changed

+172
-63
lines changed
Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,39 @@
11
package connections
22

3+
const (
4+
// DefaultScreenWidth is the default width of the screen
5+
DefaultScreenWidth = 80
6+
// DefaultScreenHeight is the default height of the screen
7+
DefaultScreenHeight = 24
8+
)
9+
310
type ClientSettings struct {
411
Display DisplaySettings
512
// Is MSP enabled?
613
MSPEnabled bool // Do they accept sound in their client?
714
SendTelnetGoAhead bool // Defaults false, should we send a IAC GA after prompts?
815
}
916

17+
func (c ClientSettings) IsMsp() bool {
18+
return c.MSPEnabled
19+
}
20+
1021
type DisplaySettings struct {
1122
ScreenWidth uint32
1223
ScreenHeight uint32
1324
}
1425

15-
func (c ClientSettings) IsMsp() bool {
16-
return c.MSPEnabled
26+
func (c DisplaySettings) GetScreenWidth() int {
27+
if c.ScreenWidth == 0 {
28+
return DefaultScreenWidth
29+
}
30+
31+
return int(c.ScreenWidth)
32+
}
33+
34+
func (c DisplaySettings) GetScreenHeight() int {
35+
if c.ScreenHeight == 0 {
36+
return DefaultScreenHeight
37+
}
38+
return int(c.ScreenHeight)
1739
}

internal/templates/layout.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package templates
2+
3+
import (
4+
"fmt"
5+
"strconv"
6+
"strings"
7+
8+
"github.com/GoMudEngine/GoMud/internal/term"
9+
)
10+
11+
// DynamicList takes a slice of NameDescription items and formats them into a string
12+
// NOTE: This is a first step to moving dynamic lists into a common function.
13+
func DynamicList(itmNames []NameDescription, colWidth, sw, numWidth, longestName int) string {
14+
if len(itmNames) == 0 {
15+
return `<ansi fg="202">No items to display.</ansi>`
16+
}
17+
18+
strOut := ``
19+
totalLen := 0
20+
for idx, itm := range itmNames {
21+
22+
if totalLen+colWidth > sw {
23+
strOut += term.CRLFStr
24+
totalLen = 0
25+
}
26+
27+
numStr := strconv.Itoa(idx + 1)
28+
29+
strOut += ` `
30+
31+
if itm.Marked {
32+
strOut += `<ansi fg="white-bold" bg="059">`
33+
}
34+
35+
strOut += strings.Repeat(` `, numWidth-len(numStr)) + fmt.Sprintf(`<ansi fg="red-bold">%s</ansi>`, strconv.Itoa(idx+1)) + `. ` +
36+
fmt.Sprintf(`<ansi fg="yellow-bold">%s</ansi>`, itm.Name) + strings.Repeat(` `, longestName-len(itm.Name))
37+
38+
if itm.Marked {
39+
strOut += `</ansi>`
40+
}
41+
42+
strOut += ` `
43+
44+
totalLen += colWidth
45+
46+
}
47+
return strOut
48+
}

internal/templates/layout_test.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package templates_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/GoMudEngine/GoMud/internal/templates"
7+
"github.com/GoMudEngine/GoMud/internal/term"
8+
"github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestDynamicList(t *testing.T) {
12+
tests := []struct {
13+
name string
14+
itmNames []templates.NameDescription
15+
colWidth int
16+
sw int
17+
numWidth int
18+
longestName int
19+
expectedOutput string
20+
}{
21+
{
22+
name: "Empty list",
23+
itmNames: []templates.NameDescription{},
24+
colWidth: 20,
25+
sw: 80,
26+
numWidth: 2,
27+
longestName: 10,
28+
expectedOutput: `<ansi fg="202">No items to display.</ansi>`,
29+
},
30+
{
31+
name: "Single item",
32+
itmNames: []templates.NameDescription{
33+
{Name: "Item1", Marked: false},
34+
},
35+
colWidth: 20,
36+
sw: 80,
37+
numWidth: 2,
38+
longestName: 10,
39+
expectedOutput: ` <ansi fg="red-bold">1</ansi>. <ansi fg="yellow-bold">Item1</ansi> `,
40+
},
41+
{
42+
name: "Multiple items with wrapping",
43+
itmNames: []templates.NameDescription{
44+
{Name: "Item1", Marked: false},
45+
{Name: "Item2", Marked: true},
46+
{Name: "Item3", Marked: false},
47+
},
48+
colWidth: 20,
49+
sw: 40,
50+
numWidth: 2,
51+
longestName: 10,
52+
expectedOutput: ` <ansi fg="red-bold">1</ansi>. <ansi fg="yellow-bold">Item1</ansi> <ansi fg="white-bold" bg="059"> <ansi fg="red-bold">2</ansi>. <ansi fg="yellow-bold">Item2</ansi> </ansi> ` + term.CRLFStr + ` <ansi fg="red-bold">3</ansi>. <ansi fg="yellow-bold">Item3</ansi> `,
53+
},
54+
}
55+
56+
for _, tt := range tests {
57+
t.Run(tt.name, func(t *testing.T) {
58+
output := templates.DynamicList(tt.itmNames, tt.colWidth, tt.sw, tt.numWidth, tt.longestName)
59+
assert.Equal(t, tt.expectedOutput, output, "DynamicList() output mismatch")
60+
})
61+
}
62+
}

internal/usercommands/admin.item.go

Lines changed: 13 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -69,87 +69,51 @@ func Item(rest string, user *users.UserRecord, room *rooms.Room, flags events.Ev
6969
return true, nil
7070
}
7171

72-
func item_List(rest string, user *users.UserRecord, room *rooms.Room, flags events.EventFlag) (bool, error) {
72+
func item_List(rest string, user *users.UserRecord, _ *rooms.Room, _ events.EventFlag) (bool, error) {
7373

7474
itmNames := []templates.NameDescription{}
75-
7675
longestName := 0
77-
for _, itm := range items.GetAllItemNames() {
76+
77+
for _, itm := range items.GetAllItemSpecs() {
7878

7979
entry := templates.NameDescription{
80-
Name: itm,
80+
Id: itm.ItemId,
81+
Name: itm.Name,
8182
}
8283

8384
// If searching for matches
8485
if len(rest) > 0 {
8586
if !strings.Contains(rest, `*`) {
8687
rest += `*`
8788
}
88-
if util.StringWildcardMatch(strings.ToLower(itm), rest) {
89-
entry.Marked = true
89+
if !util.StringWildcardMatch(strings.ToLower(entry.Name), rest) {
90+
continue
9091
}
9192
}
9293

93-
if len(itm) > longestName {
94-
longestName = len(itm)
94+
if len(entry.Name) > longestName {
95+
longestName = len(entry.Name)
9596
}
9697

9798
itmNames = append(itmNames, entry)
9899
}
99100

100101
sort.SliceStable(itmNames, func(i, j int) bool {
101-
return itmNames[i].Name < itmNames[j].Name
102+
return strings.ToLower(itmNames[i].Name) < strings.ToLower(itmNames[j].Name)
102103
})
103104

104105
numWidth := len(strconv.Itoa(len(itmNames)))
105-
colWidth := 1 + numWidth + 2 +
106-
longestName + 1
107-
sw := 80
108-
if user.ClientSettings().Display.ScreenWidth > 0 {
109-
sw = int(user.ClientSettings().Display.ScreenWidth)
110-
}
111-
112-
//cols := int(math.Floor(float64(sw) / float64(colWidth)))
106+
colWidth := 1 + numWidth + 2 + longestName + 1
113107

114108
user.SendText(``)
115-
strOut := ``
116-
totalLen := 0
117-
for idx, itm := range itmNames {
118-
119-
if totalLen+colWidth > sw {
120-
strOut += term.CRLFStr
121-
totalLen = 0
122-
}
123-
124-
numStr := strconv.Itoa(idx + 1)
125-
126-
strOut += ` `
127-
128-
if itm.Marked {
129-
strOut += `<ansi fg="white-bold" bg="059">`
130-
}
131-
132-
strOut += strings.Repeat(` `, numWidth-len(numStr)) + fmt.Sprintf(`<ansi fg="red-bold">%s</ansi>`, strconv.Itoa(idx+1)) + `. ` +
133-
fmt.Sprintf(`<ansi fg="yellow-bold">%s</ansi>`, itm.Name) + strings.Repeat(` `, longestName-len(itm.Name))
134-
135-
if itm.Marked {
136-
strOut += `</ansi>`
137-
}
138-
139-
strOut += ` `
140-
141-
totalLen += colWidth
142-
143-
}
144-
109+
sw := user.ClientSettings().Display.GetScreenWidth()
110+
strOut := templates.DynamicList(itmNames, colWidth, sw, numWidth, longestName)
145111
user.SendText(strOut)
146112
user.SendText(``)
147113

148114
return true, nil
149115
}
150116

151-
// 107. wooden shield 108. worn boots
152-
153117
func item_Spawn(rest string, user *users.UserRecord, room *rooms.Room, flags events.EventFlag) (bool, error) {
154118

155119
itemId := items.FindItem(rest)

internal/usercommands/admin.mob.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,34 +71,47 @@ func Mob(rest string, user *users.UserRecord, room *rooms.Room, flags events.Eve
7171
return true, nil
7272
}
7373

74-
func mob_List(rest string, user *users.UserRecord, room *rooms.Room, flags events.EventFlag) (bool, error) {
74+
func mob_List(rest string, user *users.UserRecord, _ *rooms.Room, _ events.EventFlag) (bool, error) {
7575

76-
mobNames := []templates.NameDescription{}
76+
mobList := []templates.NameDescription{}
77+
longestName := 0
7778

78-
for _, nm := range mobs.GetAllMobNames() {
79+
for _, mob := range mobs.GetAllMobInfo() {
80+
81+
entry := templates.NameDescription{
82+
Id: mob.MobId,
83+
Name: mob.Character.Name,
84+
}
7985

8086
// If searching for matches
8187
if len(rest) > 0 {
8288
if !strings.Contains(rest, `*`) {
8389
rest += `*`
8490
}
85-
86-
if !util.StringWildcardMatch(strings.ToLower(nm), rest) {
91+
if !util.StringWildcardMatch(strings.ToLower(entry.Name), rest) {
8792
continue
8893
}
8994
}
9095

91-
mobNames = append(mobNames, templates.NameDescription{
92-
Name: nm,
93-
})
96+
if len(entry.Name) > longestName {
97+
longestName = len(entry.Name)
98+
}
99+
100+
mobList = append(mobList, entry)
94101
}
95102

96-
sort.SliceStable(mobNames, func(i, j int) bool {
97-
return mobNames[i].Name < mobNames[j].Name
103+
sort.SliceStable(mobList, func(i, j int) bool {
104+
return strings.ToLower(mobList[i].Name) < strings.ToLower(mobList[j].Name)
98105
})
99106

100-
tplTxt, _ := templates.Process("tables/numbered-list-doubled", mobNames, user.UserId)
101-
user.SendText(tplTxt)
107+
numWidth := len(strconv.Itoa(len(mobList)))
108+
colWidth := 1 + numWidth + 2 + longestName + 1
109+
110+
user.SendText(``)
111+
sw := user.ClientSettings().Display.GetScreenWidth()
112+
strOut := templates.DynamicList(mobList, colWidth, sw, numWidth, longestName)
113+
user.SendText(strOut)
114+
user.SendText(``)
102115

103116
return true, nil
104117
}

0 commit comments

Comments
 (0)