diff --git a/TODO b/TODO index dc9ac89..b84dfa5 100644 --- a/TODO +++ b/TODO @@ -9,13 +9,9 @@ GAME - + * fix news popup window -* change world to 2D array - -* optimise world creation & map transfer - * fix response to prolonged key presses * implement look/walk/attack modes @@ -30,6 +26,8 @@ * create help window +* remove char & colour attribute from map transfer + * generate secondary seeds to smoothen landscape * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? diff --git a/TODO b/TODO index dc9ac89..b84dfa5 100644 --- a/TODO +++ b/TODO @@ -9,13 +9,9 @@ GAME - + * fix news popup window -* change world to 2D array - -* optimise world creation & map transfer - * fix response to prolonged key presses * implement look/walk/attack modes @@ -30,6 +26,8 @@ * create help window +* remove char & colour attribute from map transfer + * generate secondary seeds to smoothen landscape * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 305fd0d..bfb46be 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -168,6 +168,7 @@ (return-from croatoan:event-case)) (#\n (croatoan:draw-menu (message-window))) ;;XXX How about moving diagonally? + ;;TODO remove the duplicated `update-ui' calls (:up (query-server "move n") (update-ui mapwin playerwin placewin newswin)) (:down (query-server "move s") @@ -177,7 +178,7 @@ (:right (query-server "move e") (update-ui mapwin playerwin placewin newswin)) ((nil) (update-ui mapwin playerwin placewin newswin)) - (otherwise (notify (string event))))))) + (otherwise (notify (string event))))))) ;;DEBUG (defun update-ui (mapwin playerwin placewin newswin) "Update all four UI elements" @@ -247,7 +248,8 @@ (defun message-window () "Return a dialog window with the last game messages." - ;;TODO complete - stop the window disappearing + ;;TODO complete - stop the window disappearing (caused by main + ;; window being drawn over this one) ;;XXX use `user-inform' instead of dialog-window? (make-instance 'croatoan:dialog-window :input-blocking t diff --git a/TODO b/TODO index dc9ac89..b84dfa5 100644 --- a/TODO +++ b/TODO @@ -9,13 +9,9 @@ GAME - + * fix news popup window -* change world to 2D array - -* optimise world creation & map transfer - * fix response to prolonged key presses * implement look/walk/attack modes @@ -30,6 +26,8 @@ * create help window +* remove char & colour attribute from map transfer + * generate secondary seeds to smoothen landscape * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 305fd0d..bfb46be 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -168,6 +168,7 @@ (return-from croatoan:event-case)) (#\n (croatoan:draw-menu (message-window))) ;;XXX How about moving diagonally? + ;;TODO remove the duplicated `update-ui' calls (:up (query-server "move n") (update-ui mapwin playerwin placewin newswin)) (:down (query-server "move s") @@ -177,7 +178,7 @@ (:right (query-server "move e") (update-ui mapwin playerwin placewin newswin)) ((nil) (update-ui mapwin playerwin placewin newswin)) - (otherwise (notify (string event))))))) + (otherwise (notify (string event))))))) ;;DEBUG (defun update-ui (mapwin playerwin placewin newswin) "Update all four UI elements" @@ -247,7 +248,8 @@ (defun message-window () "Return a dialog window with the last game messages." - ;;TODO complete - stop the window disappearing + ;;TODO complete - stop the window disappearing (caused by main + ;; window being drawn over this one) ;;XXX use `user-inform' instead of dialog-window? (make-instance 'croatoan:dialog-window :input-blocking t diff --git a/params.lisp b/params.lisp index 3b1f3fa..06dca1f 100644 --- a/params.lisp +++ b/params.lisp @@ -25,7 +25,7 @@ (defparameter *world-size* 250) ;;Milliseconds between world updates and screen refreshes -(defparameter *framerate* 1000) +(defparameter *framerate* 500) ;default: 1000 ;;Localhost defaults (defparameter *defaulthost* '("127.0.0.1" 21895)) ;default port: 21895 diff --git a/TODO b/TODO index dc9ac89..b84dfa5 100644 --- a/TODO +++ b/TODO @@ -9,13 +9,9 @@ GAME - + * fix news popup window -* change world to 2D array - -* optimise world creation & map transfer - * fix response to prolonged key presses * implement look/walk/attack modes @@ -30,6 +26,8 @@ * create help window +* remove char & colour attribute from map transfer + * generate secondary seeds to smoothen landscape * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 305fd0d..bfb46be 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -168,6 +168,7 @@ (return-from croatoan:event-case)) (#\n (croatoan:draw-menu (message-window))) ;;XXX How about moving diagonally? + ;;TODO remove the duplicated `update-ui' calls (:up (query-server "move n") (update-ui mapwin playerwin placewin newswin)) (:down (query-server "move s") @@ -177,7 +178,7 @@ (:right (query-server "move e") (update-ui mapwin playerwin placewin newswin)) ((nil) (update-ui mapwin playerwin placewin newswin)) - (otherwise (notify (string event))))))) + (otherwise (notify (string event))))))) ;;DEBUG (defun update-ui (mapwin playerwin placewin newswin) "Update all four UI elements" @@ -247,7 +248,8 @@ (defun message-window () "Return a dialog window with the last game messages." - ;;TODO complete - stop the window disappearing + ;;TODO complete - stop the window disappearing (caused by main + ;; window being drawn over this one) ;;XXX use `user-inform' instead of dialog-window? (make-instance 'croatoan:dialog-window :input-blocking t diff --git a/params.lisp b/params.lisp index 3b1f3fa..06dca1f 100644 --- a/params.lisp +++ b/params.lisp @@ -25,7 +25,7 @@ (defparameter *world-size* 250) ;;Milliseconds between world updates and screen refreshes -(defparameter *framerate* 1000) +(defparameter *framerate* 500) ;default: 1000 ;;Localhost defaults (defparameter *defaulthost* '("127.0.0.1" 21895)) ;default port: 21895 diff --git a/server/player.lisp b/server/player.lisp index b11a943..f3fd761 100644 --- a/server/player.lisp +++ b/server/player.lisp @@ -15,7 +15,8 @@ (password "") (online NIL) (human NIL) - (messages NIL)) + (messages NIL) + (last-move 0)) (defclass human (animal) ;; The game entity representing a human player diff --git a/TODO b/TODO index dc9ac89..b84dfa5 100644 --- a/TODO +++ b/TODO @@ -9,13 +9,9 @@ GAME - + * fix news popup window -* change world to 2D array - -* optimise world creation & map transfer - * fix response to prolonged key presses * implement look/walk/attack modes @@ -30,6 +26,8 @@ * create help window +* remove char & colour attribute from map transfer + * generate secondary seeds to smoothen landscape * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 305fd0d..bfb46be 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -168,6 +168,7 @@ (return-from croatoan:event-case)) (#\n (croatoan:draw-menu (message-window))) ;;XXX How about moving diagonally? + ;;TODO remove the duplicated `update-ui' calls (:up (query-server "move n") (update-ui mapwin playerwin placewin newswin)) (:down (query-server "move s") @@ -177,7 +178,7 @@ (:right (query-server "move e") (update-ui mapwin playerwin placewin newswin)) ((nil) (update-ui mapwin playerwin placewin newswin)) - (otherwise (notify (string event))))))) + (otherwise (notify (string event))))))) ;;DEBUG (defun update-ui (mapwin playerwin placewin newswin) "Update all four UI elements" @@ -247,7 +248,8 @@ (defun message-window () "Return a dialog window with the last game messages." - ;;TODO complete - stop the window disappearing + ;;TODO complete - stop the window disappearing (caused by main + ;; window being drawn over this one) ;;XXX use `user-inform' instead of dialog-window? (make-instance 'croatoan:dialog-window :input-blocking t diff --git a/params.lisp b/params.lisp index 3b1f3fa..06dca1f 100644 --- a/params.lisp +++ b/params.lisp @@ -25,7 +25,7 @@ (defparameter *world-size* 250) ;;Milliseconds between world updates and screen refreshes -(defparameter *framerate* 1000) +(defparameter *framerate* 500) ;default: 1000 ;;Localhost defaults (defparameter *defaulthost* '("127.0.0.1" 21895)) ;default port: 21895 diff --git a/server/player.lisp b/server/player.lisp index b11a943..f3fd761 100644 --- a/server/player.lisp +++ b/server/player.lisp @@ -15,7 +15,8 @@ (password "") (online NIL) (human NIL) - (messages NIL)) + (messages NIL) + (last-move 0)) (defclass human (animal) ;; The game entity representing a human player diff --git a/server/server.lisp b/server/server.lisp index ad1049f..185c13d 100644 --- a/server/server.lisp +++ b/server/server.lisp @@ -166,13 +166,34 @@ (cmd (car reqelts)) (args (cdr reqelts))) (logf 4 "SERVER: received request ~S" reqelts) - (if (member cmd (keys *API*) :test #'equalp) - ;;XXX Surely there must be a way to simplify the next few lines?! - (if (and (equalp (thread-player) "anon") - (not (or (equalp cmd "login") (equalp cmd "signup")))) - "ERROR: not logged in" - (apply (cassoc cmd *API* :test #'equalp) args)) - "ERROR: unknown command"))) + ;; Make sure the request is valid + (cond ((not (member cmd (keys *API*) :test #'equalp)) + "ERROR: unknown command") + ((and (equalp (thread-player) "anon") + (not (or (equalp cmd "login") (equalp cmd "signup")))) + "ERROR: not logged in") + ((eq (third (assoc cmd *API* :test #'equalp)) 'ACTION) + ;; Make sure each player only executes one action per turn + ;;XXX This needs some more thinking about + (symbol-macrolet ((age (age-of-the-world)) + (am (player-last-move + (get-player (thread-player))))) + (if (< am age) + (progn (setf am age) + (apply (cassoc cmd *API* :test #'equalp) args)) + (progn (logf 4 "SERVER: dropped request") "")))) + (T (apply (cassoc cmd *API* :test #'equalp) args))))) + + ;; (if (member cmd (keys *API*) :test #'equalp) + ;; ;;XXX Surely there must be a way to simplify the next few lines?! + ;; ;; `cond'?! + ;; (if (and (equalp (thread-player) "anon") + ;; (not (or (equalp cmd "login") (equalp cmd "signup")))) + ;; "ERROR: not logged in" + ;; (if (eq (third (assoc cmd *API* :test #'equalp)) 'ACTION) + ;; (if () + ;; (apply (cassoc cmd *API* :test #'equalp) args)) + ;; "ERROR: unknown command"))) ;;; COMMUNICATION FUNCTIONS @@ -291,12 +312,14 @@ (defparameter *API* ;; An alist of API commands and their corresponding functions + ;; The third symbol designates the request type ;;XXX move all listed functions to another file? - (list (list "login" #'login) - (list "signup" #'create-player) - (list "map" #'get-map) - (list "describe-patch" #'describe-patch) - (list "describe-player" #'describe-player) - (list "move" #'move-player) + (list (list "login" #'login 'CONNECTION) + (list "signup" #'create-player 'CONNECTION) + (list "map" #'get-map 'INFORMATION) + (list "describe-patch" #'describe-patch 'INFORMATION) + (list "describe-player" #'describe-player 'INFORMATION) + (list "move" #'move-player 'ACTION) (list "messages" - #'(lambda () (collect-messages (get-player (thread-player))))))) + #'(lambda () (collect-messages (get-player (thread-player)))) + 'INFORMATION))) diff --git a/TODO b/TODO index dc9ac89..b84dfa5 100644 --- a/TODO +++ b/TODO @@ -9,13 +9,9 @@ GAME - + * fix news popup window -* change world to 2D array - -* optimise world creation & map transfer - * fix response to prolonged key presses * implement look/walk/attack modes @@ -30,6 +26,8 @@ * create help window +* remove char & colour attribute from map transfer + * generate secondary seeds to smoothen landscape * split `naledi-ya-africa` package into `naledi-server` and `naledi-client`? diff --git a/client/user-interface.lisp b/client/user-interface.lisp index 305fd0d..bfb46be 100644 --- a/client/user-interface.lisp +++ b/client/user-interface.lisp @@ -168,6 +168,7 @@ (return-from croatoan:event-case)) (#\n (croatoan:draw-menu (message-window))) ;;XXX How about moving diagonally? + ;;TODO remove the duplicated `update-ui' calls (:up (query-server "move n") (update-ui mapwin playerwin placewin newswin)) (:down (query-server "move s") @@ -177,7 +178,7 @@ (:right (query-server "move e") (update-ui mapwin playerwin placewin newswin)) ((nil) (update-ui mapwin playerwin placewin newswin)) - (otherwise (notify (string event))))))) + (otherwise (notify (string event))))))) ;;DEBUG (defun update-ui (mapwin playerwin placewin newswin) "Update all four UI elements" @@ -247,7 +248,8 @@ (defun message-window () "Return a dialog window with the last game messages." - ;;TODO complete - stop the window disappearing + ;;TODO complete - stop the window disappearing (caused by main + ;; window being drawn over this one) ;;XXX use `user-inform' instead of dialog-window? (make-instance 'croatoan:dialog-window :input-blocking t diff --git a/params.lisp b/params.lisp index 3b1f3fa..06dca1f 100644 --- a/params.lisp +++ b/params.lisp @@ -25,7 +25,7 @@ (defparameter *world-size* 250) ;;Milliseconds between world updates and screen refreshes -(defparameter *framerate* 1000) +(defparameter *framerate* 500) ;default: 1000 ;;Localhost defaults (defparameter *defaulthost* '("127.0.0.1" 21895)) ;default port: 21895 diff --git a/server/player.lisp b/server/player.lisp index b11a943..f3fd761 100644 --- a/server/player.lisp +++ b/server/player.lisp @@ -15,7 +15,8 @@ (password "") (online NIL) (human NIL) - (messages NIL)) + (messages NIL) + (last-move 0)) (defclass human (animal) ;; The game entity representing a human player diff --git a/server/server.lisp b/server/server.lisp index ad1049f..185c13d 100644 --- a/server/server.lisp +++ b/server/server.lisp @@ -166,13 +166,34 @@ (cmd (car reqelts)) (args (cdr reqelts))) (logf 4 "SERVER: received request ~S" reqelts) - (if (member cmd (keys *API*) :test #'equalp) - ;;XXX Surely there must be a way to simplify the next few lines?! - (if (and (equalp (thread-player) "anon") - (not (or (equalp cmd "login") (equalp cmd "signup")))) - "ERROR: not logged in" - (apply (cassoc cmd *API* :test #'equalp) args)) - "ERROR: unknown command"))) + ;; Make sure the request is valid + (cond ((not (member cmd (keys *API*) :test #'equalp)) + "ERROR: unknown command") + ((and (equalp (thread-player) "anon") + (not (or (equalp cmd "login") (equalp cmd "signup")))) + "ERROR: not logged in") + ((eq (third (assoc cmd *API* :test #'equalp)) 'ACTION) + ;; Make sure each player only executes one action per turn + ;;XXX This needs some more thinking about + (symbol-macrolet ((age (age-of-the-world)) + (am (player-last-move + (get-player (thread-player))))) + (if (< am age) + (progn (setf am age) + (apply (cassoc cmd *API* :test #'equalp) args)) + (progn (logf 4 "SERVER: dropped request") "")))) + (T (apply (cassoc cmd *API* :test #'equalp) args))))) + + ;; (if (member cmd (keys *API*) :test #'equalp) + ;; ;;XXX Surely there must be a way to simplify the next few lines?! + ;; ;; `cond'?! + ;; (if (and (equalp (thread-player) "anon") + ;; (not (or (equalp cmd "login") (equalp cmd "signup")))) + ;; "ERROR: not logged in" + ;; (if (eq (third (assoc cmd *API* :test #'equalp)) 'ACTION) + ;; (if () + ;; (apply (cassoc cmd *API* :test #'equalp) args)) + ;; "ERROR: unknown command"))) ;;; COMMUNICATION FUNCTIONS @@ -291,12 +312,14 @@ (defparameter *API* ;; An alist of API commands and their corresponding functions + ;; The third symbol designates the request type ;;XXX move all listed functions to another file? - (list (list "login" #'login) - (list "signup" #'create-player) - (list "map" #'get-map) - (list "describe-patch" #'describe-patch) - (list "describe-player" #'describe-player) - (list "move" #'move-player) + (list (list "login" #'login 'CONNECTION) + (list "signup" #'create-player 'CONNECTION) + (list "map" #'get-map 'INFORMATION) + (list "describe-patch" #'describe-patch 'INFORMATION) + (list "describe-player" #'describe-player 'INFORMATION) + (list "move" #'move-player 'ACTION) (list "messages" - #'(lambda () (collect-messages (get-player (thread-player))))))) + #'(lambda () (collect-messages (get-player (thread-player)))) + 'INFORMATION))) diff --git a/server/world.lisp b/server/world.lisp index 0b233e7..012366c 100644 --- a/server/world.lisp +++ b/server/world.lisp @@ -53,16 +53,6 @@ (setf (aref world y x) (make-patch :pos (list x y))))))) -(defun init-matrix-old (size) - "Create a square matrix of empty patches" - ;;TODO change this to arrays for performance - (logf 4 "~&Creating a ~S/~S matrix." size size) - (do ((y 0 (1+ y)) (world NIL) (row NIL NIL)) - ((= y size) world) - (dotimes (x size) - (setf row (append row (list (make-patch :pos (list x y)))))) - (setf world (append world (list row))))) - (defun distance (x1 y1 x2 y2 &optional (pythag NIL)) "Find the distance between two sets of coordinates" (if pythag (round (sqrt (+ (expt (- x1 x2) 2) (expt (- y1 y2) 2))))