;;;; Mapping.
;;;; This file implements mapping and movement ("speedwalking") commands
;;;; similar to those found in tintin. Once mapping is enabled with /mark,
;;;; all movement commands (n,s,e,w,ne,sw,nw,se,u,d) will be remembered in
;;;; your "path".
;;;; usage:
;;; /map
Add to remembered path.
;;; /mark Reset path and enable mapping.
;;; /path Display remembered path.
;;; /revert Move in the opposite direction of the last remembered
;;; movement, and remove that last movement from the path.
;;; /savepath Create a macro to execute the current path.
;;; Note: macro is not written to a file.
;;; /unpath Remove the last movement from the path.
;;; /unmark Disable maping.
;;; /dopath Execute , where is a space-separated list
;;; of commands with optional repeat counts. E.g.,
;;; "/dopath 10 n 3 e d 2 w" will execute "n" 10
;;; times, "e" 3 times, "d" once, and "w" twice.
;/~loaded map.tf
/eval /set path=%{path-}
/def -i mark = \
/echo -e %% Will start mapping here.%;\
/set path=%;\
; note: _map_hook can also be called from speedwalk.tf.
/def -iFp9999 -mglob -h'send {n|s|e|w|ne|sw|nw|se|u|d}' _map_hook = \
/let op=$$(/opposite_path %%{1})%%;\
/let last=$$(/last %%path)%%;\
/if (last !~ op) \
/map %%*%%;\
/else \
/set path=$$(/all_but_last %%path)%%;\
/endif%%;\
/longmap %%* %;\
; _map_send catches and sends anything _map_hook caught, unless there was
; a non-fall-thru hook of intermediate priority that blocked it.
; note: _map_send is tested by speedwalk.tf.
/def -i -mglob -h'send {n|s|e|w|ne|sw|nw|se|u|d}' _map_send = \
/send %%*
/def -i longmap = /set longpath=%longpath %1
/def -i map = /set path=%path %1
/def -i unmark =\
/set path=%;\
/undef _map_hook%;\
/undef _map_send%;\
/echo -e %% Mapping disabled.
/def -i path = /echo -e %% Path: %path
/def -i savepath= /def -i %1 = /dopath %path
/def -i dopath = \
/if (speed_enabled == 1) \
/speedwalk %;\
/endif%;\
/if ( {1} =/ '[0-9]*' & {#} >= 2 ) \
/for i 1 %1 %2%;\
/dopath %-2%;\
/elseif ({#}) \
%1%;\
/dopath %-1%;\
/endif%;\
/if (speed_enabled != 1) \
/speedwalk %;\
/endif
/def -i reversepath = \
/if ( {1} =/ '[0-9]*' & {#} >= 2 ) \
/for i 1 %1 $(/opposite_path %2)%;\
/reversepath %-2%;\
/elseif ({#}) \
$(/opposite_path %1) %;\
/reversepath %-1%;\
/endif
/def -i unpath = /set path=$(/all_but_last %path)
/def -i revert = \
/let dir=$(/last %path)%;\
/unpath%;\
/send $(/opposite_path %dir)
/alias setpathlen /eval /set pathlen $(/eval /eval /length %%{%{area}_path})
/alias setpathpoint /eval /set pathpoint $(/eval /length %{path})%;/eval /set pathwalked $[{pathlen}-{pathpoint}]
/def -i step = \
/let dir=$(/first %path)%;\
setpathpoint%;\
/if ( regmatch(":",dir) ) \
/send %{PL}%;\
/else \
/send %{dir} %;\
/endif%;\
/if (abagbag) bags%;/endif%;\
/set path=$(/all_but_first %path)%;\
/set revpath=%revpath $(/opposite_path %dir)
/def -i rev = /eval /dopath %{revpath}
/def -i backstep = /revert
/def -i unstep = /revert
/def -i revert_all = \
/set tmp_revert_all_len=$(/length %path) %;\
/while (tmp_revert_all_len != 0) \
/revert %; \
/set tmp_revert_all_len=$(/length %path) %;\
/done %; \
/unset tmp_revert_all_len
/def -i opposite_path = \
/if ( regmatch(":",{1}) )\
/echo %{PR}%;\
/return %{PR}%;\
/endif%;\
/if ({1} =~ "n") \
/echo s %;\
/return s %;\
/elseif ({1} =~ "s") \
/echo n %;\
/return n %;\
/elseif ({1} =~ "e") \
/echo w %;\
/return w %;\
/elseif ({1} =~ "w") \
/echo e %;\
/return e %;\
/elseif ({1} =~ "u") \
/echo d %;\
/return d %;\
/elseif ({1} =~ "d") \
/echo u %;\
/return u %;\
/elseif ({1} =~ "ne") \
/echo sw %;\
/return sw %;\
/elseif ({1} =~ "se") \
/echo nw %;\
/return nw %;\
/elseif ({1} =~ "sw") \
/echo ne %;\
/return ne %;\
/elseif ({1} =~ "nw") \
/echo se %;\
/return se %;\
/endif
/def -i length = /echo %#
/def -i all_but_last = /echo - %-L
/def -i all_but_first = /echo - %-1