aboutsummaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/action/behavior.go1
-rw-r--r--internal/game/action_default_target.go79
-rw-r--r--internal/game/action_gather.go8
-rw-r--r--internal/game/game.go19
4 files changed, 103 insertions, 4 deletions
diff --git a/internal/action/behavior.go b/internal/action/behavior.go
index a3c8802..4ffd7e5 100644
--- a/internal/action/behavior.go
+++ b/internal/action/behavior.go
@@ -9,6 +9,7 @@ type GatherConfig struct {
Bait string `yaml:"bait"`
Success SuccessFormula `yaml:"success"`
GatherMsg string `yaml:"gather_message"`
+ DepletedMessage string `yaml:"depleted_message"`
FailMsg string `yaml:"fail_message"`
Drops []DropEntry `yaml:"drops"`
DepleteDelay int `yaml:"deplete_delay"`
diff --git a/internal/game/action_default_target.go b/internal/game/action_default_target.go
new file mode 100644
index 0000000..45060cc
--- /dev/null
+++ b/internal/game/action_default_target.go
@@ -0,0 +1,79 @@
+package game
+
+import (
+ "strings"
+)
+
+func verbToSkill(verb string) string {
+ switch verb {
+ case "mine":
+ return "mining"
+ case "chop", "cut":
+ return "woodcutting"
+ case "fish":
+ return "fishing"
+ }
+ return ""
+}
+
+func (g *Game) resolveDefaultTarget(roomID int, verb string) string {
+ skill := verbToSkill(verb)
+ if skill == "" {
+ return ""
+ }
+
+ objStates := g.World.AllObjInstances(roomID)
+
+ type candidate struct {
+ defID string
+ name string
+ }
+ var candidates []candidate
+ seen := make(map[string]bool)
+
+ for _, st := range objStates {
+ if seen[st.DefID] {
+ continue
+ }
+ seen[st.DefID] = true
+
+ objDef, err := g.ObjectStore.Load(st.DefID)
+ if err != nil || objDef.BehaviorID == "" {
+ continue
+ }
+
+ bh, err := g.BehaviorStore.Load(objDef.BehaviorID)
+ if err != nil || bh.Type != "gather" {
+ continue
+ }
+
+ cfg, err := g.BehaviorStore.LoadGather(objDef.BehaviorID)
+ if err != nil {
+ continue
+ }
+
+ if strings.EqualFold(cfg.Skill, skill) {
+ candidates = append(candidates, candidate{defID: st.DefID, name: objDef.Name})
+ }
+ }
+
+ if len(candidates) == 1 {
+ return candidates[0].name
+ }
+ return ""
+}
+
+func (g *Game) resolveDefaultMob(roomID int) string {
+ mobs := g.MobStore.MobsInRoom(roomID)
+ if len(mobs) == 0 {
+ return ""
+ }
+
+ firstDef := mobs[0].DefID
+ for _, m := range mobs[1:] {
+ if m.DefID != firstDef {
+ return ""
+ }
+ }
+ return mobs[0].Name
+}
diff --git a/internal/game/action_gather.go b/internal/game/action_gather.go
index 62637c3..2ca2e82 100644
--- a/internal/game/action_gather.go
+++ b/internal/game/action_gather.go
@@ -26,7 +26,13 @@ func (g *Game) startGather(sess *net.Session, p *player.Player, obj *object.Obje
}
if st.Depleted {
- if cfg.SharedDeplete > 0 {
+ if cfg.DepletedMessage != "" {
+ msg := cfg.DepletedMessage
+ if p.OptionBool("depletion") {
+ msg += fmt.Sprintf(" (%d ticks to respawn)", st.DepleteTimer)
+ }
+ sess.WriteLine(msg)
+ } else if cfg.SharedDeplete > 0 {
sess.WriteLine(fmt.Sprintf("The %s has been cut down for %d more ticks.", obj.Name, st.DepleteTimer))
} else {
sess.WriteLine(fmt.Sprintf("The %s is depleted for %d more ticks.", obj.Name, st.DepleteTimer))
diff --git a/internal/game/game.go b/internal/game/game.go
index 8151877..cc187a7 100644
--- a/internal/game/game.go
+++ b/internal/game/game.go
@@ -100,7 +100,8 @@ func (g *Game) handleGameCommand(sess *net.Session, input string) {
return
}
- if p, ok := sess.Player.(*player.Player); ok {
+ p, _ := sess.Player.(*player.Player)
+ if p != nil {
g.cancelRest(p.Name)
}
@@ -153,7 +154,13 @@ func (g *Game) handleGameCommand(sess *net.Session, input string) {
}
case "attack", "kill":
if len(args) == 0 {
- sess.WriteLine("Attack what?")
+ target := g.resolveDefaultMob(p.RoomID)
+ if target == "" {
+ sess.WriteLine("Attack what?")
+ break
+ }
+ g.doAttack(sess, target)
+ return
} else {
g.doAttack(sess, strings.Join(args, " "))
return
@@ -209,7 +216,13 @@ func (g *Game) handleGameCommand(sess *net.Session, input string) {
}
case "mine", "chop", "fish", "cut", "use", "pull", "push":
if len(args) == 0 {
- sess.WriteLine(fmt.Sprintf("%s what?", cmd))
+ target := g.resolveDefaultTarget(p.RoomID, cmd)
+ if target == "" {
+ sess.WriteLine(fmt.Sprintf("%s what?", cmd))
+ break
+ }
+ g.StartAction(sess, cmd, target)
+ return
} else {
g.StartAction(sess, cmd, strings.Join(args, " "))
return