// move implements the directional movement commands. This allows movement from // location to location by typing a direction such as N or North. // // TODO: Modify command so that it can handle buffering of multiple location // broadcasts. func (b *Basic) move(cmd *command.Command, d direction) (handled bool) { if to := b.directionalExits[d]; to != nil { if !cmd.CanLock(to) { cmd.AddLock(to) return true } b.Remove(cmd.Issuer) // If the location is crowded you are not going to notice someone leaving if !b.Crowded() { b.Broadcast([]thing.Interface{cmd.Issuer}, "[YELLOW]You see %s go %s.", cmd.Issuer.Name(), directionLongNames[d]) } to.Add(cmd.Issuer) // If the location is crowded you are not going to notice someone entering if !to.Crowded() { to.Broadcast([]thing.Interface{cmd.Issuer}, "[YELLOW]You see %s walk in.", cmd.Issuer.Name()) } to.look(cmd) } else { cmd.Respond("[RED]You can't go %s from here!", directionLongNames[d]) } return true }
// parseStage2 is called by Parse to take advantage of defer unwinding. By // splitting the parsing we can easily obtain the locks we want and defer the // unlocking. This makes both Parse and parseStage2 very simple. func (p *Player) parseStage2(cmd *command.Command) (retry bool) { for _, l := range cmd.Locks { l.Lock() defer l.Unlock() } // If player moved before we locked we need to retry if !cmd.CanLock(p.Locate()) { return true } handled := p.Process(cmd) retry = cmd.LocksModified() if !handled && !retry { cmd.Respond("[RED]Eh?") } if !retry { cmd.Flush() } return }