(require 'diku-modes-common-defs "mud.el") ;; Mode specific stuff (beginning) (defun install-wld-keybindings (map) (define-key map "\C-ci" 'wld-insert-flags) (define-key map "\C-cr" 'wld-reset-flags) (define-key map "\C-cs" 'wld-set-flags) (define-key map "\C-cl" 'wld-door-set-level)) (defvar wld-mode-map nil "The mode map used in wld-mode.") (defvar wld-room-flags (list "FOG" "NOASTRAL" "NOSTAT" "NORELOCATE" "NOFLEE" "COUNCIL_LAIR" "GODROOM" "SAFE" "ARENA" "PRIVATE" "TUNNEL" "NO_MAGIC" "CHAOTIC" "NEUTRAL" "LAWFUL" "INDOORS" "NO_MOB" "DEATH" "DARK") "This variable contains a list of flag names (strings) used by wld-mode to determine the values of bits in room fields. If you alter wld-room-flags' value, you should alter wld-formatted-room-flags correspondingly.") (defvar wld-formatted-room-flags (list " FOG: " " NOASTRAL: " " NOSTAT: " "\nNORELOCATE: " " NOFLEE: " " COUNCIL_LAIR: " " GODROOM: " "\nSAFE: " " ARENA: " " PRIVATE: " " TUNNEL: " "\nNO_MAGIC: " " CHAOTIC: " " NEUTRAL: " " LAWFUL: " "\nINDOORS: " " NO_MOB: " " DEATH: " " DARK: ") "This variable contains a list of flag names (formatted strings) used by wld-mode to display room flags. If you alter wld-formatted-room-flags' value, you should alter wld-room-flags correspondingly.") (defvar wld-mode-hooks nil "This variable contains hooks that are executed after entering Diku wld mode.") (defvar wld-door-flags (list "ANTI_EVIL" "ANTI_NEUTRAL" "ANTI_GOOD" "SECRET" "NO_MAGIC" "NO_MOUNT" "LEVEL_32" "LEVEL_16" "LEVEL_8" "LEVEL_4" "LEVEL_2" "LEVEL_1" "MIN" "PICKPROOF" "RSLOCKED" "RSCLOSED" "LOCKED" "CLOSED" "ISDOOR") "This variable contains a list of flag names (strings) used by wld-mode to determine the values of bits in door fields. If you alter wld-door-flags' value, you should alter wld-formatted-door-flags correspondingly.") (defvar wld-formatted-door-flags (list " ANTI_EVIL: " " ANTI_NEUTRAL: " " ANTI_GOOD: " "\nSECRET: " " NO_MAGIC: " " NO_MOUNT: " " LEVEL_32: " "\nLEVEL_16: " " LEVEL_8: " " LEVEL_4: " " LEVEL_2: " "\nLEVEL_1: " " MIN: " " PICKPROOF: " " RSLOCKED: " "\nRSCLOSED: " " LOCKED: " " CLOSED: " " ISDOOR ") "This variable contains a list of flag names (formatted strings) used by wld-mode to display door fields. If you alter wld-formatted-door-flags' value, you should alter wld-door-flags correspondingly.") (cond ((not wld-mode-map) (setq wld-mode-map (make-sparse-keymap)) (install-wld-keybindings wld-mode-map))) (defun wld-mode() " Major mode for editing Diku .wld-files. By Jan Garefelt, d90-jga@nada.kth.se. Distributed under GPL. Version: 1.0 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Check this mud out: burning.stacken.kth.se 4000 \\{wld-mode-map} As you move the point in the file, an info-window will be updated. If you place the point over a flag field, the following functions will be useful: wld-insert-flags ; Prompts for flag names or abbreviations ; of flag names and inserts the value at the ; point, replacing the old value (if any). ; ; Note that the point must be placed over a ; flag field for this function to work! wld-set-flags ; Prompts for flag names or abbreviations ; of flag names, and sets the corresponding ; flags. Replaces the old value by setting ; named flags in old flags. ; ; Note that the point must be placed over a ; flag field for this function to work! wld-reset-flags ; Prompts for flag names or abbreviations ; of flag names, and resets the corresponding ; flags. Replaces the old value by resetting ; named flags in old flags. ; ; Note that the point must be placed over a ; flag field for this function to work! wld-set-door-level ; Prompts for a level, and changes the door's ; level accordingly. ; Note that the point must be placed over a ; door field for this function to work! When you find bugs, please report them to me (d90-jga@nada.kth.se). If you like this mode, please send me a postcard (by snail-mail). Jan Garefelt Sandelsgatan 42 S-115 33 Stockholm SWEDEN " (interactive) (kill-all-local-variables) (use-local-map wld-mode-map) (setq major-mode 'wld-mode) (setq mode-name "Diku WLD") (add-hook 'post-command-hook 'wld-describe-field) (setq wld-previous-modified-tick (buffer-modified-tick)) (setq wld-previous-point (point)) (make-local-variable 'wld-previous-point) (make-local-variable 'wld-previous-modified-tick) (message "Diku WLD-mode. Type C-h m for information") (run-hooks 'wld-mode-hooks)) ;; Mode specific stuff (end) ;; User level wld-functions (beginning) (defun wld-describe-field () (interactive) (if (and (string-equal "Diku WLD" mode-name) (or (not (= (buffer-modified-tick) wld-previous-modified-tick)) (not (= wld-previous-point (point))))) (progn (mud-display-string (wld-field-description)) (setq wld-previous-point (point)) (setq wld-previous-modified-tick (buffer-modified-tick))))) (defun wld-field-description() (let ((wld-field (wld-field))) (cond ((or (string-equal "Direction" (car wld-field)) (string-equal "Door flags" (car wld-field)) (string-equal "Key" (car wld-field)) (string-equal "Sector type" (car wld-field)) (string-equal "Room flags" (car wld-field))) (cdr wld-field)) (t (car wld-field))))) (defun wld-insert-flags() "Calling wld-insert-flags results in: a) The user is prompted to enter a (space-separated) string of flag names or flag-abbreviations. b) The values of the flags are computed. c) The values are combined by bitwise-or and the result is inserted in the current buffer. If many flag names match an abbreviation, the flag corresponding to the lowest bit is selected unless otherwise stated. To select the second lowest flag matching an abbreviation one writes: .<flag abbreviation>" (interactive) (cond ((wld-at-room-flagsp) (wld-insert-room-flags)) ((wld-at-door-flagsp) (wld-insert-door-flags)) (t (error "Place the cursor on room-flags or door-flags!")))) (defun wld-set-flags() "Calling wld-set-flags results in: a) The user is prompted to enter a (space-separated) string of flag names or flag-abbreviations. b) The values of the flags are computed. c) The corresponding flags are set in the field in the buffer. If many flag names match an abbreviation, the flag corresponding to the lowest bit is selected unless otherwise stated. To select the second lowest flag matching an abbreviation one writes: .<flag abbreviation>" (interactive) (cond ((wld-at-room-flagsp) (wld-set-room-flags)) ((wld-at-door-flagsp) (wld-set-door-flags)) (t (error "Place the cursor on room-flags or door-flags!")))) (defun wld-door-set-level() (interactive) (if (wld-at-door-flagsp) (save-excursion (mud-reset-flags-in-trodden-num 8064) (mud-set-flags-in-trodden-num (lsh (logand 63 (string-to-int (read-string "Level: "))) 7))))) (defun wld-reset-flags() "Calling wld-set-flags results in: a) The user is prompted to enter a (space-separated) string of flag names or flag-abbreviations. b) The values of the flags are computed. c) The corresponding flags are reset in the field in the buffer. If many flag names match an abbreviation, the flag corresponding to the lowest bit is selected unless otherwise stated. To select the second lowest flag matching an abbreviation one writes: .<flag abbreviation>" (interactive) (cond ((wld-at-room-flagsp) (wld-reset-room-flags)) ((wld-at-door-flagsp) (wld-reset-door-flags)) (t (error "Place the cursor on room-flags or door-flags!")))) (defun wld-insert-room-flags() (interactive) (mud-insert-flags "Insert room flags: " wld-room-flags)) (defun wld-reset-room-flags() (interactive) (mud-reset-flags "Reset room flags:" wld-room-flags) (wld-describe-field)) (defun wld-set-room-flags () (interactive) (mud-set-flags "Set room flags:" wld-room-flags)) (defun wld-insert-door-flags() (interactive) (mud-insert-flags "Insert door flags: " wld-door-flags)) (defun wld-reset-door-flags() (interactive) (mud-reset-flags "Reset door flags:" wld-door-flags)) (defun wld-set-door-flags() (interactive) (mud-set-flags "Set door flags:" wld-door-flags)) ;; User level wld-functions (end) ;; Parsing wld-files (beginning) (defun wld-field() (interactive) (save-excursion (let ((point (point)) (virtual-number (virtual-number)) (room-name (room-name)) (room-description (room-description)) (zone-number (zone-number)) (room-flags (room-flags)) (sector-type (sector-type)) (direction-or-extra-description (direction-or-extra-description))) (cond ((and (>= point virtual-number) (< point room-name)) (cons "Virtual number" nil)) ((and (>= point room-name) (< point room-description)) (cons "Room name" nil)) ((and (>= point room-description) (< point zone-number)) (cons "Room description" nil)) ((and (>= point zone-number) (< point room-flags)) (cons "Zone number" nil)) ((and (>= point room-flags) (< point sector-type)) (cons "Room flags" (wld-room-flags room-flags))) ((and (>= point sector-type) (< point direction-or-extra-description)) (cons "Sector type" (determine-sector-type sector-type))) (t (parse-direction-or-extra-description point)))))) (defun parse-direction-or-extra-description(point) (progn (let ((return-text nil)) (while (and (looking-at "D[0-5]*") (eq return-text nil)) (let ((direction-clause-beginning (point)) (direction-general-description (direction-general-description)) (direction-keyword-list (direction-keyword-list)) (direction-door-flag (direction-door-flag)) (direction-key-number (direction-key-number)) (direction-to-room (direction-to-room)) (direction-end-of (direction-end-of))) (cond ((and (>= point direction-clause-beginning) (< point direction-general-description)) (setq return-text (cons "Direction" (determine-direction direction-clause-beginning)))) ((and (>= point direction-general-description) (< point direction-keyword-list)) (setq return-text (cons "Direction general description" nil))) ((and (>= point direction-keyword-list) (< point direction-door-flag)) (setq return-text (cons "Keyword list" nil))) ((and (>= point direction-door-flag) (< point direction-key-number)) (setq return-text (cons "Door flags" (wld-door-flags direction-door-flag)))) ((and (>= point direction-key-number) (< point direction-to-room)) (setq return-text (cons "Key" (determine-key-number direction-key-number)))) ((and (>= point direction-to-room) (< point direction-end-of)) (setq return-text (cons "To room" nil))) ((looking-at "S" ) (setq return-text (cons "End of room" nil)))))) (while (and (looking-at "E") (eq return-text nil)) (let ((extra-description-beginning (point)) (extra-description-keyword-list (extra-description-keyword-list)) (extra-description-general-description (extra-description-general-description)) (extra-description-end (extra-description-end))) (cond ((and (>= point extra-description-beginning) (< point extra-description-keyword-list)) (setq return-text (cons "Extra description" nil))) ((and (>= point extra-description-keyword-list) (< point extra-description-general-description)) (setq return-text (cons "Extra description keyword list" nil))) ((and (>= point extra-description-general-description) (< point extra-description-end)) (setq return-text (cons "Extra description general description" nil))) ((looking-at "S" ) (setq return-text (cons "End of room" nil)))))) (if (null return-text) (cons "Bad end of room - try an S to end the room, D0-D5 for directions or E for extra description" nil) return-text)))) ;; Parsing wld-files: helper functions for parsing direction fields ;; (beginning) (defun direction-general-description() (progn (mud-safe-forward-char) (mud-safe-forward-char) (mud-safe-forward-char))) (defun direction-keyword-list() (progn (re-search-backward "D[0-5] " nil t) (re-search-forward "[^~]~" nil t) (mud-safe-forward-char ) (point))) (defun direction-door-flag() (progn (re-search-forward "~ " nil t) (point))) (defun direction-key-number() (progn (re-search-forward "-?[0-9]+" nil t) (mud-safe-forward-char ) (point))) (defun direction-to-room() (progn (re-search-forward "-?[0-9]+" nil t) (mud-safe-forward-char ) (point))) (defun direction-end-of() (progn (re-search-forward " " nil t) (point))) ;; Parsing wld-files: helper functions for parsing direction fields ;; (end) ;; Parsing wld-files: helper functions for parsing extra description ;; fields (beginning) (defun extra-description-keyword-list() (progn (re-search-forward " " nil t) (point))) (defun extra-description-general-description() (progn (re-search-forward "~ " nil t) (point))) (defun extra-description-end() (progn (re-search-forward "~ " nil t) (point))) ;; Parsing wld-files: helper functions for parsing extra description ;; fields (end) ;; Parsing wld-files: helper functions for field values (beginning) (defun wld-room-flags (point) (mud-flags-and-fields point wld-formatted-room-flags)) (defun determine-direction (point) (save-excursion (progn (goto-char point) (concat (cond ((looking-at "D0") "NORTH.\n") ((looking-at "D1") "EAST.\n") ((looking-at "D2") "SOUTH.\n") ((looking-at "D3") "WEST.\n") ((looking-at "D4") "UP.\n") ((looking-at "D5") "DOWN.\n") ( t "INVALID DIRECTION! ")) "\n North: D0 Up: D4 \nWest: D3 East: D1 Down: D5\n South: D2")))) (defun determine-sector-type (point) (save-excursion (progn (goto-char point) (concat (cond ((looking-at "0") "Walking indoors.\n") ((looking-at "1") "Walking in a city.\n") ((looking-at "2") "Walking in a field.\n") ((looking-at "3") "Walking in a forest.\n") ((looking-at "4") "Walking in hills.\n") ((looking-at "5") "Climbing in mountains.\n") ((looking-at "6") "Swimming.\n") ((looking-at "7") "Requires a boat.\n") ( t "Invalid sector type.\n")) "\nIndoors: 0 City: 1 Field: 2 Forest: 3 \nHills: 4 Mountains: 5 Swim: 6 Boat: 7\n")))) (defun wld-door-flags (point) (concat (concat (mud-flags-and-fields point wld-formatted-door-flags) (progn (goto-char point) (let ((wld-door-flag (logand (lsh 1 6) (mud-get-trodden-num)))) (if (not (= 0 wld-door-flag)) " Minlevel: " " Maxlevel: ")))) (progn (goto-char point) (int-to-string (logand (lsh (mud-get-trodden-num) -7) 63))))) (defun determine-key-number (point) (save-excursion (progn (goto-char point) (concat (cond ((looking-at "-1") "NO KEY HOLE.") ((looking-at "[0-9]+") "KEY NUMBER.") (t "INVALID KEY.")) "\n\nNo keyhole =-1 \nPositive number = Key number.")))) ;; Parsing wld-files: helper functions for field values (end) ;; Parsing wld-files: placing the point in fields (beginning) (defun virtual-number() (progn (forward-line) (re-search-backward "#[0-9]+" nil t) (point))) (defun room-name() (progn (re-search-forward " " nil t) (point))) (defun room-description() (progn (re-search-forward "~" nil t) (mud-safe-forward-char) (point))) (defun zone-number() (progn (re-search-forward "~" nil t) (mud-safe-forward-char) (point))) (defun room-flags() (progn (re-search-forward "[0-9]+" nil t) (mud-safe-forward-char) (point))) (defun wld-at-room-flagsp() (interactive) (string-equal (car (wld-field)) "Room flags")) (defun wld-at-door-flagsp() (interactive) (string-equal (car (wld-field)) "Door flags")) (defun sector-type() (progn (re-search-forward "[0-9]+" nil t) (mud-safe-forward-char))) (defun direction-or-extra-description() (let ((wld-direction-old-point (point))) (progn (re-search-forward "[DE]+" nil t) (backward-char) (if (>= wld-direction-old-point (point)) 0 (point))))) (defun forward-direction() (progn (re-search-forward "[^~]*~[^~]*~ [0-9]+ -?[0-9]+ -?[0-9]+ ") (point))) (defun forward-extra-description() (progn (re-search-forward "[^~]*~[^~]*~ ") (point))) ;; Parsing wld-files: placing the point in fields (end) ;; Parsing wld-files (end)