Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions internal/events/eventtypes.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/volte6/gomud/internal/configs"
"github.com/volte6/gomud/internal/connections"
"github.com/volte6/gomud/internal/items"
"github.com/volte6/gomud/internal/stats"
)

// Used to apply or remove buffs
Expand Down Expand Up @@ -185,3 +186,28 @@ type Log struct {
}

func (l Log) Type() string { return `Log` }

type LevelUp struct {
UserId int
RoomId int
Username string
CharacterName string
NewLevel int
StatsDelta stats.Statistics
TrainingPoints int
StatPoints int
LivesGained int
}

func (l LevelUp) Type() string { return `LevelUp` }

type PlayerDeath struct {
UserId int
RoomId int
Username string
CharacterName string
Permanent bool
KilledByUsers []int
}

func (l PlayerDeath) Type() string { return `PlayerDeath` }
38 changes: 38 additions & 0 deletions internal/hooks/LevelUp_CheckGuide.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package hooks

import (
"github.com/volte6/gomud/internal/events"
"github.com/volte6/gomud/internal/mobs"
"github.com/volte6/gomud/internal/mudlog"
"github.com/volte6/gomud/internal/users"
)

// Checks whether their level is too high for a guide
func CheckGuide(e events.Event) bool {

evt, typeOk := e.(events.LevelUp)
if !typeOk {
mudlog.Error("Event", "Expected Type", "LevelUp", "Actual Type", e.Type())
return false
}

user := users.GetByUserId(evt.UserId)
if user == nil {
return true
}

if user.Character.Level >= 5 {
for _, mobInstanceId := range user.Character.CharmedMobs {
if mob := mobs.GetInstance(mobInstanceId); mob != nil {

if mob.MobId == 38 {
mob.Command(`say I see you have grown much stronger and more experienced. My assistance is now needed elsewhere. I wish you good luck!`)
mob.Command(`emote clicks their heels together and disappears in a cloud of smoke.`, 10)
mob.Command(`suicide vanish`, 10)
}
}
}
}

return true
}
44 changes: 44 additions & 0 deletions internal/hooks/LevelUp_SendLevelNotifications.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package hooks

import (
"fmt"

"github.com/volte6/gomud/internal/events"
"github.com/volte6/gomud/internal/mudlog"
"github.com/volte6/gomud/internal/templates"
"github.com/volte6/gomud/internal/term"
"github.com/volte6/gomud/internal/users"
)

func SendLevelNotifications(e events.Event) bool {

evt, typeOk := e.(events.LevelUp)
if !typeOk {
mudlog.Error("Event", "Expected Type", "LevelUp", "Actual Type", e.Type())
return false
}

user := users.GetByUserId(evt.UserId)
if user == nil {
return true
}

levelUpData := map[string]interface{}{
"level": evt.NewLevel,
"statsDelta": evt.StatsDelta,
"trainingPoints": evt.TrainingPoints,
"statPoints": evt.StatPoints,
"livesUp": evt.LivesGained,
}
levelUpStr, _ := templates.Process("character/levelup", levelUpData)

user.SendText(levelUpStr)

user.PlaySound(`levelup`, `other`)

events.AddToQueue(events.Broadcast{
Text: fmt.Sprintf(`<ansi fg="magenta-bold">***</ansi> <ansi fg="username">%s</ansi> <ansi fg="yellow">has reached level %d!</ansi> <ansi fg="magenta-bold">***</ansi>%s`, evt.CharacterName, evt.NewLevel, term.CRLFStr),
})

return true
}
81 changes: 0 additions & 81 deletions internal/hooks/NewTurn_LevelUp.go

This file was deleted.

