package game import ( "fmt" "thirdcollapse/internal/combat" "thirdcollapse/internal/net" "thirdcollapse/internal/player" ) func (g *Game) doMove(sess *net.Session, dir string) { p := sess.Player.(*player.Player) exitDir := g.World.ResolveExit(dir) if exitDir == "" { sess.WriteLine("Go where?") return } room, err := g.World.LoadRoom(p.RoomID) if err != nil { sess.WriteLine("You can't move from here.") return } exitDef, ok := room.Exits[exitDir] if !ok { sess.WriteLine("You can't go that way.") return } if exitDef.Condition != nil && !g.checkCondition(sess, exitDef.Condition) { msg := exitDef.BlockedMessage if msg == "" { msg = fmt.Sprintf("The way %s is blocked.", exitDir) } sess.WriteLine(msg) return } targetID := exitDef.Room _, err = g.World.LoadRoom(targetID) if err != nil { sess.WriteLine("That path seems blocked.") return } if cs := combat.GetCombat(p.Name); cs != nil && cs.LockedTicks > 0 { sess.WriteLine(fmt.Sprintf("You are locked in combat for another %d tick%s!", cs.LockedTicks, plural(cs.LockedTicks))) return } g.stopCombat(p.Name) if p.Action != nil { g.CancelAction(p) } oldRoom := p.RoomID p.RoomID = targetID g.AccountStore.SaveCharacter(p) g.World.SeedGroundItems(p.RoomID) g.seedRoomMobs(p.RoomID) g.seedRoomObjects(p.RoomID) if g.Hub != nil { for _, other := range g.Hub.PlayersInRoom(oldRoom) { if other != sess { other.WriteLine(fmt.Sprintf("\n%s leaves to the %s.", p.Name, exitDir)) } } g.Hub.EnterRoom(sess, targetID) for _, other := range g.Hub.PlayersInRoom(targetID) { if other != sess { other.WriteLine(fmt.Sprintf("\n%s arrives.", p.Name)) } } } sess.WriteLine(fmt.Sprintf("\nYou walk %s.", exitDir)) p.ActionState = &ActionState{Type: ActionMoving, Direction: string(exitDir)} if p.OptionBool("description") { g.doLook(sess) } else { targetRoom, _ := g.World.LoadRoom(targetID) if targetRoom != nil { sess.WriteLine(targetRoom.Name) } } if p.OptionBool("automap") { g.doMap(sess) } g.RunEnterSteps(sess, targetID) } func (g *Game) seedRoomMobs(roomID int) { room, err := g.World.LoadRoom(roomID) if err != nil || len(room.Mobs) == 0 { return } g.MobStore.SeedMobs(roomID, room.Mobs) } func (g *Game) seedRoomObjects(roomID int) { room, err := g.World.LoadRoom(roomID) if err != nil { return } var ids []string for _, obj := range room.Objects { ids = append(ids, obj.ID) } g.World.EnsureObjectStates(roomID, ids) for _, obj := range room.Objects { def, err := g.ObjectStore.Load(obj.ID) if err != nil { continue } g.World.SetObjName(roomID, obj.ID, def.Name) if len(obj.WanderRooms) > 0 { g.World.SetObjWander(roomID, obj.ID, obj.WanderRooms, obj.WanderInterval) } if def.BehaviorID != "" { cfg, err := g.BehaviorStore.LoadGather(def.BehaviorID) if err == nil && cfg.DepleteTimer > 0 { g.World.SetObjDepleteTimer(roomID, obj.ID, cfg.DepleteTimer) } } } }