;;;; Copyright © 2023, Jaidyn Ann ;;;; ;;;; This program is free software: you can redistribute it and/or ;;;; modify it under the terms of the GNU General Public License as ;;;; published by the Free Software Foundation, either version 3 of ;;;; the License, or (at your option) any later version. ;;;; ;;;; This program is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;;;; GNU General Public License for more details. ;;;; ;;;; You should have received a copy of the GNU General Public License ;;;; along with this program. If not, see . ;;;; FLORA-SEARCH-AURORA ;;;; 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) (:use :cl :flora-search-aurora.input :flora-search-aurora.display :flora-search-aurora.overworld :flora-search-aurora.dialogue :flora-search-aurora.ui)) (in-package :flora-search-aurora) (defvar *casino-map* nil) (defvar *outdoors-map* nil) ;;; ——————————————————————————————————— ;;; Trans-map entity interactions ;;; ——————————————————————————————————— (defun take-item (map entity-id) "Take an entity from the MAP :ENTITIES and place it in the player’s pockets. That is, into MAP’s :ITEMS." (let ((item-plist (cdr (getf-entity map entity-id)))) (when item-plist (setf (aget-item map entity-id) item-plist) (removef-entity map entity-id)))) (defun take-item-dialogue (item-plist) "Return some dialogue expressing surprise/dread or whatever at the collection of a new item. The attributes set for the entity item should be: ID NAME-[EO|EN] DESC-[EO|EN] ADJECTIVE-[EO|EN] REACTION-FACE REACTION-TALKING All are optional, save ID." (start-dialogue (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")) :eo (format nil "(Ho, jen ~A! ~A!)" (or (getf item-plist :name-eo) (getf item-plist :id)) (or (getf item-plist :adjective-eo) "Interese"))) (mumble 'player :en (if (getf item-plist :desc-en) (format nil "~~~~ ~A ~~~~" (getf item-plist :desc-en)) "(I'm glad I found it.)") :eo (if (getf item-plist :desc-eo) (format nil "~~~~ ~A ~~~~" (getf item-plist :desc-eo)) "(Kia bonŝanco!)")))) (defun take-item-interact (map interactee-id) "Try to “pick up” the interactee entity, then have the player react to the pickup. See TAKE-ITEM-DIALOGUE for customizing the reaction dialogue. Should be the `interact` function for takeable items." (let ((item-plist (cdr (getf-entity map interactee-id)))) (when (take-item map interactee-id) (make-dialogue-state map (take-item-dialogue item-plist))))) ;;; ——————————————————————————————————— ;;; The Outside World™ ;;; ——————————————————————————————————— (load "res/maps/outdoors.tmx.lisp") (defun casino-entrance-trigger (&optional map) (list :map (🌍:merge-maps map *casino-map*))) ;;; ——————————————————————————————————— ;;; Childhood friend (Sasha) arc ;;; ——————————————————————————————————— (defun childhood-friend-greetings (map) (…:incf-0 (getf-act map :sasha-greetings)) (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<") (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 "V<" ">O<") (say gambler :eo "Tiom amuze! Bona ŝerco!" :en "Shit that's funny!" :face ">V<") (face 'player "^^\"") (say gambler :eo "Mi tute ruinigis mian vivon! MDR!" :en "I totally fucked my life! LMAO!" :face ">V<") (face 'player "o-o" "ouo") (say gambler :en "HAHAHAHAHAHAHAHAHAHAAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAAHAHAHAHAHAHAHAHAHAHAHAHA") (face gambler "=w=" "=w=") (mumble gambler :en "...") (mumble gambler :eo "Fek'." :en "Fuck."))) (1 (start-dialogue (say 'player :eo "Ĉu... ĉio enordas, samideano?" :en "Everything alright, friend..?") (say gambler :eo "Jes! Tutorde! Bonas!" :en "Yup! For sure! All good!") (say gambler :eo "Mi simple trafis iujn monproblemojn, ne problemas." :en "I've just hit a slight snag financially, it's no problem.") (say gambler :eo "Nur povas ne repagi monprunton." :en "I just can't repay my mortgage.") (say gambler :eo "... kiun mi pruntis por repagi alian monprunton." :en "... that I took out to pay back a loan.") (say gambler :eo "... kiun mi pruntis por subteni la kompanion de mia frato." :en "... that I borrowed to support my bro's company.") (say gambler :eo "... kiu estas senpaga lernejo por handikapuloj." :en "... that's a non-profit school for disabled kids.") (say gambler :eo "... danke al kiu mia filino povas edukiĝi bone." :en "... thanks to which my daughter can receive a good education.") (say gambler :eo "Kial mi forĵetis la monon tie ĉi?! FEK'!!" :en "Why'd I waste it all here?! FUCK!!" :face ">O<"))) (2 (start-dialogue (say gambler :eo "Nu, ĉio enordas! Ni simple perdos la domon, jen ĉio." :en "Anyways, all good! We'll just lose the house, that's all.") (say gambler :eo "Kompreneble, perdinte la domon, mia edzino lasos min, kunprenante la gefilojn..." :en "Obviously, after losing the house, my wife'll take leave with the kids...") (say gambler :eo "Dommastrino sen domo ja ne sencas, do!" :en "A house-mistress without a house is no mistress at all, of course!") (say gambler :eo "Kaj kromvirino sen edzino ja ne sencas, do lasos min ankaŭ ŝi..." :en "And a side-piece without a 'main-piece' is no side-piece at all, so she'll leave me too...") (say gambler :eo "Neniu mono, neniu domo, neniu filo, neniu edzino, neniu kromvirino!" :en "No money, no house, no children, no wife, no mistress!") (say gambler :eo "Neniu vivo!" :en "No life!"))) (3 (start-dialogue (say gambler :eo "Mi cedu al la vakuo. Tre komfortas ĉe la fundo, kamarado." :en "I'm giving into the void. It's quite peaceful down here, pal.") (say gambler :eo "Mi lasu min falu entute, ĉu ne, kara amiko? Ĉu neee?" :en "I should let go, right, pal? Righttt?") (face 'player ";w;" ";o;") (say 'player :eo "Ne tro senesperu -- sinjoro, restas al vi fuĝvojo, sendube!" :en "Guy, there's still hope for you, somewhere!") (face gambler "=v=" "=v=") (say gambler :eo "Mi ideas IAN fuĝvojon..." :en "Five feet under, maybe...")))))) (defun bad-gambler-partings (map) (let ((messages '((:eo "... kaj ŝiaj mamoj tiom belis..." :en "... her titties were so nice, too...") (:eo "... vakuo, nenio, detruo..." :en "... emptiness, nothing, destruction...") (:eo "... vivo, bruo. morto, paco..." :en "... life, noise. death, peace...") (:eo "... laco, kaco, maĉo-veneno..." :en "... tired, weary, dreary...") (:eo "... tempo, tik-tok, malfruo..." :en "... time, tick-tock, too late...") (:eo "... finiĝo, ĉesiĝo, paciĝo..." :en "... endings, partings, peace-ings...")))) (start-dialogue (apply #'say (append '("bad-gambler") (nth (random (length messages)) messages)))))) (defun bad-gambler-dialogue (map) (let ((greetings (getf-act map :gambler-greetings))) (cond ((or (not greetings) (< greetings 3)) (bad-gambler-greetings map)) ('t (bad-gambler-partings))))) (defun bad-gambler-interact (map &optional interactee-id) (make-dialogue-state map (bad-gambler-dialogue map))) ;;; ——————————————————————————————————— ;;; Main-menu data ;;; ——————————————————————————————————— (defparameter *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)))) ;;; ——————————————————————————————————— ;;; Invocation station! 🚆 ;;; ——————————————————————————————————— (defun main () "A pathetic fascimile of a main loop. What does it do? WHAST DOES TI DODOO? What a mysteryyy! You’ll have to check out the engine to uncover it. engine.lisp, that is. Cheers! :D" (⚙:main (list (📋:make-menu-state *main-menu*)))) (main) ;; — Knock-knock ;; — Who’s there? ;; — Yo momma! ;; — “Yo momma” who? ;; — Yo momma’s a sweet lady, and I’d like to take her out for some tea!