diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/action/behavior.go | 1 | ||||
| -rw-r--r-- | internal/game/action_default_target.go | 79 | ||||
| -rw-r--r-- | internal/game/action_gather.go | 8 | ||||
| -rw-r--r-- | internal/game/game.go | 19 |
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 |