5 changes: 4 additions & 1 deletion internal/hooks/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ func RegisterListeners() {
events.RegisterListener(events.NewTurn{}, AutoSave)
events.RegisterListener(events.NewTurn{}, PruneBuffs)
events.RegisterListener(events.NewTurn{}, ActionPoints)
events.RegisterListener(events.NewTurn{}, LevelUp)

// ItemOwnership
events.RegisterListener(events.ItemOwnership{}, CheckItemQuests)
Expand All @@ -52,6 +51,10 @@ func RegisterListeners() {
events.RegisterListener(events.PlayerSpawn{}, HandleJoin)
events.RegisterListener(events.PlayerDespawn{}, HandleLeave, events.Last) // This is a final listener, has to happen last

// Levelup Notifications
events.RegisterListener(events.LevelUp{}, SendLevelNotifications)
events.RegisterListener(events.LevelUp{}, CheckGuide)

// Listener for debugging some stuff (catches all events)
/*
events.RegisterListener(nil, func(e events.Event) bool {
Expand Down
2 changes: 2 additions & 0 deletions internal/integrations/discord/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ func registerListeners() {
events.RegisterListener(events.PlayerSpawn{}, HandlePlayerSpawn)
events.RegisterListener(events.PlayerDespawn{}, HandlePlayerDespawn)
events.RegisterListener(events.Log{}, HandleLogs)
events.RegisterListener(events.LevelUp{}, HandleLevelup)
events.RegisterListener(events.PlayerDeath{}, HandleDeath)
}

// Sends an embed message to discord which includes a colored bar to the left
Expand Down
32 changes: 30 additions & 2 deletions internal/integrations/discord/listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,37 @@ func HandleLogs(e events.Event) bool {
return true
}

msgOut = strings.Replace(msgOut, evt.Level, `**`+evt.Level+`**`, 1)
if strings.Contains(msgOut, `Stopping server`) || strings.Contains(msgOut, `Starting server`) {
msgOut = strings.Replace(msgOut, evt.Level, `**NOTICE**`, 1)
} else {
msgOut = strings.Replace(msgOut, evt.Level, `**`+evt.Level+`**`, 1)
}

message := fmt.Sprintf(":bangbang: %s", msgOut)
SendMessage(message)

return true
}

func HandleLevelup(e events.Event) bool {
evt, typeOk := e.(events.LevelUp)
if !typeOk {
return false
}

message := fmt.Sprintf(`:crown: **%s** *has reached **level %d**!*`, evt.CharacterName, evt.NewLevel)
SendMessage(message)

return true
}

func HandleDeath(e events.Event) bool {
evt, typeOk := e.(events.PlayerDeath)
if !typeOk {
return false
}

message := fmt.Sprintf(":bangbang: %s :bangbang:", msgOut)
message := fmt.Sprintf(`:skull: **%s** *has **DIED**!*`, evt.CharacterName)
SendMessage(message)

return true
Expand Down
12 changes: 12 additions & 0 deletions internal/usercommands/suicide.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func Suicide(rest string, user *users.UserRecord, room *rooms.Room, flags events
user.Character.KD.AddMobDeath()
}

killedByUserIds := []int{}
killedBy := ``
for uid, _ := range user.Character.PlayerDamage {

Expand All @@ -73,6 +74,8 @@ func Suicide(rest string, user *users.UserRecord, room *rooms.Room, flags events
killedBy += `<ansi fg="username">` + u.Character.Name + `</ansi>`
i++
}

killedByUserIds = append(killedByUserIds, uid)
}

msg := fmt.Sprintf(`<ansi fg="magenta-bold">***</ansi> <ansi fg="username">%s</ansi> has <ansi fg="red-bold">DIED!</ansi> <ansi fg="magenta-bold">***</ansi>%s`, user.Character.Name, term.CRLFStr)
Expand All @@ -86,6 +89,15 @@ func Suicide(rest string, user *users.UserRecord, room *rooms.Room, flags events

allowPenalties := user.Character.Level > int(config.OnDeathProtectionLevels)

events.AddToQueue(events.PlayerDeath{
UserId: user.UserId,
RoomId: user.Character.RoomId,
Username: user.Username,
CharacterName: user.Character.Name,
Permanent: allowPenalties && bool(config.PermaDeath) && user.Character.ExtraLives == 0,
KilledByUsers: killedByUserIds,
})

// If permadeath is enabled, do some extra bookkeeping
if allowPenalties && bool(config.PermaDeath) {

Expand Down
30 changes: 30 additions & 0 deletions internal/users/userrecord.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,36 @@ func (u *UserRecord) GrantXP(amt int, source string) {
u.EventLog.Add(`xp`, fmt.Sprintf(`Gained <ansi fg="yellow-bold">%d experience points</ansi>! <ansi fg="7">(%s)</ansi>`, grantXP, source))
}

if newLevel, statsDelta := u.Character.LevelUp(); newLevel {

c := configs.GetConfig()

livesBefore := u.Character.ExtraLives

if c.PermaDeath && c.LivesOnLevelUp > 0 {
u.Character.ExtraLives += int(c.LivesOnLevelUp)
if u.Character.ExtraLives > int(c.LivesMax) {
u.Character.ExtraLives = int(c.LivesMax)
}
}

u.EventLog.Add(`xp`, fmt.Sprintf(`<ansi fg="username">%s</ansi> is now <ansi fg="magenta-bold">level %d</ansi>!`, u.Character.Name, u.Character.Level))

SaveUser(*u)

events.AddToQueue(events.LevelUp{
UserId: u.UserId,
RoomId: u.Character.RoomId,
Username: u.Username,
CharacterName: u.Character.Name,
NewLevel: u.Character.Level,
StatsDelta: statsDelta,
TrainingPoints: 1,
StatPoints: 1,
LivesGained: u.Character.ExtraLives - livesBefore,
})

}
}

func (u *UserRecord) PlayMusic(musicFileOrId string) {
Expand Down
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,9 @@ func main() {
// Otherwise we end up getting flushed file saves incomplete.
wg.Wait()

// Give it a second to disaptch any final messages in the event queue
// Example: discord server shutdown
time.Sleep(1 * time.Second)
}

func handleTelnetConnection(connDetails *connections.ConnectionDetails, wg *sync.WaitGroup) {
Expand Down
16 changes: 16 additions & 0 deletions world.go
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,22 @@ func (w *World) EventLoop() {
events.DoListeners(eq.Poll())
}

//
// Player Levelup Notifications
//
eq = events.GetQueue(events.LevelUp{})
for eq.Len() > 0 {
events.DoListeners(eq.Poll())
}

//
// Death Notifications
//
eq = events.GetQueue(events.PlayerDeath{})
for eq.Len() > 0 {
events.DoListeners(eq.Poll())
}

//
// ScriptedEvents
//
Expand Down
Loading