Create and ASDF system for the game

This might help cool stuff get working, later!
Maybe! :D
This commit is contained in:
Jaidyn Ann 2023-06-26 21:49:34 -05:00
parent 74d713b76d
commit 51c913a700
12 changed files with 132 additions and 123 deletions

View File

@ -96,7 +96,7 @@ If not, have some tea on me: Im paying. =w="
(defun dialogue-speaker (dialogue)
"Get the DIALOGUE-speakers corresponding identifying symbol.
Because theyre stored in strings. So we gotta, like, unstringify. Ya dig?"
(intern (string-upcase (getf dialogue :speaker))))
(getf dialogue :speaker))
@ -124,7 +124,7 @@ If FACE is NIL… guess what that does. :^)"
(defun update-speaking-face (map dialogue)
"Given a line (plist) of DIALOGUE, change speakers face to either their
talking-face or the face given by the DIALOGUE."
(let* ((speaker (intern (string-upcase (getf dialogue :speaker))))
(let* ((speaker (getf dialogue :speaker))
(new-face (appropriate-face map speaker (getf dialogue :face))))
;; Replace the face, when appropriate.
(when new-face
@ -134,7 +134,7 @@ talking-face or the face given by the DIALOGUE."
(defun update-entity-data (map dialogue)
"Given a plist of DIALOGUE, update an arbitrary bit of data in the speaker's
data, using :SET and :TO of the DIALOGUE."
(let* ((speaker (intern (string-upcase (getf dialogue :speaker))))
(let* ((speaker (getf dialogue :speaker))
(key (getf dialogue :set))
(data (getf dialogue :to)))
(when (and key data)
@ -295,7 +295,7 @@ The data returned is a list of the boxes top-left coordinate, max-column,
and max-row; for use with RENDER-STRING. Like so:
((:x X :y Y) MAX-COLUMN MAX-ROW)"
(let* ((speaker-id (dialogue-speaker dialogue))
(playerp (eq speaker-id '🌍:player))
(playerp (eq speaker-id 'player)) ;;'✿:player))
(leftp (not (🌍:getf-entity-data map speaker-id :facing-right)))
(text (getf dialogue :text))
(coords (🌍:world-coords->screen-coords (🌍:getf-entity-data map speaker-id :coords))))

16
flora-search-aurora.asd Normal file
View File

@ -0,0 +1,16 @@
(defsystem "flora-search-aurora"
:depends-on ("alexandria" "assoc-utils" "cl-charms" "cl-tiled" "str")
:build-operation "program-op"
:build-pathname "flora-search-aurora"
:entry-point "flora-search-aurora:main"
:components ((:file "util")
(:file "display")
(:file "input")
(:file "ui")
(:file "overworld.util")
(:file "overworld")
(:file "dialogue")
(:file "engine")
(:file "flora-search-aurora")
(:file "res/maps/casino.tmx")
(:file "res/maps/outdoors.tmx")))

View File

@ -17,17 +17,6 @@
;;;; A simple TUI-game made for the text-flavoured LibreJam of 2023-06!
;;;; See: https://jamgaroo.xyz/jams/2
(ql:quickload '(alexandria anaphora assoc-utils cl-charms cl-tiled str))
(load "util.lisp")
(load "input.lisp")
(load "display.lisp")
(load "ui.lisp")
(load "overworld.util.lisp")
(load "overworld.lisp")
(load "dialogue.lisp")
(load "engine.lisp")
(defpackage :flora-search-aurora
(:nicknames :fsa :)
(:export #:main)
@ -42,8 +31,6 @@
(defvar *outdoors-map* nil)
;;; ———————————————————————————————————
;;; Trans-map entity interactions
@ -68,11 +55,11 @@ of a new item. The attributes set for the entity item should be:
REACTION-TALKING
All are optional, save ID."
(start-dialogue
(face 'player (or (getf item-plist :reaction-face) "^_^")
(or (getf item-plist :reaction-talking) "^o^"))
(face 'player (or (getf item-plist :reaction-face) "^_^")
(or (getf item-plist :reaction-talking) "^o^"))
(mumble 'player :en (format nil "(Hey, it's a ~A! ~A!)"
(or (getf item-plist :name-en) (getf item-plist :id))
(or (getf item-plist :adjective-en) "Nice"))
(or (getf item-plist :name-en) (getf item-plist :id))
(or (getf item-plist :adjective-en) "Nice"))
:eo (format nil "(Ho, jen ~A! ~A!)"
(or (getf item-plist :name-eo) (getf item-plist :id))
(or (getf item-plist :adjective-eo) "Interese")))
@ -97,7 +84,7 @@ Should be the `interact` function for takeable items."
;;; ———————————————————————————————————
;;; The Outside World™
;;; ———————————————————————————————————
(load "res/maps/outdoors.tmx.lisp")
;;(load "res/maps/outdoors.tmx.lisp")
(defun casino-entrance-trigger (&optional map)
(list :map (🌍:merge-maps map *casino-map*)))
@ -109,60 +96,60 @@ Should be the `interact` function for takeable items."
;;; ———————————————————————————————————
(defun childhood-friend-greetings (map)
(:incf-0 (getf-act map :sasha-greetings))
(let ((sasha "childhood-friend"))
(let ((sasha 'childhood-friend))
(case (getf-act map :sasha-greetings)
(0
(💬:start-dialogue
(💬:mumble sasha :en "...")
(💬:say "player" :eo "Kielas apud la mar'?"
:en "How's the view?")
(💬:face "player" "<.<" "<o<")
(💬:say sasha :eo "Kielas apud la ruinoj de via viv'?"
:en "How's your trainwreck of a life?")))
(💬:mumble sasha :en "...")
(💬:say 'player :eo "Kielas apud la mar'?"
:en "How's the view?")
(💬:face 'player "<.<" "<o<")
(💬:say sasha :eo "Kielas apud la ruinoj de via viv'?"
:en "How's your trainwreck of a life?")))
(1
(start-dialogue
(mumble "player" :en "...")
(face "player" "<w<")
(say sasha :eo "Kial vi restas? Ĉu tiom solecas ke nur ideas ĝeni min?"
:en "Why are you still here? Are you so lonely you've only got me to bother?")
(face "player" ":w:" ":u:")
(mumble "player" :eo "(Ŝi parolas pri si mem, ĉu ne?)"
:en "(She's projecting, isn't she?)")))
(mumble 'player :en "...")
(face 'player "<w<")
(say sasha :eo "Kial vi restas? Ĉu tiom solecas ke nur ideas ĝeni min?"
:en "Why are you still here? Are you so lonely you've only got me to bother?")
(face 'player ":w:" ":u:")
(mumble 'player :eo "(Ŝi parolas pri si mem, ĉu ne?)"
:en "(She's projecting, isn't she?)")))
(2
(start-dialogue
(face "player" ":w:" ":o:")
(say "player" :eo "Nu... Vi staris tie ĉi senmove dum la pastintaj tri tagoj..."
:en "So... You've stood around here for three days already, you've hardly moved...")
(say sasha :eo "Pŝ! Do?! Mi simple havas multajn pripensindaĵojn! Mi tiom multe okupiĝas!"
:en "Pff! So what?! My mind's just busy! I've got a lot going on right now!"
:face "vov")
(say sasha :eo "Ne ŝajnigu vin supera al mi, dum vi mem senespere sencelas!!"
:en "Don't act all haughty when you're such an aimless loser yourself!!"
:face ">o<")
(face "player" "=w=" "=u=")
(mumble "player" :eo "Eee.. pardonu."
:en "Well... sorry.")))
(face 'player ":w:" ":o:")
(say 'player :eo "Nu... Vi staris tie ĉi senmove dum la pastintaj tri tagoj..."
:en "So... You've stood around here for three days already, you've hardly moved...")
(say sasha :eo "Pŝ! Do?! Mi simple havas multajn pripensindaĵojn! Mi tiom multe okupiĝas!"
:en "Pff! So what?! My mind's just busy! I've got a lot going on right now!"
:face "vov")
(say sasha :eo "Ne ŝajnigu vin supera al mi, dum vi mem senespere sencelas!!"
:en "Don't act all haughty when you're such an aimless loser yourself!!"
:face ">o<")
(face 'player "=w=" "=u=")
(mumble 'player :eo "Eee.. pardonu."
:en "Well... sorry.")))
(3
(start-dialogue
(say "player" :eo "Nu, vere, mia celo sufiĉe klaras al mi. Jam baldaŭ redungiĝos."
:en "I'm not too aimless, actually. I've got good job prospects, right about now."
:face "<w<")
(say sasha :eo "Mi tute ne prizorgas."
:en "I really don't care."))))))
(say 'player :eo "Nu, vere, mia celo sufiĉe klaras al mi. Jam baldaŭ redungiĝos."
:en "I'm not too aimless, actually. I've got good job prospects, right about now."
:face "<w<")
(say sasha :eo "Mi tute ne prizorgas."
:en "I really don't care."))))))
(defun childhood-friend-partings ()
(let ((partings
'((:eo "Nu? Ĝis! Adiaŭ!"
:en "Well? Bye! Ta-ta!")
(:eo "Ve! Eĉ via rigardo sentas strange!"
:en "God! The way you look at me gives me the creeps!")
(:eo "Ve! Eĉ via rigardo malkomfortigas!"
:en "God! You're such a creep!")
(:eo "Lasu! Min! Sooooola!"
:en "Leave me! The hell! Alooooone!")
(:eo "Subvermo!"
:en "Worm!"))))
(start-dialogue
(apply #'say (append '("childhood-friend")
(apply #'say (append '(childhood-friend)
(nth (random (length partings)) partings))))))
@ -183,7 +170,7 @@ Should be the `interact` function for takeable items."
;;; ———————————————————————————————————
;;; Casino!
;;; ———————————————————————————————————
(load "res/maps/casino.tmx.lisp")
;;(load "res/maps/casino.tmx.lisp")
(defun casino-exit-trigger (&optional map)
(list :map (🌍:merge-maps map *outdoors-map*)))
@ -210,7 +197,7 @@ Should be the `interact` function for takeable items."
(:eo "kaj mi diris RIKAŜIKA! DIN-DON!"
:en "and I said BAZINGA! CA-CHOW!"))))
(start-dialogue
(apply #'say (append '("boozy-lady")
(apply #'say (append '(boozy-lady)
(nth (random (length messages)) messages))))))
@ -222,32 +209,32 @@ Should be the `interact` function for takeable items."
(make-dialogue-state
map
(start-dialogue
(say "boozy-friend" :eo "Kial ŝi ĉiufoje tiom ebriiĝas?"
:en "I swear, she gets like this every time.")
(say "boozy-friend" :eo "Kia ĝeno, tiom hontindas...!"
:en "It's so embarrasing..."))))
(say 'boozy-friend :eo "Kial ŝi ĉiufoje tiom ebriiĝas?"
:en "I swear, she gets like this every time.")
(say 'boozy-friend :eo "Kia ĝeno, tiom hontindas...!"
:en "It's so embarrasing..."))))
(defun casino-attendant-interact (map &optional interactee-id)
(make-dialogue-state
map
(start-dialogue
(say "casino-attendant" :eo "Bonvenon, estimata sinjoro!"
:en "Welcome in, good sir!")
(say "casino-attendant" :eo "Ĝuu la ludadon, kaj sorto ridetu al vi!"
:en "Have fun; may lady luck blow you a kiss!"))))
(say 'casino-attendant :eo "Bonvenon, estimata sinjoro!"
:en "Welcome in, good sir!")
(say 'casino-attendant :eo "Ĝuu la ludadon, kaj sorto ridetu al vi!"
:en "Have fun; may lady luck blow you a kiss!"))))
(defun casino-bartender-interact (map &optional interactee-id)
(make-dialogue-state
map
(start-dialogue
(say "casino-bartender" :eo "Pffff, ŝi tiom amuzas!"
:en "Pffff, this broad's a riot!"
:face "xD ~")
(say "casino-bartender" :eo "Fojfoje mi ja ŝatas mian fakon, mdr."
:en "Sometimes I really do like my job. lol"
:face "=w=~"))))
(say 'casino-bartender :eo "Pffff, ŝi tiom amuzas!"
:en "Pffff, this broad's a riot!"
:face "xD ~")
(say 'casino-bartender :eo "Fojfoje mi ja ŝatas mian fakon, mdr."
:en "Sometimes I really do like my job. lol"
:face "=w=~"))))
@ -256,7 +243,7 @@ Should be the `interact` function for takeable items."
;;; ———————————————————————————————————
(defun bad-gambler-greetings (map)
(:incf-0 (getf-act map :gambler-greetings))
(let ((gambler "bad-gambler"))
(let ((gambler 'bad-gambler))
(case (getf-act map :gambler-greetings)
(0
(start-dialogue
@ -331,7 +318,7 @@ Should be the `interact` function for takeable items."
:en "Five feet under, maybe..."))))))
(defun bad-gambler-partings (map)
(defun bad-gambler-partings (&optional map)
(let ((messages
'((:eo "... kaj ŝiaj mamoj tiom belis..."
:en "... her titties were so nice, too...")
@ -346,7 +333,7 @@ Should be the `interact` function for takeable items."
(:eo "... finiĝo, ĉesiĝo, paciĝo..."
:en "... endings, partings, peace-ings..."))))
(start-dialogue
(apply #'say (append '("bad-gambler")
(apply #'say (append '(bad-gambler)
(nth (random (length messages)) messages))))))
@ -367,17 +354,19 @@ Should be the `interact` function for takeable items."
;;; ———————————————————————————————————
;;; Main-menu data
;;; ———————————————————————————————————
(defparameter *submenu* `(((LABEL :en "IDK") (selection . 100) (selected t))
((LABEL :en "GO BACK") (return . nil))))
(defun submenu ()
`(((LABEL :en "IDK") (selection . 100) (selected t))
((LABEL :en "GO BACK") (return . nil))))
(defparameter *main-menu* `(((LABEL :en "PLAY" :eo "EKLUDI")
(selection . 100) (selected . t)
(return . ,(🌍:make-overworld-state *casino-map*)))
((LABEL :en "SUBMENU" :eo "SUBMENUO")
(return . ,(📋:make-menu-state *submenu*)))
((LABEL :en "QUIT" :eo "REZIGNI")
(return . nil))))
(defun main-menu ()
`(((LABEL :en "PLAY" :eo "EKLUDI")
(selection . 100) (selected . t)
(return . ,(🌍:make-overworld-state *casino-map*)))
((LABEL :en "SUBMENU" :eo "SUBMENUO")
(return . ,(📋:make-menu-state (submenu))))
((LABEL :en "QUIT" :eo "REZIGNI")
(return . nil))))
@ -388,10 +377,9 @@ Should be the `interact` function for takeable items."
"A pathetic fascimile of a main loop. What does it do? WHAST DOES TI DODOO?
What a mysteryyy! Youll have to check out the engine to uncover it.
engine.lisp, that is. Cheers! :D"
(:main (list (📋:make-menu-state *main-menu*))))
(:main (list (🌍:make-overworld-state *casino-map*))))
(main) ;; — Knock-knock
;; — Whos there?
;; — Yo momma!
;; — “Yo momma” who?

