Skip to content

Commit d7fc8ec

Browse files
authored
Follow module (#354)
# Description This removes the old `follow` command and creates a new module called `follow` with extended functionality. It also adds a `MobIdle{}` event that can be handled for when mobs are idle. Mobs out of alignment with players won't let players follow them. ## Changes - Added mob and user `follow` commands - Includes `unfollow`/`follow stop`, and `lose`/`follow lose` - Players can now follow mobs, not just other players. - Mobs can now follow players/mobs, a behavior that did not exist previously. - Added helpfile, keywords, etc. into module - Removed character `followers` slice and functions that use it. - Adjusted listener adding logic for default "add to end" behavior - mob commands now look for any keyword aliases that are defined to use. - Fixed up some bugginess with keyword aliases that was appending a space to the end, causing things to break. - Added `MobIdle{}` event and handlers. Moved some of the existing mob idle calculation to a new handler function. - follow module abort MobIdle{} event if mob is in the middle of a follow behavior. ## Links #348
1 parent e37138d commit d7fc8ec

File tree

17 files changed

+638
-130
lines changed

17 files changed

+638
-130
lines changed

_datafiles/world/default/keywords.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ help:
8787
- online
8888
- quit
8989
parties:
90-
- follow
9190
- party
9291
- share
9392
locks:

_datafiles/world/default/mobs/frostfang/scripts/2-guard.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ var PathTargets = [
99

1010
function onIdle(mob, room) {
1111

12+
if ( mob.PathingAtWaypoint() && mob.IsHome() ) {
13+
mob.SetAdjective("patrolling", false);
14+
}
15+
1216
var random = Math.floor(Math.random() * 10);
1317
switch (random) {
1418
case 0:
@@ -19,8 +23,10 @@ function onIdle(mob, room) {
1923
case 2:
2024
// Start a patrol path
2125
var randomPath = Math.floor(Math.random() * PathTargets.length);
22-
var selectedPath = PathTargets[randomPath]
26+
var selectedPath = PathTargets[randomPath];
27+
mob.SetAdjective("patrolling", true);
2328
mob.Command("pathto "+selectedPath.join(' '));
29+
2430
return true;
2531
case 3:
2632
// wander randomly.

_datafiles/world/empty/keywords.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ help:
8787
- online
8888
- quit
8989
parties:
90-
- follow
9190
- party
9291
- share
9392
locks:

_datafiles/world/empty/templates/help/follow.template

Lines changed: 0 additions & 9 deletions
This file was deleted.

internal/characters/character.go

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ type Character struct {
8585
roomHistory []int // A stack FILO of the last X rooms the character has been in
8686
PlayerDamage map[int]int `yaml:"-"` // key = who, value = how much
8787
LastPlayerDamage uint64 `yaml:"-"` // last round a player damaged this character
88-
followers []int // everyone following this user
8988
permaBuffIds []int // Buff Id's that are always present for this character
9089
userId int // User ID of the character if any
9190
}
@@ -532,10 +531,6 @@ func (c *Character) GetRandomItem() (items.Item, bool) {
532531
return c.Items[util.Rand(len(c.Items))], true
533532
}
534533

535-
func (c *Character) AddFollower(uId int) {
536-
c.followers = append(c.followers, uId)
537-
}
538-
539534
// USERNAME appears to be <BLANK>
540535
func (c *Character) GetHealthAppearance() string {
541536

@@ -561,10 +556,6 @@ func (c *Character) GetHealthAppearance() string {
561556
return fmt.Sprintf(`<ansi fg="username">%s</ansi> is in <ansi fg="%s">perfect health.</ansi>`, c.Name, className)
562557
}
563558

564-
func (c *Character) GetFollowers() []int {
565-
return append([]int{}, c.followers...)
566-
}
567-
568559
func (c *Character) GetAllSkillRanks() map[string]int {
569560
retMap := make(map[string]int)
570561
for skillName, skillLevel := range c.Skills {

internal/events/eventtypes.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ type NewTurn struct {
153153

154154
func (n NewTurn) Type() string { return `NewTurn` }
155155

156+
// Anytime a mob is idle
157+
type MobIdle struct {
158+
MobInstanceId int
159+
}
160+
161+
func (i MobIdle) Type() string { return `MobIdle` }
162+
156163
// Gained or lost an item
157164
type EquipmentChange struct {
158165
UserId int
@@ -339,6 +346,8 @@ type Party struct {
339346
Position map[int]string
340347
}
341348

349+
func (p Party) Type() string { return `Party` }
350+
342351
type RedrawPrompt struct {
343352
UserId int
344353
OnlyIfChanged bool

internal/events/listeners.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,16 @@ func RegisterListener(emptyEvent any, cbFunc Listener, qFlag ...QueueFlag) Liste
9191
} else if listenerDetails.isFinal {
9292
eventListeners[eType] = append(eventListeners[eType], listenerDetails)
9393

94-
} else {
94+
} else { // end of the list, but before any "final" listeners
9595

9696
insertPosition := 0
97-
for idx := 0; idx < len(eventListeners[eType]); idx++ {
97+
98+
for idx := len(eventListeners[eType]) - 1; idx >= 0; idx-- {
9899
// If we're looking at a "final" listener, we can't go any farther down the list
99100
if !eventListeners[eType][idx].isFinal {
100-
insertPosition = idx
101-
continue
101+
insertPosition = idx + 1
102+
break
102103
}
103-
break
104104
}
105105

106106
eventListeners[eType] = append(eventListeners[eType], ListenerWrapper{})
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package hooks
2+
3+
import (
4+
"github.com/GoMudEngine/GoMud/internal/configs"
5+
"github.com/GoMudEngine/GoMud/internal/events"
6+
"github.com/GoMudEngine/GoMud/internal/mobcommands"
7+
"github.com/GoMudEngine/GoMud/internal/mobs"
8+
"github.com/GoMudEngine/GoMud/internal/rooms"
9+
"github.com/GoMudEngine/GoMud/internal/scripting"
10+
"github.com/GoMudEngine/GoMud/internal/util"
11+
)
12+
13+
//
14+
// Handles default mob idle behavior
15+
//
16+
17+
func HandleIdleMobs(e events.Event) events.ListenerReturn {
18+
19+
evt := e.(events.MobIdle)
20+
21+
mob := mobs.GetInstance(evt.MobInstanceId)
22+
if mob == nil {
23+
return events.Cancel
24+
}
25+
26+
// if a mob shouldn't be allowed to leave their area (via wandering)
27+
// but has somehow been displaced, such as pulling through combat, spells, or otherwise
28+
// tell them to path back home
29+
if mob.MaxWander == 0 && mob.Character.RoomId != mob.HomeRoomId {
30+
mob.Command("pathto home")
31+
}
32+
33+
if mob.CanConverse() && util.Rand(100) < int(configs.GetGamePlayConfig().MobConverseChance) {
34+
if mobRoom := rooms.LoadRoom(mob.Character.RoomId); mobRoom != nil {
35+
mobcommands.Converse(``, mob, mobRoom) // Execute this directly so that target mob doesn't leave the room before this command executes
36+
}
37+
}
38+
39+
// If they have idle commands, maybe do one of them?
40+
handled, _ := scripting.TryMobScriptEvent("onIdle", mob.InstanceId, 0, ``, nil)
41+
if !handled {
42+
43+
if !mob.Character.IsCharmed() { // Won't do this stuff if befriended
44+
45+
if mob.MaxWander > -1 && mob.WanderCount > mob.MaxWander {
46+
mob.Command(`pathto home`)
47+
}
48+
49+
}
50+
51+
//
52+
// Look for trouble
53+
//
54+
if mob.Character.IsCharmed() {
55+
// Only some mobs can apply first aid
56+
if mob.Character.KnowsFirstAid() {
57+
mob.Command(`lookforaid`)
58+
}
59+
} else {
60+
61+
idleCmd := `lookfortrouble`
62+
if util.Rand(100) < mob.ActivityLevel {
63+
idleCmd = mob.GetIdleCommand()
64+
if idleCmd == `` {
65+
idleCmd = `lookfortrouble`
66+
}
67+
}
68+
mob.Command(idleCmd)
69+
}
70+
}
71+
72+
return events.Continue
73+
}

internal/hooks/NewRound_IdleMobs.go

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@ import (
88

99
"github.com/GoMudEngine/GoMud/internal/configs"
1010
"github.com/GoMudEngine/GoMud/internal/events"
11-
"github.com/GoMudEngine/GoMud/internal/mobcommands"
1211
"github.com/GoMudEngine/GoMud/internal/mobs"
1312
"github.com/GoMudEngine/GoMud/internal/rooms"
14-
"github.com/GoMudEngine/GoMud/internal/scripting"
1513
"github.com/GoMudEngine/GoMud/internal/users"
1614
"github.com/GoMudEngine/GoMud/internal/util"
1715
)
@@ -25,10 +23,8 @@ func IdleMobs(e events.Event) events.ListenerReturn {
2523
mobPathAnnounce := false // useful for debugging purposes.
2624

2725
mc := configs.GetMemoryConfig()
28-
gp := configs.GetGamePlayConfig()
2926

3027
maxBoredom := uint8(mc.MaxMobBoredom)
31-
globalConverseChance := int(gp.MobConverseChance)
3228

3329
allMobInstances := mobs.GetAllMobInstanceIds()
3430

@@ -143,55 +139,7 @@ func IdleMobs(e events.Event) events.ListenerReturn {
143139
mob.Path.Clear()
144140
}
145141

146-
// if a mob shouldn't be allowed to leave their area (via wandering)
147-
// but has somehow been displaced, such as pulling through combat, spells, or otherwise
148-
// tell them to path back home
149-
if mob.MaxWander == 0 && mob.Character.RoomId != mob.HomeRoomId {
150-
mob.Command("pathto home")
151-
continue
152-
}
153-
154-
if mob.CanConverse() && util.Rand(100) < globalConverseChance {
155-
if mobRoom := rooms.LoadRoom(mob.Character.RoomId); mobRoom != nil {
156-
mobcommands.Converse(``, mob, mobRoom) // Execute this directly so that target mob doesn't leave the room before this command executes
157-
//mob.Command(`converse`)
158-
}
159-
continue
160-
}
161-
162-
// If they have idle commands, maybe do one of them?
163-
handled, _ := scripting.TryMobScriptEvent("onIdle", mob.InstanceId, 0, ``, nil)
164-
if !handled {
165-
166-
if !mob.Character.IsCharmed() { // Won't do this stuff if befriended
167-
168-
if mob.MaxWander > -1 && mob.WanderCount > mob.MaxWander {
169-
mob.Command(`pathto home`)
170-
continue
171-
}
172-
173-
}
174-
175-
//
176-
// Look for trouble
177-
//
178-
if mob.Character.IsCharmed() {
179-
// Only some mobs can apply first aid
180-
if mob.Character.KnowsFirstAid() {
181-
mob.Command(`lookforaid`)
182-
}
183-
} else {
184-
185-
idleCmd := `lookfortrouble`
186-
if util.Rand(100) < mob.ActivityLevel {
187-
idleCmd = mob.GetIdleCommand()
188-
if idleCmd == `` {
189-
idleCmd = `lookfortrouble`
190-
}
191-
}
192-
mob.Command(idleCmd)
193-
}
194-
}
142+
events.AddToQueue(events.MobIdle{MobInstanceId: mobId})
195143

196144
}
197145

internal/hooks/hooks.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ func RegisterListeners() {
3131
//
3232
events.RegisterListener(events.NewRound{}, AutoHeal)
3333
events.RegisterListener(events.NewRound{}, IdleMobs)
34+
events.RegisterListener(events.MobIdle{}, HandleIdleMobs)
3435

3536
// Turn Hooks
3637
events.RegisterListener(events.NewTurn{}, CleanupZombies)

0 commit comments

Comments
 (0)