View File

@ -225,7 +225,7 @@ Returns parameters to be used in the next invocation of OVERWORLD-STATE."
(interactee-id (car interactee))
(interaction (getf (cdr interactee) :interact)))
(if interaction
(apply (intern (string-upcase interaction)) (list map interactee-id))
(apply (string->symbol interaction) (list map interactee-id))
(list :map map))))
;; The pause-menu…
;; ((plist = input '(:modifier nil :char #\Esc)))
@ -248,7 +248,7 @@ Returns parameters to be used in the next invocation of OVERWORLD-STATE."
(let* ((coords (getf-entity-data map 'player :coords))
(trigger (trigger-at-coords map (list :x (getf coords :x) :y (getf coords :y)))))
(if (and trigger (getf trigger :function))
(apply (intern (string-upcase (getf trigger :function)))
(apply (string->symbol (getf trigger :function))
(list map))
(list :map map))))

View File

@ -65,7 +65,7 @@ character-scale world coordinates in plist form."
(when (not (tiled-rectangle-p tiled-obj))
(let ((properties (cl-tiled:properties tiled-obj)))
(append
(list (intern (string-upcase (gethash "id" properties))))
(list (string->symbol (gethash "id" properties)))
(loop for key being the hash-keys in properties
for val being the hash-values in properties
collect (intern (string-upcase key) "KEYWORD")

View File

@ -23,19 +23,32 @@
#:world-coords->screen-coords
#:world-coords-chunk
#:map->plist #:plist->map
#:string->symbol
#:save-map-to-file))
(in-package :flora-search-aurora.overworld.util)
(defun coords->symbol (x y)
(intern (format nil "~A,~A" x y)))
(intern (format nil "~A,~A" x y) "KEYWORD"))
(defun symbol->coords (coords-symbol)
(str:split #\, (symbol-name coords-symbol)))
(defun string->symbol (string)
"Given a STRING with an optionally defined package (e.g., package:symbol),
return it as an appopriate symbol."
(let* ((split (str:split ":" (string-upcase string)))
(package (when (eq (length split) 2)
(car split)))
(symbol (or (cadr split) (car split))))
(if package
(intern symbol package)
(intern symbol))))
(defun world-coords->screen-coords (world-coords &key (chunk-width 72) (chunk-height 20))
"Given a set of world coordinates, determine where this spot would be on the screen.
The world is split into screen-sized chunks to this end.

View File

@ -1,17 +0,0 @@
(ql:quickload '(alexandria cl-tiled assoc-utils str uiop))
(load "util.lisp")
(load "overworld.util.lisp")
(load "overworld.tiled.lisp")
(defun local-path (subpath)
(format nil "~A~A" (uiop:getcwd) subpath))
(mapcar
(lambda (map-name)
(🌍.::save-map-to-file
(local-path (format nil "res/maps/~A.tmx.lisp" map-name))
(overworld.tiled:load-map (local-path (format nil "res/maps/~A.tmx" map-name)))
":FLORA-SEARCH-AURORA"
(format nil "*~A-map*" map-name)))
'("casino" "outdoors"))

View File

@ -146,7 +146,7 @@
<object id="1" name="Player" type="Person" x="604.788" y="657.818">
<properties>
<property name="facing-right" type="bool" value="true"/>
<property name="id" value="player"/>
<property name="id" value="✿:player"/>
<property name="normal-face" value="^_^"/>
<property name="talking-face" value="^o^"/>
</properties>
@ -155,8 +155,8 @@
<object id="2" name="Boozy Bird" type="Person" x="230.833" y="49.3333">
<properties>
<property name="facing-right" type="bool" value="false"/>
<property name="id" value="boozy-lady"/>
<property name="interact" value="boozy-lady-interact"/>
<property name="id" value="✿:boozy-lady"/>
<property name="interact" value="✿:boozy-lady-interact"/>
<property name="normal-face" value="=///="/>
<property name="talking-face" value="=///="/>
</properties>
@ -165,8 +165,8 @@
<object id="3" name="Boozy Friend" type="Person" x="210" y="100">
<properties>
<property name="facing-right" type="bool" value="false"/>
<property name="id" value="boozy-friend"/>
<property name="interact" value="boozy-friend-interact"/>
<property name="id" value="✿:boozy-friend"/>
<property name="interact" value="✿:boozy-friend-interact"/>
<property name="normal-face" value="&lt;s&lt;"/>
<property name="talking-face" value="&lt;o&lt;"/>
</properties>
@ -175,8 +175,8 @@
<object id="4" name="Bad Gambler" type="Person" x="213.175" y="219.086">
<properties>
<property name="facing_right" type="bool" value="false"/>
<property name="id" value="bad-gambler"/>
<property name="interact" value="bad-gambler-interact"/>
<property name="id" value="✿:bad-gambler"/>
<property name="interact" value="✿:bad-gambler-interact"/>
<property name="normal-face" value=";~:"/>
<property name="talking-face" value="&gt;o&lt;"/>
</properties>
@ -185,8 +185,8 @@
<object id="5" name="Desk Attendant" type="Person" x="602" y="520.667">
<properties>
<property name="facing-right" type="bool" value="false"/>
<property name="id" value="casino-attendant"/>
<property name="interact" value="casino-attendant-interact"/>
<property name="id" value="✿:casino-attendant"/>
<property name="interact" value="✿:casino-attendant-interact"/>
<property name="normal-face" value="^3^"/>
<property name="talking-face" value="^O^"/>
</properties>
@ -195,15 +195,15 @@
<object id="6" name="Bartender" type="Person" x="75.9405" y="164.485">
<properties>
<property name="facing-right" type="bool" value="false"/>
<property name="id" value="casino-bartender"/>
<property name="interact" value="casino-bartender-interact"/>
<property name="id" value="✿:casino-bartender"/>
<property name="interact" value="✿:casino-bartender-interact"/>
<property name="normal-face" value="uvu~"/>
</properties>
<point/>
</object>
<object id="8" name="Exit" type="Trigger" x="578.776" y="663.718" width="66.8802" height="14.6666">
<properties>
<property name="function" value="casino-exit-trigger"/>
<property name="function" value="✿:casino-exit-trigger"/>
</properties>
</object>
<object id="10" name="Ring" type="Entity" x="603.68" y="620.126">
@ -212,8 +212,8 @@
<property name="adjective-eo" value="bele"/>
<property name="avatar" value="~o~"/>
<property name="desc-en" value="It shines in the moonlight, as all else is gone."/>
<property name="id" value="ring"/>
<property name="interact" value="take-item-interact"/>
<property name="id" value="✿:ring"/>
<property name="interact" value="✿:TAKE-ITEM-INTERACT"/>
<property name="name-en" value="ring"/>
<property name="name-eo" value="ringo"/>
<property name="reaction-face" value="&gt;_&lt;"/>

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

@ -250,7 +250,7 @@
<properties>
<property name="facing-right" type="bool" value="false"/>
<property name="id" value="childhood-friend"/>
<property name="interact" value="childhood-friend-interact"/>
<property name="interact" value="✿:childhood-friend-interact"/>
<property name="normal-face" value="=_="/>
<property name="talking-face" value="=o="/>
</properties>
@ -258,7 +258,7 @@
</object>
<object id="10" name="Exit" type="Trigger" x="576.601" y="340.729" width="22.3792" height="15.3923">
<properties>
<property name="function" value="casino-entrance-trigger"/>
<property name="function" value="✿:casino-entrance-trigger"/>
</properties>
</object>
</objectgroup>

View File

@ -3,6 +3,12 @@
(load "overworld.util.lisp")
(load "overworld.tiled.lisp")
(defpackage :flora-search-aurora
(:nicknames :fsa :)
(:export #:main)
(:use :cl))
(defun local-path (subpath)
(format nil "~A~A" (uiop:getcwd) subpath))

3
run.lisp Normal file
View File

@ -0,0 +1,3 @@
(ql:quickload :flora-search-aurora)
(load "res/maps/casino.tmx.lisp")
(flora-search-aurora:main)